Skip to content
This repository was archived by the owner on Jul 19, 2019. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*~
node_modules
.DS_Store
_build/
mix.lock
deps/
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ cpan Mojolicious
perl server.pl
```

### Elixir
```elixir
mix deps.get
mix run --no-halt
```

And visit <http://localhost:3000/>. Try opening multiple tabs!

## Changing the port
Expand Down
22 changes: 22 additions & 0 deletions lib/reacttutorial.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule ReactTutorial do
def version, do: unquote(Mix.Project.config[:version])
def elixir_version, do: unquote(System.version)

use Application

def start( _type, _args ) do
import Supervisor.Spec, warn: false

children = [
worker(__MODULE__, [], function: :run)
]

opts = [strategy: :one_for_one, name: ReactTutorial.Supervisor]
Supervisor.start_link(children, opts)
end

def run do
{ :ok, _ } = Plug.Adapters.Cowboy.http(Server, [], port: 3000)
end

end
101 changes: 101 additions & 0 deletions lib/server.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
defmodule Server do
import Plug.Conn

def init(options) do
Hex.Shell.info("Server started: http://localhost:3000/")
options
end

def call(conn, _opts) do
http_res(conn, conn.request_path)
end

def http_res(conn, uri) do
cond do
uri =~ ~r"index.html$|^/$|.js$|.css" ->
fileName = get_file_name(uri)
conn
|> put_resp_content_type(get_content_type(conn.request_path))
|> send_resp(200, get_file_content(fileName))
uri == "/api/comments" ->
case conn.method do
"POST" ->
conn = parse(conn)
author = conn.params["author"]
text = conn.params["text"]
id = conn.params["id"]
# Hex.Shell.info("post #{conn.query_string} author:#{author} text:#{text} id:#{id}")
fileName = Path.join(root_path(), "comments.json")
newComment = %{"author" => author, "id" => id, "text" => text}
{:ok, content} = File.read("comments.json")
currentComments = Poison.Parser.parse!(content)
updatedCommentsJson = List.insert_at(currentComments, -1, newComment)
content = Poison.encode!(updatedCommentsJson)
File.write(fileName, content)
conn
|> send_resp(200, "post success")
_ ->
fileName = Path.join(root_path(), "comments.json")
conn
|> put_resp_content_type("application/json")
|> send_resp(200, get_file_content(fileName))
end
true ->
conn
|> send_resp(200, "Hello world")
end
end

def parse(conn, opts \\ []) do
opts = Keyword.put_new(opts, :parsers, [Plug.Parsers.URLENCODED, Plug.Parsers.MULTIPART])
Plug.Parsers.call(conn, Plug.Parsers.init(opts))
end

def get_file_name(uri) do
cond do
uri =~ ~r"index.html$|^/$" ->
Path.join(root_path(), "public/index.html")
uri =~ ~r".js$|.css" ->
Path.join(root_path(), "public" <> uri)
true ->
uri
end
end

def root_path() do
Path.join(__DIR__, "../") |> Path.expand()
end

def get_file_content(file) do
case File.read(file) do
{:ok, content} ->
content
{:error, _} ->
"404 not find!"
end
end

def get_content_type(request_path) do
cond do
request_path == "/" ->
"text/html"
request_path =~ ~r".html$|.htm$|.jsp$" ->
"text/html"
request_path =~ ~r".css$" ->
"text/css"
request_path =~ ~r".png$" ->
"image/png"
request_path =~ ~r".ico$" ->
"image/x-icon"
request_path =~ ~r".gif$" ->
"image/gif"
request_path =~ ~r".jpe$|.jpeg$" ->
"image/jpeg"
request_path =~ ~r".jpg$" ->
"application/x-jpg"
true ->
"text/plain"
end
end

end
35 changes: 35 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule Reacttutorial.Mixfile do
use Mix.Project

def project do
[app: :reacttutorial,
version: "0.0.1",
elixir: "~> 1.1",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps]
end

# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
[applications: [:logger,:cowboy],
mod: {ReactTutorial, []}]
end

# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type "mix help deps" for more examples and options
defp deps do
[{:cowboy, "~> 1.0" },
{:plug, "~> 0.14" },
{:poison, "~> 2.0"}]
end
end