]> Entropealabs - photography.git/commitdiff
initial commit
authorChristopher Coté <chris@entropealabs.com>
Wed, 5 Jan 2022 02:53:07 +0000 (21:53 -0500)
committerChristopher Coté <chris@entropealabs.com>
Wed, 5 Jan 2022 02:53:07 +0000 (21:53 -0500)
.tool-versions [new file with mode: 0644]
default.env [new file with mode: 0644]
image_metadata.exs [new file with mode: 0644]

diff --git a/.tool-versions b/.tool-versions
new file mode 100644 (file)
index 0000000..3e7be09
--- /dev/null
@@ -0,0 +1,2 @@
+erlang 24.2
+elixir 1.13.1-otp-24
diff --git a/default.env b/default.env
new file mode 100644 (file)
index 0000000..1e9f263
--- /dev/null
@@ -0,0 +1,2 @@
+export IMAGE_ROOT_PATH=/media/entone/extradrive1/Photos
+export IMAGE_OUTPUT_DIRECTORY=darktable_exported
diff --git a/image_metadata.exs b/image_metadata.exs
new file mode 100644 (file)
index 0000000..228af27
--- /dev/null
@@ -0,0 +1,83 @@
+Mix.install([
+  {:exexif, "~> 0.0.5"}
+])
+
+defmodule Images do
+  defmodule Image do
+    defstruct [
+      :datetime,
+      :flash,
+      :contrast,
+      :focal_length,
+      :white_balance,
+      :width,
+      :height,
+      :iso,
+      :aperture,
+      :orientation,
+      :path
+    ]
+  end
+
+  def parse_root(files, output_directory, root_path, meta \\ []) do
+    meta ++ Enum.flat_map(files, &parse_dir(&1, output_directory, Path.join(root_path, &1)))
+  end
+
+  def parse_dir(dir, dir, path) do
+    path
+    |> File.ls!()
+    |> Enum.map(&parse_image(Path.join(path, &1)))
+  end
+
+  def parse_dir(_dir, output_directory, path) do
+    if File.dir?(path) do
+      path
+      |> File.ls!()
+      |> Enum.flat_map(&parse_dir(&1, output_directory, Path.join(path, &1)))
+    else
+      []
+    end
+  end
+
+  def parse_date(datetime) do
+    [date, time] = String.split(datetime, " ")
+    date = String.replace(date, ":", "-")
+    {:ok, datetime, 0} = DateTime.from_iso8601("#{date}T#{time}Z")
+    datetime
+  end
+
+  def parse_image(path) do
+    {:ok, data} = Exexif.exif_from_jpeg_file(path)
+    datetime = parse_date(data.datetime_original)
+
+    %Image{
+      datetime: datetime,
+      flash: data.exif.flash,
+      contrast: data.exif.contrast,
+      focal_length: data.exif.focal_length,
+      white_balance: data.exif.white_balance,
+      width: data.exif.exif_image_width,
+      height: data.exif.exif_image_height,
+      iso: data.exif.iso_speed_ratings,
+      aperture: data.exif.f_number,
+      orientation: data.orientation,
+      path: get_path(path, datetime)
+    }
+  end
+
+  def get_path(image, datetime) do
+    data = File.read!(image)
+    hash = :crypto.hash(:md5, data)
+    encoded = Base.encode16(hash, case: :lower)
+    file = encoded <> ".jpg"
+    "/#{datetime.year}/#{datetime.month}/#{datetime.day}/#{file}"
+  end
+end
+
+root_path = System.fetch_env!("IMAGE_ROOT_PATH")
+output_directory = System.fetch_env!("IMAGE_OUTPUT_DIRECTORY")
+
+root_path
+|> File.ls!()
+|> Images.parse_root(output_directory, root_path)
+|> IO.inspect()