defmodule Reblog.Provider do @moduledoc """ Reblog providers used to deploy built blogs. """ require Logger def deploy("local", args) do from = Map.get(args, :from) port = String.to_integer(Map.get(args, :port, "7575")) livereload = Map.get(args, :livereload, true) mapping = get_source_mapping(from) src = mapping["src"] {:ok, wsm_pid} = Reblog.Provider.Local.Livereload.start_link( %{ context: %{ src: Path.expand(Path.join(from, src)), name: mapping["name"], out: mapping["out"], generated_time: mapping["generated_time"], template_layout: mapping["template_layout"], pages: mapping["pages"], posts: mapping["posts"], assets: mapping["assets"], blog: mapping["blog"] } }) Logger.debug(fn -> ["Process:WebsocketManager@#{inspect wsm_pid}"] end) {:ok, cb_pid} = start_cowboy(wsm_pid, from, port, livereload) Logger.debug(fn -> ["Process:Cowboy@#{inspect cb_pid}"] end) Logger.info(fn -> ["Deployed -> http://localhost:#{port}"] end) ref = Process.monitor(cb_pid) receive do {:DOWN, ^ref, _, _, _} -> Logger.info(fn -> ["Server shutting down..."] end) end end # obtain source mapping used for livereload. defp get_source_mapping(from) do out_mapping = Path.join(from, ".map.yml") if not File.exists?(out_mapping) do raise "Unable to find '.map.yml' file in '#{from}'." end YamlElixir.read_from_file(out_mapping) end # http/ws host. defp start_cowboy(wsm, from, port, livereload) do dispatch = :cowboy_router.compile([ {:_, get_routes(wsm, from, livereload)} ]) :cowboy.start_clear(:http, [{:port, port}], %{ env: %{dispatch: dispatch}, middlewares: [:cowboy_router, :cowboy_handler] }) end defp get_routes(wsm, from, livereload) do cowboy_routes = if livereload do [ {"/live/[...]", Reblog.Provider.Local.Livereload.ClientHandler, %{from: from}}, {"/livereload", Reblog.Provider.Local.Livereload.WebSocket, [wsm]} ] else [] end cowboy_routes = cowboy_routes ++ [ {"/[...]", :cowboy_static, {:dir, from, [{:mimetypes, :cow_mimetypes, :all}]}} ] cowboy_routes end end