mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
image options area
This commit is contained in:
parent
bd6614452f
commit
600d37c7c0
21 changed files with 514 additions and 9 deletions
|
@ -18,10 +18,12 @@ defmodule Philomena.Polymorphic do
|
||||||
}
|
}
|
||||||
|
|
||||||
@preloads %{
|
@preloads %{
|
||||||
"Comment" => [:user],
|
"Comment" => [:user, :image],
|
||||||
|
"Commission" => [:user],
|
||||||
|
"Conversation" => [:from, :to],
|
||||||
"Gallery" => [:creator],
|
"Gallery" => [:creator],
|
||||||
"Image" => [:user, :tags],
|
"Image" => [:user, :tags],
|
||||||
"Post" => [:user],
|
"Post" => [:user, topic: :forum],
|
||||||
"Topic" => [:forum, :user]
|
"Topic" => [:forum, :user]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ defmodule Philomena.Reports do
|
||||||
alias Philomena.Repo
|
alias Philomena.Repo
|
||||||
|
|
||||||
alias Philomena.Reports.Report
|
alias Philomena.Reports.Report
|
||||||
|
alias Philomena.Polymorphic
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of reports.
|
Returns the list of reports.
|
||||||
|
@ -49,9 +50,9 @@ defmodule Philomena.Reports do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def create_report(attrs \\ %{}) do
|
def create_report(reportable_id, reportable_type, attribution, attrs \\ %{}) do
|
||||||
%Report{}
|
%Report{reportable_id: reportable_id, reportable_type: reportable_type}
|
||||||
|> Report.changeset(attrs)
|
|> Report.creation_changeset(attrs, attribution)
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,4 +102,18 @@ defmodule Philomena.Reports do
|
||||||
def change_report(%Report{} = report) do
|
def change_report(%Report{} = report) do
|
||||||
Report.changeset(report, %{})
|
Report.changeset(report, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reindex_report(%Report{} = report) do
|
||||||
|
spawn fn ->
|
||||||
|
Report
|
||||||
|
|> where(id: ^report.id)
|
||||||
|
|> preload([:user, :admin])
|
||||||
|
|> Repo.all()
|
||||||
|
|> Polymorphic.load_polymorphic(reportable: [reportable_id: :reportable_type])
|
||||||
|
|> hd()
|
||||||
|
|> Report.index_document()
|
||||||
|
end
|
||||||
|
|
||||||
|
report
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
57
lib/philomena/reports/elasticsearch.ex
Normal file
57
lib/philomena/reports/elasticsearch.ex
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
defmodule Philomena.Reports.Elasticsearch do
|
||||||
|
def mapping do
|
||||||
|
%{
|
||||||
|
settings: %{
|
||||||
|
index: %{
|
||||||
|
number_of_shards: 5,
|
||||||
|
max_result_window: 10_000_000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mappings: %{
|
||||||
|
report: %{
|
||||||
|
_all: %{enabled: false},
|
||||||
|
dynamic: false,
|
||||||
|
properties: %{
|
||||||
|
id: %{type: "integer"},
|
||||||
|
image_id: %{type: "integer"},
|
||||||
|
created_at: %{type: "date"},
|
||||||
|
ip: %{type: "ip"},
|
||||||
|
fingerprint: %{type: "keyword"},
|
||||||
|
state: %{type: "keyword"},
|
||||||
|
user: %{type: "keyword"},
|
||||||
|
user_id: %{type: "keyword"},
|
||||||
|
admin: %{type: "keyword"},
|
||||||
|
admin_id: %{type: "keyword"},
|
||||||
|
reportable_type: %{type: "keyword"},
|
||||||
|
reportable_id: %{type: "keyword"},
|
||||||
|
open: %{type: "boolean"},
|
||||||
|
reason: %{type: "text", analyzer: "snowball"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def as_json(report) do
|
||||||
|
%{
|
||||||
|
id: report.id,
|
||||||
|
image_id: image_id(report),
|
||||||
|
created_at: report.created_at,
|
||||||
|
ip: report.ip |> to_string(),
|
||||||
|
state: report.state,
|
||||||
|
user: if(report.user, do: String.downcase(report.user.name)),
|
||||||
|
user_id: report.user_id,
|
||||||
|
admin: if(report.admin, do: String.downcase(report.admin.name)),
|
||||||
|
admin_id: report.admin_id,
|
||||||
|
reportable_type: report.reportable_type,
|
||||||
|
reportable_id: report.reportable_id,
|
||||||
|
fingerprint: report.fingerprint,
|
||||||
|
open: report.open,
|
||||||
|
reason: report.reason
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp image_id(%{reportable_type: "Image", reportable_id: image_id}), do: image_id
|
||||||
|
defp image_id(%{reportable_type: "Comment", reportable: %{image_id: image_id}}), do: image_id
|
||||||
|
defp image_id(_report), do: nil
|
||||||
|
end
|
|
@ -2,6 +2,11 @@ defmodule Philomena.Reports.Report do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
use Philomena.Elasticsearch,
|
||||||
|
definition: Philomena.Reports.Elasticsearch,
|
||||||
|
index_name: "reports",
|
||||||
|
doc_type: "report"
|
||||||
|
|
||||||
alias Philomena.Users.User
|
alias Philomena.Users.User
|
||||||
|
|
||||||
schema "reports" do
|
schema "reports" do
|
||||||
|
@ -21,6 +26,7 @@ defmodule Philomena.Reports.Report do
|
||||||
field :reportable_type, :string
|
field :reportable_type, :string
|
||||||
|
|
||||||
field :reportable, :any, virtual: true
|
field :reportable, :any, virtual: true
|
||||||
|
field :category, :string, virtual: true
|
||||||
|
|
||||||
timestamps(inserted_at: :created_at)
|
timestamps(inserted_at: :created_at)
|
||||||
end
|
end
|
||||||
|
@ -31,4 +37,25 @@ defmodule Philomena.Reports.Report do
|
||||||
|> cast(attrs, [])
|
|> cast(attrs, [])
|
||||||
|> validate_required([])
|
|> validate_required([])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def creation_changeset(report, attrs, attribution) do
|
||||||
|
report
|
||||||
|
|> cast(attrs, [:category, :reason])
|
||||||
|
|> merge_category()
|
||||||
|
|> change(attribution)
|
||||||
|
|> validate_required([:reportable_id, :reportable_type, :category, :reason, :ip, :fingerprint, :user_agent])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp merge_category(changeset) do
|
||||||
|
reason = get_field(changeset, :reason)
|
||||||
|
category = get_field(changeset, :category)
|
||||||
|
|
||||||
|
changeset
|
||||||
|
|> change(reason: joiner(category, reason))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp joiner(category, ""), do: category
|
||||||
|
defp joiner(category, nil), do: category
|
||||||
|
defp joiner(category, reason), do: category <> ": " <> reason
|
||||||
end
|
end
|
||||||
|
|
11
lib/philomena_web/controllers/image/favorites_controller.ex
Normal file
11
lib/philomena_web/controllers/image/favorites_controller.ex
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
defmodule PhilomenaWeb.Image.FavoritesController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
|
||||||
|
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true, preload: [faves: :user]
|
||||||
|
|
||||||
|
def index(conn, _params) do
|
||||||
|
render(conn, "index.html", layout: false, image: conn.assigns.image)
|
||||||
|
end
|
||||||
|
end
|
34
lib/philomena_web/controllers/image/report_controller.ex
Normal file
34
lib/philomena_web/controllers/image/report_controller.ex
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
defmodule PhilomenaWeb.Image.ReportController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias PhilomenaWeb.ReportController
|
||||||
|
alias PhilomenaWeb.ReportView
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Reports.Report
|
||||||
|
alias Philomena.Reports
|
||||||
|
|
||||||
|
plug PhilomenaWeb.FilterBannedUsersPlug
|
||||||
|
plug PhilomenaWeb.UserAttributionPlug
|
||||||
|
plug PhilomenaWeb.CaptchaPlug when action in [:create]
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, new: :show, create: :show
|
||||||
|
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true, preload: [:tags]
|
||||||
|
|
||||||
|
def new(conn, _params) do
|
||||||
|
image = conn.assigns.image
|
||||||
|
action = Routes.image_report_path(conn, :create, image)
|
||||||
|
changeset =
|
||||||
|
%Report{reportable_type: "Image", reportable_id: image.id}
|
||||||
|
|> Reports.change_report()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_view(ReportView)
|
||||||
|
|> render("new.html", reportable: image, changeset: changeset, action: action)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create(conn, params) do
|
||||||
|
image = conn.assigns.image
|
||||||
|
action = Routes.image_report_path(conn, :create, image)
|
||||||
|
|
||||||
|
ReportController.create(conn, action, image, "Image", params)
|
||||||
|
end
|
||||||
|
end
|
27
lib/philomena_web/controllers/image/reporting_controller.ex
Normal file
27
lib/philomena_web/controllers/image/reporting_controller.ex
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
defmodule PhilomenaWeb.Image.ReportingController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.DuplicateReports.DuplicateReport
|
||||||
|
alias Philomena.DuplicateReports
|
||||||
|
alias Philomena.Repo
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true, preload: [:tags]
|
||||||
|
|
||||||
|
def show(conn, _params) do
|
||||||
|
image = conn.assigns.image
|
||||||
|
|
||||||
|
dupe_reports =
|
||||||
|
DuplicateReport
|
||||||
|
|> preload([image: :tags, duplicate_of_image: :tags])
|
||||||
|
|> where([d], d.image_id == ^image.id or d.duplicate_of_image_id == ^image.id)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
changeset =
|
||||||
|
%DuplicateReport{}
|
||||||
|
|> DuplicateReports.change_duplicate_report()
|
||||||
|
|
||||||
|
render(conn, "show.html", layout: false, image: image, dupe_reports: dupe_reports, changeset: changeset)
|
||||||
|
end
|
||||||
|
end
|
89
lib/philomena_web/controllers/report_controller.ex
Normal file
89
lib/philomena_web/controllers/report_controller.ex
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
defmodule PhilomenaWeb.ReportController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Polymorphic
|
||||||
|
alias Philomena.Reports.Report
|
||||||
|
alias Philomena.Reports
|
||||||
|
alias Philomena.Repo
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
def index(conn, _params) do
|
||||||
|
user = conn.assigns.current_user
|
||||||
|
reports =
|
||||||
|
Report
|
||||||
|
|> where(user_id: ^user.id)
|
||||||
|
|> Repo.paginate(conn.assigns.scrivener)
|
||||||
|
|
||||||
|
polymorphic =
|
||||||
|
reports
|
||||||
|
|> Polymorphic.load_polymorphic(reportable: [reportable_id: :reportable_type])
|
||||||
|
|
||||||
|
reports =
|
||||||
|
%{reports | entries: polymorphic}
|
||||||
|
|
||||||
|
render(conn, "index.html", reports: reports)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Make sure that you load the resource in your controller:
|
||||||
|
#
|
||||||
|
# plug PhilomenaWeb.FilterBannedUsersPlug
|
||||||
|
# plug PhilomenaWeb.UserAttributionPlug
|
||||||
|
# plug PhilomenaWeb.CaptchaPlug when action in [:create]
|
||||||
|
# plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||||
|
|
||||||
|
def create(conn, action, reportable, reportable_type, %{"report" => report_params}) do
|
||||||
|
attribution = conn.assigns.attributes
|
||||||
|
|
||||||
|
case too_many_reports?(conn) do
|
||||||
|
true ->
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, "You may not have more than 5 open reports at a time. Did you read the reporting tips?")
|
||||||
|
|> redirect(to: "/")
|
||||||
|
|
||||||
|
_falsy ->
|
||||||
|
case Reports.create_report(reportable.id, reportable_type, attribution, report_params) do
|
||||||
|
{:ok, report} ->
|
||||||
|
Reports.reindex_report(report)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_flash(:info, "Your report has been received and will be checked by staff shortly.")
|
||||||
|
|> redirect(to: "/")
|
||||||
|
|
||||||
|
{:error, changeset} ->
|
||||||
|
# Note that we are depending on the controller that called
|
||||||
|
# us to have set up the view already (Phoenix does this)
|
||||||
|
conn
|
||||||
|
|> render("new.html", reportable: reportable, changeset: changeset, action: action)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp too_many_reports?(conn) do
|
||||||
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
|
too_many_reports_user?(user) or too_many_reports_ip?(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp too_many_reports_user?(nil), do: false
|
||||||
|
defp too_many_reports_user?(user) do
|
||||||
|
reports_open =
|
||||||
|
Report
|
||||||
|
|> where(user_id: ^user.id)
|
||||||
|
|> where([r], r.state in ["open", "in_progress"])
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
|
|
||||||
|
reports_open >= 5
|
||||||
|
end
|
||||||
|
|
||||||
|
defp too_many_reports_ip?(conn) do
|
||||||
|
attribution = conn.assigns.attributes
|
||||||
|
|
||||||
|
reports_open =
|
||||||
|
Report
|
||||||
|
|> where(ip: ^attribution[:ip])
|
||||||
|
|> where([r], r.state in ["open", "in_progress"])
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
|
|
||||||
|
reports_open >= 5
|
||||||
|
end
|
||||||
|
end
|
|
@ -114,6 +114,8 @@ defmodule PhilomenaWeb.Router do
|
||||||
scope "/filters", Filter, as: :filter do
|
scope "/filters", Filter, as: :filter do
|
||||||
resources "/spoiler_type", SpoilerTypeController, only: [:update], singleton: true
|
resources "/spoiler_type", SpoilerTypeController, only: [:update], singleton: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources "/reports", ReportController, only: [:index]
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", PhilomenaWeb do
|
scope "/", PhilomenaWeb do
|
||||||
|
@ -134,6 +136,9 @@ defmodule PhilomenaWeb.Router do
|
||||||
resources "/source_changes", Image.SourceChangeController, only: [:index]
|
resources "/source_changes", Image.SourceChangeController, only: [:index]
|
||||||
resources "/description", Image.DescriptionController, only: [:update], singleton: true
|
resources "/description", Image.DescriptionController, only: [:update], singleton: true
|
||||||
resources "/navigate", Image.NavigateController, only: [:index]
|
resources "/navigate", Image.NavigateController, only: [:index]
|
||||||
|
resources "/reports", Image.ReportController, only: [:new, :create]
|
||||||
|
resources "/reporting", Image.ReportingController, only: [:show], singleton: true
|
||||||
|
resources "/favorites", Image.FavoritesController, only: [:index]
|
||||||
end
|
end
|
||||||
scope "/tags", Tag, as: :tag do
|
scope "/tags", Tag, as: :tag do
|
||||||
resources "/autocomplete", AutocompleteController, only: [:show], singleton: true
|
resources "/autocomplete", AutocompleteController, only: [:show], singleton: true
|
||||||
|
@ -170,7 +175,7 @@ defmodule PhilomenaWeb.Router do
|
||||||
resources "/stats", StatController, only: [:index]
|
resources "/stats", StatController, only: [:index]
|
||||||
resources "/channels", ChannelController, only: [:index, :show]
|
resources "/channels", ChannelController, only: [:index, :show]
|
||||||
resources "/settings", SettingController, only: [:edit, :update], singleton: true
|
resources "/settings", SettingController, only: [:edit, :update], singleton: true
|
||||||
resources "/duplicate_reports", DuplicateReportController, only: [:index, :show]
|
resources "/duplicate_reports", DuplicateReportController, only: [:index, :show, :create]
|
||||||
|
|
||||||
get "/:id", ImageController, :show
|
get "/:id", ImageController, :show
|
||||||
# get "/:forum_id", ForumController, :show # impossible to do without constraints
|
# get "/:forum_id", ForumController, :show # impossible to do without constraints
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
= form_for @changeset, Routes.duplicate_report_path(@conn, :create), fn f ->
|
||||||
|
= hidden_input f, :image_id, value: @image.id
|
||||||
|
.field
|
||||||
|
' Delete this image and redirect to
|
||||||
|
= number_input f, :duplicate_of_image_id, class: "input", min: 0, placeholder: "image number.", required: true
|
||||||
|
= text_input f, :reason, class: "input input--separate-left", placeholder: "Explanation"
|
||||||
|
.actions
|
||||||
|
= submit "Report Duplicate", class: "button"
|
55
lib/philomena_web/templates/image/_options.html.slime
Normal file
55
lib/philomena_web/templates/image/_options.html.slime
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#image_options_area
|
||||||
|
.block__header.block__header--js-tabbed
|
||||||
|
a href="#" data-click-tab="reporting" data-load-tab=Routes.image_reporting_path(@conn, :show, @image)
|
||||||
|
i.fa.fa-exclamation-triangle>
|
||||||
|
| Report
|
||||||
|
a href="#" data-click-tab="sharing"
|
||||||
|
i.fa.fa-share>
|
||||||
|
| Share
|
||||||
|
a href="#" data-click-tab="favoriters" data-load-tab=Routes.image_favorites_path(@conn, :index, @image)
|
||||||
|
i.fa.fa-star>
|
||||||
|
| List favoriters
|
||||||
|
|
||||||
|
.block__tab.hidden data-tab="favoriters"
|
||||||
|
p Loading...
|
||||||
|
.block__tab.hidden data-tab="reporting"
|
||||||
|
p Loading...
|
||||||
|
.block__tab.hidden data-tab="sharing"
|
||||||
|
#embed_options
|
||||||
|
- source_link = if @image.source_url in [nil, ""], do: " (Original source unknown at time of posting)", else: " - [url=#{@image.source_url}]Original source[/url]"
|
||||||
|
h5 Derpibooru
|
||||||
|
p
|
||||||
|
strong> Small thumbnail
|
||||||
|
input.input#embed_small_thumbnail_tag type="text" value=">>#{@image.id}s" cols="10" readonly="readonly"
|
||||||
|
a< href="#" data-click-copy="#embed_small_thumbnail_tag"
|
||||||
|
i.fa.fa-clipboard>
|
||||||
|
| Copy
|
||||||
|
p
|
||||||
|
strong> Thumbnail
|
||||||
|
input.input#embed_thumbnail_tag type="text" value=">>#{@image.id}t" cols="10" readonly="readonly"
|
||||||
|
a< href="#" data-click-copy="#embed_thumbnail_tag"
|
||||||
|
i.fa.fa-clipboard>
|
||||||
|
| Copy
|
||||||
|
p
|
||||||
|
strong> Preview
|
||||||
|
input.input#embed_preview_tag type="text" value=">>#{@image.id}p" cols="10" readonly="readonly"
|
||||||
|
a< href="#" data-click-copy="#embed_preview_tag"
|
||||||
|
i.fa.fa-clipboard>
|
||||||
|
| Copy
|
||||||
|
h5 BBCode
|
||||||
|
p
|
||||||
|
strong> Full size BBcode
|
||||||
|
a href="#" data-click-copy="#bbcode_embed_full_tag"
|
||||||
|
i.fa.fa-clipboard>
|
||||||
|
| Copy
|
||||||
|
br
|
||||||
|
textarea.input.input--wide.input--separate-top#bbcode_embed_full_tag rows="2" cols="100" readonly="readonly"
|
||||||
|
= "[img]#{thumb_url(@image, false, :full)}[/img]\n[url=#{Routes.image_url(@conn, :show, @image)}]View on Derpibooru[/url]#{source_link}"
|
||||||
|
p
|
||||||
|
strong> Thumbnailed BBcode
|
||||||
|
a href="#" data-click-copy="#bbcode_embed_thumbnail_tag"
|
||||||
|
i.fa.fa-clipboard>
|
||||||
|
| Copy
|
||||||
|
br
|
||||||
|
textarea.input.input--wide.input--separate-top#bbcode_embed_thumbnail_tag rows="2" cols="100" readonly="readonly"
|
||||||
|
= "[img]#{thumb_url(@image, false, :medium)}[/img]\n[url=#{Routes.image_url(@conn, :show, @image)}]View on Derpibooru[/url]#{source_link}"
|
|
@ -0,0 +1,4 @@
|
||||||
|
h5 Favorited by
|
||||||
|
|
||||||
|
= for fave <- Enum.sort_by(@image.faves, & &1.user.name) do
|
||||||
|
=> link fave.user.name, to: Routes.profile_path(@conn, :show, fave.user), class: "interaction-user-list-item"
|
23
lib/philomena_web/templates/image/reporting/show.html.slime
Normal file
23
lib/philomena_web/templates/image/reporting/show.html.slime
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
a href=Routes.image_report_path(@conn, :new, @image)
|
||||||
|
button.button.button--link
|
||||||
|
i.fa.fa-exclamation-triangle>
|
||||||
|
' General reporting
|
||||||
|
|
||||||
|
.report-duplicate
|
||||||
|
- checked = Enum.any?(@dupe_reports, & &1.state == "open")
|
||||||
|
|
||||||
|
input.toggle-box id="image-dedupe" type="checkbox" checked=checked
|
||||||
|
label for="image-dedupe" Updating/merging
|
||||||
|
.toggle-box-container
|
||||||
|
.toggle-box-container__content
|
||||||
|
= if @conn.assigns.current_user do
|
||||||
|
= render PhilomenaWeb.DuplicateReportView, "_form.html", image: @image, conn: @conn, changeset: @changeset
|
||||||
|
- else
|
||||||
|
p
|
||||||
|
' You must
|
||||||
|
a> href=Routes.pow_session_path(@conn, :new) log in
|
||||||
|
' to report duplicate images.
|
||||||
|
|
||||||
|
h4 Existing duplicate reports
|
||||||
|
= render PhilomenaWeb.DuplicateReportView, "_list.html", duplicate_reports: Enum.filter(@dupe_reports, & &1.duplicate_of_image_id == @image.id)
|
||||||
|
= render PhilomenaWeb.DuplicateReportView, "_list.html", duplicate_reports: Enum.filter(@dupe_reports, & &1.image_id == @image.id)
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
= render PhilomenaWeb.ImageView, "_tags.html", image: @image, changeset: @image_changeset, conn: @conn
|
= render PhilomenaWeb.ImageView, "_tags.html", image: @image, changeset: @image_changeset, conn: @conn
|
||||||
= render PhilomenaWeb.ImageView, "_source.html", image: @image, changeset: @image_changeset, conn: @conn
|
= render PhilomenaWeb.ImageView, "_source.html", image: @image, changeset: @image_changeset, conn: @conn
|
||||||
|
= render PhilomenaWeb.ImageView, "_options.html", image: @image, conn: @conn
|
||||||
|
|
||||||
h4 Comments
|
h4 Comments
|
||||||
= cond do
|
= cond do
|
||||||
|
|
|
@ -27,7 +27,7 @@ meta name="robots" content="noindex, nofollow"
|
||||||
meta name="og:video" content=ImageView.thumb_url(image, false, :full)
|
meta name="og:video" content=ImageView.thumb_url(image, false, :full)
|
||||||
|
|
||||||
- image.image_mime_type == "image/svg+xml" and !filtered ->
|
- image.image_mime_type == "image/svg+xml" and !filtered ->
|
||||||
meta name="og:type" content="video.other"
|
meta name="og:type" content="website"
|
||||||
meta name="og:image" content=ImageView.thumb_url(image, false, :rendered)
|
meta name="og:image" content=ImageView.thumb_url(image, false, :rendered)
|
||||||
|
|
||||||
- !filtered ->
|
- !filtered ->
|
||||||
|
|
23
lib/philomena_web/templates/report/index.html.slime
Normal file
23
lib/philomena_web/templates/report/index.html.slime
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
h1 Your Reports
|
||||||
|
.block
|
||||||
|
.block__header
|
||||||
|
span.block__header__title Reports
|
||||||
|
- route = fn p -> Routes.report_path(@conn, :index, p) end
|
||||||
|
= render PhilomenaWeb.PaginationView, "_pagination.html", page: @reports, route: route, conn: @conn
|
||||||
|
|
||||||
|
.block__content
|
||||||
|
table.table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th State
|
||||||
|
th Reported Thing
|
||||||
|
th Reason
|
||||||
|
th Opened
|
||||||
|
tbody
|
||||||
|
= for r <- @reports do
|
||||||
|
tr
|
||||||
|
td class=report_row_class(r)
|
||||||
|
= pretty_state(r)
|
||||||
|
td = link_to_reported_thing(@conn, r.reportable)
|
||||||
|
td = r.reason
|
||||||
|
td = pretty_time(r.created_at)
|
53
lib/philomena_web/templates/report/new.html.slime
Normal file
53
lib/philomena_web/templates/report/new.html.slime
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
h2 Submit a report
|
||||||
|
p
|
||||||
|
strong
|
||||||
|
= link_to_reported_thing(@conn, @reportable)
|
||||||
|
|
||||||
|
.image-other
|
||||||
|
.dnp-warning
|
||||||
|
h3 Reporting Tips
|
||||||
|
ul
|
||||||
|
li
|
||||||
|
' Make sure to report for the correct
|
||||||
|
= link "rule", to: "/pages/rules"
|
||||||
|
' .
|
||||||
|
li One report per problem (mention all things affected, please).
|
||||||
|
li
|
||||||
|
strong Do not report someone just because they disagree with you. Abusing the report system is a bannable offense.
|
||||||
|
br
|
||||||
|
|
||||||
|
= if image?(@changeset) do
|
||||||
|
.dnp-warning
|
||||||
|
h3 Takedown Policy
|
||||||
|
p
|
||||||
|
strong> Only an owner of an image's rights (normally the artist) can request a takedown.
|
||||||
|
' If you're the artist, you'll
|
||||||
|
strong> need
|
||||||
|
' a verified user link.
|
||||||
|
p
|
||||||
|
' For more information, please read the
|
||||||
|
= link "takedown policy", to: "/pages/takedowns"
|
||||||
|
' .
|
||||||
|
br
|
||||||
|
|
||||||
|
= if conversation?(@changeset) do
|
||||||
|
.dnp-warning
|
||||||
|
h3 Privacy note
|
||||||
|
p
|
||||||
|
' The whole conversation will be readable by site staff.
|
||||||
|
br
|
||||||
|
|
||||||
|
= form_for @changeset, @action, fn f ->
|
||||||
|
.field
|
||||||
|
= select f, :category, report_categories(), class: "input"
|
||||||
|
.field
|
||||||
|
= textarea f, :reason, class: "input input--wide", placeholder: "Provide anything else we should know here."
|
||||||
|
|
||||||
|
= if !@conn.assigns.current_user do
|
||||||
|
.field
|
||||||
|
= checkbox f, :captcha, class: "js-captcha", value: 0
|
||||||
|
= label f, :captcha, "I am not a robot!"
|
||||||
|
p
|
||||||
|
' This helps stop bot spam; log in if you don't want to deal with captchas.
|
||||||
|
|
||||||
|
= submit "Send Report", class: "button"
|
3
lib/philomena_web/views/image/favorites_view.ex
Normal file
3
lib/philomena_web/views/image/favorites_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule PhilomenaWeb.Image.FavoritesView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
end
|
3
lib/philomena_web/views/image/reporting_view.ex
Normal file
3
lib/philomena_web/views/image/reporting_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule PhilomenaWeb.Image.ReportingView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
end
|
65
lib/philomena_web/views/report_view.ex
Normal file
65
lib/philomena_web/views/report_view.ex
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
defmodule PhilomenaWeb.ReportView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Comments.Comment
|
||||||
|
alias Philomena.Commissions.Commission
|
||||||
|
alias Philomena.Conversations.Conversation
|
||||||
|
alias Philomena.Posts.Post
|
||||||
|
alias Philomena.Users.User
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
def report_categories do
|
||||||
|
[
|
||||||
|
"Rule #0: Namecalling, trolling, discrimination": "Rule #0",
|
||||||
|
"Rule #1: DNP, content theft, pay content, trace/bad edit": "Rule #1",
|
||||||
|
"Rule #2: Bad tagging/sourcing": "Rule #2",
|
||||||
|
"Rule #3: Image not MLP-related/obligatory pony": "Rule #3",
|
||||||
|
"Rule #4: Whining about filterable content": "Rule #4",
|
||||||
|
"Rule #5: Underage+human/anthro-looking porn": "Rule #5",
|
||||||
|
"Rule #6: Spam, off-topic, or general site abuse": "Rule #6",
|
||||||
|
"Rule #7: Above topic rating (NOT swear words)": "Rule #7",
|
||||||
|
"Rule #8: Privacy violation": "Rule #8",
|
||||||
|
"Rule #9: Commissions": "Rule #9",
|
||||||
|
"Rule #n: Spirit of the rules": "Rule #n",
|
||||||
|
"Other (please explain)": "Other",
|
||||||
|
"Takedown request": "Takedown request"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def image?(changeset), do: get_field(changeset, :reportable_type) == "Image"
|
||||||
|
def conversation?(changeset), do: get_field(changeset, :reportable_type) == "Conversation"
|
||||||
|
|
||||||
|
def report_row_class(%{state: "closed"}), do: "success"
|
||||||
|
def report_row_class(%{state: "in_progress"}), do: "warning"
|
||||||
|
def report_row_class(_report), do: "danger"
|
||||||
|
|
||||||
|
def pretty_state(%{state: "closed"}), do: "Closed"
|
||||||
|
def pretty_state(%{state: "in_progress"}), do: "In progress"
|
||||||
|
def pretty_state(%{state: "claimed"}), do: "Claimed"
|
||||||
|
def pretty_state(_report), do: "Open"
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Image{} = r) when not is_nil(r),
|
||||||
|
do: link "Image >>#{r.id}", to: Routes.image_path(conn, :show, r)
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Comment{} = r) when not is_nil(r),
|
||||||
|
do: link "Comment on image >>#{r.image.id}", to: Routes.image_path(conn, :show, r.image)
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Conversation{} = r) when not is_nil(r),
|
||||||
|
do: link "Conversation between #{r.from.name} and #{r.to.name}", to: Routes.conversation_path(conn, :show, r)
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Commission{} = r) when not is_nil(r),
|
||||||
|
do: link "#{r.user}'s commission page", to: Routes.commission_path(conn, :show, r)
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Post{} = r) when not is_nil(r),
|
||||||
|
do: link "Post in #{r.topic.title}", to: Routes.forum_topic_path(conn, :show, r.topic.forum, r.topic, post_id: r.id) <> "#post_#{r.id}"
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %User{} = r) when not is_nil(r),
|
||||||
|
do: link "User '#{r.name}'", to: Routes.profile_path(conn, :show, r)
|
||||||
|
|
||||||
|
def link_to_reported_thing(_conn, report) do
|
||||||
|
IO.inspect report
|
||||||
|
"Reported item permanently destroyed."
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,12 +10,12 @@
|
||||||
# We recommend using the bang functions (`insert!`, `update!`
|
# We recommend using the bang functions (`insert!`, `update!`
|
||||||
# and so on) as they will fail if something goes wrong.
|
# and so on) as they will fail if something goes wrong.
|
||||||
|
|
||||||
alias Philomena.{Repo, Comments.Comment, Filters.Filter, Forums.Forum, Galleries.Gallery, Posts.Post, Images.Image, Tags.Tag, Users.User}
|
alias Philomena.{Repo, Comments.Comment, Filters.Filter, Forums.Forum, Galleries.Gallery, Posts.Post, Images.Image, Reports.Report, Tags.Tag, Users.User}
|
||||||
alias Philomena.Tags
|
alias Philomena.Tags
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
IO.puts "---- Creating Elasticsearch indices"
|
IO.puts "---- Creating Elasticsearch indices"
|
||||||
for model <- [Image, Comment, Gallery, Tag, Post] do # Report
|
for model <- [Image, Comment, Gallery, Tag, Post, Report] do # Report
|
||||||
model.delete_index!
|
model.delete_index!
|
||||||
model.create_index!
|
model.create_index!
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue