From: Christopher Coté Date: Sat, 14 Oct 2023 10:36:20 +0000 (-0400) Subject: add videos X-Git-Url: http://git.entropealabs.com/?a=commitdiff_plain;h=e0e9cca371713a38d2e83a512faec4f14995adc5;p=photography.git add videos --- diff --git a/media/database.db b/media/database.db index b8960097..20fc448e 100644 Binary files a/media/database.db and b/media/database.db differ diff --git a/media/database.db-shm b/media/database.db-shm index e2a1c8be..8730d8f9 100644 Binary files a/media/database.db-shm and b/media/database.db-shm differ diff --git a/media/database.db-wal b/media/database.db-wal index aa2dd10d..4d8eb336 100644 Binary files a/media/database.db-wal and b/media/database.db-wal differ diff --git a/media/default.env b/media/default.env index dbce8d59..8a19af83 100644 --- a/media/default.env +++ b/media/default.env @@ -1,5 +1,6 @@ export IMAGE_ROOT_PATH=XXXXXXXXXXXXXXXXXX export IMAGE_OUTPUT_DIRECTORY=XXXXXXXXXXXXXX +export VIDEO_ROOT_PATH=XXXXXXXXXXXXXXXXXX export AWS_ACCESS_KEY_ID=XXXXXXX export AWS_SECRET_ACCESS_KEY=XXXXXXXX export AWS_REGION=XXXXXXX diff --git a/media/image_metadata.exs b/media/image_metadata.exs index de6ae9c5..1c52c202 100644 --- a/media/image_metadata.exs +++ b/media/image_metadata.exs @@ -5,7 +5,8 @@ Mix.install( {:exexif, "~> 0.0.5"}, {:hackney, "~> 1.18"}, {:jason, "~> 1.3"}, - {:ecto_sqlite3, "~> 0.12"} + {:ecto_sqlite3, "~> 0.12"}, + {:sweet_xml, "~> 0.6"} ], config: [ ex_aws: [ @@ -62,6 +63,28 @@ defmodule Image do end end +defmodule Video do + use Ecto.Schema + import Ecto.Changeset + + schema "videos" do + field(:datetime, :utc_datetime) + field(:name, :string) + field(:hash, :string) + field(:original_path, :string) + field(:path, :string) + field(:uploaded, :boolean, default: false) + end + + def changeset(image, attrs) do + image + |> cast( + attrs, + ~w[datetime name hash original_path path uploaded]a + ) + end +end + defmodule Migration do use Ecto.Migration @@ -87,6 +110,136 @@ defmodule Migration do end end +defmodule Migration0 do + use Ecto.Migration + + def change do + create table("videos") do + add(:datetime, :utc_datetime) + add(:name, :string) + add(:hash, :string) + add(:original_path, :string) + add(:path, :string) + add(:uploaded, :boolean, default: false) + end + end +end + +defmodule Videos do + import Ecto.Query, warn: false + + def parse_root(root_path) do + files = + root_path + |> File.ls!() + + Enum.flat_map(files, &parse_dir(&1, Path.join(root_path, &1))) + end + + def parse_dir(dir, path) do + project = Path.join(path, "project.mp4") + thumb = Path.join(path, "thumbnail.jpg") + + if(File.dir?(path) and File.exists?(project) and File.exists?(thumb)) do + stat = File.stat!(project) + data = File.read!(project) + hash = :crypto.hash(:md5, data) + encoded = Base.encode16(hash, case: :lower) + file = encoded <> ".mp4" + + v = + case Repo.one(from(v in Video, where: v.original_path == ^project)) do + nil -> %Video{} + vi -> vi + end + + cs = + Video.changeset(v, %{ + name: dir, + datetime: NaiveDateTime.from_erl!(stat.mtime), + hash: encoded, + original_path: project, + path: "videos/#{file}" + }) + + cs = + if Ecto.Changeset.changed?(cs, :datetime) do + Ecto.Changeset.put_change(cs, :uploaded, false) + else + cs + end + + [cs] + else + [] + end + end + + def create_videos(videos, media_server) do + f = + EEx.eval_file("templates/videos.html.eex", + videos: videos, + media_server: media_server, + current_tag: "videos" + ) + + File.write!("../www/videos.html", f) + + Enum.each(videos, fn v -> + f = + EEx.eval_file("templates/video.html.eex", + video: v, + media_server: media_server, + current_tag: v.name + ) + + File.write!("../www/videos/#{v.hash}.html", f) + end) + end + + def upload_new(videos, bucket, region) do + new = Enum.reject(videos, & &1.uploaded) + + Enum.each(new, fn %{original_path: src_path, path: dest_path, hash: hash} = record -> + [_ | path] = + src_path + |> String.split("/") + |> Enum.reverse() + + thumbnail = ["thumbnail.jpg" | path] |> Enum.reverse() |> Enum.join("/") + thumbnail_data = File.read!(thumbnail) + + bucket + |> ExAws.S3.put_object("videos/#{hash}.jpg", thumbnail_data, + content_type: "image/jpeg", + acl: :public_read + ) + |> IO.inspect() + |> ExAws.request(region: region) + |> IO.inspect() + + src_path + |> ExAws.S3.Upload.stream_file() + |> ExAws.S3.upload(bucket, dest_path, + timeout: :infinity, + content_type: "video/mp4", + acl: :public_read + ) + |> IO.inspect() + |> ExAws.request(region: region) + |> IO.inspect() + |> handle_result(record) + end) + end + + def handle_result({:ok, _}, video) do + cs = Video.changeset(video, %{uploaded: true}) + Repo.update(cs) + end + + def handle_result({:error, er}), do: IO.inspect(er) +end + defmodule Images do import Ecto.Query, warn: false @@ -292,11 +445,16 @@ defmodule Main do _ok = Repo.__adapter__().storage_up(Repo.config()) {:ok, _} = Supervisor.start_link(children, strategy: :one_for_one) - Ecto.Migrator.run(Repo, [{0, Migration}], :up, all: true, log_migrations_sql: :debug) + + Ecto.Migrator.run(Repo, [{0, Migration}, {1, Migration0}], :up, + all: true, + log_migrations_sql: :debug + ) end end root_path = System.fetch_env!("IMAGE_ROOT_PATH") +video_root_path = System.fetch_env!("VIDEO_ROOT_PATH") output_directory = System.fetch_env!("IMAGE_OUTPUT_DIRECTORY") bucket = System.fetch_env!("AWS_BUCKET_NAME") region = System.fetch_env!("AWS_REGION") @@ -321,3 +479,12 @@ Images.create_images(images, tag_keys, date_keys, media_server) Images.create_tags(tags, tag_keys, date_keys, media_server) Images.create_dates(dates, tag_keys, date_keys, media_server) Images.upload_new(images, bucket, region) + +videos = + video_root_path + |> Videos.parse_root() + |> Enum.map(&Repo.insert_or_update!/1) + |> Enum.sort_by(& &1.datetime, {:desc, DateTime}) + +Videos.create_videos(videos, media_server) +Videos.upload_new(videos, bucket, region) diff --git a/media/templates/video.html.eex b/media/templates/video.html.eex new file mode 100644 index 00000000..e6f22e01 --- /dev/null +++ b/media/templates/video.html.eex @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/media/templates/videos.html.eex b/media/templates/videos.html.eex new file mode 100644 index 00000000..46681176 --- /dev/null +++ b/media/templates/videos.html.eex @@ -0,0 +1,27 @@ + + + + + + + + + + +
+
+ <%= for i <- videos do %> +
+ + + + <%= i.datetime |> DateTime.to_string() |> String.replace_suffix("Z", "") %> +
+ <% end %> +
+
+ + + diff --git a/www/css/videos.css b/www/css/videos.css new file mode 100644 index 00000000..7c88639f --- /dev/null +++ b/www/css/videos.css @@ -0,0 +1,48 @@ +html,body{ + background-color: #232323; + width: 100%; + margin: 0; + color: #cccccc; + font-family: sans-serif; +} + +main { + max-width: 1024px; + margin: auto; +} + +#header{ + height: 20px; + width: 100%; + background-color: #111111; + margin-bottom: 30px; + padding-top: 10px; + padding-bottom: 10px; +} + +#header span{ + margin-left: 10px; +} + +span#tag{ + color: #22FF22; + margin: 0; +} +span.datetime{ + color: #333333; + margin-top: 7px; + float: right; + font-size: 10px; +} + +.video{ + padding: 7px; + padding-bottom: 30px; + background-color: #EEEEEE; + margin-bottom: 30px; +} + +img{ + width: 100%; + padding-bottom: 33px; +} diff --git a/www/videos.html b/www/videos.html new file mode 100644 index 00000000..fa7e7cc1 --- /dev/null +++ b/www/videos.html @@ -0,0 +1,125 @@ + + + + + + + + + + +
+
+ +
+ + + + 2023-10-10 17:13:37 +
+ +
+ + + + 2023-10-06 14:42:29 +
+ +
+ + + + 2023-10-06 01:45:38 +
+ +
+ + + + 2023-09-10 22:50:39 +
+ +
+ + + + 2023-09-09 18:56:58 +
+ +
+ + + + 2023-09-01 14:49:26 +
+ +
+ + + + 2023-08-30 18:00:21 +
+ +
+ + + + 2023-08-21 18:50:32 +
+ +
+ + + + 2023-08-18 00:37:40 +
+ +
+ + + + 2023-08-11 02:41:09 +
+ +
+ + + + 2023-08-10 20:31:30 +
+ +
+ + + + 2023-08-09 16:46:48 +
+ +
+ + + + 2023-08-08 15:08:29 +
+ +
+ + + + 2023-08-07 18:41:39 +
+ +
+ + + + 2023-08-03 00:14:18 +
+ +
+
+ + + diff --git a/www/videos/096f12b38af0717d3d836dc059021a24.html b/www/videos/096f12b38af0717d3d836dc059021a24.html new file mode 100644 index 00000000..d68a0c6d --- /dev/null +++ b/www/videos/096f12b38af0717d3d836dc059021a24.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/0de505a86fe73b5f7af5f15115bf789f.html b/www/videos/0de505a86fe73b5f7af5f15115bf789f.html new file mode 100644 index 00000000..9ed2f281 --- /dev/null +++ b/www/videos/0de505a86fe73b5f7af5f15115bf789f.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/167e29dc5b7c05c05021395b4cca29e2.html b/www/videos/167e29dc5b7c05c05021395b4cca29e2.html new file mode 100644 index 00000000..053204e3 --- /dev/null +++ b/www/videos/167e29dc5b7c05c05021395b4cca29e2.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/326f1664b717ebb4a624881df2064332.html b/www/videos/326f1664b717ebb4a624881df2064332.html new file mode 100644 index 00000000..fbc236ff --- /dev/null +++ b/www/videos/326f1664b717ebb4a624881df2064332.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/3a3063a44387fc9d4f052754ea802733.html b/www/videos/3a3063a44387fc9d4f052754ea802733.html new file mode 100644 index 00000000..7d739d07 --- /dev/null +++ b/www/videos/3a3063a44387fc9d4f052754ea802733.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/3e7ce3ef0b169606cdbe342928719634.html b/www/videos/3e7ce3ef0b169606cdbe342928719634.html new file mode 100644 index 00000000..47efd93a --- /dev/null +++ b/www/videos/3e7ce3ef0b169606cdbe342928719634.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/3ea6f31ec67c8dad7bc3c20b796bda4c.html b/www/videos/3ea6f31ec67c8dad7bc3c20b796bda4c.html new file mode 100644 index 00000000..c9c556f4 --- /dev/null +++ b/www/videos/3ea6f31ec67c8dad7bc3c20b796bda4c.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/5d36ea72180a0640549445d93414eb6b.html b/www/videos/5d36ea72180a0640549445d93414eb6b.html new file mode 100644 index 00000000..76ff9e13 --- /dev/null +++ b/www/videos/5d36ea72180a0640549445d93414eb6b.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/64f7d344c9993bf7837bd5dbcc553207.html b/www/videos/64f7d344c9993bf7837bd5dbcc553207.html new file mode 100644 index 00000000..73a6a0e5 --- /dev/null +++ b/www/videos/64f7d344c9993bf7837bd5dbcc553207.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/716e81c5b84a2f691fdf0d183c4d84ea.html b/www/videos/716e81c5b84a2f691fdf0d183c4d84ea.html new file mode 100644 index 00000000..ac84cf4f --- /dev/null +++ b/www/videos/716e81c5b84a2f691fdf0d183c4d84ea.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/871d582560962db4cbd0593000d6bf9a.html b/www/videos/871d582560962db4cbd0593000d6bf9a.html new file mode 100644 index 00000000..3d6957c5 --- /dev/null +++ b/www/videos/871d582560962db4cbd0593000d6bf9a.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/a51ffdbe691059d692706ecd511eb756.html b/www/videos/a51ffdbe691059d692706ecd511eb756.html new file mode 100644 index 00000000..51909a65 --- /dev/null +++ b/www/videos/a51ffdbe691059d692706ecd511eb756.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/ab0f82d4281c57188c9f7e335aea6a65.html b/www/videos/ab0f82d4281c57188c9f7e335aea6a65.html new file mode 100644 index 00000000..acbc61bf --- /dev/null +++ b/www/videos/ab0f82d4281c57188c9f7e335aea6a65.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/c567671795fa33a74a1e9b77d2487470.html b/www/videos/c567671795fa33a74a1e9b77d2487470.html new file mode 100644 index 00000000..83069125 --- /dev/null +++ b/www/videos/c567671795fa33a74a1e9b77d2487470.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/c58497d555f0886271fe42ae18a69ba9.html b/www/videos/c58497d555f0886271fe42ae18a69ba9.html new file mode 100644 index 00000000..64ffe7fd --- /dev/null +++ b/www/videos/c58497d555f0886271fe42ae18a69ba9.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/cfeaa8d830c1da8ecf7f8749019c9c44.html b/www/videos/cfeaa8d830c1da8ecf7f8749019c9c44.html new file mode 100644 index 00000000..8f8eeb59 --- /dev/null +++ b/www/videos/cfeaa8d830c1da8ecf7f8749019c9c44.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/d1680f15b97bbe30f087cb95cc4a778c.html b/www/videos/d1680f15b97bbe30f087cb95cc4a778c.html new file mode 100644 index 00000000..35ac7291 --- /dev/null +++ b/www/videos/d1680f15b97bbe30f087cb95cc4a778c.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + + diff --git a/www/videos/dad6b28a1f34b2d7cb4f7af929ae7c05.html b/www/videos/dad6b28a1f34b2d7cb4f7af929ae7c05.html new file mode 100644 index 00000000..014cf98f --- /dev/null +++ b/www/videos/dad6b28a1f34b2d7cb4f7af929ae7c05.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+
+
+ +
+
+
+ + +