-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Asset Configuration #239
Asset Configuration #239
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @xn some comments before we can move forward. Thanks
sites = Beacon.Registry.registered_sites() | ||
Enum.map(sites, fn site -> to_string(site) end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can let phoenix convert to string:
sites = Beacon.Registry.registered_sites() | |
Enum.map(sites, fn site -> to_string(site) end) | |
Beacon.Registry.registered_sites() |
|> send_to_provider(metadata) | ||
end | ||
|
||
def send_to_provider(asset, metadata) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def send_to_provider(asset, metadata) do | |
defp send_to_provider(asset, metadata) do |
@@ -0,0 +1,16 @@ | |||
defmodule Beacon.Admin.MediaLibrary.Provider.Repo do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The config is list(backend :: module())
. Perhaps we should rename to Backend.Repo
or rename :backends
to :providers
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backend.Repo is just fine.
"dockyard_2.jpg", | ||
"image/jpg" | ||
) | ||
metadata = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if we make building this struct private by moving FileMetadata.new/5
to inside def upload/1
? the caller doesn't need to know about it and it's less risky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The caller would just Beacon developers, right?
So my thinking for doing this is developer experience
- Lower cognitive overhead. It's easier to reason about a well defined struct, than a 5 param function (which order?) and still have to keep the idea of the struct anyway for working on the internals.
- The growth of the function signature of upload. 5 params in upload is already a bit much. Adding any opts to this turns it into a mess to think about. vid, What's an option vs parameter, etc.
- Testing. I can now create well named Metadata factories for reuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the benefits for testing and I agree that 5+ args is too much (it has 4 now). I'm just worried that we're exposing FileMetadata
internals that should be private. One could write upload(%FileMetadata{config: nil})
and break the pipeline, which I see is possible since the spec would look like @spec upload(FileMetadata.t)
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add a TODO: https://github.com/BeaconCMS/beacon/pull/239#discussion_r1194160478
close to def new
? To serve as a reminder to revisit it before v0.1 so we can move forward with this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
A developer could write upload(%FileMetadata{config: nil})
without a catchall, but it would have to go through a PR process.
If you simply prefer to have the FileMetadata constructed inside the function, that is fine and I'm happy to change it.
Doing that though means either upload needs to accept a file size, or we need to calculate it somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep it as it's and see how it plays as we work on Admin
lib/beacon/config.ex
Outdated
Registry.config!(site) | ||
end | ||
|
||
@spec config_for_mime_type(Beacon.Config.t(), MIME.t()) :: term() | ||
def config_for_mime_type(beacon_config, mime_type) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this fn can raise it's better to be append !
def config_for_mime_type(beacon_config, mime_type) do | |
def config_for_mime_type!(beacon_config, mime_type) do |
But it should be better to return a Beacon error with a friendly message instead of KeyError.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
lib/beacon/config.ex
Outdated
Registry.config!(site) | ||
end | ||
|
||
@spec config_for_mime_type(Beacon.Config.t(), MIME.t()) :: term() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could move Enum.into(%{})
into config_for_mime_type/2
@spec config_for_mime_type(Beacon.Config.t(), MIME.t()) :: term() | |
@spec config_for_mime_type(Beacon.Config.t(), MIME.t()) :: map() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the question here is, this function currently returns data of a type encoded by this module and do we want to return something else? I think when I originally wrote this, I hadn't created the mime_config
type.
So it should be @spec config_for_mime_type(Beacon.Config.t(), MIME.t()) :: mime_config()
unless you really want to return a map there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unless you really want to return a map there.
Nope. It was just to avoid forcing the caller to transform the returned data.
lib/beacon/config.ex
Outdated
@@ -48,6 +48,14 @@ defmodule Beacon.Config do | |||
""" | |||
@type template_formats :: [{format :: atom(), description :: String.t()}] | |||
|
|||
@type asset :: [{MIME.t(), mime_config()}] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think MIME.t/0
exists, it's just a String.t/0
:)
but we can have our own custom type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I meant to ask if you wanted anything special there and that was a place keeper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String.t/0
or a custom ContentType.t()
MediaType.t/0
works for me, whatever you prefer 👍🏻
|> Beacon.Config.config_for_mime_type(mime_type) | ||
|> Enum.into(%{}) | ||
|
||
%__MODULE__{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see some inconsistency on the "type" key:
- config.asset_formats
- metadata.allowed_types
- metadata.mime_type
- asset.file_type
The term "MIME type" was updated to "Media Type" as noted at https://www.iana.org/assignments/media-types/media-types.xhtml so we have 3 acceptable suggestions:
media_type
- technically the correct namemime_type
- still populartype
I'm more inclined to suggest calling it just type
because image/*
isn't a registered and valid media type and IANA calls the main categoryimage
as "type", see https://www.iana.org/assignments/media-types/image/webp - that would look like:
- config.asset_types
- metadata.allowed_types
- metadata.type
- asset.type
Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct on multiple accounts here.
*
is not a valid mime sub type- naming variance.
image/*
is a valid content type
, however.
I'm comfortable with your name changes. Does content_type
hold anything for you? It can point the way on what is expected there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
image/* is a valid content type, however
that's a good point, I'm okay with using content_type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was also glomming onto what Plug.Conn was doing:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the confusion but giving a second thought, I think it's better to call it media_type
for the following reasons:
type
is too genericmedia_type
is technically correctcontent_type
serves to another purpose- having
image/*
as the media type is fine since content type and Plug accepts it
Sounds good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
works for me!
Thanks for the great feedback, @leandrocp ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one
Adds config for assets allowed, backends and validations.
"image/jpeg"
or"image/*"