@@ -746,10 +746,52 @@ defmodule Algora.Accounts do
746
746
Repo . all ( from m in UserMedia , where: m . user_id == ^ user . id )
747
747
end
748
748
749
+ defp youtube_url? ( url ) do
750
+ String . contains? ( url , "youtube.com" ) or String . contains? ( url , "youtu.be" )
751
+ end
752
+
749
753
def create_user_media ( % User { } = user , attrs ) do
750
- % UserMedia { }
751
- |> UserMedia . changeset ( Map . put ( attrs , "user_id" , user . id ) )
752
- |> Repo . insert ( )
754
+ if youtube_url? ( attrs [ "url" ] ) do
755
+ % UserMedia { }
756
+ |> UserMedia . changeset ( Map . put ( attrs , "user_id" , user . id ) )
757
+ |> Repo . insert ( )
758
+ else
759
+ with { :ok , % { body: body , headers: headers } } <- fetch_media ( attrs [ "url" ] ) ,
760
+ object_path = media_object_path ( user . id , body ) ,
761
+ { :ok , _ } <-
762
+ Algora.S3 . upload ( body , object_path ,
763
+ content_type: extract_content_type ( headers ) ,
764
+ cache_control: "public, max-age=31536000, immutable"
765
+ ) do
766
+ s3_url = Path . join ( Algora.S3 . bucket_url ( ) , object_path )
767
+
768
+ % UserMedia { }
769
+ |> UserMedia . changeset ( attrs |> Map . put ( "user_id" , user . id ) |> Map . put ( "url" , s3_url ) )
770
+ |> Repo . insert ( )
771
+ else
772
+ error ->
773
+ Logger . error ( "Failed to process media: #{ inspect ( error ) } " )
774
+ { :error , :media_processing_failed }
775
+ end
776
+ end
777
+ end
778
+
779
+ defp media_object_path ( user_id , body ) do
780
+ hash = :md5 |> :crypto . hash ( body ) |> Base . encode16 ( case: :lower )
781
+ Path . join ( [ "media" , to_string ( user_id ) , hash ] )
782
+ end
783
+
784
+ defp fetch_media ( url ) do
785
+ :get
786
+ |> Finch . build ( url )
787
+ |> Finch . request ( Algora.Finch )
788
+ end
789
+
790
+ defp extract_content_type ( headers ) do
791
+ case List . keyfind ( headers , "content-type" , 0 ) do
792
+ { _ , content_type } -> content_type
793
+ nil -> "application/octet-stream"
794
+ end
753
795
end
754
796
755
797
def delete_user_media ( % UserMedia { } = media ) do
0 commit comments