Add report media uploads
This commit is contained in:
@@ -63,25 +63,30 @@ void sendService(Json::Value body,
|
||||
callback(visione::http::json(std::move(body), status));
|
||||
}
|
||||
|
||||
bool isAllowedImage(const drogon::HttpFile &file)
|
||||
struct MediaType
|
||||
{
|
||||
const auto type = file.getContentType();
|
||||
return type == drogon::CT_IMAGE_JPG || type == drogon::CT_IMAGE_PNG ||
|
||||
type == drogon::CT_IMAGE_WEBP;
|
||||
}
|
||||
std::string kind;
|
||||
std::string contentType;
|
||||
};
|
||||
|
||||
std::string imageContentType(const drogon::HttpFile &file)
|
||||
std::optional<MediaType> allowedMediaType(const drogon::HttpFile &file)
|
||||
{
|
||||
switch (file.getContentType())
|
||||
{
|
||||
case drogon::CT_IMAGE_JPG:
|
||||
return "image/jpeg";
|
||||
return MediaType{"IMAGE", "image/jpeg"};
|
||||
case drogon::CT_IMAGE_PNG:
|
||||
return "image/png";
|
||||
return MediaType{"IMAGE", "image/png"};
|
||||
case drogon::CT_IMAGE_WEBP:
|
||||
return "image/webp";
|
||||
return MediaType{"IMAGE", "image/webp"};
|
||||
case drogon::CT_VIDEO_MP4:
|
||||
return MediaType{"VIDEO", "video/mp4"};
|
||||
case drogon::CT_VIDEO_WEBM:
|
||||
return MediaType{"VIDEO", "video/webm"};
|
||||
case drogon::CT_VIDEO_QUICKTIME:
|
||||
return MediaType{"VIDEO", "video/quicktime"};
|
||||
default:
|
||||
return "application/octet-stream";
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@@ -226,7 +231,7 @@ void ReportController::addFeedback(
|
||||
sendService(service.addFeedback(*user, reportId, body), std::move(callback));
|
||||
}
|
||||
|
||||
void ReportController::uploadPhotos(
|
||||
void ReportController::uploadMedia(
|
||||
const drogon::HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
long long reportId)
|
||||
@@ -254,7 +259,7 @@ void ReportController::uploadPhotos(
|
||||
std::filesystem::path(reportsPath) / std::to_string(reportId);
|
||||
|
||||
visione::services::ReportService service;
|
||||
auto allowed = service.canAddPhoto(*user, reportId);
|
||||
auto allowed = service.canAddMedia(*user, reportId);
|
||||
if (!allowed.get("ok", false).asBool())
|
||||
{
|
||||
callback(visione::http::json(std::move(allowed), drogon::k403Forbidden));
|
||||
@@ -262,16 +267,16 @@ void ReportController::uploadPhotos(
|
||||
}
|
||||
|
||||
if (parser.getFiles().size() >
|
||||
static_cast<size_t>(allowed.get("remaining_photo_slots", 0).asInt()))
|
||||
static_cast<size_t>(allowed.get("remaining_media_slots", 0).asInt()))
|
||||
{
|
||||
callback(visione::http::error("too_many_photos", drogon::k400BadRequest));
|
||||
callback(visione::http::error("too_many_media", drogon::k400BadRequest));
|
||||
return;
|
||||
}
|
||||
for (const auto &file : parser.getFiles())
|
||||
{
|
||||
if (!isAllowedImage(file))
|
||||
if (!allowedMediaType(file))
|
||||
{
|
||||
callback(visione::http::error("unsupported_photo_type",
|
||||
callback(visione::http::error("unsupported_media_type",
|
||||
drogon::k400BadRequest));
|
||||
return;
|
||||
}
|
||||
@@ -281,10 +286,12 @@ void ReportController::uploadPhotos(
|
||||
|
||||
Json::Value response;
|
||||
response["ok"] = true;
|
||||
response["media"] = Json::arrayValue;
|
||||
response["photos"] = Json::arrayValue;
|
||||
|
||||
for (const auto &file : parser.getFiles())
|
||||
{
|
||||
const auto mediaType = allowedMediaType(file).value();
|
||||
auto extension = std::string(file.getFileExtension());
|
||||
if (!extension.empty() && extension.front() != '.')
|
||||
{
|
||||
@@ -294,24 +301,30 @@ void ReportController::uploadPhotos(
|
||||
const auto fullPath = reportDir / fileName;
|
||||
if (file.saveAs(fullPath.string()) != 0)
|
||||
{
|
||||
callback(visione::http::error("photo_save_failed",
|
||||
callback(visione::http::error("media_save_failed",
|
||||
drogon::k500InternalServerError));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto url = publicBasePath + "/reports/" + std::to_string(reportId) +
|
||||
"/" + fileName;
|
||||
auto saved = service.addPhoto(*user,
|
||||
auto saved = service.addMedia(*user,
|
||||
reportId,
|
||||
url,
|
||||
file.getFileName(),
|
||||
imageContentType(file),
|
||||
mediaType.contentType,
|
||||
mediaType.kind,
|
||||
file.fileLength());
|
||||
if (!saved.get("ok", false).asBool())
|
||||
{
|
||||
callback(visione::http::json(std::move(saved), drogon::k403Forbidden));
|
||||
return;
|
||||
}
|
||||
Json::Value item;
|
||||
item["url"] = url;
|
||||
item["kind"] = mediaType.kind;
|
||||
item["content_type"] = mediaType.contentType;
|
||||
response["media"].append(item);
|
||||
response["photos"].append(url);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@ class ReportController : public drogon::HttpController<ReportController>
|
||||
ADD_METHOD_TO(ReportController::addFeedback,
|
||||
"/api/v1/reports/{1}/feedback",
|
||||
drogon::Post);
|
||||
ADD_METHOD_TO(ReportController::uploadPhotos,
|
||||
ADD_METHOD_TO(ReportController::uploadMedia,
|
||||
"/api/v1/reports/{1}/media",
|
||||
drogon::Post);
|
||||
ADD_METHOD_TO(ReportController::uploadMedia,
|
||||
"/api/v1/reports/{1}/photos",
|
||||
drogon::Post);
|
||||
METHOD_LIST_END
|
||||
@@ -63,7 +66,7 @@ class ReportController : public drogon::HttpController<ReportController>
|
||||
const drogon::HttpRequestPtr &req,
|
||||
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
|
||||
long long reportId);
|
||||
void uploadPhotos(
|
||||
void uploadMedia(
|
||||
const drogon::HttpRequestPtr &req,
|
||||
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
|
||||
long long reportId);
|
||||
|
||||
Reference in New Issue
Block a user