add: chunk conten_provider for file download
This commit is contained in:
@@ -192,15 +192,32 @@ void Api::file(const httplib::Request& rq, httplib::Response& rs)
|
||||
sql << fmt::format("SELECT * FROM Files WHERE hash='{}';", file), soci::into(dw);
|
||||
|
||||
|
||||
std::ifstream fs(dw.local_path, std::ios_base::binary);
|
||||
fs.seekg(0, std::ios_base::end);
|
||||
auto size = fs.tellg();
|
||||
fs.seekg(0);
|
||||
rs.body.resize(static_cast<size_t>(size));
|
||||
fs.read(&rs.body[0], static_cast<std::streamsize>(size));
|
||||
auto fs = std::make_shared<std::ifstream>(dw.local_path, std::ios_base::binary | std::ios::in);
|
||||
fs->seekg(0, std::ios_base::end);
|
||||
auto size = fs->tellg();
|
||||
fs->seekg(0);
|
||||
|
||||
// rs.body.resize(static_cast<size_t>(size));
|
||||
// fs.read(&rs.body[0], static_cast<std::streamsize>(size));
|
||||
|
||||
rs.set_header("Content-Disposition", fmt::format("attachment; filename={};", dw.filename));
|
||||
rs.set_header("content-type", fmt::format("application/{}", dw.format));
|
||||
|
||||
rs.set_content_provider(
|
||||
static_cast<size_t>(size),
|
||||
fmt::format("application/{}", dw.format).c_str(),
|
||||
[file = fs](size_t offset, size_t length, httplib::DataSink& sink) mutable {
|
||||
size_t size = std::min(length, (size_t)1024 * 500);
|
||||
|
||||
//spdlog::info("Stream offset {} length {}", offset, length);
|
||||
std::vector<char> data;
|
||||
data.resize(size);
|
||||
|
||||
file->seekg(offset);
|
||||
file->read(data.data(), data.size());
|
||||
|
||||
sink.write(data.data(), data.size());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
|
||||
@@ -124,12 +124,21 @@ bool Worker::download(Task& task)
|
||||
args += task.format.value();
|
||||
}
|
||||
|
||||
args += "--restrict-filenames";
|
||||
args += task.url;
|
||||
|
||||
/* ** Download ** */
|
||||
spdlog::debug("youtube-dl {}", fmt::join(args, " "));
|
||||
|
||||
bp::child c("youtube-dl.exe", bp::args(args), bp::std_out > out, bp::std_err > err);
|
||||
#ifdef __linux__
|
||||
constexpr std::string_view youtube_dl = "youtube-dl";
|
||||
#elif _WIN32
|
||||
constexpr std::string_view youtube_dl = "youtube-dl.exe";
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
bp::child c(std::string{youtube_dl}, bp::args(args), bp::std_out > out, bp::std_err > err);
|
||||
|
||||
std::string destination_file;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module Globals exposing (..)
|
||||
|
||||
api : String
|
||||
api =
|
||||
"http://127.0.0.1/api/"
|
||||
"/api/"
|
||||
|
||||
|
||||
apiEndpoint : String -> String
|
||||
@@ -14,6 +14,9 @@ apiEndpoint path =
|
||||
apiStatus : String -> String
|
||||
apiStatus id = String.concat [apiEndpoint "status/", id]
|
||||
|
||||
apiAdd : String
|
||||
apiAdd = apiEndpoint "add"
|
||||
|
||||
apiDownloadFile : String -> String
|
||||
apiDownloadFile id = String.concat [apiEndpoint "file/", id]
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import Json.Decode exposing (Decoder, int, string, succeed)
|
||||
import Json.Decode.Pipeline exposing (required)
|
||||
import Json.Encode as Encode
|
||||
import Html.Events exposing (onMouseOver)
|
||||
|
||||
import Globals exposing(apiAdd)
|
||||
|
||||
type alias Form =
|
||||
{ url : String
|
||||
@@ -179,7 +179,7 @@ update navKey msg model =
|
||||
if not (String.isEmpty form.url) then
|
||||
( model
|
||||
, Http.post
|
||||
{ url = "http://127.0.0.1/api/add"
|
||||
{ url = apiAdd
|
||||
, body = Http.jsonBody (formPostEncoder form)
|
||||
, expect = Http.expectJson PostResult formDecoder
|
||||
}
|
||||
|
||||
@@ -15,5 +15,8 @@ cmake
|
||||
soci:shared=True
|
||||
soci:with_boost=True
|
||||
soci:with_sqlite3=True
|
||||
soci:with_odbc=True
|
||||
soci:with_postgresql=True
|
||||
|
||||
|
||||
|
||||
[imports]
|
||||
lib, *.so* -> ./bin
|
||||
|
||||
Reference in New Issue
Block a user