Commit 82f09ddb authored by Rémy Coutable's avatar Rémy Coutable

Initial commit

Signed-off-by: Rémy Coutable's avatarRémy Coutable <remy@rymai.me>
parents
# App artifacts
/_build
/db
/deps
/*.ez
# Generated on crash by the VM
erl_crash.dump
# Generated on crash by NPM
npm-debug.log
# Static artifacts
/assets/node_modules
# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
# this depending on your deployment strategy.
/priv/static/
# Files matching config/*.secret.exs pattern contain sensitive
# data and you should not commit them into version control.
#
# Alternatively, you may comment the line below and commit the
# secrets files as long as you replace their contents by environment
# variables.
/config/*.secret.exs
\ No newline at end of file
# ILoveBackend
To start your Phoenix server:
* Install dependencies with `mix deps.get`
* Create and migrate your database with `mix ecto.create && mix ecto.migrate`
* Install Node.js dependencies with `cd assets && npm install`
* Start Phoenix endpoint with `mix phx.server`
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
Ready to run in production? Please [check our deployment guides](http://www.phoenixframework.org/docs/deployment).
## Learn more
* Official website: http://www.phoenixframework.org/
* Guides: http://phoenixframework.org/docs/overview
* Docs: https://hexdocs.pm/phoenix
* Mailing list: http://groups.google.com/group/phoenix-talk
* Source: https://github.com/phoenixframework/phoenix
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"
// To use a separate vendor.js bundle, specify two files path
// http://brunch.io/docs/config#-files-
// joinTo: {
// "js/app.js": /^js/,
// "js/vendor.js": /^(?!js)/
// }
//
// To change the order of concatenation of files, explicitly mention here
// order: {
// before: [
// "vendor/js/jquery-2.1.1.js",
// "vendor/js/bootstrap.min.js"
// ]
// }
},
stylesheets: {
joinTo: "css/app.css"
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
// This option sets where we should place non-css and non-js assets in.
// By default, we set this to "/assets/static". Files in this directory
// will be copied to `paths.public`, which is "priv/static" by default.
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor"],
// Where to compile files to
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
}
},
modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},
npm: {
enabled: true
}
};
/* This file is for your main application css. */
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
// Brunch automatically concatenates all files in your
// watched paths. Those paths can be configured at
// config.paths.watched in "brunch-config.js".
//
// However, those files will only be executed if
// explicitly imported. The only exception are files
// in vendor, which are never wrapped in imports and
// therefore are always executed.
// Import dependencies
//
// If you no longer want to use a dependency, remember
// to also remove its path from "config.paths.watched".
import "phoenix_html"
// Import local files
//
// Local files can be imported directly using relative
// paths "./socket" or full ones "web/static/js/socket".
// import socket from "./socket"
// NOTE: The contents of this file will only be executed if
// you uncomment its entry in "assets/js/app.js".
// To use Phoenix channels, the first step is to import Socket
// and connect at the socket path in "lib/web/endpoint.ex":
import {Socket} from "phoenix"
let socket = new Socket("/socket", {params: {token: window.userToken}})
// When you connect, you'll often need to authenticate the client.
// For example, imagine you have an authentication plug, `MyAuth`,
// which authenticates the session and assigns a `:current_user`.
// If the current user exists you can assign the user's token in
// the connection for use in the layout.
//
// In your "lib/web/router.ex":
//
// pipeline :browser do
// ...
// plug MyAuth
// plug :put_user_token
// end
//
// defp put_user_token(conn, _) do
// if current_user = conn.assigns[:current_user] do
// token = Phoenix.Token.sign(conn, "user socket", current_user.id)
// assign(conn, :user_token, token)
// else
// conn
// end
// end
//
// Now you need to pass this token to JavaScript. You can do so
// inside a script tag in "lib/web/templates/layout/app.html.eex":
//
// <script>window.userToken = "<%= assigns[:user_token] %>";</script>
//
// You will need to verify the user token in the "connect/2" function
// in "lib/web/channels/user_socket.ex":
//
// def connect(%{"token" => token}, socket) do
// # max_age: 1209600 is equivalent to two weeks in seconds
// case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do
// {:ok, user_id} ->
// {:ok, assign(socket, :user, user_id)}
// {:error, reason} ->
// :error
// end
// end
//
// Finally, pass the token on connect as below. Or remove it
// from connect if you don't care about authentication.
socket.connect()
// Now that you are connected, you can join channels with a topic:
let channel = socket.channel("topic:subtopic", {})
channel.join()
.receive("ok", resp => { console.log("Joined successfully", resp) })
.receive("error", resp => { console.log("Unable to join", resp) })
export default socket
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"repository": {},
"license": "MIT",
"scripts": {
"deploy": "brunch build --production",
"watch": "brunch watch --stdin"
},
"dependencies": {
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html"
},
"devDependencies": {
"babel-brunch": "6.1.1",
"brunch": "2.10.9",
"clean-css-brunch": "2.10.0",
"uglify-js-brunch": "2.10.0"
}
}
# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
#
# To ban all spiders from the entire site uncomment the next two lines:
# User-agent: *
# Disallow: /
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
use Mix.Config
# General application configuration
config :i_love_backend,
ecto_repos: [ILoveBackend.Repo]
# Configures the endpoint
config :i_love_backend, ILoveBackendWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "BsSzuYD4hw+cvO9s5ZosMB4G1k0/oI22ZdKwcd+GKq97AYRFeZk3ZEa2/Mhaj0aC",
render_errors: [view: ILoveBackendWeb.ErrorView, accepts: ~w(html json)],
pubsub: [name: ILoveBackend.PubSub,
adapter: Phoenix.PubSub.PG2]
config :i_love_backend, admin_basic_auth: [
username: System.get_env("BASIC_AUTH_USERNAME") || "admin",
password: System.get_env("BASIC_AUTH_PASSWORD") || "admin",
realm: "Admin Area"
]
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env}.exs"
use Mix.Config
# For development, we disable any cache and enable
# debugging and code reloading.
#
# The watchers configuration can be used to run external
# watchers to your application. For example, we use it
# with brunch.io to recompile .js and .css sources.
config :i_love_backend, ILoveBackendWeb.Endpoint,
http: [port: 4000],
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
cd: Path.expand("../assets", __DIR__)]]
# ## SSL Support
#
# In order to use HTTPS in development, a self-signed
# certificate can be generated by running the following
# command from your terminal:
#
# openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout priv/server.key -out priv/server.pem
#
# The `http:` config above can be replaced with:
#
# https: [port: 4000, keyfile: "priv/server.key", certfile: "priv/server.pem"],
#
# If desired, both `http:` and `https:` keys can be
# configured to run both http and https servers on
# different ports.
# Watch static and templates for browser reloading.
config :i_love_backend, ILoveBackendWeb.Endpoint,
live_reload: [
patterns: [
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
~r{priv/gettext/.*(po)$},
~r{lib/i_love_backend_web/views/.*(ex)$},
~r{lib/i_love_backend_web/templates/.*(eex)$}
]
]
# Do not include metadata nor timestamps in development logs
config :logger, :console, format: "[$level] $message\n"
# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
config :phoenix, :stacktrace_depth, 20
# Configure your database
config :i_love_backend, ILoveBackend.Repo,
adapter: Ecto.Adapters.Postgres,
username: "postgres",
password: "postgres",
database: "i_love_backend_dev",
hostname: "localhost",
pool_size: 10
use Mix.Config
# For production, we often load configuration from external
# sources, such as your system environment. For this reason,
# you won't find the :http configuration below, but set inside
# ILoveBackendWeb.Endpoint.init/2 when load_from_system_env is
# true. Any dynamic configuration should be done there.
#
# Don't forget to configure the url host to something meaningful,
# Phoenix uses this information when generating URLs.
#
# Finally, we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the mix phx.digest task
# which you typically run after static files are built.
config :i_love_backend, ILoveBackendWeb.Endpoint,
load_from_system_env: true,
url: [host: "example.com", port: 80],
cache_static_manifest: "priv/static/cache_manifest.json"
# Do not print debug messages in production
config :logger, level: :info
# ## SSL Support
#
# To get SSL working, you will need to add the `https` key
# to the previous section and set your `:url` port to 443:
#
# config :i_love_backend, ILoveBackendWeb.Endpoint,
# ...
# url: [host: "example.com", port: 443],
# https: [:inet6,
# port: 443,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")]
#
# Where those two env variables return an absolute path to
# the key and cert in disk or a relative path inside priv,
# for example "priv/ssl/server.key".
#
# We also recommend setting `force_ssl`, ensuring no data is
# ever sent via http, always redirecting to https:
#
# config :i_love_backend, ILoveBackendWeb.Endpoint,
# force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.
# ## Using releases
#
# If you are doing OTP releases, you need to instruct Phoenix
# to start the server for all endpoints:
#
# config :phoenix, :serve_endpoints, true
#
# Alternatively, you can configure exactly which server to
# start per endpoint:
#
# config :i_love_backend, ILoveBackendWeb.Endpoint, server: true
#
# Finally import the config/prod.secret.exs
# which should be versioned separately.
import_config "prod.secret.exs"
use Mix.Config
# We don't run a server during test. If one is required,
# you can enable the server option below.
config :i_love_backend, ILoveBackendWeb.Endpoint,
http: [port: 4001],
server: false
# Print only warnings and errors during test
config :logger, level: :warn
# Configure your database
config :i_love_backend, ILoveBackend.Repo,
adapter: Ecto.Adapters.Postgres,
username: "postgres",
password: "postgres",
database: "i_love_backend_test",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox
defmodule ILoveBackend do
@moduledoc """
ILoveBackend keeps the contexts that define your domain
and business logic.
Contexts are also responsible for managing your data, regardless
if it comes from the database, an external API or others.
"""
end
defmodule ILoveBackend.Accounts do
@moduledoc """
The Accounts context.
"""
import Ecto.Query, warn: false
alias ILoveBackend.Repo
alias ILoveBackend.Accounts.User
@doc """
Returns the list of users.
## Examples
iex> list_users()
[%User{}, ...]
"""
def list_users do
Repo.all(User)
|> Repo.preload(:scores)
end
@doc """
Gets a single user.
Raises `Ecto.NoResultsError` if the User does not exist.
## Examples
iex> get_user!(123, 789)
%User{}
iex> get_user!(456, 789)
** (Ecto.NoResultsError)
"""
def get_user!(id) do
User
|> Repo.get!(id)
|> Repo.preload(:scores)
end
@doc """
Gets a single user.
Raises `Ecto.NoResultsError` if the User does not exist.
## Examples
iex> get_user!(123, 789)
%User{}
iex> get_user!(456, 789)
** (Ecto.NoResultsError)
"""
def get_user!(id, uuid) do
user = User
|> Repo.get!(id)
|> Repo.preload(:scores)
if user.uuid == uuid do
user
else
{:error, :wrong_uuid}
end
end
@doc """
Creates a user.
## Examples
iex> create_user(%{field: value})
{:ok, %User{}}
iex> create_user(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_user(attrs \\ %{}) do
%User{}
|> User.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a user.
## Examples
iex> update_user(user, %{field: new_value})
{:ok, %User{}}
iex> update_user(user, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_user(%User{} = user, attrs) do
user
|> User.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a User.
## Examples
iex> delete_user(user)
{:ok, %User{}}
iex> delete_user(user)
{:error, %Ecto.Changeset{}}
"""
def delete_user(%User{} = user) do
Repo.delete(user)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking user changes.
## Examples
iex> change_user(user)
%Ecto.Changeset{source: %User{}}
"""
def change_user(%User{} = user) do
User.changeset(user, %{})
end
end
defmodule ILoveBackend.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
alias ILoveBackend.Accounts.User
schema "users" do
field :username, :string
field :uuid, :string
has_many :scores, ILoveBackend.Scores.Score
timestamps()
end
@doc false
def changeset(%User{} = user, attrs) do
user
|> cast(attrs, [:uuid, :username])
|> validate_required([:uuid, :username])
|> unique_constraint(:username)
end
end
defmodule ILoveBackend.Api do
@moduledoc """
The Api context.
"""
alias ILoveBackend.Repo
alias ILoveBackend.Accounts.User
alias ILoveBackend.Scores.Score
@doc """
Returns the list of users.
## Examples
iex> list_users()
[%User{}, ...]
"""
def list_users do
Repo.all(User)
end
@doc """
Returns the list of scores.
## Examples
iex> list_scores()
[%Score{}, ...]
"""
def list_scores do
Score
|> Repo.all()
|> Repo.preload(:user)
end
end
defmodule ILoveBackend.Application do
use Application
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec
# Define workers and child supervisors to be supervised
children = [
# Start the Ecto repository
supervisor(ILoveBackend.Repo, []),
# Start the endpoint when the application starts
supervisor(ILoveBackendWeb.Endpoint, []),
# Start your own worker by calling: ILoveBackend.Worker.start_link(arg1, arg2, arg3)
# worker(ILoveBackend.Worker, [arg1, arg2, arg3]),
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: ILoveBackend.Supervisor]
Supervisor.start_link(children, opts)
end
# Tell Phoenix to update the endpoint configuration
# whenever the application is updated.
def config_change(changed, _new, removed) do
ILoveBackendWeb.Endpoint.config_change(changed, removed)
:ok
end
end
defmodule ILoveBackend.Repo do
use Ecto.Repo, otp_app: :i_love_backend
@doc """
Dynamically loads the repository url from the
DATABASE_URL environment variable.
"""
def init(_, opts) do
{:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
end
end
defmodule ILoveBackend.Scores.Score do
use Ecto.Schema
import Ecto.Changeset
alias ILoveBackend.Scores.Score
schema "scores" do
field :point, :integer
belongs_to :user, ILoveBackend.Accounts.User
timestamps()
end
@doc false
def changeset(%Score{} = score, attrs) do
score
|> cast(attrs, [:point, :user_id])
|> validate_required([:point, :user_id])
end
end
defmodule ILoveBackend.Scores do
@moduledoc """
The Scores context.
"""
import Ecto.Query, warn: false
alias ILoveBackend.Repo
alias ILoveBackend.Scores.Score
alias ILoveBackend.Accounts
alias ILoveBackend.Accounts.User
@doc """
Returns the list of scores.
## Examples
iex> list_scores()
[%Score{}, ...]
"""
def list_scores do
Score
|> Repo.all()
|> Repo.preload(:user)
end
@doc """
Gets a single score.