diff options
author | Alex Auvolat <alex@adnab.me> | 2018-11-05 15:40:18 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2018-11-05 15:40:18 +0100 |
commit | 0b27af3dab56b667b50fd80590cdfd9df0feffbd (patch) | |
tree | 7c1185496166b04aa21ea66f285650d62e954f20 | |
parent | 72906c6bb473ea605235c84b6d01c318f7b6cef8 (diff) | |
download | shard-0b27af3dab56b667b50fd80590cdfd9df0feffbd.tar.gz shard-0b27af3dab56b667b50fd80590cdfd9df0feffbd.zip |
File progress
-rw-r--r-- | shard/lib/app/file.ex | 15 | ||||
-rw-r--r-- | shardweb/lib/controllers/directory_controller.ex | 31 | ||||
-rw-r--r-- | shardweb/lib/router.ex | 2 | ||||
-rw-r--r-- | shardweb/lib/templates/directory/view.html.eex | 30 | ||||
-rw-r--r-- | shardweb/lib/templates/identity/view.html.eex | 2 | ||||
-rw-r--r-- | shardweb/lib/templates/page/shard_entry.html.eex | 11 | ||||
-rw-r--r-- | shardweb/mix.exs | 2 | ||||
-rw-r--r-- | shardweb/mix.lock | 1 |
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"}, } |