From 6b74ecdbb5ed5708162fb7a4857768595d3e6224 Mon Sep 17 00:00:00 2001 From: Benjamin Piouffle Date: Sat, 6 Dec 2025 18:17:44 +0100 Subject: [PATCH 1/2] chore: Fix compilation warnings --- apps/cf/config/config.exs | 6 ++--- apps/cf/config/dev.exs | 4 ++-- apps/cf/lib/accounts/accounts.ex | 2 +- apps/cf/lib/accounts/username_generator.ex | 4 +++- apps/cf/lib/application.ex | 8 +++---- apps/cf/lib/authenticator/oauth/facebook.ex | 2 +- apps/cf/lib/errors/errors.ex | 23 +------------------ apps/cf/lib/llms/statements_creator.ex | 5 +--- apps/cf/lib/sources/fetcher.ex | 20 ++++++++++++---- .../cf/lib/videos/captions_fetcher_youtube.ex | 1 - apps/cf/lib/videos/videos.ex | 2 +- apps/cf_atom_feed/config/config.exs | 6 ++--- apps/cf_atom_feed/config/dev.exs | 2 +- apps/cf_atom_feed/lib/application.ex | 12 +++++----- apps/cf_atom_feed/lib/router.ex | 12 +++++++++- apps/cf_graphql/config/config.exs | 6 ++--- apps/cf_graphql/config/dev.exs | 2 +- apps/cf_graphql/lib/application.ex | 4 +--- apps/cf_graphql/lib/resolvers/statements.ex | 3 --- apps/cf_graphql/lib/resolvers/users.ex | 3 --- apps/cf_graphql/lib/resolvers/videos.ex | 5 ++-- apps/cf_graphql/lib/schema/schema.ex | 2 -- apps/cf_jobs/config/config.exs | 4 ++-- apps/cf_jobs/config/dev.exs | 2 +- apps/cf_jobs/lib/application.ex | 14 +++++------ apps/cf_jobs/lib/jobs/create_notifications.ex | 6 +++-- apps/cf_jobs/lib/jobs/download_captions.ex | 6 ++--- apps/cf_jobs/lib/jobs/flags.ex | 4 +++- apps/cf_jobs/lib/jobs/moderation.ex | 4 +++- apps/cf_jobs/lib/jobs/reputation.ex | 4 +++- apps/cf_rest_api/config/config.exs | 4 ++-- apps/cf_rest_api/config/dev.exs | 2 +- apps/cf_rest_api/lib/application.ex | 6 ++--- .../lib/channels/video_debate_channel.ex | 13 ++--------- .../lib/controllers/auth_controller.ex | 11 ++++----- .../lib/controllers/user_controller.ex | 1 - apps/cf_rest_api/lib/cors.ex | 3 +++ apps/cf_rest_api/lib/endpoint.ex | 4 ++-- apps/cf_rest_api/lib/security_headers.ex | 2 +- apps/cf_reverse_proxy/config/config.exs | 4 ++-- apps/cf_reverse_proxy/config/dev.exs | 2 +- apps/cf_reverse_proxy/lib/plug.ex | 10 +------- apps/db/config/config.exs | 4 ++-- apps/db/config/dev.exs | 2 +- apps/db/lib/db/application.ex | 6 ++--- apps/db/lib/db/release_tasks.ex | 2 +- apps/db/lib/db_schema/source.ex | 4 ++-- apps/db/lib/db_schema/video.ex | 11 +-------- apps/db/lib/db_type/flag_reason.ex | 2 ++ config/config.exs | 13 ++++++++--- 50 files changed, 128 insertions(+), 156 deletions(-) diff --git a/apps/cf/config/config.exs b/apps/cf/config/config.exs index 7ed63549..157b2d3d 100644 --- a/apps/cf/config/config.exs +++ b/apps/cf/config/config.exs @@ -1,9 +1,9 @@ # This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. +# and its dependencies with the aid of the Config module. # # This configuration file is loaded before any dependency and # is restricted to this project. -use Mix.Config +import Config # General application configuration config :cf, @@ -41,7 +41,7 @@ config :algoliax, application_id: "N5GW2EAIFX" # Import environment specific config -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") config :cf, openai_model: "gpt-4o" diff --git a/apps/cf/config/dev.exs b/apps/cf/config/dev.exs index e77a62c6..ced1bd7b 100644 --- a/apps/cf/config/dev.exs +++ b/apps/cf/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config dev_secret = "8C6FsJwjV11d+1WPUIbkEH6gB/VavJrcXWoPLujgpclfxjkLkoNFSjVU9XfeNm6s" @@ -32,5 +32,5 @@ config :cf, CF.Mailer, adapter: Bamboo.LocalAdapter # Import local secrets if any - use wildcard to ignore errors for config <- "*dev.secret.exs" |> Path.expand(__DIR__) |> Path.wildcard() do - import_config config + Config.import_config(config) end diff --git a/apps/cf/lib/accounts/accounts.ex b/apps/cf/lib/accounts/accounts.ex index 70072861..7acf059c 100644 --- a/apps/cf/lib/accounts/accounts.ex +++ b/apps/cf/lib/accounts/accounts.ex @@ -24,7 +24,7 @@ defmodule CF.Accounts do @request_validity 48 * 60 * 60 # Configure Fetching of user picture on Gravatar - @fetch_default_picture Application.get_env(:cf, :fetch_default_user_picture, true) + @fetch_default_picture Application.compile_env(:cf, :fetch_default_user_picture, true) # ---- User creation ---- diff --git a/apps/cf/lib/accounts/username_generator.ex b/apps/cf/lib/accounts/username_generator.ex index fa542358..d0477a89 100644 --- a/apps/cf/lib/accounts/username_generator.ex +++ b/apps/cf/lib/accounts/username_generator.ex @@ -1,4 +1,6 @@ defmodule CF.Accounts.UsernameGenerator do + use Agent + @moduledoc """ Generates a unique username based on user id """ @@ -6,7 +8,7 @@ defmodule CF.Accounts.UsernameGenerator do @name __MODULE__ @username_prefix "NewUser-" - def start_link do + def start_link(_opts \\ []) do Agent.start_link( fn -> Hashids.new( diff --git a/apps/cf/lib/application.ex b/apps/cf/lib/application.ex index 93d1a21c..63c2bc3c 100644 --- a/apps/cf/lib/application.ex +++ b/apps/cf/lib/application.ex @@ -4,16 +4,14 @@ defmodule CF.Application do # See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do - import Supervisor.Spec - # Define workers and child supervisors to be supervised children = [ # Other custom supervisors - supervisor(CF.Sources.Fetcher, []), + CF.Sources.Fetcher, # Misc workers - worker(CF.Accounts.UsernameGenerator, []), + CF.Accounts.UsernameGenerator, # Sweep tokens from db - worker(Guardian.DB.Token.SweeperServer, []) + Guardian.DB.Token.SweeperServer ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html diff --git a/apps/cf/lib/authenticator/oauth/facebook.ex b/apps/cf/lib/authenticator/oauth/facebook.ex index 165eff9f..9308863d 100644 --- a/apps/cf/lib/authenticator/oauth/facebook.ex +++ b/apps/cf/lib/authenticator/oauth/facebook.ex @@ -105,7 +105,7 @@ defmodule CF.Authenticator.OAuth.Facebook do end defp hmac(data, type, key) do - :crypto.hmac(type, key, data) + :crypto.mac(:hmac, type, key, data) end # ---- Private ---- diff --git a/apps/cf/lib/errors/errors.ex b/apps/cf/lib/errors/errors.ex index b693fc34..183bda66 100644 --- a/apps/cf/lib/errors/errors.ex +++ b/apps/cf/lib/errors/errors.ex @@ -36,30 +36,9 @@ defmodule CF.Errors do end @spec do_report(:error | :exit | :throw, any(), [any()], cf_error_params()) :: :ok - def do_report(type, value, stacktrace, params) do + def do_report(type, value, stacktrace, _params) do # Any call to Sentry, Rollbar, etc. should be done here Logger.error("[ERROR][#{type}] #{inspect(value)} - #{inspect(stacktrace)}") :ok end - - defp build_occurence_data(params) do - default_occurrence_data() - |> add_user(params[:user]) - |> Map.merge(params[:data] || %{}) - end - - defp default_occurrence_data() do - %{ - "code_version" => CF.Application.version() - } - end - - defp add_user(base, nil), - do: base - - defp add_user(base, %{id: id, username: username}), - do: Map.merge(base, %{"person" => %{"id" => Integer.to_string(id), "username" => username}}) - - defp add_user(base, %{id: id}), - do: Map.merge(base, %{"person" => %{"id" => Integer.to_string(id)}}) end diff --git a/apps/cf/lib/llms/statements_creator.ex b/apps/cf/lib/llms/statements_creator.ex index c07ff128..401d18f0 100644 --- a/apps/cf/lib/llms/statements_creator.ex +++ b/apps/cf/lib/llms/statements_creator.ex @@ -65,9 +65,6 @@ defmodule CF.LLMs.StatementsCreator do end end - @doc """ - Chunk captions everytime we reach the max caption length - """ defp chunk_captions(captions) do # TODO: Add last captions from previous batch to preserve context Enum.chunk_every(captions, @captions_chunk_size) @@ -138,7 +135,7 @@ defmodule CF.LLMs.StatementsCreator do defp create_statements_from_inputs(statements_inputs, video) do inserted_at = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) - {nb_statements, statements} = + {_nb_statements, statements} = DB.Repo.insert_all( DB.Schema.Statement, Enum.map(statements_inputs, fn %{"text" => text, "time" => time} -> diff --git a/apps/cf/lib/sources/fetcher.ex b/apps/cf/lib/sources/fetcher.ex index 47b53b47..8c1c5c87 100644 --- a/apps/cf/lib/sources/fetcher.ex +++ b/apps/cf/lib/sources/fetcher.ex @@ -10,9 +10,17 @@ defmodule CF.Sources.Fetcher do # ---- Public API ---- - def start_link() do - import Supervisor.Spec + def child_spec(opts) do + %{ + id: __MODULE__, + start: {__MODULE__, :start_link, [opts]}, + type: :supervisor, + restart: :permanent, + shutdown: 500 + } + end + def start_link(_opts \\ []) do Supervisor.start_link( [ :hackney_pool.child_spec( @@ -20,7 +28,7 @@ defmodule CF.Sources.Fetcher do timeout: @request_timeout, max_connections: @max_connections ), - worker(CF.Sources.Fetcher.LinkChecker, []) + CF.Sources.Fetcher.LinkChecker ], strategy: :one_for_all, name: __MODULE__ @@ -75,7 +83,7 @@ defmodule CF.Sources.Fetcher do hackney: [pool: pool_name()] ) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> - {:ok, source_params_from_tree(Floki.parse(body))} + {:ok, source_params_from_tree(Floki.parse_document(body))} {:ok, %HTTPoison.Response{status_code: 404}} -> {:error, :not_found} @@ -137,10 +145,12 @@ defmodule CF.Sources.Fetcher do # Link checker defmodule LinkChecker do + use Agent + @doc """ Agent that record which links are currently fetched """ - def start_link() do + def start_link(_opts \\ []) do Agent.start_link(fn -> MapSet.new() end, name: Fetcher.link_checker_name()) end diff --git a/apps/cf/lib/videos/captions_fetcher_youtube.ex b/apps/cf/lib/videos/captions_fetcher_youtube.ex index 03ba4a5b..7d7a6816 100644 --- a/apps/cf/lib/videos/captions_fetcher_youtube.ex +++ b/apps/cf/lib/videos/captions_fetcher_youtube.ex @@ -7,7 +7,6 @@ defmodule CF.Videos.CaptionsFetcherYoutube do @behaviour CF.Videos.CaptionsFetcher require Logger - import SweetXml @user_agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/135.0" diff --git a/apps/cf/lib/videos/videos.ex b/apps/cf/lib/videos/videos.ex index e975a42f..e1eed22a 100644 --- a/apps/cf/lib/videos/videos.ex +++ b/apps/cf/lib/videos/videos.ex @@ -21,7 +21,7 @@ defmodule CF.Videos do alias CF.Accounts.UserPermissions alias CF.Videos.MetadataFetcher - @captions_fetcher Application.get_env(:cf, :captions_fetcher) + @captions_fetcher Application.compile_env(:cf, :captions_fetcher, nil) @doc """ TODO with_speakers param is only required by REST API diff --git a/apps/cf_atom_feed/config/config.exs b/apps/cf_atom_feed/config/config.exs index 1027be97..e7fe075a 100644 --- a/apps/cf_atom_feed/config/config.exs +++ b/apps/cf_atom_feed/config/config.exs @@ -1,9 +1,9 @@ # This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. +# and its dependencies with the aid of the Config module. # # This configuration file is loaded before any dependency and # is restricted to this project. -use Mix.Config +import Config # General application configuration config :cf_atom_feed, @@ -20,4 +20,4 @@ config :db, DB.Repo, pool_size: 1 # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/cf_atom_feed/config/dev.exs b/apps/cf_atom_feed/config/dev.exs index ab729319..243ae932 100644 --- a/apps/cf_atom_feed/config/dev.exs +++ b/apps/cf_atom_feed/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # Do not include metadata nor timestamps in development logs config :logger, :console, format: "[$level] $message\n" diff --git a/apps/cf_atom_feed/lib/application.ex b/apps/cf_atom_feed/lib/application.ex index 087c5585..41e416eb 100644 --- a/apps/cf_atom_feed/lib/application.ex +++ b/apps/cf_atom_feed/lib/application.ex @@ -4,14 +4,14 @@ defmodule CF.AtomFeed.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do - import Supervisor.Spec - - children = [] config = Application.get_env(:cf_atom_feed, CF.AtomFeed.Router) - if config[:cowboy] do - children = [supervisor(CF.AtomFeed.Router, []) | children] - end + children = + if config[:cowboy] do + [CF.AtomFeed.Router] + else + [] + end # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options diff --git a/apps/cf_atom_feed/lib/router.ex b/apps/cf_atom_feed/lib/router.ex index 009adae0..bc0a7ebc 100644 --- a/apps/cf_atom_feed/lib/router.ex +++ b/apps/cf_atom_feed/lib/router.ex @@ -6,7 +6,17 @@ defmodule CF.AtomFeed.Router do plug(:match) plug(:dispatch) - def start_link do + def child_spec(opts) do + %{ + id: __MODULE__, + start: {__MODULE__, :start_link, [opts]}, + type: :worker, + restart: :permanent, + shutdown: 500 + } + end + + def start_link(_opts \\ []) do config = Application.get_env(:cf_atom_feed, CF.AtomFeed.Router) Logger.info("Running CF.AtomFeed.Router with cowboy on port #{config[:cowboy][:port]}") Plug.Cowboy.http(CF.AtomFeed.Router, [], config[:cowboy]) diff --git a/apps/cf_graphql/config/config.exs b/apps/cf_graphql/config/config.exs index 2ba311b6..7c21a153 100644 --- a/apps/cf_graphql/config/config.exs +++ b/apps/cf_graphql/config/config.exs @@ -1,9 +1,9 @@ # This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. +# and its dependencies with the aid of the Config module. # # This configuration file is loaded before any dependency and # is restricted to this project. -use Mix.Config +import Config # General application configuration config :cf_graphql, @@ -28,4 +28,4 @@ config :db, DB.Repo, pool_size: 5 # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/cf_graphql/config/dev.exs b/apps/cf_graphql/config/dev.exs index a5d597d6..8471d424 100644 --- a/apps/cf_graphql/config/dev.exs +++ b/apps/cf_graphql/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config config :cf_graphql, CF.GraphQLWeb.Endpoint, http: [port: 4002], diff --git a/apps/cf_graphql/lib/application.ex b/apps/cf_graphql/lib/application.ex index 64ca65a6..9da7939e 100644 --- a/apps/cf_graphql/lib/application.ex +++ b/apps/cf_graphql/lib/application.ex @@ -4,14 +4,12 @@ defmodule CF.Graphql.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do - import Supervisor.Spec - # Define workers and child supervisors to be supervised children = [ # Start the PubSub system {Phoenix.PubSub, name: CF.Graphql.PubSub}, # Start the endpoint when the application starts - supervisor(CF.GraphQLWeb.Endpoint, []) + {CF.GraphQLWeb.Endpoint, []} ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/apps/cf_graphql/lib/resolvers/statements.ex b/apps/cf_graphql/lib/resolvers/statements.ex index bea634d5..33f03f66 100644 --- a/apps/cf_graphql/lib/resolvers/statements.ex +++ b/apps/cf_graphql/lib/resolvers/statements.ex @@ -5,9 +5,6 @@ defmodule CF.Graphql.Resolvers.Statements do alias Kaur.Result - import Ecto.Query - import Absinthe.Resolution.Helpers, only: [batch: 3] - alias DB.Repo alias DB.Schema.Statement diff --git a/apps/cf_graphql/lib/resolvers/users.ex b/apps/cf_graphql/lib/resolvers/users.ex index ce90e4ff..01aa3c98 100644 --- a/apps/cf_graphql/lib/resolvers/users.ex +++ b/apps/cf_graphql/lib/resolvers/users.ex @@ -39,9 +39,6 @@ defmodule CF.Graphql.Resolvers.Users do {:ok, user} end - @doc """ - Get logged in user - """ def get_logged_in(_, _, _) do {:ok, nil} end diff --git a/apps/cf_graphql/lib/resolvers/videos.ex b/apps/cf_graphql/lib/resolvers/videos.ex index 27d8b094..044669e1 100644 --- a/apps/cf_graphql/lib/resolvers/videos.ex +++ b/apps/cf_graphql/lib/resolvers/videos.ex @@ -37,7 +37,8 @@ defmodule CF.Graphql.Resolvers.Videos do end end - @deprecated "Use paginated_list/3" + # Deprecated: Use paginated_list/3 instead + # Keeping for backward compatibility with deprecated all_videos field def list(_root, args, _info) do Video |> Video.query_list(Map.get(args, :filters, []), args[:limit]) @@ -126,7 +127,7 @@ defmodule CF.Graphql.Resolvers.Videos do |> Ecto.Multi.update(:video, fn _repo -> changeset end) - |> Ecto.Multi.run(:action, fn _repo, %{video: video} -> + |> Ecto.Multi.run(:action, fn _repo, %{video: _video} -> Repo.insert(CF.Actions.ActionCreator.action_update(user.id, changeset)) end) |> Repo.transaction() diff --git a/apps/cf_graphql/lib/schema/schema.ex b/apps/cf_graphql/lib/schema/schema.ex index e30a7a33..7020de55 100644 --- a/apps/cf_graphql/lib/schema/schema.ex +++ b/apps/cf_graphql/lib/schema/schema.ex @@ -2,7 +2,6 @@ defmodule CF.Graphql.Schema do use Absinthe.Schema alias CF.Graphql.Resolvers alias CF.Graphql.Schema.Middleware - import Absinthe.Resolution.Helpers, only: [dataloader: 1] import_types(Absinthe.Plug.Types) @@ -44,7 +43,6 @@ defmodule CF.Graphql.Schema do query do @desc "[Deprecated] Get all videos" @deprecated "Please update to the paginated version (videos). This will be removed in 0.9." - @since "0.8.16" field :all_videos, list_of(:video) do arg(:filters, :video_filter) arg(:limit, :integer) diff --git a/apps/cf_jobs/config/config.exs b/apps/cf_jobs/config/config.exs index 660da45d..335d5c94 100644 --- a/apps/cf_jobs/config/config.exs +++ b/apps/cf_jobs/config/config.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # Configure scheduler config :cf_jobs, CF.Jobs.Scheduler, @@ -52,4 +52,4 @@ config :cf_jobs, CF.Jobs.Scheduler, config :db, DB.Repo, pool_size: 3 # Import environment specific config -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/cf_jobs/config/dev.exs b/apps/cf_jobs/config/dev.exs index d2d855e6..becde769 100644 --- a/apps/cf_jobs/config/dev.exs +++ b/apps/cf_jobs/config/dev.exs @@ -1 +1 @@ -use Mix.Config +import Config diff --git a/apps/cf_jobs/lib/application.ex b/apps/cf_jobs/lib/application.ex index de190a0b..50773c41 100644 --- a/apps/cf_jobs/lib/application.ex +++ b/apps/cf_jobs/lib/application.ex @@ -4,8 +4,6 @@ defmodule CF.Jobs.Application do # See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do - import Supervisor.Spec - # Wait 10s before starting to give some time for the migrations to run :timer.sleep(1000) @@ -14,18 +12,18 @@ defmodule CF.Jobs.Application do # Define workers and child supervisors to be supervised children = [ # Jobs - worker(CF.Jobs.Reputation, []), - worker(CF.Jobs.Flags, []), - worker(CF.Jobs.Moderation, []), - worker(CF.Jobs.CreateNotifications, []), - worker(CF.Jobs.DownloadCaptions, []) + CF.Jobs.Reputation, + CF.Jobs.Flags, + CF.Jobs.Moderation, + CF.Jobs.CreateNotifications, + CF.Jobs.DownloadCaptions ] # Do not start scheduler in tests children = if env == :test or Application.get_env(:cf, :disable_scheduler), do: children, - else: children ++ [worker(CF.Jobs.Scheduler, [])] + else: children ++ [CF.Jobs.Scheduler] opts = [strategy: :one_for_one, name: CF.Jobs.Supervisor] Supervisor.start_link(children, opts) diff --git a/apps/cf_jobs/lib/jobs/create_notifications.ex b/apps/cf_jobs/lib/jobs/create_notifications.ex index 2605dbb6..40206d2d 100644 --- a/apps/cf_jobs/lib/jobs/create_notifications.ex +++ b/apps/cf_jobs/lib/jobs/create_notifications.ex @@ -1,4 +1,6 @@ defmodule CF.Jobs.CreateNotifications do + use GenServer + @moduledoc """ Eat `UserAction` items, digest them using `Subscriptions` and poop notifications in Database. @@ -41,8 +43,8 @@ defmodule CF.Jobs.CreateNotifications do @spec name() :: :create_notifications def name, do: @name - @spec start_link() :: :ignore | {:error, any()} | {:ok, pid()} - def start_link() do + @spec start_link(any()) :: :ignore | {:error, any()} | {:ok, pid()} + def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end diff --git a/apps/cf_jobs/lib/jobs/download_captions.ex b/apps/cf_jobs/lib/jobs/download_captions.ex index ce4db1e4..7061c373 100644 --- a/apps/cf_jobs/lib/jobs/download_captions.ex +++ b/apps/cf_jobs/lib/jobs/download_captions.ex @@ -1,4 +1,6 @@ defmodule CF.Jobs.DownloadCaptions do + use GenServer + @behaviour CF.Jobs.Job require Logger @@ -7,16 +9,14 @@ defmodule CF.Jobs.DownloadCaptions do alias DB.Repo alias DB.Schema.Video alias DB.Schema.VideoCaption - alias DB.Schema.UsersActionsReport @name :download_captions - @analyser_id UsersActionsReport.analyser_id(@name) # --- Client API --- def name, do: @name - def start_link() do + def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end diff --git a/apps/cf_jobs/lib/jobs/flags.ex b/apps/cf_jobs/lib/jobs/flags.ex index 443ed193..d9064247 100644 --- a/apps/cf_jobs/lib/jobs/flags.ex +++ b/apps/cf_jobs/lib/jobs/flags.ex @@ -1,4 +1,6 @@ defmodule CF.Jobs.Flags do + use GenServer + @moduledoc """ Analyse flags periodically to report innapropriate content @@ -26,7 +28,7 @@ defmodule CF.Jobs.Flags do def name, do: @name - def start_link() do + def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end diff --git a/apps/cf_jobs/lib/jobs/moderation.ex b/apps/cf_jobs/lib/jobs/moderation.ex index 847cb64a..ba042a09 100644 --- a/apps/cf_jobs/lib/jobs/moderation.ex +++ b/apps/cf_jobs/lib/jobs/moderation.ex @@ -1,4 +1,6 @@ defmodule CF.Jobs.Moderation do + use GenServer + @moduledoc """ This job analyze moderation feebacks and ban or unreport comments accordingly. @@ -30,7 +32,7 @@ defmodule CF.Jobs.Moderation do def name, do: @name - def start_link() do + def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end diff --git a/apps/cf_jobs/lib/jobs/reputation.ex b/apps/cf_jobs/lib/jobs/reputation.ex index 672fd5ec..ed1d7dcc 100644 --- a/apps/cf_jobs/lib/jobs/reputation.ex +++ b/apps/cf_jobs/lib/jobs/reputation.ex @@ -1,4 +1,6 @@ defmodule CF.Jobs.Reputation do + use GenServer + @moduledoc """ Updates a user reputation periodically, verifying at the same time that the maximum reputation gain per day quota is respected. @@ -28,7 +30,7 @@ defmodule CF.Jobs.Reputation do def name, do: @name - def start_link() do + def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, :ok, name: __MODULE__) end diff --git a/apps/cf_rest_api/config/config.exs b/apps/cf_rest_api/config/config.exs index a6e4b34c..094247b8 100644 --- a/apps/cf_rest_api/config/config.exs +++ b/apps/cf_rest_api/config/config.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config config :cf_rest_api, cors_origins: [] @@ -14,4 +14,4 @@ config :cf_rest_api, CF.RestApi.Endpoint, config :db, DB.Repo, pool_size: 10 # Import environment specific config -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/cf_rest_api/config/dev.exs b/apps/cf_rest_api/config/dev.exs index c944961f..d83561b2 100644 --- a/apps/cf_rest_api/config/dev.exs +++ b/apps/cf_rest_api/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config dev_secret = "8C6FsJwjV11d+1WPUIbkEH6gB/VavJrcXWoPLujgpclfxjkLkoNFSjVU9XfeNm6s" diff --git a/apps/cf_rest_api/lib/application.ex b/apps/cf_rest_api/lib/application.ex index 33368ed0..f2753f1f 100644 --- a/apps/cf_rest_api/lib/application.ex +++ b/apps/cf_rest_api/lib/application.ex @@ -2,16 +2,14 @@ defmodule CF.RestApi.Application do use Application def start(_type, _args) do - import Supervisor.Spec - # Define workers and child supervisors to be supervised children = [ # Start the PubSub system {Phoenix.PubSub, name: CF.RestApi.PubSub}, # Start the endpoint when the application starts - supervisor(CF.RestApi.Endpoint, []), + {CF.RestApi.Endpoint, []}, # Presence to track number of connected users to a channel - supervisor(CF.RestApi.Presence, []) + {CF.RestApi.Presence, []} ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html diff --git a/apps/cf_rest_api/lib/channels/video_debate_channel.ex b/apps/cf_rest_api/lib/channels/video_debate_channel.ex index a6228ddd..e771003e 100644 --- a/apps/cf_rest_api/lib/channels/video_debate_channel.ex +++ b/apps/cf_rest_api/lib/channels/video_debate_channel.ex @@ -49,7 +49,7 @@ defmodule CF.RestApi.VideoDebateChannel do end @doc """ - Register a public connection in presence tracker + Register a connection in presence tracker (public or user) """ def handle_info(:after_join, socket = %{assigns: %{user_id: nil}}) do push(socket, "presence_state", Presence.list(socket)) @@ -57,9 +57,6 @@ defmodule CF.RestApi.VideoDebateChannel do {:noreply, socket} end - @doc """ - Register a user connection in presence tracker - """ def handle_info(:after_join, socket = %{assigns: %{user_id: user_id}}) do push(socket, "presence_state", Presence.list(socket)) {:ok, _} = Presence.track(socket, :users, %{user_id: user_id}) @@ -71,7 +68,7 @@ defmodule CF.RestApi.VideoDebateChannel do end @doc """ - Shift all video's statements + Handle authenticated channel messages """ def handle_in_authenticated!("shift_statements", offsets, socket) do user = Repo.get(DB.Schema.User, socket.assigns.user_id) @@ -91,9 +88,6 @@ defmodule CF.RestApi.VideoDebateChannel do end end - @doc """ - Add an existing speaker to the video - """ def handle_in_authenticated!("new_speaker", %{"id" => id}, socket) do %{user_id: user_id, video_id: video_id} = socket.assigns UserPermissions.check!(user_id, :add, :speaker) @@ -118,9 +112,6 @@ defmodule CF.RestApi.VideoDebateChannel do end end - @doc """ - Create a new speaker and add it to the video - """ def handle_in_authenticated!("new_speaker", params, socket) do %{user_id: user_id, video_id: video_id} = socket.assigns UserPermissions.check!(user_id, :create, :speaker) diff --git a/apps/cf_rest_api/lib/controllers/auth_controller.ex b/apps/cf_rest_api/lib/controllers/auth_controller.ex index 6831c979..14fe33da 100644 --- a/apps/cf_rest_api/lib/controllers/auth_controller.ex +++ b/apps/cf_rest_api/lib/controllers/auth_controller.ex @@ -22,7 +22,7 @@ defmodule CF.RestApi.AuthController do @err_invalid_email_password "invalid_email_password" @doc """ - Auth with identity (name|email + password) + Handle authentication callback for identity or OAuth providers """ def callback(conn, %{"provider" => "identity", "email" => email, "password" => password}) do case Authenticator.get_user_for_email_or_name_password(email, password) do @@ -37,11 +37,10 @@ defmodule CF.RestApi.AuthController do end end - @doc """ - Auth with third party provider (OAuth, only Facebook for now). - If user is connected -> associate account with third party - If not -> get or create account from third party infos - """ + def callback(_conn, %{"provider" => provider}) when provider in ["facebook"] do + # This will be handled by the OAuth callback below + end + def callback(conn, params = %{"provider" => provider_str, "code" => code}) do user = GuardianImpl.Plug.current_resource(conn) provider = provider_atom!(provider_str) diff --git a/apps/cf_rest_api/lib/controllers/user_controller.ex b/apps/cf_rest_api/lib/controllers/user_controller.ex index 60a22a71..47fc73d2 100644 --- a/apps/cf_rest_api/lib/controllers/user_controller.ex +++ b/apps/cf_rest_api/lib/controllers/user_controller.ex @@ -8,7 +8,6 @@ defmodule CF.RestApi.UserController do alias CF.Accounts.Invitations alias CF.Accounts.UserPermissions alias CF.Authenticator.GuardianImpl - alias CF.RestApi.UserView alias Kaur.Result diff --git a/apps/cf_rest_api/lib/cors.ex b/apps/cf_rest_api/lib/cors.ex index d594f9c0..096c2ca1 100644 --- a/apps/cf_rest_api/lib/cors.ex +++ b/apps/cf_rest_api/lib/cors.ex @@ -9,4 +9,7 @@ defmodule CF.RestApi.CORS do origin in origins end end + + @spec check_origin(Plug.Conn.t(), String.t()) :: boolean() + def check_origin(_conn, origin), do: check_origin(origin) end diff --git a/apps/cf_rest_api/lib/endpoint.ex b/apps/cf_rest_api/lib/endpoint.ex index 2a7d3acf..ca00bf49 100644 --- a/apps/cf_rest_api/lib/endpoint.ex +++ b/apps/cf_rest_api/lib/endpoint.ex @@ -3,7 +3,7 @@ defmodule CF.RestApi.Endpoint do socket("/socket", CF.RestApi.UserSocket, websocket: true, longpoll: false) - if Application.get_env(:arc, :storage) == Arc.Storage.Local, + if Application.compile_env(:arc, :storage, nil) == Arc.Storage.Local, do: plug(Plug.Static, at: "/resources", from: "./resources", gzip: false) plug(Plug.RequestId) @@ -14,7 +14,7 @@ defmodule CF.RestApi.Endpoint do Corsica, max_age: 3600, allow_headers: ~w(Accept Content-Type Authorization Origin), - origins: {CF.RestApi.CORS, :check_origin} + origins: {CF.RestApi.CORS, :check_origin, []} ) plug( diff --git a/apps/cf_rest_api/lib/security_headers.ex b/apps/cf_rest_api/lib/security_headers.ex index b6fd7fd6..fa17757c 100644 --- a/apps/cf_rest_api/lib/security_headers.ex +++ b/apps/cf_rest_api/lib/security_headers.ex @@ -1,5 +1,5 @@ defmodule CF.RestApi.SecurityHeaders do - @x_frame_options if Application.get_env(:cf, :env) == :dev, + @x_frame_options if Application.compile_env(:cf, :env, :prod) == :dev, do: "SAMEORIGIN", else: "DENY" diff --git a/apps/cf_reverse_proxy/config/config.exs b/apps/cf_reverse_proxy/config/config.exs index 0f2425fc..16a65f77 100644 --- a/apps/cf_reverse_proxy/config/config.exs +++ b/apps/cf_reverse_proxy/config/config.exs @@ -1,7 +1,7 @@ -use Mix.Config +import Config # Configures the endpoint config :cf_reverse_proxy, port: 5000 # Import environment specific config -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/cf_reverse_proxy/config/dev.exs b/apps/cf_reverse_proxy/config/dev.exs index d2d855e6..becde769 100644 --- a/apps/cf_reverse_proxy/config/dev.exs +++ b/apps/cf_reverse_proxy/config/dev.exs @@ -1 +1 @@ -use Mix.Config +import Config diff --git a/apps/cf_reverse_proxy/lib/plug.ex b/apps/cf_reverse_proxy/lib/plug.ex index 64447300..2eb0b34b 100644 --- a/apps/cf_reverse_proxy/lib/plug.ex +++ b/apps/cf_reverse_proxy/lib/plug.ex @@ -10,14 +10,6 @@ defmodule CF.ReverseProxy.Plug do origins: [~r/(.*)\.captainfact\.io$/] ) - @default_host CF.RestApi.Endpoint - @base_host_regex ~r/^(?rest|graphql|feed)\./ - @subdomains %{ - "graphql" => CF.GraphQLWeb.Endpoint, - "rest" => CF.RestApi.Endpoint, - "feed" => CF.AtomFeed.Router - } - def init(opts), do: opts # See https://github.com/wojtekmach/acme_bank/blob/master/apps/master_proxy/lib/master_proxy/plug.ex @@ -25,7 +17,7 @@ defmodule CF.ReverseProxy.Plug do # https://elixirforum.com/t/umbrella-with-2-phoenix-apps-how-to-forward-request-from-1-to-2-and-vice-versa/1797/18?u=betree # https://github.com/jesseshieh/master_proxy - if Application.get_env(:cf, :env) == :dev do + if Application.compile_env(:cf, :env, :prod) == :dev do # Dev requests are routed through here def call(conn, _) do if conn.request_path == "/status" do diff --git a/apps/db/config/config.exs b/apps/db/config/config.exs index 518d95a0..5c98e8d8 100644 --- a/apps/db/config/config.exs +++ b/apps/db/config/config.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # General application configuration config :db, @@ -14,4 +14,4 @@ config :db, DB.Repo, ] # Import environment specific config -import_config "#{Mix.env()}.exs" +Config.import_config("#{Mix.env()}.exs") diff --git a/apps/db/config/dev.exs b/apps/db/config/dev.exs index d3d464c2..27e2d4cf 100644 --- a/apps/db/config/dev.exs +++ b/apps/db/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Config # Configure your database config :db, DB.Repo, diff --git a/apps/db/lib/db/application.ex b/apps/db/lib/db/application.ex index f9ba5589..aa5060b2 100644 --- a/apps/db/lib/db/application.ex +++ b/apps/db/lib/db/application.ex @@ -5,13 +5,11 @@ defmodule DB.Application do require Logger def start(_type, _args) do - import Supervisor.Spec, warn: false - # Define workers and child supervisors to be supervised children = [ # Starts a worker by calling: DB.Worker.start_link(arg1, arg2, arg3) - # worker(DB.Worker, [arg1, arg2, arg3]), - supervisor(DB.Repo, []) + # {DB.Worker, [arg1, arg2, arg3]}, + {DB.Repo, []} ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html diff --git a/apps/db/lib/db/release_tasks.ex b/apps/db/lib/db/release_tasks.ex index 99ce0d3f..5020d12e 100644 --- a/apps/db/lib/db/release_tasks.ex +++ b/apps/db/lib/db/release_tasks.ex @@ -49,7 +49,7 @@ defmodule DB.ReleaseTasks do init() Application.ensure_all_started(:httpoison) seed_script = Path.join([priv_dir(:db), "repo", "seed_politicians.exs"]) - [{module, _}] = Code.load_file(seed_script) + [{module, _}] = Code.compile_file(seed_script) url = "https://raw.githubusercontent.com/CaptainFact/captain-fact-data/master/Wikidata/data/politicians_born_after_1945_having_a_picture.csv" diff --git a/apps/db/lib/db_schema/source.ex b/apps/db/lib/db_schema/source.ex index 52b1b013..6929dbdc 100644 --- a/apps/db/lib/db_schema/source.ex +++ b/apps/db/lib/db_schema/source.ex @@ -16,7 +16,7 @@ defmodule DB.Schema.Source do @url_max_length 2048 # Allow to add localhost urls as sources during tests - @url_regex if Application.get_env(:db, :env) == :test, + @url_regex if Application.compile_env(:db, :env, :prod) == :test, do: ~r/(^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))|localhost/, else: @@ -65,7 +65,7 @@ defmodule DB.Schema.Source do end defp validate_file_mime_type(:file_mime_type, mime_type) do - if MIME.valid?(mime_type) do + if MIME.extensions(mime_type) != [] do [] else [file_mime_type: "Invalid MIME type"] diff --git a/apps/db/lib/db_schema/video.ex b/apps/db/lib/db_schema/video.ex index fab12df6..df374c0b 100644 --- a/apps/db/lib/db_schema/video.ex +++ b/apps/db/lib/db_schema/video.ex @@ -122,7 +122,7 @@ defmodule DB.Schema.Video do do: "https://www.facebook.com/video.php?v=#{id}" # Add a special case for building test URLs - if Application.get_env(:db, :env) == :test do + if Application.compile_env(:db, :env, :prod) == :test do def build_url(%{youtube_id: id, facebook_id: fb_id}), do: "__TEST__/#{id || fb_id}" end @@ -308,13 +308,4 @@ defmodule DB.Schema.Video do ) end) end - - # Return IDs of videos with at least 3 statements - defp popular_videos_subquery do - Video - |> join(:inner, [v], s in assoc(v, :statements)) - |> select([:id]) - |> group_by([v], v.id) - |> having([v, s], count(s.id) >= 3) - end end diff --git a/apps/db/lib/db_type/flag_reason.ex b/apps/db/lib/db_type/flag_reason.ex index 5a45bac6..7534e481 100644 --- a/apps/db/lib/db_type/flag_reason.ex +++ b/apps/db/lib/db_type/flag_reason.ex @@ -54,6 +54,8 @@ defmodule DB.Type.FlagReason do reason1 == reason2 end + def embed_as(_format), do: :self + # ---- Custom functions ---- @doc """ diff --git a/config/config.exs b/config/config.exs index 129dc422..a7e192ae 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,4 +1,11 @@ -use Mix.Config +import Config -import_config "../apps/*/config/config.exs" -import_config "./*.secret.exs" # TODO should filter by env +# Import all app config files +for config <- "../apps/*/config/config.exs" |> Path.expand(__DIR__) |> Path.wildcard() do + Config.import_config(config) +end + +# Import secret config files +for config <- "./*.secret.exs" |> Path.expand(__DIR__) |> Path.wildcard() do + Config.import_config(config) +end From e1309fc3bf822e611891dd830bd45d9aec9e30aa Mon Sep 17 00:00:00 2001 From: Benjamin Piouffle Date: Sun, 21 Dec 2025 18:40:18 +0100 Subject: [PATCH 2/2] fix sources fetcher --- apps/cf/lib/sources/fetcher.ex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/cf/lib/sources/fetcher.ex b/apps/cf/lib/sources/fetcher.ex index 8c1c5c87..64e471c1 100644 --- a/apps/cf/lib/sources/fetcher.ex +++ b/apps/cf/lib/sources/fetcher.ex @@ -16,7 +16,7 @@ defmodule CF.Sources.Fetcher do start: {__MODULE__, :start_link, [opts]}, type: :supervisor, restart: :permanent, - shutdown: 500 + shutdown: 2000 } end @@ -60,15 +60,15 @@ defmodule CF.Sources.Fetcher do def get_queue, do: Fetcher.LinkChecker.get_queue() - @url_regex ~r/^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/ - defp fetch(url, callback) do - without_domain = Regex.replace(@url_regex, url, "\\1") - path = Regex.replace(~r/\?.+$/, without_domain, "") + uri = URI.parse(url) + + case do_fetch_source_metadata(url, MIME.from_path(uri.path)) do + {:error, err} -> + :error - case do_fetch_source_metadata(url, MIME.from_path(path)) do - {:error, _} -> :error - {:ok, result} -> callback.(result) + {:ok, result} -> + callback.(result) end end @@ -77,13 +77,13 @@ defmodule CF.Sources.Fetcher do defp do_fetch_source_metadata(url, mime_types) when mime_types in @fetchable_mime_types do case HTTPoison.get( url, - [], + [{"User-Agent", "CaptainFact/2.0"}], follow_redirect: true, max_redirect: 5, hackney: [pool: pool_name()] ) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> - {:ok, source_params_from_tree(Floki.parse_document(body))} + {:ok, source_params_from_tree(Floki.parse_document!(body))} {:ok, %HTTPoison.Response{status_code: 404}} -> {:error, :not_found}