forked from Qortal/qortal
Added support for multiple block/follow lists.
Any list with the following prefix will be used in block/follow logic: blockedNames blockedAddresses followedNames For instance, any names in a list named "blockedNames_CustomBlockList" would also be blocked, along with those in the standard "blockedNames" list. This will ultimately allow apps to offer custom block/follow lists to users (once list functionality is added to the Q-Apps API).
This commit is contained in:
parent
2086a2c476
commit
35def54ecc
@ -52,6 +52,15 @@ public class ResourceList {
|
|||||||
String jsonString = ResourceList.listToJSONString(this.list);
|
String jsonString = ResourceList.listToJSONString(this.list);
|
||||||
Path filePath = this.getFilePath();
|
Path filePath = this.getFilePath();
|
||||||
|
|
||||||
|
// Don't create list if it's empty
|
||||||
|
if (this.list != null && this.list.isEmpty()) {
|
||||||
|
if (filePath != null && Files.exists(filePath)) {
|
||||||
|
// Delete empty list
|
||||||
|
Files.delete(filePath);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Create parent directory if needed
|
// Create parent directory if needed
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(filePath.getParent());
|
Files.createDirectories(filePath.getParent());
|
||||||
@ -109,6 +118,13 @@ public class ResourceList {
|
|||||||
this.list.remove(resource);
|
this.list.remove(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if (this.list == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean contains(String resource, boolean caseSensitive) {
|
public boolean contains(String resource, boolean caseSensitive) {
|
||||||
if (resource == null || this.list == null) {
|
if (resource == null || this.list == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,8 +2,11 @@ package org.qortal.list;
|
|||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.qortal.settings.Settings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,6 +21,7 @@ public class ResourceListManager {
|
|||||||
|
|
||||||
|
|
||||||
public ResourceListManager() {
|
public ResourceListManager() {
|
||||||
|
this.lists = this.fetchLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized ResourceListManager getInstance() {
|
public static synchronized ResourceListManager getInstance() {
|
||||||
@ -27,6 +31,38 @@ public class ResourceListManager {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static synchronized void reset() {
|
||||||
|
if (instance != null) {
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ResourceList> fetchLists() {
|
||||||
|
List<ResourceList> lists = new ArrayList<>();
|
||||||
|
Path listsPath = Paths.get(Settings.getInstance().getListsPath());
|
||||||
|
|
||||||
|
if (listsPath.toFile().isDirectory()) {
|
||||||
|
String[] files = listsPath.toFile().list();
|
||||||
|
|
||||||
|
for (String fileName : files) {
|
||||||
|
try {
|
||||||
|
// Remove .json extension
|
||||||
|
if (fileName.endsWith(".json")) {
|
||||||
|
fileName = fileName.substring(0, fileName.length() - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceList list = new ResourceList(fileName);
|
||||||
|
if (list != null) {
|
||||||
|
lists.add(list);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore this list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lists;
|
||||||
|
}
|
||||||
|
|
||||||
private ResourceList getList(String listName) {
|
private ResourceList getList(String listName) {
|
||||||
for (ResourceList list : this.lists) {
|
for (ResourceList list : this.lists) {
|
||||||
if (Objects.equals(list.getName(), listName)) {
|
if (Objects.equals(list.getName(), listName)) {
|
||||||
@ -48,6 +84,18 @@ public class ResourceListManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ResourceList> getListsByPrefix(String listNamePrefix) {
|
||||||
|
List<ResourceList> lists = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ResourceList list : this.lists) {
|
||||||
|
if (list != null && list.getName() != null && list.getName().startsWith(listNamePrefix)) {
|
||||||
|
lists.add(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lists;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean addToList(String listName, String item, boolean save) {
|
public boolean addToList(String listName, String item, boolean save) {
|
||||||
ResourceList list = this.getList(listName);
|
ResourceList list = this.getList(listName);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
@ -95,6 +143,16 @@ public class ResourceListManager {
|
|||||||
return list.contains(item, caseSensitive);
|
return list.contains(item, caseSensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean listWithPrefixContains(String listNamePrefix, String item, boolean caseSensitive) {
|
||||||
|
List<ResourceList> lists = getListsByPrefix(listNamePrefix);
|
||||||
|
for (ResourceList list : lists) {
|
||||||
|
if (list.contains(item, caseSensitive)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void saveList(String listName) {
|
public void saveList(String listName) {
|
||||||
ResourceList list = this.getList(listName);
|
ResourceList list = this.getList(listName);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
@ -133,6 +191,15 @@ public class ResourceListManager {
|
|||||||
return list.getList();
|
return list.getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getStringsInListsWithPrefix(String listNamePrefix) {
|
||||||
|
List<String> items = new ArrayList<>();
|
||||||
|
List<ResourceList> lists = getListsByPrefix(listNamePrefix);
|
||||||
|
for (ResourceList list : lists) {
|
||||||
|
items.addAll(list.getList());
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
public int getItemCountForList(String listName) {
|
public int getItemCountForList(String listName) {
|
||||||
ResourceList list = this.getList(listName);
|
ResourceList list = this.getList(listName);
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
|
@ -9,26 +9,26 @@ public class ListUtils {
|
|||||||
/* Blocking */
|
/* Blocking */
|
||||||
|
|
||||||
public static List<String> blockedNames() {
|
public static List<String> blockedNames() {
|
||||||
return ResourceListManager.getInstance().getStringsInList("blockedNames");
|
return ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNameBlocked(String name) {
|
public static boolean isNameBlocked(String name) {
|
||||||
return ResourceListManager.getInstance().listContains("blockedNames", name, false);
|
return ResourceListManager.getInstance().listWithPrefixContains("blockedNames", name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAddressBlocked(String address) {
|
public static boolean isAddressBlocked(String address) {
|
||||||
return ResourceListManager.getInstance().listContains("blockedAddresses", address, true);
|
return ResourceListManager.getInstance().listWithPrefixContains("blockedAddresses", address, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Following */
|
/* Following */
|
||||||
|
|
||||||
public static List<String> followedNames() {
|
public static List<String> followedNames() {
|
||||||
return ResourceListManager.getInstance().getStringsInList("followedNames");
|
return ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFollowingName(String name) {
|
public static boolean isFollowingName(String name) {
|
||||||
return ResourceListManager.getInstance().listContains("followedNames", name, false);
|
return ResourceListManager.getInstance().listWithPrefixContains("followedNames", name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int followedNamesCount() {
|
public static int followedNamesCount() {
|
||||||
|
129
src/test/java/org/qortal/test/ListTests.java
Normal file
129
src/test/java/org/qortal/test/ListTests.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package org.qortal.test;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.qortal.list.ResourceList;
|
||||||
|
import org.qortal.list.ResourceListManager;
|
||||||
|
import org.qortal.repository.DataException;
|
||||||
|
import org.qortal.settings.Settings;
|
||||||
|
import org.qortal.test.common.Common;
|
||||||
|
import org.qortal.utils.ListUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ListTests {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeTest() throws DataException, IOException {
|
||||||
|
Common.useDefaultSettings();
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterTest() throws DataException, IOException {
|
||||||
|
this.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup() throws IOException {
|
||||||
|
// Delete custom lists created by test methods
|
||||||
|
ResourceList followedNamesTestList = new ResourceList("followedNames_test");
|
||||||
|
followedNamesTestList.clear();
|
||||||
|
followedNamesTestList.save();
|
||||||
|
|
||||||
|
ResourceList blockedNamesTestList = new ResourceList("blockedNames_test");
|
||||||
|
blockedNamesTestList.clear();
|
||||||
|
blockedNamesTestList.save();
|
||||||
|
|
||||||
|
// Clear resource list manager instance
|
||||||
|
ResourceListManager.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSingleList() {
|
||||||
|
ResourceListManager resourceListManager = ResourceListManager.getInstance();
|
||||||
|
String listName = "followedNames_test";
|
||||||
|
String name = "testName";
|
||||||
|
|
||||||
|
resourceListManager.addToList(listName, name, false);
|
||||||
|
|
||||||
|
List<String> followedNames = resourceListManager.getStringsInList(listName);
|
||||||
|
assertEquals(1, followedNames.size());
|
||||||
|
assertEquals(followedNames.size(), ListUtils.followedNamesCount());
|
||||||
|
assertEquals(name, followedNames.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListPrefix() {
|
||||||
|
ResourceListManager resourceListManager = ResourceListManager.getInstance();
|
||||||
|
|
||||||
|
List<String> initialFollowedNames = resourceListManager.getStringsInListsWithPrefix("followedNames");
|
||||||
|
assertEquals(0, initialFollowedNames.size());
|
||||||
|
|
||||||
|
List<String> initialBlockedNames = resourceListManager.getStringsInListsWithPrefix("blockedNames");
|
||||||
|
assertEquals(0, initialBlockedNames.size());
|
||||||
|
|
||||||
|
// Add to multiple lists
|
||||||
|
resourceListManager.addToList("followedNames_CustomList1", "testName1", false);
|
||||||
|
resourceListManager.addToList("followedNames_CustomList1", "testName2", false);
|
||||||
|
resourceListManager.addToList("followedNames_CustomList2", "testName3", false);
|
||||||
|
resourceListManager.addToList("followedNames_CustomList3", "testName4", false);
|
||||||
|
resourceListManager.addToList("blockedNames_CustomList1", "testName5", false);
|
||||||
|
|
||||||
|
// Check followedNames
|
||||||
|
List<String> followedNames = resourceListManager.getStringsInListsWithPrefix("followedNames");
|
||||||
|
assertEquals(4, followedNames.size());
|
||||||
|
assertEquals(followedNames.size(), ListUtils.followedNamesCount());
|
||||||
|
assertTrue(followedNames.contains("testName1"));
|
||||||
|
assertTrue(followedNames.contains("testName2"));
|
||||||
|
assertTrue(followedNames.contains("testName3"));
|
||||||
|
assertTrue(followedNames.contains("testName4"));
|
||||||
|
assertFalse(followedNames.contains("testName5"));
|
||||||
|
|
||||||
|
// Check blockedNames
|
||||||
|
List<String> blockedNames = resourceListManager.getStringsInListsWithPrefix("blockedNames");
|
||||||
|
assertEquals(1, blockedNames.size());
|
||||||
|
assertEquals(blockedNames.size(), ListUtils.blockedNames().size());
|
||||||
|
assertTrue(blockedNames.contains("testName5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDataPersistence() {
|
||||||
|
// Ensure lists are empty to begin with
|
||||||
|
assertEquals(0, ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames").size());
|
||||||
|
assertEquals(0, ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames").size());
|
||||||
|
|
||||||
|
// Add some items to multiple lists
|
||||||
|
ResourceListManager.getInstance().addToList("followedNames_test", "testName1", true);
|
||||||
|
ResourceListManager.getInstance().addToList("followedNames_test", "testName2", true);
|
||||||
|
ResourceListManager.getInstance().addToList("blockedNames_test", "testName3", true);
|
||||||
|
|
||||||
|
// Ensure they are added
|
||||||
|
assertEquals(2, ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames").size());
|
||||||
|
assertEquals(1, ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames").size());
|
||||||
|
|
||||||
|
// Clear local state
|
||||||
|
ResourceListManager.reset();
|
||||||
|
|
||||||
|
// Ensure items are automatically loaded back in from disk
|
||||||
|
assertEquals(2, ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames").size());
|
||||||
|
assertEquals(1, ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames").size());
|
||||||
|
|
||||||
|
// Delete followedNames file
|
||||||
|
File followedNamesFile = Paths.get(Settings.getInstance().getListsPath(), "followedNames_test.json").toFile();
|
||||||
|
followedNamesFile.delete();
|
||||||
|
|
||||||
|
// Clear local state again
|
||||||
|
ResourceListManager.reset();
|
||||||
|
|
||||||
|
// Ensure only the blocked names are loaded back in
|
||||||
|
assertEquals(0, ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames").size());
|
||||||
|
assertEquals(1, ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user