forked from Qortal/qortal
Added DELETE /data/file API endpoint
This deletes a file referenced by a user supplied SHA256 digest string (which we will use as the file's "ID" in the Qortal data system). In the future this could be extended to delete all associated chunks, but first we need to build out the data chain so we have a way to look up chunks associated with a file hash.
This commit is contained in:
parent
76742c3869
commit
f82f2bd287
@ -20,6 +20,7 @@ import org.qortal.storage.DataFile;
|
||||
import org.qortal.storage.DataFile.ValidationResult;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.core.Context;
|
||||
@ -95,4 +96,40 @@ public class DataResource {
|
||||
}
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/file")
|
||||
@Operation(
|
||||
summary = "Delete file using supplied base58 encoded SHA256 digest string",
|
||||
requestBody = @RequestBody(
|
||||
required = true,
|
||||
content = @Content(
|
||||
mediaType = MediaType.TEXT_PLAIN,
|
||||
schema = @Schema(
|
||||
type = "string", example = "FZdHKgF5CbN2tKihvop5Ts9vmWmA9ZyyPY6bC1zivjy4"
|
||||
)
|
||||
)
|
||||
),
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
description = "true if deleted, false if not",
|
||||
content = @Content(
|
||||
mediaType = MediaType.TEXT_PLAIN,
|
||||
schema = @Schema(
|
||||
type = "string"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiErrors({ApiError.REPOSITORY_ISSUE})
|
||||
public String deleteFile(String base58Digest) {
|
||||
Security.checkApiCallAllowed(request);
|
||||
|
||||
DataFile dataFile = DataFile.fromBase58Digest(base58Digest);
|
||||
if (dataFile.delete()) {
|
||||
return "true";
|
||||
}
|
||||
return "false";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -72,6 +72,11 @@ public class DataFile {
|
||||
this(file.getPath());
|
||||
}
|
||||
|
||||
public static DataFile fromBase58Digest(String base58Digest) {
|
||||
String filePath = DataFile.getOutputFilePath(base58Digest);
|
||||
return new DataFile(filePath);
|
||||
}
|
||||
|
||||
private boolean createDataDirectory() {
|
||||
// Create the data directory if it doesn't exist
|
||||
String dataPath = Settings.getInstance().getDataPath();
|
||||
@ -97,7 +102,7 @@ public class DataFile {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getOutputFilePath(String base58Digest) {
|
||||
public static String getOutputFilePath(String base58Digest) {
|
||||
String base58DigestFirst2Chars = base58Digest.substring(0, Math.min(base58Digest.length(), 2));
|
||||
String base58DigestNext2Chars = base58Digest.substring(2, Math.min(base58Digest.length(), 4));
|
||||
String outputDirectory = String.format("%s/%s/%s", Settings.getInstance().getDataPath(), base58DigestFirst2Chars, base58DigestNext2Chars);
|
||||
@ -169,7 +174,7 @@ public class DataFile {
|
||||
return this.chunks.size();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
public boolean delete() {
|
||||
// Delete the complete file
|
||||
Path path = Paths.get(this.filePath);
|
||||
if (Files.exists(path)) {
|
||||
@ -177,15 +182,17 @@ public class DataFile {
|
||||
Files.delete(path);
|
||||
this.cleanupFilesystem();
|
||||
LOGGER.debug("Deleted file {}", path.toString());
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Couldn't delete DataFileChunk at path {}", this.filePath);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
public boolean deleteAll() {
|
||||
// Delete the complete file
|
||||
this.delete();
|
||||
boolean success = this.delete();
|
||||
|
||||
// Delete the individual chunks
|
||||
if (this.chunks != null && this.chunks.size() > 0) {
|
||||
@ -194,8 +201,10 @@ public class DataFile {
|
||||
DataFileChunk chunk = (DataFileChunk) iterator.next();
|
||||
chunk.delete();
|
||||
iterator.remove();
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
protected void cleanupFilesystem() {
|
||||
|
Loading…
Reference in New Issue
Block a user