From 94b1f6b0ae387b7fcb0714a4c6e213212097a100 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 2 Nov 2018 14:04:52 +0100 Subject: Directory stuff --- shardweb/lib/controllers/chat_controller.ex | 8 ++- shardweb/lib/controllers/directory_controller.ex | 63 +++++++++++++++----- shardweb/lib/controllers/identity_controller.ex | 4 +- shardweb/lib/router.ex | 3 + shardweb/lib/shard_uri.ex | 42 +++++++++++++ shardweb/lib/templates/chat/chat.html.eex | 4 +- shardweb/lib/templates/directory/view.html.eex | 75 ++++++++++++++++++++++-- shardweb/lib/templates/identity/view.html.eex | 3 +- shardweb/lib/templates/layout/app.html.eex | 8 +++ shardweb/lib/templates/page/shard_list.html.eex | 8 +-- shardweb/lib/views/directory_view.ex | 2 +- 11 files changed, 191 insertions(+), 29 deletions(-) create mode 100644 shardweb/lib/shard_uri.ex (limited to 'shardweb/lib') diff --git a/shardweb/lib/controllers/chat_controller.ex b/shardweb/lib/controllers/chat_controller.ex index 080ee61..1ca66d4 100644 --- a/shardweb/lib/controllers/chat_controller.ex +++ b/shardweb/lib/controllers/chat_controller.ex @@ -4,11 +4,13 @@ defmodule ShardWeb.ChatController do def chat(conn, %{"chan" => chan}) do conn = put_gon(conn, chat_channel: "chat:" <> chan) - shard = %SApp.Chat.Manifest{channel: chan} |> SData.term_hash + manifest = %SApp.Chat.Manifest{channel: chan} + shard = manifest |> SData.term_hash render conn, "chat.html", public: true, shard: shard, + manifest: manifest, chan: chan end @@ -37,10 +39,12 @@ defmodule ShardWeb.ChatController do |> Enum.map(&SApp.Identity.get_nick/1) |> Enum.join(", ") - shard = [conn.assigns.pk | pk_list] |> SApp.Chat.PrivChat.Manifest.new |> SData.term_hash + manifest = [conn.assigns.pk | pk_list] |> SApp.Chat.PrivChat.Manifest.new + shard = manifest |> SData.term_hash render conn, "chat.html", public: false, + manifest: manifest, shard: shard, nicks: name else diff --git a/shardweb/lib/controllers/directory_controller.ex b/shardweb/lib/controllers/directory_controller.ex index 1e3a0b0..10fdec2 100644 --- a/shardweb/lib/controllers/directory_controller.ex +++ b/shardweb/lib/controllers/directory_controller.ex @@ -1,29 +1,64 @@ defmodule ShardWeb.DirectoryController do use ShardWeb, :controller - def view_pub(conn, %{"owner" => owner, "name" => name}) do - owner = Base.decode16! owner - shard = %SApp.Directory.Manifest{public: true, owner: owner, name: name} - pid = Shard.Manager.find_or_start shard + def view_pub(conn, args) do + view(conn, true, args) + end - render conn, "view.html", - public: true, - shard: shard, - pid: pid, - owner: owner, - name: name + def view_priv(conn, args) do + view(conn, false, args) end - def view_priv(conn, %{"owner" => owner, "name" => name}) do + def view(conn, public, %{"owner" => owner, "name" => name}=args) do owner = Base.decode16! owner - shard = %SApp.Directory.Manifest{public: false, owner: owner, name: name} - pid = Shard.Manager.find_or_start shard + manifest = %SApp.Directory.Manifest{public: public, owner: owner, name: name} + shard = SData.term_hash manifest + pid = Shard.Manager.find_or_start manifest render conn, "view.html", - public: false, + public: public, shard: shard, + manifest: manifest, pid: pid, owner: owner, name: name end + + def dir_add(conn, %{"dir_name" => dir_name, "dir_public" => dir_public, "add_name" => add_name, "add_uri" => add_uri, "add_stored" => add_stored}) do + dir_public = (dir_public == "true") + + manifest = %SApp.Directory.Manifest{public: dir_public, owner: conn.assigns.pk, name: dir_name} + shard = SData.term_hash manifest + pid = Shard.Manager.find_or_start manifest + + item_manifest = ShardURI.to_manifest(add_uri) + SApp.Directory.add_item(pid, add_name, item_manifest, (add_stored == "yes")) + + redirect conn, to: directory_path(conn, (if dir_public do :view_pub else :view_priv end), conn.assigns.pk|>Base.encode16, dir_name) + end + + def dir_rm(conn, %{"dir_name" => dir_name, "dir_public" => dir_public, "item_name" => rm_name}) do + dir_public = (dir_public == "true") + + manifest = %SApp.Directory.Manifest{public: dir_public, owner: conn.assigns.pk, name: dir_name} + shard = SData.term_hash manifest + pid = Shard.Manager.find_or_start manifest + + SApp.Directory.rm_item(pid, rm_name) + + redirect conn, to: directory_path(conn, (if dir_public do :view_pub else :view_priv end), conn.assigns.pk|>Base.encode16, dir_name) + end + + def dir_set_stored(conn, %{"dir_name" => dir_name, "dir_public" => dir_public, "item_name" => item_name, "item_stored" => item_stored}) do + dir_public = (dir_public == "true") + item_stored = (item_stored == "true") + + manifest = %SApp.Directory.Manifest{public: dir_public, owner: conn.assigns.pk, name: dir_name} + shard = SData.term_hash manifest + pid = Shard.Manager.find_or_start manifest + + SApp.Directory.set_stored(pid, item_name, item_stored) + + redirect conn, to: directory_path(conn, (if dir_public do :view_pub else :view_priv end), conn.assigns.pk|>Base.encode16, dir_name) + end end diff --git a/shardweb/lib/controllers/identity_controller.ex b/shardweb/lib/controllers/identity_controller.ex index 962a888..7452453 100644 --- a/shardweb/lib/controllers/identity_controller.ex +++ b/shardweb/lib/controllers/identity_controller.ex @@ -11,7 +11,8 @@ defmodule ShardWeb.IdentityController do def view(conn, %{"pk" => pk}) do {:ok, pk} = Base.decode16(pk) - shard = %SApp.Identity.Manifest{pk: pk} |> SData.term_hash + manifest = %SApp.Identity.Manifest{pk: pk} + shard = manifest |> SData.term_hash pid = Shard.Manager.find_proc shard if pid == nil do @@ -21,6 +22,7 @@ defmodule ShardWeb.IdentityController do view_pk: pk, view_nick: SApp.Identity.get_nick(pk), shard: shard, + manifest: manifest, pid: pid end end diff --git a/shardweb/lib/router.ex b/shardweb/lib/router.ex index 61f8209..3f78afd 100644 --- a/shardweb/lib/router.ex +++ b/shardweb/lib/router.ex @@ -31,6 +31,9 @@ defmodule ShardWeb.Router do get "/pub/:owner/:name", DirectoryController, :view_pub get "/priv/:owner/:name", DirectoryController, :view_priv + post "/dir/add", DirectoryController, :dir_add + post "/dir/rm", DirectoryController, :dir_rm + post "/dir/set_stored", DirectoryController, :dir_set_stored get "/chat/:chan", ChatController, :chat get "/pm/:people_list", ChatController, :privchat diff --git a/shardweb/lib/shard_uri.ex b/shardweb/lib/shard_uri.ex new file mode 100644 index 0000000..71c0904 --- /dev/null +++ b/shardweb/lib/shard_uri.ex @@ -0,0 +1,42 @@ +defmodule ShardURI do + @moduledoc""" + Convert Shard manifests to and from strings. + """ + + def from_manifest(m) do + case m do + %SApp.Chat.Manifest{channel: chan} -> "shard:chat:#{chan}" + %SApp.Chat.PrivChat.Manifest{pk_list: pk_list} -> + "shard:privchat:#{pk_list|>Enum.map(&Base.encode16/1)|>Enum.join(",")}" + %SApp.Identity.Manifest{pk: pk} -> + "shard:identity:#{pk|>Base.encode16}" + %SApp.Directory.Manifest{owner: owner, public: true, name: name} -> + "shard:dir:pub:#{owner|>Base.encode16}:#{name}" + %SApp.Directory.Manifest{owner: owner, public: false, name: name} -> + "shard:dir:priv:#{owner|>Base.encode16}:#{name}" + end + end + + def to_manifest(p) do + case p do + "shard:chat:" <> chan -> + %SApp.Chat.Manifest{channel: chan} + "shard:privchat:" <> pklist -> + pklist + |> String.split(",") + |> Enum.map(&parse_pk/1) + |> SApp.Chat.PrivChat.Manifest.new() + "shard:identity:" <> pk -> + %SApp.Identity.Manifest{pk: parse_pk pk} + "shard:dir:pub:" <> <> <> ":" <> name -> + %SApp.Directory.Manifest{owner: parse_pk(pk), public: true, name: name} + "shard:dir:priv:" <> <> <> ":" <> name -> + %SApp.Directory.Manifest{owner: parse_pk(pk), public: false, name: name} + end + end + + def parse_pk(pkstr) do + 64 = byte_size pkstr + Base.decode16! pkstr + end +end diff --git a/shardweb/lib/templates/chat/chat.html.eex b/shardweb/lib/templates/chat/chat.html.eex index 499e14d..947e4c3 100644 --- a/shardweb/lib/templates/chat/chat.html.eex +++ b/shardweb/lib/templates/chat/chat.html.eex @@ -4,11 +4,11 @@

<%= if @public do %> #<%= @chan %> - public chat room <% else %> <%= @nicks %> - private chat <% end %> + <%= @manifest |> ShardURI.from_manifest %> +