Added initial (unfinished) category list, as well as the GET /arbitrary/categories API, and converted the category field from a string to an enum

This commit is contained in:
CalDescent 2022-01-22 12:11:16 +00:00
parent 79f87babdf
commit a79ed02ccf
8 changed files with 130 additions and 29 deletions

View File

@ -33,10 +33,12 @@ import org.qortal.api.resource.TransactionsResource.ConfirmationStatus;
import org.qortal.arbitrary.*; import org.qortal.arbitrary.*;
import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType;
import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.exception.MissingDataException;
import org.qortal.arbitrary.misc.Category;
import org.qortal.arbitrary.misc.Service; import org.qortal.arbitrary.misc.Service;
import org.qortal.controller.Controller; import org.qortal.controller.Controller;
import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; import org.qortal.controller.arbitrary.ArbitraryDataStorageManager;
import org.qortal.data.account.AccountData; import org.qortal.data.account.AccountData;
import org.qortal.data.arbitrary.ArbitraryCategoryInfo;
import org.qortal.data.arbitrary.ArbitraryResourceInfo; import org.qortal.data.arbitrary.ArbitraryResourceInfo;
import org.qortal.data.arbitrary.ArbitraryResourceNameInfo; import org.qortal.data.arbitrary.ArbitraryResourceNameInfo;
import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.arbitrary.ArbitraryResourceStatus;
@ -388,6 +390,28 @@ public class ArbitraryResource {
return Settings.getInstance().isRelayModeEnabled(); return Settings.getInstance().isRelayModeEnabled();
} }
@GET
@Path("/categories")
@Operation(
summary = "List arbitrary transaction categories",
responses = {
@ApiResponse(
content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ArbitraryCategoryInfo.class))
)
}
)
@ApiErrors({ApiError.REPOSITORY_ISSUE})
public List<ArbitraryCategoryInfo> getCategories() {
List<ArbitraryCategoryInfo> categories = new ArrayList<>();
for (Category category : Category.values()) {
ArbitraryCategoryInfo arbitraryCategory = new ArbitraryCategoryInfo();
arbitraryCategory.id = category.toString();
arbitraryCategory.name = category.getName();
categories.add(arbitraryCategory);
}
return categories;
}
@GET @GET
@Path("/hosted/transactions") @Path("/hosted/transactions")
@Operation( @Operation(
@ -645,7 +669,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String path) { String path) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -690,7 +714,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String path) { String path) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -736,7 +760,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String base64) { String base64) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -779,7 +803,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String base64) { String base64) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -824,7 +848,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String base64Zip) { String base64Zip) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -867,7 +891,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String base64Zip) { String base64Zip) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -915,7 +939,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String string) { String string) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -960,7 +984,7 @@ public class ArbitraryResource {
@QueryParam("title") String title, @QueryParam("title") String title,
@QueryParam("description") String description, @QueryParam("description") String description,
@QueryParam("tags") String tags, @QueryParam("tags") String tags,
@QueryParam("category") String category, @QueryParam("category") Category category,
String string) { String string) {
Security.checkApiCallAllowed(request); Security.checkApiCallAllowed(request);
@ -977,7 +1001,7 @@ public class ArbitraryResource {
private String upload(Service service, String name, String identifier, private String upload(Service service, String name, String identifier,
String path, String string, String base64, boolean zipped, String path, String string, String base64, boolean zipped,
String title, String description, String tags, String category) { String title, String description, String tags, Category category) {
// Fetch public key from registered name // Fetch public key from registered name
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
NameData nameData = repository.getNameRepository().fromName(name); NameData nameData = repository.getNameRepository().fromName(name);

View File

@ -6,6 +6,7 @@ import org.qortal.arbitrary.exception.MissingDataException;
import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType;
import org.qortal.arbitrary.ArbitraryDataDiff.*; import org.qortal.arbitrary.ArbitraryDataDiff.*;
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch; import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
import org.qortal.arbitrary.misc.Category;
import org.qortal.arbitrary.misc.Service; import org.qortal.arbitrary.misc.Service;
import org.qortal.block.BlockChain; import org.qortal.block.BlockChain;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
@ -55,7 +56,7 @@ public class ArbitraryDataTransactionBuilder {
private final String title; private final String title;
private final String description; private final String description;
private final String tags; private final String tags;
private final String category; private final Category category;
private int chunkSize = ArbitraryDataFile.CHUNK_SIZE; private int chunkSize = ArbitraryDataFile.CHUNK_SIZE;
@ -64,7 +65,7 @@ public class ArbitraryDataTransactionBuilder {
public ArbitraryDataTransactionBuilder(Repository repository, String publicKey58, Path path, String name, public ArbitraryDataTransactionBuilder(Repository repository, String publicKey58, Path path, String name,
Method method, Service service, String identifier, Method method, Service service, String identifier,
String title, String description, String tags, String category) { String title, String description, String tags, Category category) {
this.repository = repository; this.repository = repository;
this.publicKey58 = publicKey58; this.publicKey58 = publicKey58;
this.path = path; this.path = path;

View File

@ -5,6 +5,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.exception.MissingDataException;
import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata;
import org.qortal.arbitrary.misc.Category;
import org.qortal.arbitrary.misc.Service; import org.qortal.arbitrary.misc.Service;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.data.transaction.ArbitraryTransactionData.*;
@ -45,12 +46,11 @@ public class ArbitraryDataWriter {
private final String title; private final String title;
private final String description; private final String description;
private final String tags; private final String tags;
private final String category; private final Category category;
private static int MAX_TITLE_LENGTH = 80; private static int MAX_TITLE_LENGTH = 80;
private static int MAX_DESCRIPTION_LENGTH = 500; private static int MAX_DESCRIPTION_LENGTH = 500;
private static int MAX_TAGS_LENGTH = 80; private static int MAX_TAGS_LENGTH = 80;
private static int MAX_CATEGORY_LENGTH = 40;
private int chunkSize = ArbitraryDataFile.CHUNK_SIZE; private int chunkSize = ArbitraryDataFile.CHUNK_SIZE;
@ -63,7 +63,7 @@ public class ArbitraryDataWriter {
private Path encryptedPath; private Path encryptedPath;
public ArbitraryDataWriter(Path filePath, String name, Service service, String identifier, Method method, Compression compression, public ArbitraryDataWriter(Path filePath, String name, Service service, String identifier, Method method, Compression compression,
String title, String description, String tags, String category) { String title, String description, String tags, Category category) {
this.filePath = filePath; this.filePath = filePath;
this.name = name; this.name = name;
this.service = service; this.service = service;
@ -77,10 +77,10 @@ public class ArbitraryDataWriter {
this.identifier = identifier; this.identifier = identifier;
// Metadata (optional) // Metadata (optional)
this.title = title.substring(0, MAX_TITLE_LENGTH);; this.title = title != null ? title.substring(0, Math.min(title.length(), MAX_TITLE_LENGTH)) : null;
this.description = description.substring(0, MAX_DESCRIPTION_LENGTH); this.description = description != null ? description.substring(0, Math.min(description.length(), MAX_DESCRIPTION_LENGTH)) : null;
this.tags = tags.substring(0, MAX_TAGS_LENGTH); this.tags = tags != null ? tags.substring(0, Math.min(tags.length(), MAX_TAGS_LENGTH)) : null;
this.category = category.substring(0, MAX_CATEGORY_LENGTH); this.category = category;
} }
public void save() throws IOException, DataException, InterruptedException, MissingDataException { public void save() throws IOException, DataException, InterruptedException, MissingDataException {

View File

@ -2,6 +2,7 @@ package org.qortal.arbitrary.metadata;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.qortal.arbitrary.misc.Category;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.utils.Base58; import org.qortal.utils.Base58;
@ -16,7 +17,7 @@ public class ArbitraryDataTransactionMetadata extends ArbitraryDataMetadata {
private String title; private String title;
private String description; private String description;
private String tags; private String tags;
private String category; private Category category;
public ArbitraryDataTransactionMetadata(Path filePath) { public ArbitraryDataTransactionMetadata(Path filePath) {
super(filePath); super(filePath);
@ -41,7 +42,7 @@ public class ArbitraryDataTransactionMetadata extends ArbitraryDataMetadata {
this.tags = metadata.getString("tags"); this.tags = metadata.getString("tags");
} }
if (metadata.has("category")) { if (metadata.has("category")) {
this.category = metadata.getString("category"); this.category = Category.valueOf(metadata.getString("category"));
} }
List<byte[]> chunksList = new ArrayList<>(); List<byte[]> chunksList = new ArrayList<>();
@ -72,8 +73,8 @@ public class ArbitraryDataTransactionMetadata extends ArbitraryDataMetadata {
if (this.tags != null && !this.tags.isEmpty()) { if (this.tags != null && !this.tags.isEmpty()) {
outer.put("tags", this.tags); outer.put("tags", this.tags);
} }
if (this.category != null && !this.category.isEmpty()) { if (this.category != null) {
outer.put("category", this.category); outer.put("category", this.category.toString());
} }
JSONArray chunks = new JSONArray(); JSONArray chunks = new JSONArray();
@ -121,11 +122,11 @@ public class ArbitraryDataTransactionMetadata extends ArbitraryDataMetadata {
return this.tags; return this.tags;
} }
public void setCategory(String category) { public void setCategory(Category category) {
this.category = category; this.category = category;
} }
public String getCategory() { public Category getCategory() {
return this.category; return this.category;
} }

View File

@ -0,0 +1,62 @@
package org.qortal.arbitrary.misc;
public enum Category {
ART_AND_DESIGN("Art and Design"),
AUTOMOTIVE("Automotive"),
BEAUTY("Beauty"),
BOOKS("Books and Reference"),
BUSINESS("Business"),
COMMUNICATIONS("Communications"),
CRYPTOCURRENCY("Cryptocurrency and Blockchain"),
DATING("Dating"),
ENTERTAINMENT("Entertainment"),
EVENTS("Events"),
FASHION("Fashion"),
FINANCE("Finance"),
FOOD("Food and Drink"),
GAMING("Gaming"),
GEOGRAPHY("Geography"),
HEALTH("Health"),
HISTORY("History"),
HOME("Home"),
KNOWLEDGE("Knowledge Share"),
LANGUAGE("Language"),
LIFESTYLE("Lifestyle"),
MANUFACTURING("Manufacturing"),
MAPS("Maps and Navigation"),
MEDICAL("Medical"),
MUSIC("Music"),
NEWS("News"),
OTHER("Other"),
PERSONALIZATION("Personalization"),
PETS("Pets"),
PHILOSOPHY("Philosophy"),
PHOTOGRAPHY("Photography"),
POLITICS("Politics"),
PRODUCTIVITY("Productivity"),
PSYCHOLOGY("Psychology"),
QORTAL("Qortal"),
RELIGION("Religion"),
SCIENCE("Science"),
SERVICES("Services"),
SHOPPING("Shopping"),
SOCIAL("Social"),
SOFTWARE("Software"),
SPORTS("Sports"),
TECHNOLOGY("Technology"),
TOOLS("Tools"),
TRAVEL("Travel"),
VIDEO("Video"),
WEATHER("Weather");
private final String name;
Category(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}

View File

@ -0,0 +1,12 @@
package org.qortal.data.arbitrary;
public class ArbitraryCategoryInfo {
public String id;
public String name;
public ArbitraryCategoryInfo() {
}
}

View File

@ -9,6 +9,7 @@ import org.qortal.arbitrary.ArbitraryDataFile;
import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.arbitrary.ArbitraryDataFile.*;
import org.qortal.arbitrary.ArbitraryDataReader; import org.qortal.arbitrary.ArbitraryDataReader;
import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.exception.MissingDataException;
import org.qortal.arbitrary.misc.Category;
import org.qortal.arbitrary.misc.Service; import org.qortal.arbitrary.misc.Service;
import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.controller.arbitrary.ArbitraryDataManager;
import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData;
@ -87,7 +88,7 @@ public class ArbitraryTransactionMetadataTests extends Common {
String title = "Test title"; String title = "Test title";
String description = "Test description"; String description = "Test description";
String tags = "Test tags"; String tags = "Test tags";
String category = "Test category"; Category category = Category.QORTAL;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -136,12 +137,11 @@ public class ArbitraryTransactionMetadataTests extends Common {
String title = "title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium"; String title = "title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium";
String description = "description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium massa, non pulvinar mi pretium id. Ut gravida sapien vitae dui posuere tincidunt. Quisque in nibh est. Curabitur at blandit nunc, id aliquet neque. Nulla condimentum eget dolor a egestas. Vestibulum vel tincidunt ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras congue lacus in risus mattis suscipit. Quisque nisl eros, facilisis a lorem quis, vehicula bibendum."; String description = "description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium massa, non pulvinar mi pretium id. Ut gravida sapien vitae dui posuere tincidunt. Quisque in nibh est. Curabitur at blandit nunc, id aliquet neque. Nulla condimentum eget dolor a egestas. Vestibulum vel tincidunt ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras congue lacus in risus mattis suscipit. Quisque nisl eros, facilisis a lorem quis, vehicula bibendum.";
String tags = "tags Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium"; String tags = "tags Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium";
String category = "category Lorem ipsum dolor sit amet, consectetur"; Category category = Category.CRYPTOCURRENCY;
String expectedTitle = "title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat "; // 80 chars String expectedTitle = "title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat "; // 80 chars
String expectedDescription = "description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium massa, non pulvinar mi pretium id. Ut gravida sapien vitae dui posuere tincidunt. Quisque in nibh est. Curabitur at blandit nunc, id aliquet neque. Nulla condimentum eget dolor a egestas. Vestibulum vel tincidunt ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras congue lacus in risus mattis suscipit. Quisque nisl eros, facilisis a lorem quis, vehicula biben"; // 500 chars String expectedDescription = "description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat pretium massa, non pulvinar mi pretium id. Ut gravida sapien vitae dui posuere tincidunt. Quisque in nibh est. Curabitur at blandit nunc, id aliquet neque. Nulla condimentum eget dolor a egestas. Vestibulum vel tincidunt ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras congue lacus in risus mattis suscipit. Quisque nisl eros, facilisis a lorem quis, vehicula biben"; // 500 chars
String expectedTags = "tags Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat p"; // 80 chars String expectedTags = "tags Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat p"; // 80 chars
String expectedCategory = "category Lorem ipsum dolor sit amet, con"; // 40 chars
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -157,7 +157,7 @@ public class ArbitraryTransactionMetadataTests extends Common {
assertEquals(expectedTitle, arbitraryDataFile.getMetadata().getTitle()); assertEquals(expectedTitle, arbitraryDataFile.getMetadata().getTitle());
assertEquals(expectedDescription, arbitraryDataFile.getMetadata().getDescription()); assertEquals(expectedDescription, arbitraryDataFile.getMetadata().getDescription());
assertEquals(expectedTags, arbitraryDataFile.getMetadata().getTags()); assertEquals(expectedTags, arbitraryDataFile.getMetadata().getTags());
assertEquals(expectedCategory, arbitraryDataFile.getMetadata().getCategory()); assertEquals(category, arbitraryDataFile.getMetadata().getCategory());
} }
} }

View File

@ -3,6 +3,7 @@ package org.qortal.test.common;
import org.qortal.account.PrivateKeyAccount; import org.qortal.account.PrivateKeyAccount;
import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataFile;
import org.qortal.arbitrary.ArbitraryDataTransactionBuilder; import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
import org.qortal.arbitrary.misc.Category;
import org.qortal.arbitrary.misc.Service; import org.qortal.arbitrary.misc.Service;
import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
@ -32,7 +33,7 @@ public class ArbitraryUtils {
public static ArbitraryDataFile createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier, public static ArbitraryDataFile createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
ArbitraryTransactionData.Method method, Service service, PrivateKeyAccount account, ArbitraryTransactionData.Method method, Service service, PrivateKeyAccount account,
int chunkSize, String title, String description, String tags, String category) throws DataException { int chunkSize, String title, String description, String tags, Category category) throws DataException {
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder( ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
repository, publicKey58, path, name, method, service, identifier, title, description, tags, category); repository, publicKey58, path, name, method, service, identifier, title, description, tags, category);