Current section
7 Versions
Jump to
Current section
7 Versions
Compare versions
6
files changed
+76
additions
-15
deletions
| @@ -1,5 +1,7 @@ | |
| 1 1 | # Honu |
| 2 2 | |
| 3 | + [](https://hex.pm/packages/honu) [](https://hexdocs.pm/honu/) |
| 4 | + |
| 3 5 | https://en.wikipedia.org/wiki/Green_sea_turtle#Taxonomy |
| 4 6 | |
| 5 7 | **A WIP file upload and attachment library for Ecto** |
| @@ -11,7 +13,7 @@ The package can be installed by adding `honu` to your list of dependencies in `m | |
| 11 13 | ```elixir |
| 12 14 | def deps do |
| 13 15 | [ |
| 14 | - {:honu, "~> 0.1.0"} |
| 16 | + {:honu, "~> 0.3.0"} |
| 15 17 | ] |
| 16 18 | end |
| 17 19 | ``` |
| @@ -38,4 +38,4 @@ | |
| 38 38 | {<<"optional">>,true}, |
| 39 39 | {<<"repository">>,<<"hexpm">>}, |
| 40 40 | {<<"requirement">>,<<"~> 0.11">>}]]}. |
| 41 | - {<<"version">>,<<"0.2.0">>}. |
| 41 | + {<<"version">>,<<"0.3.0">>}. |
| @@ -5,6 +5,22 @@ defmodule Honu.Attachments do | |
| 5 5 | alias Honu.Storage |
| 6 6 | alias Honu.Attachments.Blob |
| 7 7 | |
| 8 | + def attached?(%Blob{}), do: true |
| 9 | + def attached?(%Ecto.Association.NotLoaded{}), do: false |
| 10 | + def attached?(nil), do: false |
| 11 | + |
| 12 | + def attached?(struct) when is_struct(struct) do |
| 13 | + struct |
| 14 | + |> Map.get(:blob) |
| 15 | + |> attached?() |
| 16 | + end |
| 17 | + |
| 18 | + def attached?(list) when is_list(list) do |
| 19 | + list |
| 20 | + |> Enum.map(&attached?/1) |
| 21 | + |> Enum.all?() |
| 22 | + end |
| 23 | + |
| 8 24 | def get_attachment_by_key!(key, repo) do |
| 9 25 | repo.get_by!(Blob, key: key) |
| 10 26 | end |
| @@ -5,12 +5,17 @@ defmodule Honu.Attachments.Attachment do | |
| 5 5 | alias Honu.Attachments.AttachmentMap |
| 6 6 | alias Honu.Attachments.Blob |
| 7 7 | |
| 8 | - def attachments_changeset(changeset, attrs, attachments_names) do |
| 9 | - # TODO: Support both atom and string in map |
| 10 | - # Currently only string keys are supported |
| 11 | - Enum.reduce(attachments_names, changeset, fn {name, func}, cset -> |
| 12 | - attachment_changeset(cset, attrs, {to_string(name), func}) |
| 13 | - end) |
| 8 | + def attachments_changeset(changeset, attrs, attachments_names) |
| 9 | + when is_list(attachments_names) do |
| 10 | + if convert?(attrs) do |
| 11 | + Enum.reduce(attachments_names, changeset, fn {name, func}, cset -> |
| 12 | + attachment_changeset(cset, attrs, {name, func}) |
| 13 | + end) |
| 14 | + else |
| 15 | + Enum.reduce(attachments_names, changeset, fn {name, func}, cset -> |
| 16 | + attachment_changeset(cset, attrs, {Atom.to_string(name), func}) |
| 17 | + end) |
| 18 | + end |
| 14 19 | end |
| 15 20 | |
| 16 21 | defp attachment_changeset(changeset, attrs, {attachment_name, changeset_func}) |
| @@ -20,9 +25,16 @@ defmodule Honu.Attachments.Attachment do | |
| 20 25 | |
| 21 26 | changeset |
| 22 27 | |> cast(Map.put(attrs, attachment_name, attachments), []) |
| 23 | - |> cast_assoc(String.to_atom(attachment_name), with: changeset_func) |
| 28 | + |> cast_assoc(attachment_name |> to_string() |> String.to_existing_atom(), |
| 29 | + with: changeset_func |
| 30 | + ) |
| 24 31 | |> prepare_changes(fn changeset -> |
| 25 | - blob_ids = get_blob_ids(changeset, String.to_atom(attachment_name)) |
| 32 | + attachment_name = |
| 33 | + attachment_name |
| 34 | + |> to_string() |
| 35 | + |> String.to_existing_atom() |
| 36 | + |
| 37 | + blob_ids = get_blob_ids(changeset, attachment_name) |
| 26 38 | query = from(b in Blob, where: b.id in ^blob_ids) |
| 27 39 | changeset.repo.update_all(query, set: [deleted_at: NaiveDateTime.utc_now()]) |
| 28 40 | |
| @@ -38,7 +50,10 @@ defmodule Honu.Attachments.Attachment do | |
| 38 50 | changes when is_list(changes) -> |
| 39 51 | changes |
| 40 52 | |> Enum.filter(&(&1.action == :replace)) |
| 41 | - |> Enum.map(&(&1.data.blob_id)) |
| 53 | + |> Enum.map(& &1.data.blob_id) |
| 54 | + |
| 55 | + nil -> |
| 56 | + [] |
| 42 57 | |
| 43 58 | _change -> |
| 44 59 | get_has_one_blob_id(changeset, attachment_name) |
| @@ -52,4 +67,11 @@ defmodule Honu.Attachments.Attachment do | |
| 52 67 | attachment -> [attachment.blob_id] |
| 53 68 | end |
| 54 69 | end |
| 70 | + |
| 71 | + defp convert?(attrs) do |
| 72 | + attrs |
| 73 | + |> Map.keys() |
| 74 | + |> List.first() |
| 75 | + |> is_atom() |
| 76 | + end |
| 55 77 | end |
| @@ -20,13 +20,22 @@ end | |
| 20 20 | defimpl Honu.Attachments.AttachmentMap, for: Map do |
| 21 21 | def build(%{"file" => file} = attrs, attachment_name) do |
| 22 22 | %{ |
| 23 | - "name" => attachment_name, |
| 23 | + "name" => to_string(attachment_name), |
| 24 24 | "blob" => Honu.Attachments.Blob.build(file) |
| 25 25 | } |
| 26 26 | |> Map.merge(Map.delete(attrs, "file")) |
| 27 27 | |> Map.delete("id") |
| 28 28 | end |
| 29 29 | |
| 30 | + def build(%{file: file} = attrs, attachment_name) do |
| 31 | + %{ |
| 32 | + name: to_string(attachment_name), |
| 33 | + blob: Honu.Attachments.Blob.build(file) |
| 34 | + } |
| 35 | + |> Map.merge(Map.delete(attrs, :file)) |
| 36 | + |> Map.delete(:id) |
| 37 | + end |
| 38 | + |
| 30 39 | def build(%{"0" => map} = attrs, attachment_name) when is_map(map) do |
| 31 40 | Enum.reduce(attrs, %{}, fn attachment, acc -> |
| 32 41 | attachment |
| @@ -35,8 +44,20 @@ defimpl Honu.Attachments.AttachmentMap, for: Map do | |
| 35 44 | end) |
| 36 45 | end |
| 37 46 | |
| 38 | - def build(attrs, attachment_name) do |
| 39 | - Map.merge(%{"name" => attachment_name}, attrs) |
| 47 | + def build(%{0 => map} = attrs, attachment_name) when is_map(map) do |
| 48 | + Enum.reduce(attrs, %{}, fn attachment, acc -> |
| 49 | + attachment |
| 50 | + |> build_one_with_index(attachment_name) |
| 51 | + |> Map.merge(acc) |
| 52 | + end) |
| 53 | + end |
| 54 | + |
| 55 | + def build(%{id: _} = attrs, attachment_name) do |
| 56 | + Map.merge(%{name: to_string(attachment_name)}, attrs) |
| 57 | + end |
| 58 | + |
| 59 | + def build(%{"id" => _} = attrs, attachment_name) do |
| 60 | + Map.merge(%{"name" => to_string(attachment_name)}, attrs) |
| 40 61 | end |
| 41 62 | |
| 42 63 | defp build_one_with_index({id, attrs}, attachment_name) when is_map(attrs) do |
Loading more files…