diff --git a/apps/cf/lib/actions/action_creator.ex b/apps/cf/lib/actions/action_creator.ex index 96f19e16..257e35dd 100644 --- a/apps/cf/lib/actions/action_creator.ex +++ b/apps/cf/lib/actions/action_creator.ex @@ -10,6 +10,7 @@ defmodule CF.Actions.ActionCreator do alias DB.Schema.Speaker alias DB.Schema.Statement alias DB.Schema.Comment + alias DB.Schema.VideoCaption alias CF.Actions.ReputationChange # Create @@ -175,6 +176,19 @@ defmodule CF.Actions.ActionCreator do ) end + def action_upload_video_captions(user_id, video_id, caption = %VideoCaption{}) do + action( + user_id, + :video_caption, + :upload, + video_id: video_id, + changes: %{ + "format" => caption.format, + "parsed" => caption.parsed + } + ) + end + def action_revert_vote(user_id, video_id, vote_type, comment = %Comment{}) when vote_type in [:revert_vote_up, :revert_vote_down, :revert_self_vote] do action( diff --git a/apps/cf/lib/videos/captions_fetcher_youtube.ex b/apps/cf/lib/videos/captions_fetcher_youtube.ex index 346e37f4..78a98b40 100644 --- a/apps/cf/lib/videos/captions_fetcher_youtube.ex +++ b/apps/cf/lib/videos/captions_fetcher_youtube.ex @@ -69,30 +69,7 @@ defmodule CF.Videos.CaptionsFetcherYoutube do end defp process_transcript(transcript) do - transcript - |> SweetXml.xpath( - ~x"//transcript/text"l, - text: ~x"./text()"s |> transform_by(&clean_text/1), - start: ~x"./@start"s |> transform_by(&parse_float/1), - duration: ~x"./@dur"os |> transform_by(&parse_float/1) - ) - |> Enum.filter(fn %{text: text, start: start} -> - start != nil and text != nil and text != "" - end) - end - - defp clean_text(text) do - text - |> String.replace("&", "&") - |> HtmlEntities.decode() - |> String.trim() - end - - defp parse_float(val) do - case Float.parse(val) do - {num, _} -> num - _ -> nil - end + CF.Videos.CaptionsSrv1Parser.parse_file(transcript) end # Below is an implementation using the official YouTube API, but it requires OAuth2 authentication. diff --git a/apps/cf/lib/videos/captions_srv1_parser.ex b/apps/cf/lib/videos/captions_srv1_parser.ex new file mode 100644 index 00000000..d4fb7a67 --- /dev/null +++ b/apps/cf/lib/videos/captions_srv1_parser.ex @@ -0,0 +1,37 @@ +defmodule CF.Videos.CaptionsSrv1Parser do + @moduledoc """ + A captions parser for the srv1 format. + """ + + require Logger + import SweetXml + + def parse_file(content) do + content + |> SweetXml.xpath( + ~x"//transcript/text"l, + text: ~x"./text()"s |> transform_by(&clean_text/1), + start: ~x"./@start"s |> transform_by(&parse_float/1), + duration: ~x"./@dur"os |> transform_by(&parse_float/1) + ) + |> Enum.filter(fn %{text: text, start: start} -> + # Filter out text in brackets, like "[Music]" + start != nil and text != nil and text != "" and + String.match?(text, ~r/^\[.*\]$/) == false + end) + end + + defp clean_text(text) do + text + |> String.replace("&", "&") + |> HtmlEntities.decode() + |> String.trim() + end + + defp parse_float(val) do + case Float.parse(val) do + {num, _} -> num + _ -> nil + end + end +end diff --git a/apps/cf/test/comments/comments_test.exs b/apps/cf/test/comments/comments_test.exs index 8f429ccc..93d7f084 100644 --- a/apps/cf/test/comments/comments_test.exs +++ b/apps/cf/test/comments/comments_test.exs @@ -141,7 +141,7 @@ defmodule CF.Comments.CommentsTest do Comments.delete_comment(random_user, comment.statement.video_id, comment) end - refute_deleted(comment) + assert_not_deleted(comment) Comments.delete_comment(comment.user, comment.statement.video_id, comment) assert_deleted(comment) @@ -168,7 +168,7 @@ defmodule CF.Comments.CommentsTest do Comments.delete_comment(comment.user, comment.statement.video_id, comment) end - refute_deleted(comment) + assert_not_deleted(comment) end test "but an admin can" do diff --git a/apps/cf/test/support/test_utils.ex b/apps/cf/test/support/test_utils.ex index de120cba..b38a062d 100644 --- a/apps/cf/test/support/test_utils.ex +++ b/apps/cf/test/support/test_utils.ex @@ -36,7 +36,7 @@ defmodule CF.TestUtils do end end - def refute_deleted(%Comment{id: id}) do + def assert_not_deleted(%Comment{id: id}) do {comment, _} = get_comment_and_actions(id) assert comment != nil diff --git a/apps/cf_graphql/lib/endpoint.ex b/apps/cf_graphql/lib/endpoint.ex index 0fbd4c6d..84883ac6 100644 --- a/apps/cf_graphql/lib/endpoint.ex +++ b/apps/cf_graphql/lib/endpoint.ex @@ -13,9 +13,9 @@ defmodule CF.GraphQLWeb.Endpoint do plug( Plug.Parsers, - parsers: [:urlencoded, :multipart, :json], + parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser], pass: ["*/*"], - json_decoder: Poison + json_decoder: Jason ) plug(Plug.MethodOverride) diff --git a/apps/cf_graphql/lib/resolvers/videos.ex b/apps/cf_graphql/lib/resolvers/videos.ex index 1e4c51a2..27d8b094 100644 --- a/apps/cf_graphql/lib/resolvers/videos.ex +++ b/apps/cf_graphql/lib/resolvers/videos.ex @@ -8,6 +8,7 @@ defmodule CF.Graphql.Resolvers.Videos do import Ecto.Query import Absinthe.Resolution.Helpers, only: [batch: 3] + alias Ecto.Multi alias DB.Repo alias DB.Schema.Video alias DB.Schema.VideoCaption @@ -137,4 +138,48 @@ defmodule CF.Graphql.Resolvers.Videos do {:error, "Failed to update video"} end end + + def set_captions( + _root, + %{video_id: video_id, captions: %{path: path, content_type: content_type}}, + %{ + context: %{user: user} + } + ) do + cond do + content_type != "text/xml" -> + {:error, "Unsupported content type: #{content_type}"} + + File.stat!(path).size > 10_000_000 -> + {:error, "File must be < 10MB"} + + true -> + video = DB.Repo.get!(DB.Schema.Video, video_id) + captions_file_content = File.read!(path) + parsed = CF.Videos.CaptionsSrv1Parser.parse_file(captions_file_content) + + Multi.new() + |> Multi.insert( + :caption, + VideoCaption.changeset(%VideoCaption{ + video_id: video.id, + raw: captions_file_content, + parsed: parsed, + format: "xml" + }) + ) + |> Multi.run( + :action, + fn _repo, %{caption: caption} -> + CF.Actions.ActionCreator.action_upload_video_captions(user.id, video.id, caption) + |> DB.Repo.insert!() + + {:ok, caption} + end + ) + |> DB.Repo.transaction() + + {:ok, video} + end + end end diff --git a/apps/cf_graphql/lib/schema/input_objects.ex b/apps/cf_graphql/lib/schema/input_objects.ex deleted file mode 100644 index 2f559970..00000000 --- a/apps/cf_graphql/lib/schema/input_objects.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule CF.Graphql.Schema.InputObjects do - use Absinthe.Schema.Notation - - import_types(CF.Graphql.Schema.InputObjects.{ - VideoFilter, - StatementFilter - }) -end diff --git a/apps/cf_graphql/lib/schema/input_objects/statement_filter.ex b/apps/cf_graphql/lib/schema/input_objects/statement_filter.ex index 212901cf..9364c70d 100644 --- a/apps/cf_graphql/lib/schema/input_objects/statement_filter.ex +++ b/apps/cf_graphql/lib/schema/input_objects/statement_filter.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.InputObjects.StatementFilter do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo @desc "Props to filter statements on" input_object :statement_filter do diff --git a/apps/cf_graphql/lib/schema/input_objects/video_filter.ex b/apps/cf_graphql/lib/schema/input_objects/video_filter.ex index 1f30dc18..55c10e8b 100644 --- a/apps/cf_graphql/lib/schema/input_objects/video_filter.ex +++ b/apps/cf_graphql/lib/schema/input_objects/video_filter.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.InputObjects.VideoFilter do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo @desc "Props to filter videos on" input_object :video_filter do diff --git a/apps/cf_graphql/lib/schema/schema.ex b/apps/cf_graphql/lib/schema/schema.ex index e0b1458e..e30a7a33 100644 --- a/apps/cf_graphql/lib/schema/schema.ex +++ b/apps/cf_graphql/lib/schema/schema.ex @@ -2,9 +2,42 @@ 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) + + import_types(CF.Graphql.Schema.Types.{ + AppInfo, + Comment, + Notification, + Paginated, + Source, + Speaker, + Statement, + Statistics, + Subscription, + UserAction, + User, + Video, + VideoCaption + }) + + import_types(CF.Graphql.Schema.InputObjects.{ + VideoFilter, + StatementFilter + }) + + def context(ctx) do + loader = + Dataloader.new() + |> Dataloader.add_source(DB.Repo, Dataloader.Ecto.new(DB.Repo)) + + Map.put(ctx, :loader, loader) + end - import_types(CF.Graphql.Schema.Types) - import_types(CF.Graphql.Schema.InputObjects) + def plugins do + [Absinthe.Middleware.Dataloader | Absinthe.Plugin.defaults()] + end # Query API @@ -110,5 +143,15 @@ defmodule CF.Graphql.Schema do resolve(&Resolvers.Videos.edit/3) end + + field :set_video_captions, :video do + middleware(Middleware.RequireAuthentication) + middleware(Middleware.RequireReputation, 450) + + arg(:video_id, non_null(:id)) + arg(:captions, non_null(:upload)) + + resolve(&Resolvers.Videos.set_captions/3) + end end end diff --git a/apps/cf_graphql/lib/schema/types.ex b/apps/cf_graphql/lib/schema/types.ex deleted file mode 100644 index dcc47593..00000000 --- a/apps/cf_graphql/lib/schema/types.ex +++ /dev/null @@ -1,19 +0,0 @@ -defmodule CF.Graphql.Schema.Types do - use Absinthe.Schema.Notation - - import_types(CF.Graphql.Schema.Types.{ - AppInfo, - Comment, - Notification, - Paginated, - Source, - Speaker, - Statement, - Statistics, - Subscription, - UserAction, - User, - Video, - VideoCaption - }) -end diff --git a/apps/cf_graphql/lib/schema/types/app_info.ex b/apps/cf_graphql/lib/schema/types/app_info.ex index 6aae1421..da0927d8 100644 --- a/apps/cf_graphql/lib/schema/types/app_info.ex +++ b/apps/cf_graphql/lib/schema/types/app_info.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.Types.AppInfo do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo @desc "Information about the application" object :app_info do diff --git a/apps/cf_graphql/lib/schema/types/comment.ex b/apps/cf_graphql/lib/schema/types/comment.ex index bbfa7e42..9e916c50 100644 --- a/apps/cf_graphql/lib/schema/types/comment.ex +++ b/apps/cf_graphql/lib/schema/types/comment.ex @@ -4,7 +4,8 @@ defmodule CF.Graphql.Schema.Types.Comment do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo + + import Absinthe.Resolution.Helpers, only: [dataloader: 1] import CF.Graphql.Schema.Utils alias CF.Graphql.Resolvers @@ -13,7 +14,7 @@ defmodule CF.Graphql.Schema.Types.Comment do field(:id, non_null(:id)) @desc "User who made the comment" field :user, :user do - resolve(assoc(:user)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end @@ -31,7 +32,7 @@ defmodule CF.Graphql.Schema.Types.Comment do @desc "Source of the scomment. If null, a text must be set" field :source, :source do - resolve(assoc(:source)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end diff --git a/apps/cf_graphql/lib/schema/types/notification.ex b/apps/cf_graphql/lib/schema/types/notification.ex index 8881678c..46b2331c 100644 --- a/apps/cf_graphql/lib/schema/types/notification.ex +++ b/apps/cf_graphql/lib/schema/types/notification.ex @@ -4,10 +4,9 @@ defmodule CF.Graphql.Schema.Types.Notification do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo - import CF.Graphql.Schema.Utils - import_types(CF.Graphql.Schema.Types.Paginated) + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import CF.Graphql.Schema.Utils @desc "A user notification" object :notification do @@ -20,7 +19,7 @@ defmodule CF.Graphql.Schema.Types.Notification do field(:seen_at, :string) @desc "Action the notification is referencing" field :action, :user_action do - resolve(assoc(:action)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end end diff --git a/apps/cf_graphql/lib/schema/types/paginated.ex b/apps/cf_graphql/lib/schema/types/paginated.ex index 578ce57c..2afadb4f 100644 --- a/apps/cf_graphql/lib/schema/types/paginated.ex +++ b/apps/cf_graphql/lib/schema/types/paginated.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.Types.Paginated do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo object :paginated do field(:page_number, :integer) diff --git a/apps/cf_graphql/lib/schema/types/source.ex b/apps/cf_graphql/lib/schema/types/source.ex index 91bf7184..ee87fe43 100644 --- a/apps/cf_graphql/lib/schema/types/source.ex +++ b/apps/cf_graphql/lib/schema/types/source.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.Types.Source do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo @desc "An URL pointing toward a source (article, video, pdf...)" object :source do diff --git a/apps/cf_graphql/lib/schema/types/speaker.ex b/apps/cf_graphql/lib/schema/types/speaker.ex index a3834511..52369075 100644 --- a/apps/cf_graphql/lib/schema/types/speaker.ex +++ b/apps/cf_graphql/lib/schema/types/speaker.ex @@ -4,7 +4,9 @@ defmodule CF.Graphql.Schema.Types.Speaker do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo + + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import Absinthe.Resolution.Helpers, only: [dataloader: 1] import CF.Graphql.Schema.Utils alias CF.Graphql.Resolvers @@ -26,7 +28,7 @@ defmodule CF.Graphql.Schema.Types.Speaker do field(:picture, :string, do: resolve(&Resolvers.Speakers.picture/3)) @desc "List of speaker's videos" field :videos, list_of(:video) do - resolve(assoc(:videos)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end end diff --git a/apps/cf_graphql/lib/schema/types/statement.ex b/apps/cf_graphql/lib/schema/types/statement.ex index 1ea1f78c..bd47d104 100644 --- a/apps/cf_graphql/lib/schema/types/statement.ex +++ b/apps/cf_graphql/lib/schema/types/statement.ex @@ -4,10 +4,9 @@ defmodule CF.Graphql.Schema.Types.Statement do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo - import CF.Graphql.Schema.Utils - import_types(CF.Graphql.Schema.Types.{Paginated, Speaker, Comment}) + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import CF.Graphql.Schema.Utils @desc "A transcript or a description of the picture" object :statement do @@ -21,19 +20,19 @@ defmodule CF.Graphql.Schema.Types.Statement do @desc "Statement's speaker. Null if statement describes picture" field :speaker, :speaker do - resolve(assoc(:speaker)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end @desc "List of users comments and facts for this statement" field :comments, list_of(:comment) do - resolve(assoc(:comments)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end @desc "The video associated with this statement" field :video, :video do - resolve(assoc(:video)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end end diff --git a/apps/cf_graphql/lib/schema/types/statistics.ex b/apps/cf_graphql/lib/schema/types/statistics.ex index bd807df8..afccff74 100644 --- a/apps/cf_graphql/lib/schema/types/statistics.ex +++ b/apps/cf_graphql/lib/schema/types/statistics.ex @@ -5,7 +5,6 @@ defmodule CF.Graphql.Schema.Types.Statistics do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo alias CF.Graphql.Resolvers @desc "Statistics about the platform community" diff --git a/apps/cf_graphql/lib/schema/types/subscription.ex b/apps/cf_graphql/lib/schema/types/subscription.ex index 74dbd85e..8939d6ec 100644 --- a/apps/cf_graphql/lib/schema/types/subscription.ex +++ b/apps/cf_graphql/lib/schema/types/subscription.ex @@ -4,8 +4,8 @@ defmodule CF.Graphql.Schema.Types.Subscription do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo + import Absinthe.Resolution.Helpers, only: [dataloader: 1] import CF.Graphql.Schema.Utils alias DB.Type.VideoHashId @@ -49,19 +49,19 @@ defmodule CF.Graphql.Schema.Types.Subscription do @desc "Associated video" field :video, :video do complexity(join_complexity()) - resolve(assoc(:video)) + resolve(dataloader(DB.Repo)) end @desc "Associated statement" field :statement, :statement do complexity(join_complexity()) - resolve(assoc(:statement)) + resolve(dataloader(DB.Repo)) end @desc "Associated comment" field :comment, :comment do complexity(join_complexity()) - resolve(assoc(:comment)) + resolve(dataloader(DB.Repo)) end end end diff --git a/apps/cf_graphql/lib/schema/types/user.ex b/apps/cf_graphql/lib/schema/types/user.ex index a47b5f40..047614bb 100644 --- a/apps/cf_graphql/lib/schema/types/user.ex +++ b/apps/cf_graphql/lib/schema/types/user.ex @@ -4,17 +4,24 @@ defmodule CF.Graphql.Schema.Types.User do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo import CF.Graphql.Schema.Utils alias CF.Graphql.Schema.Middleware alias CF.Graphql.Resolvers - import_types(CF.Graphql.Schema.Types.Paginated) - import_types(CF.Graphql.Schema.Types.Notification) + @desc "The notifications status" + enum :notifications_filter do + value(:all, description: "All notifications") + value(:seen, description: "Seen notifications") + value(:unseen, description: "Unseen notifications") + end - enum(:notifications_filter, values: [:all, :seen, :unseen]) - enum(:activity_log_direction, values: [:all, :author, :target]) + @desc "Whether the user was a target or an author of the action" + enum :activity_log_direction do + value(:all, description: "All actions") + value(:author, description: "Actions taken by the author") + value(:target, description: "Actions taken against the target") + end @desc "A user registered on the website" object :user do diff --git a/apps/cf_graphql/lib/schema/types/user_action.ex b/apps/cf_graphql/lib/schema/types/user_action.ex index 189f9878..bacf5393 100644 --- a/apps/cf_graphql/lib/schema/types/user_action.ex +++ b/apps/cf_graphql/lib/schema/types/user_action.ex @@ -4,7 +4,8 @@ defmodule CF.Graphql.Schema.Types.UserAction do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo + + import Absinthe.Resolution.Helpers, only: [dataloader: 1] import CF.Graphql.Schema.Utils alias DB.Type.VideoHashId @@ -16,7 +17,7 @@ defmodule CF.Graphql.Schema.Types.UserAction do field(:user_id, :id) @desc "User who made the action" field :user, :user do - resolve(assoc(:user)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end @@ -24,7 +25,7 @@ defmodule CF.Graphql.Schema.Types.UserAction do field(:target_user_id, :id) @desc "User targeted by the action" field :target_user, :user do - resolve(assoc(:target_user)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end @@ -60,25 +61,25 @@ defmodule CF.Graphql.Schema.Types.UserAction do @desc "Associated video" field :video, :video do complexity(join_complexity()) - resolve(assoc(:video)) + resolve(dataloader(DB.Repo)) end @desc "Associated statement" field :statement, :statement do complexity(join_complexity()) - resolve(assoc(:statement)) + resolve(dataloader(DB.Repo)) end @desc "Associated comment" field :comment, :comment do complexity(join_complexity()) - resolve(assoc(:comment)) + resolve(dataloader(DB.Repo)) end @desc "Associated speaker" field :speaker, :speaker do complexity(join_complexity()) - resolve(assoc(:speaker)) + resolve(dataloader(DB.Repo)) end @desc "A map with all the changes made by this action" diff --git a/apps/cf_graphql/lib/schema/types/video.ex b/apps/cf_graphql/lib/schema/types/video.ex index 309f6397..eacbac4f 100644 --- a/apps/cf_graphql/lib/schema/types/video.ex +++ b/apps/cf_graphql/lib/schema/types/video.ex @@ -4,12 +4,11 @@ defmodule CF.Graphql.Schema.Types.Video do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo + + import Absinthe.Resolution.Helpers, only: [dataloader: 1] import CF.Graphql.Schema.Utils alias CF.Graphql.Resolvers - import_types(CF.Graphql.Schema.Types.{Paginated, Statement, Speaker}) - @desc "Identifies a video. Only Youtube is supported at the moment" object :video do @desc "Unique identifier as an integer" @@ -42,7 +41,7 @@ defmodule CF.Graphql.Schema.Types.Video do field(:unlisted, non_null(:boolean)) @desc "List all non-removed speakers for this video" field :speakers, list_of(:speaker) do - resolve(assoc(:speakers)) + resolve(dataloader(DB.Repo)) complexity(join_complexity()) end diff --git a/apps/cf_graphql/lib/schema/types/video_caption.ex b/apps/cf_graphql/lib/schema/types/video_caption.ex index 6a964a4f..f3dba243 100644 --- a/apps/cf_graphql/lib/schema/types/video_caption.ex +++ b/apps/cf_graphql/lib/schema/types/video_caption.ex @@ -4,7 +4,6 @@ defmodule CF.Graphql.Schema.Types.VideoCaption do """ use Absinthe.Schema.Notation - use Absinthe.Ecto, repo: DB.Repo @desc "Information about the application" object :video_caption do diff --git a/apps/cf_graphql/mix.exs b/apps/cf_graphql/mix.exs index a9121937..2dbcafd9 100644 --- a/apps/cf_graphql/mix.exs +++ b/apps/cf_graphql/mix.exs @@ -38,8 +38,8 @@ defmodule CF.Graphql.Mixfile do {:plug, "~> 1.7"}, {:cowboy, "~> 2.0"}, {:corsica, "~> 2.1"}, - {:absinthe_ecto, "~> 0.1.3"}, - {:absinthe_plug, "~> 1.4.1"}, + {:absinthe_plug, "~> 1.5"}, + {:dataloader, "~> 2.0.2"}, {:kaur, "~> 1.1"}, {:poison, "~> 3.1"}, diff --git a/apps/cf_jobs/lib/jobs/download_captions.ex b/apps/cf_jobs/lib/jobs/download_captions.ex index c5d0214d..8e2b3ae8 100644 --- a/apps/cf_jobs/lib/jobs/download_captions.ex +++ b/apps/cf_jobs/lib/jobs/download_captions.ex @@ -47,7 +47,7 @@ defmodule CF.Jobs.DownloadCaptions do defp get_videos() do Repo.all( from(v in Video, - limit: 15, + limit: 5, left_join: captions in VideoCaption, on: captions.video_id == v.id, where: diff --git a/apps/cf_jobs/test/jobs/moderation_test.exs b/apps/cf_jobs/test/jobs/moderation_test.exs index 5e1471a1..a6848bef 100644 --- a/apps/cf_jobs/test/jobs/moderation_test.exs +++ b/apps/cf_jobs/test/jobs/moderation_test.exs @@ -44,7 +44,7 @@ defmodule CF.Jobs.ModerationTest do CF.Jobs.Moderation.update() CF.Jobs.Reputation.update() - refute_deleted(comment) + assert_not_deleted(comment) # Un-report comment assert Repo.get!(Comment, comment.id).is_reported == false # Flags are cleared @@ -63,7 +63,7 @@ defmodule CF.Jobs.ModerationTest do CF.Jobs.Moderation.update() CF.Jobs.Reputation.update() - refute_deleted(comment) + assert_not_deleted(comment) # Stays reported assert Repo.get!(Comment, comment.id).is_reported == true # Doesn't clear flags diff --git a/apps/cf_rest_api/mix.exs b/apps/cf_rest_api/mix.exs index 1da9a4d3..4f2b53d7 100644 --- a/apps/cf_rest_api/mix.exs +++ b/apps/cf_rest_api/mix.exs @@ -44,7 +44,7 @@ defmodule CF.RestApi.Mixfile do {:phoenix_pubsub, "~> 2.0"}, {:jason, "~> 1.4"}, {:poison, "~> 3.1"}, - {:plug_cowboy, "~> 2.1"}, + {:plug_cowboy, "~> 2.7.2"}, # ---- Internal ---- {:cf, in_umbrella: true}, diff --git a/apps/db/lib/db_type/entity.ex b/apps/db/lib/db_type/entity.ex index 9baffe67..20e3cc0f 100644 --- a/apps/db/lib/db_type/entity.ex +++ b/apps/db/lib/db_type/entity.ex @@ -8,5 +8,6 @@ defenum( comment: 4, fact: 5, user_action: 6, - user: 7 + user: 7, + video_caption: 8 ) diff --git a/apps/db/lib/db_type/user_action_type.ex b/apps/db/lib/db_type/user_action_type.ex index 3fba7623..4fe32c93 100644 --- a/apps/db/lib/db_type/user_action_type.ex +++ b/apps/db/lib/db_type/user_action_type.ex @@ -27,9 +27,11 @@ defenum( email_confirmed: 100, collective_moderation: 101, start_automatic_statements_extraction: 102, - # Deprecated. Can safelly be re-used - action_banned: 102, + upload: 110, + # Flags abused_flag: 103, confirmed_flag: 104, + # Deprecated + action_banned: 102, social_network_linked: 105 ) diff --git a/mix.lock b/mix.lock index 5a9c2ba9..3df9cba7 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,6 @@ %{ - "absinthe": {:hex, :absinthe, "1.4.16", "0933e4d9f12652b12115d5709c0293a1bf78a22578032e9ad0dad4efee6b9eb1", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "076b8bd9552f4966ba1242f412f6c439b731169a36a0ddaaffcd3893828f5bf6"}, - "absinthe_ecto": {:hex, :absinthe_ecto, "0.1.3", "420b68129e79fe4571a4838904ba03e282330d335da47729ad52ffd7b8c5fcb1", [:mix], [{:absinthe, "~> 1.3.0 or ~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "355b9db34abfab96ae1e025434b66e11002babcf4fe6b7144d26ff7548985f52"}, - "absinthe_plug": {:hex, :absinthe_plug, "1.4.7", "939b6b9e1c7abc6b399a5b49faa690a1fbb55b195c670aa35783b14b08ccec7a", [:mix], [{:absinthe, "~> 1.4.11", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c6ecb0e56a963287ac252d0563e5b33b84b300ce8203d3d1410dddb5dc6d08e9"}, + "absinthe": {:hex, :absinthe, "1.7.8", "43443d12ad2b4fcce60e257ac71caf3081f3d5c4ddd5eac63a02628bcaf5b556", [:mix], [{:dataloader, "~> 1.0.0 or ~> 2.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2.1 or ~> 0.3", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c4085df201892a498384f997649aedb37a4ce8a726c170d5b5617ed3bf45d40b"}, + "absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"}, "algoliax": {:hex, :algoliax, "0.7.1", "473746d748c14bd6b8bc34ad7725e331d968cd1c67e3daf35f93c873123fe812", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:hackney, "~> 1.18", [hex: :hackney, repo: "hexpm", optional: false]}, {:inflex, "~> 2.0.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "399f76a412d20eb81c9977097890514a29d1b8cfffe191a69b660366fe906ed6"}, "approximate_histogram": {:hex, :approximate_histogram, "0.1.1", "198eb36681e763ed4baab6ca0682acec4ef642f60ba272f251d3059052f4f378", [:mix], [], "hexpm", "6cce003d09656efbfe80b4a50f19e6c1f8eaf1424f08e4a96036b340fc67019d"}, "arc": {:hex, :arc, "0.11.0", "ac7a0cc03035317b6fef9fe94c97d7d9bd183a3e7ce1606aa0c175cfa8d1ba6d", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "e91a8bd676fca716f6e46275ae81fb96c0bbc7a9d5b96cac511ae190588eddd0"}, @@ -21,14 +20,15 @@ "comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "corsica": {:hex, :corsica, "2.1.3", "dccd094ffce38178acead9ae743180cdaffa388f35f0461ba1e8151d32e190e6", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "616c08f61a345780c2cf662ff226816f04d8868e12054e68963e95285b5be8bc"}, - "cowboy": {:hex, :cowboy, "2.11.0", "356bf784599cf6f2cdc6ad12fdcfb8413c2d35dab58404cf000e1feaed3f5645", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "0fa395437f1b0e104e0e00999f39d2ac5f4082ac5049b67a5b6d56ecc31b1403"}, - "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"}, - "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, + "cowboy": {:hex, :cowboy, "2.13.0", "09d770dd5f6a22cc60c071f432cd7cb87776164527f205c5a6b0f24ff6b38990", [:make, :rebar3], [{:cowlib, ">= 2.14.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e724d3a70995025d654c1992c7b11dbfea95205c047d86ff9bf1cda92ddc5614"}, + "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, + "cowlib": {:hex, :cowlib, "2.14.0", "623791c56c1cc9df54a71a9c55147a401549917f00a2e48a6ae12b812c586ced", [:make, :rebar3], [], "hexpm", "0af652d1550c8411c3b58eed7a035a7fb088c0b86aff6bc504b0bc3b7f791aa2"}, "credo": {:hex, :credo, "1.7.5", "643213503b1c766ec0496d828c90c424471ea54da77c8a168c725686377b9545", [: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", "f799e9b5cd1891577d8c773d245668aa74a2fcd15eb277f51a0131690ebfb3fd"}, "crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"}, "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "12c0d07bcf00b41a9b3da1e9cf52eb05c04cb9ed1714b1ae2209d0d41b19af3c"}, + "dataloader": {:hex, :dataloader, "2.0.2", "c45075e0692e68638a315e14f747bd8d7065fb5f38705cf980f62d4cd344401f", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:opentelemetry_process_propagator, "~> 0.2.1 or ~> 0.3", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4c6cabc0b55e96e7de74d14bf37f4a5786f0ab69aa06764a1f39dda40079b098"}, "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, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"}, + "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"}, "dns": {:hex, :dns, "2.2.0", "4721a79c2bccc25481930dffbfd06f40851321c3d679986af307111214bf124c", [:mix], [{:socket, "~> 0.3.13", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm", "13ed1ef36ce896211ec6ce5e02709dbfb12aa61d6255bda8d531577a0a5a56e0"}, "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, @@ -61,7 +61,7 @@ "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inflex": {:hex, :inflex, "2.0.0", "db69d542b8fdb23ac667f9bc0c2395a3983fa2da6ae2efa7ab5dc541928f7a75", [:mix], [], "hexpm", "c018852409bd48b03ad96ed53594186bc074bdd1519043a0ad1fa5697aac4399"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "kaur": {:hex, :kaur, "1.1.0", "fc60fd18100d73616d7370dc7aa1e0f869d904c21f33c93389597264f297d1a2", [:mix], [], "hexpm", "4089542e7a58030ae086b4db8100173515ee62c98db1c2a0d9bbdced98c9f8c4"}, @@ -75,6 +75,7 @@ "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm", "b93e2b1e564bdbadfecc297277f9e6d0902da645b417d6c9210f6038ac63489a"}, "mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "not_qwerty123": {:hex, :not_qwerty123, "2.2.1", "656e940159517f2d2f07ea0bb14e4ad376d176b5f4de07115e7a64902b5e13e3", [:mix], [{:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: false]}], "hexpm", "7637173b09eb7b26b29925039d5b92f7107c94a27cbe4d2ba8efb8b84d060c4b"}, "oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"}, @@ -84,14 +85,14 @@ "phoenix": {:hex, :phoenix, "1.5.14", "2d5db884be496eefa5157505ec0134e66187cb416c072272420c5509d67bf808", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "207f1aa5520320cbb7940d7ff2dde2342162cf513875848f88249ea0ba02fef7"}, "phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, - "plug": {:hex, :plug, "1.16.0", "1d07d50cb9bb05097fdf187b31cf087c7297aafc3fed8299aac79c128a707e47", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cbf53aa1f5c4d758a7559c0bd6d59e286c2be0c6a1fac8cc3eee2f638243b93e"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.6.2", "753611b23b29231fb916b0cdd96028084b12aff57bfd7b71781bd04b1dbeb5c9", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "951ed2433df22f4c97b85fdb145d4cee561f36b74854d64c06d896d7cd2921a7"}, + "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.7.2", "fdadb973799ae691bf9ecad99125b16625b1c6039999da5fe544d99218e662e4", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "245d8a11ee2306094840c000e8816f0cbed69a23fc0ac2bcf8d7835ae019bb2f"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "postgrex": {:hex, :postgrex, "0.17.4", "5777781f80f53b7c431a001c8dad83ee167bcebcf3a793e3906efff680ab62b3", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "6458f7d5b70652bc81c3ea759f91736c16a31be000f306d3c64bcdfe9a18b3cc"}, "quantum": {:hex, :quantum, "2.3.3", "83f565de81ac43b8fda4dd4266b209eaed29545d1c41e17aa6b75b08736c80f6", [:mix], [{:calendar, "~> 0.17", [hex: :calendar, repo: "hexpm", optional: true]}, {:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.12", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:swarm, "~> 3.3", [hex: :swarm, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: true]}], "hexpm", "01a63089a17f00f360ddad6c2f068c26d4e280999c2a6c2bce170d0bd6b2bd2e"}, - "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "ranch": {:hex, :ranch, "1.8.1", "208169e65292ac5d333d6cdbad49388c1ae198136e4697ae2f474697140f201c", [:make, :rebar3], [], "hexpm", "aed58910f4e21deea992a67bf51632b6d60114895eb03bb392bb733064594dd0"}, "req": {:hex, :req, "0.5.0", "6d8a77c25cfc03e06a439fb12ffb51beade53e3fe0e2c5e362899a18b50298b3", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "dda04878c1396eebbfdec6db6f3d4ca609e5c8846b7ee88cc56eb9891406f7a3"}, "scrivener": {:hex, :scrivener, "2.7.2", "1d913c965ec352650a7f864ad7fd8d80462f76a32f33d57d1e48bc5e9d40aba2", [:mix], [], "hexpm", "7866a0ec4d40274efbee1db8bead13a995ea4926ecd8203345af8f90d2b620d9"}, "scrivener_ecto": {:hex, :scrivener_ecto, "2.7.0", "cf64b8cb8a96cd131cdbcecf64e7fd395e21aaa1cb0236c42a7c2e34b0dca580", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm", "e809f171687806b0031129034352f5ae44849720c48dd839200adeaf0ac3e260"}, @@ -101,7 +102,7 @@ "stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"}, "swarm": {:hex, :swarm, "3.3.1", "b4d29c49310b92b4a84bd3be6a51d9616eaeda1899b7619201d0908d8d789bd8", [:mix], [{:gen_state_machine, "~> 2.0", [hex: :gen_state_machine, repo: "hexpm", optional: false]}, {:libring, "~> 1.0", [hex: :libring, repo: "hexpm", optional: false]}], "hexpm", "228dcaa2bbff0bf5a5e5bb4541cb0e2afcfc38afdd01f44e81912d2ad7a2e33b"}, "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, - "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "tesla": {:hex, :tesla, "1.10.0", "31c73de1e6b8c063e32bf4115922ed50eb1f56b3530907a49e39dd685bae95be", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "eb1cab91a367667ba7391d3d2c7c46c0ac016a80718b32fb179b54880962e0a8"}, "timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"}, "tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"}, diff --git a/scripts/download-captions.sh b/scripts/download-captions.sh new file mode 100755 index 00000000..0d62352d --- /dev/null +++ b/scripts/download-captions.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# A simple script that uses yt-dlp to download captions +# Usage: ./download-captions.sh [--locale=locale] + + + + +# Formats: vtt/ttml/srv3/srv2/srv1/json3 + +yt-dlp --write-auto-sub --skip-download --sub-langs fr --sub-format srv1 --output "subtitles.%(ext)s" "$1" \ No newline at end of file