Compare commits
18 Commits
feature/me
...
main
Author | SHA1 | Date | |
---|---|---|---|
dec8a0660e | |||
283e25178b | |||
4cde4c8f67 | |||
d497eaa522 | |||
eb47a26de7 | |||
256c883488 | |||
6d64449c1b | |||
6751ade1d9 | |||
bf7f1a4601 | |||
bab66c8079 | |||
914246f08a | |||
0c52c18d92 | |||
cb66d127b6 | |||
ce5a011d90 | |||
8383d00335 | |||
4cc2ee8276 | |||
36d97eebec | |||
c29ae7f3e4 |
217
.credo.exs
Normal file
217
.credo.exs
Normal file
@ -0,0 +1,217 @@
|
||||
# This file contains the configuration for Credo and you are probably reading
|
||||
# this after creating it with `mix credo.gen.config`.
|
||||
#
|
||||
# If you find anything wrong or unclear in this file, please report an
|
||||
# issue on GitHub: https://github.com/rrrene/credo/issues
|
||||
#
|
||||
%{
|
||||
#
|
||||
# You can have as many configs as you like in the `configs:` field.
|
||||
configs: [
|
||||
%{
|
||||
#
|
||||
# Run any config using `mix credo -C <name>`. If no config name is given
|
||||
# "default" is used.
|
||||
#
|
||||
name: "default",
|
||||
#
|
||||
# These are the files included in the analysis:
|
||||
files: %{
|
||||
#
|
||||
# You can give explicit globs or simply directories.
|
||||
# In the latter case `**/*.{ex,exs}` will be used.
|
||||
#
|
||||
included: [
|
||||
"lib/",
|
||||
"src/",
|
||||
"test/",
|
||||
"web/",
|
||||
"apps/*/lib/",
|
||||
"apps/*/src/",
|
||||
"apps/*/test/",
|
||||
"apps/*/web/"
|
||||
],
|
||||
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
|
||||
},
|
||||
#
|
||||
# Load and configure plugins here:
|
||||
#
|
||||
plugins: [],
|
||||
#
|
||||
# If you create your own checks, you must specify the source files for
|
||||
# them here, so they can be loaded by Credo before running the analysis.
|
||||
#
|
||||
requires: [],
|
||||
#
|
||||
# If you want to enforce a style guide and need a more traditional linting
|
||||
# experience, you can change `strict` to `true` below:
|
||||
#
|
||||
strict: true,
|
||||
#
|
||||
# To modify the timeout for parsing files, change this value:
|
||||
#
|
||||
parse_timeout: 5000,
|
||||
#
|
||||
# If you want to use uncolored output by default, you can change `color`
|
||||
# to `false` below:
|
||||
#
|
||||
color: true,
|
||||
#
|
||||
# You can customize the parameters of any check by adding a second element
|
||||
# to the tuple.
|
||||
#
|
||||
# To disable a check put `false` as second element:
|
||||
#
|
||||
# {Credo.Check.Design.DuplicatedCode, false}
|
||||
#
|
||||
checks: %{
|
||||
enabled: [
|
||||
#
|
||||
## Consistency Checks
|
||||
#
|
||||
{Credo.Check.Consistency.ExceptionNames, []},
|
||||
{Credo.Check.Consistency.LineEndings, []},
|
||||
{Credo.Check.Consistency.ParameterPatternMatching, []},
|
||||
{Credo.Check.Consistency.SpaceAroundOperators, []},
|
||||
{Credo.Check.Consistency.SpaceInParentheses, []},
|
||||
{Credo.Check.Consistency.TabsOrSpaces, []},
|
||||
|
||||
#
|
||||
## Design Checks
|
||||
#
|
||||
# You can customize the priority of any check
|
||||
# Priority values are: `low, normal, high, higher`
|
||||
#
|
||||
{Credo.Check.Design.AliasUsage,
|
||||
[priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
|
||||
{Credo.Check.Design.TagFIXME, []},
|
||||
# You can also customize the exit_status of each check.
|
||||
# If you don't want TODO comments to cause `mix credo` to fail, just
|
||||
# set this value to 0 (zero).
|
||||
#
|
||||
{Credo.Check.Design.TagTODO, [exit_status: 2]},
|
||||
|
||||
#
|
||||
## Readability Checks
|
||||
#
|
||||
{Credo.Check.Readability.AliasOrder, []},
|
||||
{Credo.Check.Readability.FunctionNames, []},
|
||||
{Credo.Check.Readability.LargeNumbers, []},
|
||||
{Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
|
||||
{Credo.Check.Readability.ModuleAttributeNames, []},
|
||||
{Credo.Check.Readability.ModuleDoc, []},
|
||||
{Credo.Check.Readability.ModuleNames, []},
|
||||
{Credo.Check.Readability.ParenthesesInCondition, []},
|
||||
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
|
||||
{Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
|
||||
{Credo.Check.Readability.PredicateFunctionNames, []},
|
||||
{Credo.Check.Readability.PreferImplicitTry, []},
|
||||
{Credo.Check.Readability.RedundantBlankLines, []},
|
||||
{Credo.Check.Readability.Semicolons, []},
|
||||
{Credo.Check.Readability.SpaceAfterCommas, []},
|
||||
{Credo.Check.Readability.StringSigils, []},
|
||||
{Credo.Check.Readability.TrailingBlankLine, []},
|
||||
{Credo.Check.Readability.TrailingWhiteSpace, []},
|
||||
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
|
||||
{Credo.Check.Readability.VariableNames, []},
|
||||
{Credo.Check.Readability.WithSingleClause, []},
|
||||
|
||||
#
|
||||
## Refactoring Opportunities
|
||||
#
|
||||
{Credo.Check.Refactor.Apply, []},
|
||||
{Credo.Check.Refactor.CondStatements, []},
|
||||
{Credo.Check.Refactor.CyclomaticComplexity, []},
|
||||
{Credo.Check.Refactor.FilterCount, []},
|
||||
{Credo.Check.Refactor.FilterFilter, []},
|
||||
{Credo.Check.Refactor.FunctionArity, []},
|
||||
{Credo.Check.Refactor.LongQuoteBlocks, []},
|
||||
{Credo.Check.Refactor.MapJoin, []},
|
||||
{Credo.Check.Refactor.MatchInCondition, []},
|
||||
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
|
||||
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
|
||||
{Credo.Check.Refactor.Nesting, []},
|
||||
{Credo.Check.Refactor.RedundantWithClauseResult, []},
|
||||
{Credo.Check.Refactor.RejectReject, []},
|
||||
{Credo.Check.Refactor.UnlessWithElse, []},
|
||||
{Credo.Check.Refactor.WithClauses, []},
|
||||
|
||||
#
|
||||
## Warnings
|
||||
#
|
||||
{Credo.Check.Warning.ApplicationConfigInModuleAttribute, []},
|
||||
{Credo.Check.Warning.BoolOperationOnSameValues, []},
|
||||
{Credo.Check.Warning.Dbg, []},
|
||||
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
|
||||
{Credo.Check.Warning.IExPry, []},
|
||||
{Credo.Check.Warning.IoInspect, []},
|
||||
{Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, []},
|
||||
{Credo.Check.Warning.OperationOnSameValues, []},
|
||||
{Credo.Check.Warning.OperationWithConstantResult, []},
|
||||
{Credo.Check.Warning.RaiseInsideRescue, []},
|
||||
{Credo.Check.Warning.SpecWithStruct, []},
|
||||
{Credo.Check.Warning.UnsafeExec, []},
|
||||
{Credo.Check.Warning.UnusedEnumOperation, []},
|
||||
{Credo.Check.Warning.UnusedFileOperation, []},
|
||||
{Credo.Check.Warning.UnusedKeywordOperation, []},
|
||||
{Credo.Check.Warning.UnusedListOperation, []},
|
||||
{Credo.Check.Warning.UnusedPathOperation, []},
|
||||
{Credo.Check.Warning.UnusedRegexOperation, []},
|
||||
{Credo.Check.Warning.UnusedStringOperation, []},
|
||||
{Credo.Check.Warning.UnusedTupleOperation, []},
|
||||
{Credo.Check.Warning.WrongTestFileExtension, []}
|
||||
],
|
||||
disabled: [
|
||||
#
|
||||
# Checks scheduled for next check update (opt-in for now)
|
||||
{Credo.Check.Refactor.UtcNowTruncate, []},
|
||||
|
||||
#
|
||||
# Controversial and experimental checks (opt-in, just move the check to `:enabled`
|
||||
# and be sure to use `mix credo --strict` to see low priority checks)
|
||||
#
|
||||
{Credo.Check.Consistency.MultiAliasImportRequireUse, []},
|
||||
{Credo.Check.Consistency.UnusedVariableNames, []},
|
||||
{Credo.Check.Design.DuplicatedCode, []},
|
||||
{Credo.Check.Design.SkipTestWithoutComment, []},
|
||||
{Credo.Check.Readability.AliasAs, []},
|
||||
{Credo.Check.Readability.BlockPipe, []},
|
||||
{Credo.Check.Readability.ImplTrue, []},
|
||||
{Credo.Check.Readability.MultiAlias, []},
|
||||
{Credo.Check.Readability.NestedFunctionCalls, []},
|
||||
{Credo.Check.Readability.OneArityFunctionInPipe, []},
|
||||
{Credo.Check.Readability.OnePipePerLine, []},
|
||||
{Credo.Check.Readability.SeparateAliasRequire, []},
|
||||
{Credo.Check.Readability.SingleFunctionToBlockPipe, []},
|
||||
{Credo.Check.Readability.SinglePipe, []},
|
||||
{Credo.Check.Readability.Specs, []},
|
||||
{Credo.Check.Readability.StrictModuleLayout, []},
|
||||
{Credo.Check.Readability.WithCustomTaggedTuple, []},
|
||||
{Credo.Check.Refactor.ABCSize, []},
|
||||
{Credo.Check.Refactor.AppendSingleItem, []},
|
||||
{Credo.Check.Refactor.DoubleBooleanNegation, []},
|
||||
{Credo.Check.Refactor.FilterReject, []},
|
||||
{Credo.Check.Refactor.IoPuts, []},
|
||||
{Credo.Check.Refactor.MapMap, []},
|
||||
{Credo.Check.Refactor.ModuleDependencies, []},
|
||||
{Credo.Check.Refactor.NegatedIsNil, []},
|
||||
{Credo.Check.Refactor.PassAsyncInTestCases, []},
|
||||
{Credo.Check.Refactor.PipeChainStart, []},
|
||||
{Credo.Check.Refactor.RejectFilter, []},
|
||||
{Credo.Check.Refactor.VariableRebinding, []},
|
||||
{Credo.Check.Warning.LazyLogging, []},
|
||||
{Credo.Check.Warning.LeakyEnvironment, []},
|
||||
{Credo.Check.Warning.MapGetUnsafePass, []},
|
||||
{Credo.Check.Warning.MixEnv, []},
|
||||
{Credo.Check.Warning.UnsafeToAtom, []}
|
||||
|
||||
# {Credo.Check.Refactor.MapInto, []},
|
||||
|
||||
#
|
||||
# Custom checks can be created using `mix credo.gen.check`.
|
||||
#
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
/* This file is for your main application CSS */
|
||||
|
||||
body {
|
||||
@apply bg-base-300 text-[14pt] leading-8 overflow-x-hidden;
|
||||
@apply bg-base-300 font-['Inter'] text-[18px] leading-6 overflow-x-hidden;
|
||||
}
|
||||
|
||||
.post {
|
||||
@ -36,11 +36,14 @@ body {
|
||||
.post .code pre:before { @apply mr-0; }
|
||||
.post .code h5 { @apply hidden; }
|
||||
.post a[href] { @apply link; }
|
||||
.post .bbc-block a[href] { @apply link; }
|
||||
.post .editedby { @apply text-sm italic opacity-70 mt-4; }
|
||||
.post .title :where(img[src*="gangtags"]) + * {
|
||||
@apply mb-1;
|
||||
}
|
||||
|
||||
.post i, .post .bbc-spoiler, .post a[href] { @apply inline-block mx-1; }
|
||||
|
||||
.pagination a svg {
|
||||
@apply h-5;
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ if config_env() == :prod do
|
||||
# ssl: true,
|
||||
url: database_url,
|
||||
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
|
||||
socket_options: maybe_ipv6
|
||||
socket_options: maybe_ipv6,
|
||||
prepare: :unnamed
|
||||
|
||||
# The secret key base is used to sign/encrypt cookies and other secrets.
|
||||
# A default value is used in config/dev.exs and config/test.exs but you
|
||||
@ -48,7 +49,11 @@ if config_env() == :prod do
|
||||
You can generate one by calling: mix phx.gen.secret
|
||||
"""
|
||||
|
||||
host = System.get_env("PHX_HOST") || "example.com"
|
||||
host =
|
||||
System.get_env("PHX_HOST") ||
|
||||
"example.com"
|
||||
|> IO.inspect()
|
||||
|
||||
port = String.to_integer(System.get_env("PORT") || "4000")
|
||||
|
||||
config :something_erlang, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
|
||||
@ -63,6 +68,7 @@ if config_env() == :prod do
|
||||
ip: {0, 0, 0, 0, 0, 0, 0, 0},
|
||||
port: port
|
||||
],
|
||||
check_origin: [host],
|
||||
secret_key_base: secret_key_base
|
||||
|
||||
# ## SSL Support
|
||||
|
@ -38,7 +38,11 @@ defmodule SomethingErlang.AwfulApi.Bookmarks do
|
||||
info = Meeseeks.one(td, css(".info"))
|
||||
|
||||
%{
|
||||
new_posts: Meeseeks.text(last_seen) |> String.to_integer(),
|
||||
new_posts:
|
||||
case Meeseeks.text(last_seen) do
|
||||
nil -> 0
|
||||
n -> String.to_integer(n)
|
||||
end,
|
||||
thread_title: Meeseeks.text(Meeseeks.one(info, css(".thread_title")))
|
||||
}
|
||||
end
|
||||
|
@ -35,7 +35,11 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
||||
end
|
||||
|
||||
posts =
|
||||
for post <- Meeseeks.all(thread, css("table.post:not(.ignored)")) do
|
||||
for post <- Meeseeks.all(thread, css("table.post")),
|
||||
post
|
||||
|> Meeseeks.attr("class")
|
||||
|> String.contains?("ignored")
|
||||
|> Kernel.not() do
|
||||
%{
|
||||
userinfo: userinfo(post),
|
||||
postdate: postdate(post),
|
||||
@ -111,7 +115,11 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
||||
if class == "sa-smilie" do
|
||||
{"img", attrs, []}
|
||||
else
|
||||
t_attrs = List.keyreplace(attrs, "class", 0, {"class", "img-responsive"})
|
||||
t_attrs =
|
||||
attrs
|
||||
|> fix_attachment_links()
|
||||
|> List.keyreplace("class", 0, {"class", "img-responsive"})
|
||||
|
||||
{"img", [{"loading", "lazy"} | t_attrs], []}
|
||||
end
|
||||
end
|
||||
@ -194,4 +202,15 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
||||
{"src", src}
|
||||
], []}
|
||||
]}
|
||||
|
||||
defp fix_attachment_links(attrs) do
|
||||
{"src", src} = List.keyfind(attrs, "src", 0)
|
||||
|
||||
if String.starts_with?(src, "attachment.php") do
|
||||
List.keyreplace(attrs, "src", 0, {"src", "https://forums.somethingawful.com/" <> src})
|
||||
|> List.keydelete("alt", 0)
|
||||
else
|
||||
attrs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -17,7 +17,7 @@ defmodule SomethingErlangWeb.BookmarksLive do
|
||||
end
|
||||
|
||||
defp bookmark(assigns) do
|
||||
assigns = assign(assigns, :pages, trunc(assigns.post_count / 40))
|
||||
assigns = assign(assigns, :pages, ceil(assigns.post_count / 40))
|
||||
|
||||
~H"""
|
||||
<div>
|
||||
@ -37,6 +37,6 @@ defmodule SomethingErlangWeb.BookmarksLive do
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, "Bookmarks")
|
||||
|> assign(:bookmarks, Grover.get_bookmarks!(1) |> dbg())}
|
||||
|> assign(:bookmarks, Grover.get_bookmarks!(1))}
|
||||
end
|
||||
end
|
||||
|
@ -69,10 +69,10 @@ defmodule SomethingErlangWeb.ThreadLive do
|
||||
~H"""
|
||||
<div class="navbar my-4 bg-base-200">
|
||||
<div class="flex-1"></div>
|
||||
<div class="pagination flex-none btn-group grid grid-cols-5">
|
||||
<div class="pagination join">
|
||||
<%= for btn <- buttons(@thread) do %>
|
||||
<.link
|
||||
class={["btn btn-sm btn-ghost", btn.special]}
|
||||
class={["btn btn-sm btn-ghost join-item", btn.special]}
|
||||
navigate={~p"/thread/#{@thread.id}?page=#{btn.page}"}
|
||||
>
|
||||
<.label_button label={btn.label} page={btn.page} />
|
||||
@ -86,8 +86,8 @@ defmodule SomethingErlangWeb.ThreadLive do
|
||||
defp label_button(%{label: label} = assigns) do
|
||||
case label do
|
||||
"«" -> ~H{<.icon name="hero-chevron-double-left-mini" /><%= @page %>}
|
||||
"‹" -> ~H{<.icon name="hero-chevron-left-mini" /><%= @page %>}
|
||||
"›" -> ~H{<%= @page %><.icon name="hero-chevron-right-mini" />}
|
||||
"‹" -> ~H{<.icon name="hero-chevron-left-mini" />}
|
||||
"›" -> ~H{<.icon name="hero-chevron-right-mini" />}
|
||||
"»" -> ~H{<%= @page %><.icon name="hero-chevron-double-right-mini" />}
|
||||
_ -> ~H{<%= @page %>}
|
||||
end
|
||||
|
@ -12,6 +12,7 @@ defmodule SomethingErlangWeb.UserAuth do
|
||||
@max_age 60 * 60 * 24 * 60
|
||||
@remember_me_cookie "_something_erlang_web_user_remember_me"
|
||||
@remember_me_options [sign: true, max_age: @max_age, same_site: "Lax"]
|
||||
@bbpassword_options [sign: false, max_age: @max_age, same_site: "Lax"]
|
||||
|
||||
@doc """
|
||||
Logs the user in.
|
||||
@ -38,7 +39,7 @@ defmodule SomethingErlangWeb.UserAuth do
|
||||
end
|
||||
|
||||
defp put_hashcookie_in_session(conn, bbpassword) do
|
||||
put_resp_cookie(conn, "bbpassword", bbpassword)
|
||||
put_resp_cookie(conn, "bbpassword", bbpassword, @bbpassword_options)
|
||||
end
|
||||
|
||||
defp maybe_write_remember_me_cookie(conn, token, %{"remember_me" => "true"}) do
|
||||
@ -185,7 +186,7 @@ defmodule SomethingErlangWeb.UserAuth do
|
||||
|
||||
defp mount_current_user(session, socket) do
|
||||
case session do
|
||||
%{"user_token" => user_token} ->
|
||||
%{"user_token" => user_token, "bbpassword" => bbpw} when not is_nil(bbpw) ->
|
||||
Phoenix.Component.assign_new(socket, :current_user, fn ->
|
||||
Accounts.get_user_by_session_token(user_token)
|
||||
end)
|
||||
|
3
mix.exs
3
mix.exs
@ -59,7 +59,8 @@ defmodule SomethingErlang.MixProject do
|
||||
{:dns_cluster, "~> 0.1.1"},
|
||||
{:bandit, "~> 1.2"},
|
||||
{:meeseeks, "~> 0.17.0"},
|
||||
{:req, "~> 0.5.0"}
|
||||
{:req, "~> 0.5.0"},
|
||||
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}
|
||||
]
|
||||
end
|
||||
|
||||
|
2
mix.lock
2
mix.lock
@ -1,6 +1,8 @@
|
||||
%{
|
||||
"bandit": {:hex, :bandit, "1.5.2", "ed0a41c43a9e529c670d0fd48371db4027e7b80d43b1942893e17deb8bed0540", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "35ddbdce7e8a2a3c6b5093f7299d70832a43ed2f4a1852885a61d334cab1b4ad"},
|
||||
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
|
||||
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
|
||||
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
|
||||
|
Reference in New Issue
Block a user