aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2018-11-05 15:40:18 +0100
committerAlex Auvolat <alex@adnab.me>2018-11-05 15:40:18 +0100
commit0b27af3dab56b667b50fd80590cdfd9df0feffbd (patch)
tree7c1185496166b04aa21ea66f285650d62e954f20
parent72906c6bb473ea605235c84b6d01c318f7b6cef8 (diff)
downloadshard-0b27af3dab56b667b50fd80590cdfd9df0feffbd.tar.gz
shard-0b27af3dab56b667b50fd80590cdfd9df0feffbd.zip
File progress
-rw-r--r--shard/lib/app/file.ex15
-rw-r--r--shardweb/lib/controllers/directory_controller.ex31
-rw-r--r--shardweb/lib/router.ex2
-rw-r--r--shardweb/lib/templates/directory/view.html.eex30
-rw-r--r--shardweb/lib/templates/identity/view.html.eex2
-rw-r--r--shardweb/lib/templates/page/shard_entry.html.eex11
-rw-r--r--shardweb/mix.exs2
-rw-r--r--shardweb/mix.lock1
8 files changed, 89 insertions, 5 deletions
diff --git a/shard/lib/app/file.ex b/shard/lib/app/file.ex
index b28f742..ce28beb 100644
--- a/shard/lib/app/file.ex
+++ b/shard/lib/app/file.ex
@@ -94,7 +94,8 @@ defmodule SApp.File do
size: state.info.size,
mime_type: state.info.mime_type,
num_blocks: nblk,
- missing_blocks: if state.missing != nil do map_size(state.missing) else nil end]
+ missing_blocks: if state.missing != nil do map_size(state.missing) else nil end,
+ path: state.path]
state.info != nil ->
[infohash: state.infohash,
file_hash: state.info.file_hash,
@@ -153,7 +154,6 @@ defmodule SApp.File do
# Ignore message
{:noreply, state}
else
- Logger.info("<- #{inspect msg}")
state = case msg do
{:get_info} ->
if state.infobin != nil do
@@ -258,7 +258,7 @@ defmodule SApp.File do
end
{:noreply, state}
else
- Logger.info(":calc_missing for #{state.infohash|>Base.encode16} -> no info")
+ Logger.info(":calc_missing for #{state.id|>Base.encode16} -> no info")
{:noreply, state}
end
end
@@ -281,7 +281,7 @@ defmodule SApp.File do
pieces = can_req |> Enum.sort() |> Enum.take(@concurrent_reqs - n_curr_req)
Enum.reduce(pieces, state, fn id, state ->
who = a_random_peer(state.missing[id])
- Logger.info("Req #{id} to #{inspect who}")
+ Logger.info("#{state.id|>Base.encode16} | Req #{id} to #{inspect who}")
SNet.Manager.send(who, {state.id, nil, {:get, id}})
Process.send_after(self(), {:req_timeout, id}, @req_timeout_msec)
put_in(state.reqs[id], who)
@@ -350,4 +350,11 @@ defmodule SApp.File do
GenServer.cast(pid, {:init_with, path, infobin, mt})
{:ok, manifest, pid}
end
+
+ @doc"""
+ Get info of a file shard including download progress
+ """
+ def get_info(pid) do
+ GenServer.call(pid, :get_info)
+ end
end
diff --git a/shardweb/lib/controllers/directory_controller.ex b/shardweb/lib/controllers/directory_controller.ex
index 10fdec2..ad5c426 100644
--- a/shardweb/lib/controllers/directory_controller.ex
+++ b/shardweb/lib/controllers/directory_controller.ex
@@ -61,4 +61,35 @@ defmodule ShardWeb.DirectoryController do
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_upload(conn, %{"dir_name" => dir_name, "dir_public" => dir_public, "upload_name" => upload_name, "file" => file}) do
+ %Plug.Upload{content_type: mime_type, filename: filename, path: path} = file
+
+ 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
+
+ {:ok, file_manifest, _file_pid} = SApp.File.create(path, mime_type)
+ name_as = if upload_name == "" do filename else upload_name end
+ SApp.Directory.add_item(pid, name_as, file_manifest, true)
+
+ 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 raw_file(conn, %{"infohash" => infohash}) do
+ infohash = Base.decode16!(infohash)
+ pid = Shard.Manager.find_or_start %SApp.File.Manifest{infohash: infohash}
+ info = SApp.File.get_info(pid)
+ if info[:missing_blocks] == 0 do
+ conn
+ |> put_resp_content_type(info[:mime_type])
+ |> send_file(200, info[:path])
+ else
+ conn
+ |> put_status(:not_found)
+ |> text("File not found or not yet completely downloaded.\n#{inspect(info)}")
+ end
+ end
end
diff --git a/shardweb/lib/router.ex b/shardweb/lib/router.ex
index 3f78afd..a6a61f9 100644
--- a/shardweb/lib/router.ex
+++ b/shardweb/lib/router.ex
@@ -34,6 +34,8 @@ defmodule ShardWeb.Router do
post "/dir/add", DirectoryController, :dir_add
post "/dir/rm", DirectoryController, :dir_rm
post "/dir/set_stored", DirectoryController, :dir_set_stored
+ post "/dir/upload", DirectoryController, :dir_upload
+ get "/raw/:infohash", DirectoryController, :raw_file
get "/chat/:chan", ChatController, :chat
get "/pm/:people_list", ChatController, :privchat
diff --git a/shardweb/lib/templates/directory/view.html.eex b/shardweb/lib/templates/directory/view.html.eex
index ef8200b..7b9be38 100644
--- a/shardweb/lib/templates/directory/view.html.eex
+++ b/shardweb/lib/templates/directory/view.html.eex
@@ -76,6 +76,34 @@
</table>
<%= if @owner == @pk do %>
+ <%= if @public do %>
+ <fieldset><legend>Upload file</legend>
+ <%= form_for @conn, directory_path(@conn, :dir_upload), [multipart: true, class: "form-horizontal"], fn f -> %>
+ <%= hidden_input f, :dir_name, value: @name %>
+ <%= hidden_input f, :dir_public, value: @public %>
+ <div class="form-group">
+ <%= label :file, "File:", class: ["col-sm-2 control-label"] %>
+ <div class="col-sm-10">
+ <%= file_input f, :file, [class: "form-control"] %>
+ </div>
+ </div>
+ <div class="form-group">
+ <%= label :upload_name, "Save as (optionnal):", class: ["col-sm-2 control-label"] %>
+ <div class="col-sm-10">
+ <%= text_input f, :upload_name, [class: "form-control", value: ""] %>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-sm-offset-2 col-sm-10">
+ <%= submit "Upload file", [class: "btn btn-primary"] %>
+ </div>
+ </div>
+ <% end %>
+ </fieldset>
+ <% else %>
+ <p>Warning: file upload in private directories does not keeps file private (yeah WTF right?), so we don't let you do that.</p>
+ <% end %>
+
<fieldset><legend>Add existing item</legend>
<%= form_for @conn, directory_path(@conn, :dir_add), [class: "form-horizontal"], fn f -> %>
<%= hidden_input f, :dir_name, value: @name %>
@@ -106,7 +134,7 @@
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <%= submit "Add", [class: "btn btn-default"] %>
+ <%= submit "Add", [class: "btn btn-primary"] %>
</div>
</div>
<% end %>
diff --git a/shardweb/lib/templates/identity/view.html.eex b/shardweb/lib/templates/identity/view.html.eex
index c5dfaf2..c81caf6 100644
--- a/shardweb/lib/templates/identity/view.html.eex
+++ b/shardweb/lib/templates/identity/view.html.eex
@@ -23,6 +23,8 @@
<a class="btn btn-s btn-primary" href="<%= chat_path(@conn, :privchat, @pk |> Base.encode16) %>"><i class="fa fa-comments"></i> PM</a>
<% end %>
+ <a class="btn btn-s btn-success" href="<%= directory_path(@conn, :view_pub, @pk |> Base.encode16, "collection") %>"><i class="fa fa-folder"></i> Public stuff</a>
+
<pre>
<%= inspect(SApp.Identity.get_info(@pid), pretty: true, width: 40) %>
</pre>
diff --git a/shardweb/lib/templates/page/shard_entry.html.eex b/shardweb/lib/templates/page/shard_entry.html.eex
index d99fc34..bc9edd4 100644
--- a/shardweb/lib/templates/page/shard_entry.html.eex
+++ b/shardweb/lib/templates/page/shard_entry.html.eex
@@ -23,6 +23,17 @@
<a href="<%= directory_path(@conn, (if public do :view_pub else :view_priv end), owner|>Base.encode16(), name) %>"><%= name %></a>
<%= if public do %><i class="fa fa-globe"></i><% else %><i class="fa fa-lock"></i><% end %>
+ <% %SApp.File.Manifest{infohash: infohash} -> %>
+ <% file_info = SApp.File.get_info(Shard.Manager.find_or_start(@manifest)) %>
+ <i class="fa fa-file"></i>
+ <%= if file_info[:size] != nil do Size.humanize!(file_info[:size]) end %>
+ <%= if file_info[:mime_type] != nil do %><code><%= file_info[:mime_type] %></code><% end %>
+ <%= if file_info[:missing_blocks] != nil and file_info[:missing_blocks] > 0 do %>
+ <%= file_info[:num_blocks] - file_info[:missing_blocks] %> / <%= file_info[:num_blocks] %>
+ <% end %>
+ <%= if file_info[:missing_blocks] == 0 do %>
+ <a href="<%= directory_path(@conn, :raw_file, infohash|>Base.encode16) %>">[raw]</a>
+ <% end %>
<% x -> %> <%= inspect x %>
<% end %>
diff --git a/shardweb/mix.exs b/shardweb/mix.exs
index 7e4b0b2..90fc530 100644
--- a/shardweb/mix.exs
+++ b/shardweb/mix.exs
@@ -41,6 +41,8 @@ defmodule ShardWeb.Mixfile do
{:cowboy, "~> 1.0"},
{:phoenix_gon, "~> 0.4.0"},
+ {:size, "~> 0.1.0"},
+
{:shard, path: Path.expand (Path.join [System.cwd!, "..", "shard"])},
]
end
diff --git a/shardweb/mix.lock b/shardweb/mix.lock
index 71267a0..fe97f67 100644
--- a/shardweb/mix.lock
+++ b/shardweb/mix.lock
@@ -16,4 +16,5 @@
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
"salty": {:hex, :libsalty, "0.1.3", "13332eb13ac995f5deb76903b44f96f740e1e3a6e511222bffdd8b42cd079ffb", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
+ "size": {:hex, :size, "0.1.0", "49c4bc026286b1f66f9d6b78756e833150b0b86b640d8e3fd5ad597e705dc846", [:mix], [], "hexpm"},
}