Hakushi.Images (Hakushi v0.6.0)

Copy Markdown View Source

The images of a canvas (Hakushi.Kits.Images), checked on the server before they become nodes, and kept in the app's store with Storehouse.

The browser's content type is a claim. Storehouse reads the bytes of the file (Storehouse.Check): a PNG, JPEG, GIF or WebP image, from its signature, with its width and height from its header (a JPEG's turned as its EXIF orientation says, as browsers draw it). Any other file is refused, an SVG too (it may hold a script), and an image whose header has no size.

store/2 checks a file and stores it under a new key, in the store of config :storehouse, adapter: ... (the local disk, S3, or one of the app's); fetch/2 downloads an image from an address of the hosts an app allows, then stores it, so an image pasted by its address, or added by an agent, is the app's own file as an upload is.

Summary

Types

A stored image: a Storehouse.File, with its key and url in the store, the client's name, its checked content_type, bytes, width, height and checksum, and the URL of a smaller copy (preview), or nil.

Functions

The content type of an image's file extension (".png"), or nil for another.

The file extensions of the images a canvas takes, as an upload's accept.

Downloads the image at url, from a host of :hosts, then checks and stores it as store/2 does (Storehouse.fetch/2).

Whether url is an address that fetch/2 takes with hosts (https only).

Whether url is an address an image node may show: http or https, or a path of the app (/uploads/…).

Checks the image at path and stores it under a new key, with Storehouse.store/2. The file at path is left where it is.

The content types of the images a canvas takes.

Types

image()

@type image() :: Storehouse.File.t()

A stored image: a Storehouse.File, with its key and url in the store, the client's name, its checked content_type, bytes, width, height and checksum, and the URL of a smaller copy (preview), or nil.

Functions

content_type(extension)

@spec content_type(String.t()) :: String.t() | nil

The content type of an image's file extension (".png"), or nil for another.

extensions()

@spec extensions() :: [String.t()]

The file extensions of the images a canvas takes, as an upload's accept.

fetch(url, opts)

@spec fetch(String.t(), keyword()) :: {:ok, image()} | {:error, term()}

Downloads the image at url, from a host of :hosts, then checks and stores it as store/2 does (Storehouse.fetch/2).

Only https addresses (and http, with http: true) of the hosts the app allows are fetched, and a redirect only to one of them: the server never fetches an address a person or an agent chose freely, which could be one of the app's own network. A host is a name ("images.example.com") or a name with a leading *. for its subdomains ("*.example.com").

Options

  • :hosts - the hosts it fetches from (required).
  • :http - whether http addresses are fetched. The default is false.
  • :timeout - in milliseconds, for the whole download. The default is 10 seconds.
  • the options of store/2.

fetchable?(url, hosts)

@spec fetchable?(String.t(), [String.t()]) :: boolean()

Whether url is an address that fetch/2 takes with hosts (https only).

iex> Hakushi.Images.fetchable?("https://images.example.com/a.png", ["*.example.com"])
true

iex> Hakushi.Images.fetchable?("https://example.org/a.png", ["*.example.com"])
false

safe_url?(url)

@spec safe_url?(term()) :: boolean()

Whether url is an address an image node may show: http or https, or a path of the app (/uploads/…).

store(path, opts \\ [])

@spec store(Path.t(), keyword()) :: {:ok, image()} | {:error, term()}

Checks the image at path and stores it under a new key, with Storehouse.store/2. The file at path is left where it is.

A file that is not an image a canvas takes gives {:error, :not_an_image}; one over a limit, {:error, :too_large}.

Options

  • :name - the file's name, for its key and its node. The default is the base name of path.
  • :adapter - the store. The default is Storehouse.adapter/0.
  • :thumbnail - a function of the stored image (a Storehouse.File) and path that gives the URL of a smaller copy, or nil: the app makes and stores it (with image or vix, say). The canvas shows it when it is zoomed out. An exception, or a result that is not a URL, gives none.
  • :max_bytes - the largest file. The default is 10 MB.
  • :max_pixels - the most pixels (width × height). The default is 50 million.

types()

@spec types() :: [String.t()]

The content types of the images a canvas takes.