Skip to content
Open
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
2 changes: 1 addition & 1 deletion Dockerfile.development
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM elixir:1.6
FROM elixir:1.4

RUN apt update
RUN yes | apt install build-essential inotify-tools postgresql-client
Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Rumbl

brunch commands
create `annotation` model

```bash
$ brunch build
$ brunch build --production
$ brunch watch
$ dc exec app \
mix phoenix.gen.model Annotation annotations \
body:text \
at:integer \
user_id:references:users \
video_id:references:videos
```
10 changes: 5 additions & 5 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Rumbl.Mixfile do
[
app: :rumbl,
version: "0.0.1",
elixir: "~> 1.2",
elixir: "~> 1.4",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
build_embedded: Mix.env() == :prod,
Expand Down Expand Up @@ -46,11 +46,11 @@ defmodule Rumbl.Mixfile do
[
{:phoenix, "~> 1.2.5"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_ecto, "~> 3.0.0"},
{:postgrex, "~> 0.11.0"},
{:phoenix_html, "~> 2.6.0"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:gettext, "~> 0.11.0"},
{:cowboy, "~> 1.0"},
{:comeonin, "~> 2.0"}
]
Expand Down
16 changes: 7 additions & 9 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
%{
"comeonin": {:hex, :comeonin, "2.6.0", "74c288338b33205f9ce97e2117bb9a2aaab103a1811d243443d76fdb62f904ac", [:make, :mix], [], "hexpm", "bc72f049a1c61048427f557821fc06e273abf09f6829377541475d7b36ac8ac6"},
%{"comeonin": {:hex, :comeonin, "2.6.0", "74c288338b33205f9ce97e2117bb9a2aaab103a1811d243443d76fdb62f904ac", [:make, :mix], [], "hexpm", "bc72f049a1c61048427f557821fc06e273abf09f6829377541475d7b36ac8ac6"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "f4763bbe08233eceed6f24bc4fcc8d71c17cfeafa6439157c57349aa1bb4f17c"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm", "db622da03aa039e6366ab953e31186cc8190d32905e33788a1acb22744e6abd2"},
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm", "5f0a16a58312a610d5eb0b07506280c65f5137868ad479045f2a2dc4ced80550"},
"decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
"ecto": {:hex, :ecto, "2.0.6", "9dcbf819c2a77f67a66b83739b7fcc00b71aaf6c100016db4f798930fa4cfd47", [:mix], [{:db_connection, "~> 1.0", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.1.2 or ~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.12.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm", "92d1a92cc379e9f3b41f42e3cd0dec87dc75b7beac67ba59bc0560944685f09a"},
"ecto": {:hex, :ecto, "2.0.4", "03fd3b9aa508b1383eb38c00ac389953ed22af53811aa2e504975a3e814a8d97", [:mix], [{:db_connection, "~> 1.0-rc.2", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.11.2", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm", "93a2b131d1ef99d66987c5d60e6aa4d16319a2154b04aca07223ee3674abc104"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
"mime": {:hex, :mime, "1.5.0", "203ef35ef3389aae6d361918bf3f952fa17a09e8e43b5aa592b93eba05d0fb8d", [:mix], [], "hexpm", "55a94c0f552249fc1a3dd9cd2d3ab9de9d3c89b559c2bd01121f824834f24746"},
"gettext": {:hex, :gettext, "0.11.0", "80c1dd42d270482418fa158ec5ba073d2980e3718bacad86f3d4ad71d5667679", [:mix], [], "hexpm", "9688cb656d6bc13d174051256784066dde15c4ddae1f0335590a62952780b58b"},
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
"phoenix": {:hex, :phoenix, "1.2.5", "dbc45a5f8fb522aaa815b003f2d5598bc45e23102ae3e265768848ab23eafcb7", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.2.4 or ~> 1.1.8 or ~> 1.0.5", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "53141e3226ccc4abbf141961699aeefb7048fb129c64825215e4ceb18c03e938"},
"phoenix_ecto": {:hex, :phoenix_ecto, "3.0.0", "b947aaf03d076f5b1448f87828f22fb7710478ee38455c67cc3fe8e9a4dfd015", [:mix], [{:ecto, "~> 2.0.0-rc", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.6", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "f7050f77b8284833561d8aa036ee5d0ef489b17ba1391d3a194162f4607b990f"},
"phoenix_html": {:hex, :phoenix_html, "2.10.5", "4f9df6b0fb7422a9440a73182a566cb9cbe0e3ffe8884ef9337ccf284fc1ef0a", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "4f38ec3263ceb746f0ee7c4955dcdae05497750d795160d87fb45e458981a696"},
"phoenix_html": {:hex, :phoenix_html, "2.6.2", "944a5e581b0d899e4f4c838a69503ebd05300fe35ba228a74439e6253e10e0c0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "697b31db7f85c648e7d554805d684272145835709a2dfa87e3a10a5fafd3322c"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.1.7", "425fff579085f7eacaf009e71940be07338c8d8b78d16e307c50c7d82a381497", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3 or ~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "67e40a225d13924e4ea810e659800532f3e78d4ebf4091cfee9cadf88f0366ae"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
"plug": {:hex, :plug, "1.3.6", "bcdf94ac0f4bc3b804bdbdbde37ebf598bd7ed2bfa5106ed1ab5984a09b7e75f", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "3f2f20bddfb606afe53fa3920d562e9b5c0f6f64052f0575c7522d0e8b15817d"},
"poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], [], "hexpm", "519bc209e4433961284174c497c8524c001e285b79bdf80212b47a1f898084cc"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.12.2", "13cfd784a148da78f0edddd433bcef5c98388fdb2963ba25ed1fa7265885e6bf", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "591f8c7742281404859bd44e8e7f8f29309c88f9f8d60ffd062aceee9cdc247d"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm", "6e56493a862433fccc3aca3025c946d6720d8eedf6e3e6fb911952a7071c357f"},
}
"postgrex": {:hex, :postgrex, "0.11.2", "139755c1359d3c5c6d6e8b1ea72556d39e2746f61c6ddfb442813c91f53487e8", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.0-rc", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "3c24cb3cca8e0a73d8f56b7b1db161a94a460891f451247581cdff1e425316ef"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm", "6e56493a862433fccc3aca3025c946d6720d8eedf6e3e6fb911952a7071c357f"}}
23 changes: 23 additions & 0 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ you will take down your environment and rebuild, as necessary
```bash
$ dc down
$ dc rm
$ docker volume prune # to blow away db volume
$ dc build
$ dc up
```
Expand Down Expand Up @@ -164,3 +165,25 @@ run a tagged test
$ dc exec app \
mix test test/controllers --only login_as
```

brunch commands

```bash
$ brunch build
$ brunch build --production
$ brunch watch
```

show outdated hex dependencies for the current project

```bash
$ dc exec app \
mix hex.outdated
```

update dependencies

```bash
$ dc exec app \
mix deps.update --all
```
17 changes: 17 additions & 0 deletions priv/repo/migrations/20210426215147_create_annotation.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Rumbl.Repo.Migrations.CreateAnnotation do
use Ecto.Migration

def change do
create table(:annotations) do
add :body, :text
add :at, :integer
add :user_id, references(:users, on_delete: :nothing)
add :video_id, references(:videos, on_delete: :nothing)

timestamps()
end
create index(:annotations, [:user_id])
create index(:annotations, [:video_id])

end
end
18 changes: 18 additions & 0 deletions test/models/annotation_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Rumbl.AnnotationTest do
use Rumbl.ModelCase

alias Rumbl.Annotation

@valid_attrs %{at: 42, body: "some content"}
@invalid_attrs %{}

test "changeset with valid attributes" do
changeset = Annotation.changeset(%Annotation{}, @valid_attrs)
assert changeset.valid?
end

test "changeset with invalid attributes" do
changeset = Annotation.changeset(%Annotation{}, @invalid_attrs)
refute changeset.valid?
end
end
39 changes: 11 additions & 28 deletions web/channels/user_socket.ex
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
defmodule Rumbl.UserSocket do
use Phoenix.Socket

## Channels
# channel "room:*", Rumbl.RoomChannel
channel "videos:*", Rumbl.VideoChannel

## Transports
transport :websocket, Phoenix.Transports.WebSocket
# transport :longpoll, Phoenix.Transports.LongPoll

# Socket params are passed from the client and can
# be used to verify and authenticate a user. After
# verification, you can put default assigns into
# the socket that will be set for all channels, ie
#
# {:ok, assign(socket, :user_id, verified_user_id)}
#
# To deny connection, return `:error`.
#
# See `Phoenix.Token` documentation for examples in
# performing token verification on connect.
def connect(_params, socket) do
{:ok, socket}
@max_age 2 * 7 * 24 * 60 * 60

def connect(%{"token" => token}, socket) do
case Phoenix.Token.verify(socket, "user socket", token, max_age: @max_age) do
{:ok, user_id} -> {:ok, assign(socket, :user_id, user_id)}
{:error, _reason} -> :error
end
end

# Socket id's are topics that allow you to identify all sockets for a given user:
#
# def id(socket), do: "users_socket:#{socket.assigns.user_id}"
#
# Would allow you to broadcast a "disconnect" event and terminate
# all active sockets and channels for a given user:
#
# Rumbl.Endpoint.broadcast("users_socket:#{user.id}", "disconnect", %{})
#
# Returning `nil` makes this socket anonymous.
def id(_socket), do: nil
def connect(_params, _socket), do: :error

def id(socket), do: "users_socket:#{socket.assigns.user_id}"
end
47 changes: 47 additions & 0 deletions web/channels/video_channel.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule Rumbl.VideoChannel do
use Rumbl.Web, :channel
alias Rumbl.AnnotationView

def join("videos:" <> video_id, params, socket) do
last_seen_id = params["last_seen_id"] || 0
video_id = String.to_integer(video_id)
video = Repo.get!(Rumbl.Video, video_id)

annotations = Repo.all(
from a in assoc(video, :annotations),
where: a.id > ^last_seen_id,
order_by: [asc: a.at, asc: a.id],
limit: 200,
preload: [:user]
)

response = %{annotations: Phoenix.View.render_many(annotations, AnnotationView, "annotation.json")}
{:ok, response, assign(socket, :video_id, video_id)}
end

def handle_in(event, params, socket) do
user = Repo.get(Rumbl.User, socket.assigns.user_id)
handle_in(event, params, user, socket)
end

def handle_in("new_annotation", params, user, socket) do
changeset = user
|> build_assoc(:annotations, video_id: socket.assigns.video_id)
|> Rumbl.Annotation.changeset(params)

case Repo.insert(changeset) do
{:ok, annotation} ->
broadcast!(socket, "new_annotation", %{
id: annotation.id,
user: Rumbl.UserView.render("user.json", %{user: user}),
body: annotation.body,
at: annotation.at
})
# broadcast!(socket, "new_annotation", AnnotationView.render("annotation.json", annotation))
{:reply, :ok, socket}
{:error, changeset} ->
{:reply, {:error, %{errors: changeset}}, socket}
end

end
end
14 changes: 11 additions & 3 deletions web/controllers/auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,29 @@ defmodule Rumbl.Auth do

cond do
user = conn.assigns[:current_user] ->
conn
put_current_user(conn, user)
user = user_id && repo.get(Rumbl.User, user_id) ->
assign(conn, :current_user, user)
put_current_user(conn, user)
true ->
assign(conn, :current_user, nil)
end
end

def login(conn, user) do
conn
|> assign(:current_user, user)
|> put_current_user(user)
|> put_session(:user_id, user.id)
|> configure_session(renew: true)
end

defp put_current_user(conn, user) do
token = Phoenix.Token.sign(conn, "user socket", user.id)
IO.inspect(token)
conn
|> assign(:current_user, user)
|> assign(:user_token, token)
end

def login_by_username_and_password(conn, username, password, opts) do
repo = Keyword.fetch!(opts, :repo)
user = repo.get_by(Rumbl.User, username: username)
Expand Down
21 changes: 21 additions & 0 deletions web/models/annotation.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Rumbl.Annotation do
use Rumbl.Web, :model

schema "annotations" do
field :body, :string
field :at, :integer
belongs_to :user, Rumbl.User
belongs_to :video, Rumbl.Video

timestamps()
end

@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:body, :at])
|> validate_required([:body, :at])
end
end
2 changes: 1 addition & 1 deletion web/models/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Rumbl.User do
field :password, :string, virtual: true
field :password_hash, :string
has_many :videos, Rumbl.Video

has_many :annotations, Rumbl.Annotation
timestamps()
end

Expand Down
3 changes: 2 additions & 1 deletion web/models/video.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Rumbl.Video do
field :slug, :string
belongs_to :user, Rumbl.User
belongs_to :category, Rubml.Category
has_many :annotations, Rumbl.Annotation
timestamps()
end

Expand All @@ -19,7 +20,7 @@ defmodule Rumbl.Video do
@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ :empty) do
def changeset(struct, params \\ :invalid) do
struct
|> cast(params, @required_fields, @optional_fields)
|> validate_required(@required_fields)
Expand Down
16 changes: 3 additions & 13 deletions web/static/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,7 @@
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"

import Player from "./player"
let video = document.getElementById("video")
import socket from "./socket"
import Video from "./video"

if(video) {
Player.init(video.id, video.getAttribute("data-player-id"), () => {
console.log("player ready")
})
}
Video.init(socket, document.getElementById("video"))
Loading