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);
|
||||
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
|
||||
try {
|
||||
Files.createDirectories(filePath.getParent());
|
||||
@ -109,6 +118,13 @@ public class ResourceList {
|
||||
this.list.remove(resource);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (this.list == null) {
|
||||
return;
|
||||
}
|
||||
this.list.clear();
|
||||
}
|
||||
|
||||
public boolean contains(String resource, boolean caseSensitive) {
|
||||
if (resource == null || this.list == null) {
|
||||
return false;
|
||||
|
@ -2,8 +2,11 @@ package org.qortal.list;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qortal.settings.Settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -18,6 +21,7 @@ public class ResourceListManager {
|
||||
|
||||
|
||||
public ResourceListManager() {
|
||||
this.lists = this.fetchLists();
|
||||
}
|
||||
|
||||
public static synchronized ResourceListManager getInstance() {
|
||||
@ -27,6 +31,38 @@ public class ResourceListManager {
|
||||
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) {
|
||||
for (ResourceList list : this.lists) {
|
||||
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) {
|
||||
ResourceList list = this.getList(listName);
|
||||
if (list == null) {
|
||||
@ -95,6 +143,16 @@ public class ResourceListManager {
|
||||
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) {
|
||||
ResourceList list = this.getList(listName);
|
||||
if (list == null) {
|
||||
@ -133,6 +191,15 @@ public class ResourceListManager {
|
||||
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) {
|
||||
ResourceList list = this.getList(listName);
|
||||
if (list == null) {
|
||||
|
@ -9,26 +9,26 @@ public class ListUtils {
|
||||
/* Blocking */
|
||||
|
||||
public static List<String> blockedNames() {
|
||||
return ResourceListManager.getInstance().getStringsInList("blockedNames");
|
||||
return ResourceListManager.getInstance().getStringsInListsWithPrefix("blockedNames");
|
||||
}
|
||||
|
||||
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) {
|
||||
return ResourceListManager.getInstance().listContains("blockedAddresses", address, true);
|
||||
return ResourceListManager.getInstance().listWithPrefixContains("blockedAddresses", address, true);
|
||||
}
|
||||
|
||||
|
||||
/* Following */
|
||||
|
||||
public static List<String> followedNames() {
|
||||
return ResourceListManager.getInstance().getStringsInList("followedNames");
|
||||
return ResourceListManager.getInstance().getStringsInListsWithPrefix("followedNames");
|
||||
}
|
||||
|
||||
public static boolean isFollowingName(String name) {
|
||||
return ResourceListManager.getInstance().listContains("followedNames", name, false);
|
||||
return ResourceListManager.getInstance().listWithPrefixContains("followedNames", name, false);
|
||||
}
|
||||
|
||||
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