diff --git a/lib/algora/admin/replace_with_youtube.ex b/lib/algora/admin/replace_with_youtube.ex new file mode 100644 index 0000000..fe516a0 --- /dev/null +++ b/lib/algora/admin/replace_with_youtube.ex @@ -0,0 +1,120 @@ +defmodule Algora.Admin.ReplaceWithYoutube do + alias Algora.Repo + alias Algora.Accounts.User + alias Algora.Library.Video + alias Algora.Ads.{Appearance, ContentMetrics, ProductReview} + alias Algora.Chat.Message + alias Algora.Library.{Segment, Subtitle} + alias Algora.Library + + import Ecto.Query + + # Algora.Admin.ReplaceWithYoutube.run(""" + # 2024-08-27,heyandras,4:49:14,https://www.youtube.com/watch?v=ooMn-3ISOmI + # 2024-08-30,heyandras,5:34:09,https://www.youtube.com/watch?v=RtYlh3ze0EI + # 2024-09-02,heyandras,6:03:05,https://www.youtube.com/watch?v=X958aGE5NfI + # 2024-09-03,heyandras,5:50:26,https://www.youtube.com/watch?v=xO0plZnHKMg + # """) + + def run(input) do + input + |> String.split("\n", trim: true) + |> Enum.each(&process_line/1) + end + + defp process_line(line) do + [date, handle, duration, youtube_url] = String.split(line, ",", trim: true) + user = Repo.get_by!(User, handle: handle) + + date = Date.from_iso8601!(date) + duration_seconds = Library.from_hhmmss(duration) + + old_videos = find_videos(user.id, date) + + new_video = create_youtube_video(user.id, duration_seconds, youtube_url, old_videos) + + transfer_related_records(old_videos, new_video) + + delete_old_videos(old_videos) + end + + defp create_youtube_video(user_id, duration_seconds, youtube_url, old_videos) do + video_id = extract_youtube_id(youtube_url) + + %Video{ + user_id: user_id, + inserted_at: get_date_from_old_videos(old_videos), + duration: duration_seconds, + url: youtube_url, + format: :youtube, + type: :vod, + uuid: Ecto.UUID.generate(), + title: get_title_from_old_videos(old_videos), + thumbnail_url: "https://i.ytimg.com/vi/#{video_id}/maxresdefault.jpg" + } + |> Repo.insert!() + end + + defp get_title_from_old_videos([first_video | _]), do: first_video.title + defp get_date_from_old_videos([first_video | _]), do: first_video.inserted_at + + defp find_videos(user_id, date) do + Video + |> where([v], v.user_id == ^user_id) + |> where([v], fragment("DATE(inserted_at) = ?", ^date)) + |> Repo.all() + end + + defp transfer_related_records(old_videos, new_video) do + old_video_ids = Enum.map(old_videos, & &1.id) + + transfer_appearances(old_video_ids, new_video.id) + transfer_content_metrics(old_video_ids, new_video.id) + transfer_product_reviews(old_video_ids, new_video.id) + transfer_messages(old_video_ids, new_video.id) + transfer_segments(old_video_ids, new_video.id) + transfer_subtitles(old_video_ids, new_video.id) + end + + defp transfer_appearances(old_video_ids, new_video_id) do + from(a in Appearance, where: a.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp transfer_content_metrics(old_video_ids, new_video_id) do + from(cm in ContentMetrics, where: cm.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp transfer_product_reviews(old_video_ids, new_video_id) do + from(pr in ProductReview, where: pr.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp transfer_messages(old_video_ids, new_video_id) do + from(m in Message, where: m.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp transfer_segments(old_video_ids, new_video_id) do + from(s in Segment, where: s.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp transfer_subtitles(old_video_ids, new_video_id) do + from(s in Subtitle, where: s.video_id in ^old_video_ids) + |> Repo.update_all(set: [video_id: new_video_id]) + end + + defp delete_old_videos(old_videos) do + Enum.each(old_videos, &Library.delete_video/1) + end + + defp extract_youtube_id(url) do + url + |> URI.parse() + |> Map.get(:query) + |> URI.decode_query() + |> Map.get("v") + end +end