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_graphql/lib/resolvers/videos.ex b/apps/cf_graphql/lib/resolvers/videos.ex index 141e8245..90dd2f87 100644 --- a/apps/cf_graphql/lib/resolvers/videos.ex +++ b/apps/cf_graphql/lib/resolvers/videos.ex @@ -114,4 +114,32 @@ defmodule CF.Graphql.Resolvers.Videos do CF.LLMs.StatementsCreator.process_video!(video.id) {:ok, video} end + + def set_captions(_root, %{video_id: video_id, captions: captions_input}, %{ + context: %{user: user} + }) do + video = DB.Repo.get!(DB.Schema.Video, video_id) + + Multi.new() + |> Multi.insert( + :caption, + VideoCaption.changeset(%VideoCaption{ + video_id: video.id, + raw: captions_input, + parsed: captions_input, + format: "user-provided" + }) + ) + |> 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 + ) + + {:ok, video} + end end diff --git a/apps/cf_graphql/lib/schema/input_objects.ex b/apps/cf_graphql/lib/schema/input_objects.ex index 2f559970..bdfa3038 100644 --- a/apps/cf_graphql/lib/schema/input_objects.ex +++ b/apps/cf_graphql/lib/schema/input_objects.ex @@ -3,6 +3,7 @@ defmodule CF.Graphql.Schema.InputObjects do import_types(CF.Graphql.Schema.InputObjects.{ VideoFilter, - StatementFilter + StatementFilter, + VideoCaption }) end diff --git a/apps/cf_graphql/lib/schema/input_objects/video_caption.ex b/apps/cf_graphql/lib/schema/input_objects/video_caption.ex new file mode 100644 index 00000000..4accccb8 --- /dev/null +++ b/apps/cf_graphql/lib/schema/input_objects/video_caption.ex @@ -0,0 +1,10 @@ +defmodule CF.Graphql.Schema.InputObjects.VideoCaption do + use Absinthe.Schema.Notation + use Absinthe.Ecto, repo: DB.Repo + + input_object :video_caption_input do + field(:text, non_null(:string)) + field(:start, non_null(:float)) + field(:duration, :float) + end +end diff --git a/apps/cf_graphql/lib/schema/schema.ex b/apps/cf_graphql/lib/schema/schema.ex index e3c55404..dbb0a50f 100644 --- a/apps/cf_graphql/lib/schema/schema.ex +++ b/apps/cf_graphql/lib/schema/schema.ex @@ -99,5 +99,15 @@ defmodule CF.Graphql.Schema do resolve(&Resolvers.Videos.start_automatic_statements_extraction/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(list_of(:video_caption_input))) + + resolve(&Resolvers.Videos.set_captions/3) + end end end diff --git a/apps/cf_jobs/config/config.exs b/apps/cf_jobs/config/config.exs index cb522d10..d2c4a178 100644 --- a/apps/cf_jobs/config/config.exs +++ b/apps/cf_jobs/config/config.exs @@ -40,12 +40,12 @@ config :cf_jobs, CF.Jobs.Scheduler, overlap: false ], # Captions - download_captions: [ - # every minute - schedule: "*/1 * * * *", - task: {CF.Jobs.DownloadCaptions, :update, []}, - overlap: false - ] + # download_captions: [ + # # every hour + # schedule: "@hourly", + # task: {CF.Jobs.DownloadCaptions, :update, []}, + # overlap: false + # ] ] # Configure Postgres pool size