--- /dev/null
+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()