mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
major classes refactoring
This commit is contained in:
@@ -12,7 +12,7 @@ import com.uaihebert.factory.EasyCriteriaFactory;
|
||||
import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
public class ApplicationSettingsService {
|
||||
public class ApplicationSettingsDAO {
|
||||
|
||||
@PersistenceContext
|
||||
protected EntityManager em;
|
||||
@@ -16,7 +16,7 @@ import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedCategoryService extends GenericDAO<FeedCategory> {
|
||||
public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
||||
|
||||
public List<FeedCategory> findAll(User user) {
|
||||
EasyCriteria<FeedCategory> criteria = createCriteria();
|
||||
@@ -20,7 +20,7 @@ import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedService extends GenericDAO<Feed> {
|
||||
public class FeedDAO extends GenericDAO<Feed> {
|
||||
|
||||
public List<Feed> findNextUpdatable(int count) {
|
||||
CriteriaQuery<Feed> query = builder.createQuery(getType());
|
||||
@@ -56,7 +56,7 @@ public class FeedService extends GenericDAO<Feed> {
|
||||
return Iterables.getFirst(feeds, null);
|
||||
}
|
||||
|
||||
public Feed getByIdWithEntries(Long feedId, int offset, int limit) {
|
||||
public Feed findByIdWithEntries(Long feedId, int offset, int limit) {
|
||||
EasyCriteria<Feed> criteria = createCriteria();
|
||||
criteria.andEquals(MF.i(proxy().getId()), feedId);
|
||||
criteria.leftJoinFetch(MF.i(proxy().getEntries()));
|
||||
38
src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java
Normal file
38
src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntry_;
|
||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||
import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
||||
|
||||
public List<FeedEntry> findByGuids(List<String> guids) {
|
||||
EasyCriteria<FeedEntry> criteria = createCriteria();
|
||||
criteria.setDistinctTrue();
|
||||
criteria.andStringIn(MF.i(proxy().getGuid()), guids);
|
||||
criteria.leftJoinFetch(MF.i(proxy().getFeeds()));
|
||||
return criteria.getResultList();
|
||||
}
|
||||
|
||||
public List<FeedEntry> findByFeed(Feed feed, int offset, int limit) {
|
||||
CriteriaQuery<FeedEntry> query = builder.createQuery(getType());
|
||||
Root<FeedEntry> root = query.from(getType());
|
||||
query.where(builder.isMember(feed, root.get(FeedEntry_.feeds)));
|
||||
query.orderBy(builder.desc(root.get(FeedEntry_.updated)));
|
||||
TypedQuery<FeedEntry> q = em.createQuery(query);
|
||||
q.setFirstResult(offset);
|
||||
q.setMaxResults(limit);
|
||||
return q.getResultList();
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedEntry_;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedEntryService extends GenericDAO<FeedEntry> {
|
||||
|
||||
@Inject
|
||||
FeedService feedService;
|
||||
|
||||
@Inject
|
||||
FeedSubscriptionService feedSubscriptionService;
|
||||
|
||||
public void updateEntries(String url, Collection<FeedEntry> entries) {
|
||||
Feed feed = feedService.findByUrl(url);
|
||||
List<String> guids = Lists.newArrayList();
|
||||
for (FeedEntry entry : entries) {
|
||||
guids.add(entry.getGuid());
|
||||
}
|
||||
|
||||
List<FeedEntry> existingEntries = guids.isEmpty() ? new ArrayList<FeedEntry>()
|
||||
: findByGuids(guids);
|
||||
for (FeedEntry entry : entries) {
|
||||
FeedEntry foundEntry = null;
|
||||
for (FeedEntry existingEntry : existingEntries) {
|
||||
if (StringUtils
|
||||
.equals(entry.getGuid(), existingEntry.getGuid())) {
|
||||
foundEntry = existingEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundEntry == null) {
|
||||
entry.setInserted(Calendar.getInstance().getTime());
|
||||
addFeedToEntry(entry, feed);
|
||||
} else {
|
||||
boolean foundFeed = false;
|
||||
for (Feed existingFeed : foundEntry.getFeeds()) {
|
||||
if (ObjectUtils.equals(existingFeed.getId(), feed.getId())) {
|
||||
foundFeed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFeed) {
|
||||
addFeedToEntry(foundEntry, feed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addFeedToEntry(FeedEntry entry, Feed feed) {
|
||||
entry.getFeeds().add(feed);
|
||||
saveOrUpdate(entry);
|
||||
List<FeedSubscription> subscriptions = feedSubscriptionService
|
||||
.findByFeed(feed);
|
||||
for (FeedSubscription sub : subscriptions) {
|
||||
FeedEntryStatus status = new FeedEntryStatus();
|
||||
status.setEntry(entry);
|
||||
status.setSubscription(sub);
|
||||
em.persist(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<FeedEntry> findByGuids(List<String> guids) {
|
||||
EasyCriteria<FeedEntry> criteria = createCriteria();
|
||||
criteria.setDistinctTrue();
|
||||
criteria.andStringIn(MF.i(proxy().getGuid()), guids);
|
||||
criteria.leftJoinFetch(MF.i(proxy().getFeeds()));
|
||||
return criteria.getResultList();
|
||||
}
|
||||
|
||||
public List<FeedEntry> findByFeed(Feed feed, int offset, int limit) {
|
||||
CriteriaQuery<FeedEntry> query = builder.createQuery(getType());
|
||||
Root<FeedEntry> root = query.from(getType());
|
||||
query.where(builder.isMember(feed, root.get(FeedEntry_.feeds)));
|
||||
query.orderBy(builder.desc(root.get(FeedEntry_.updated)));
|
||||
TypedQuery<FeedEntry> q = em.createQuery(query);
|
||||
q.setFirstResult(offset);
|
||||
q.setMaxResults(limit);
|
||||
return q.getResultList();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
@@ -33,10 +32,7 @@ import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
@Inject
|
||||
FeedCategoryService feedCategoryService;
|
||||
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
public FeedEntryStatus findById(User user, Long id) {
|
||||
|
||||
@@ -58,7 +54,7 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
return status;
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatusesByKeywords(User user,
|
||||
public List<FeedEntryStatus> findByKeywords(User user,
|
||||
String keywords, int offset, int limit, boolean includeContent) {
|
||||
|
||||
String joinedKeywords = StringUtils.join(
|
||||
@@ -93,12 +89,12 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(User user, boolean unreadOnly,
|
||||
public List<FeedEntryStatus> findAll(User user, boolean unreadOnly,
|
||||
ReadingOrder order, boolean includeContent) {
|
||||
return getStatuses(user, unreadOnly, -1, -1, order, includeContent);
|
||||
return findAll(user, unreadOnly, -1, -1, order, includeContent);
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(User user, boolean unreadOnly,
|
||||
public List<FeedEntryStatus> findAll(User user, boolean unreadOnly,
|
||||
int offset, int limit, ReadingOrder order, boolean includeContent) {
|
||||
CriteriaQuery<FeedEntryStatus> query = builder.createQuery(getType());
|
||||
Root<FeedEntryStatus> root = query.from(getType());
|
||||
@@ -138,13 +134,13 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(Feed feed, User user,
|
||||
public List<FeedEntryStatus> findByFeed(Feed feed, User user,
|
||||
boolean unreadOnly, ReadingOrder order, boolean includeContent) {
|
||||
return getStatuses(feed, user, unreadOnly, -1, -1, order,
|
||||
return findByFeed(feed, user, unreadOnly, -1, -1, order,
|
||||
includeContent);
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(Feed feed, User user,
|
||||
public List<FeedEntryStatus> findByFeed(Feed feed, User user,
|
||||
boolean unreadOnly, int offset, int limit, ReadingOrder order,
|
||||
boolean includeContent) {
|
||||
|
||||
@@ -173,14 +169,14 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(List<FeedCategory> categories,
|
||||
public List<FeedEntryStatus> findByCategories(List<FeedCategory> categories,
|
||||
User user, boolean unreadOnly, ReadingOrder order,
|
||||
boolean includeContent) {
|
||||
return getStatuses(categories, user, unreadOnly, -1, -1, order,
|
||||
return findByCategories(categories, user, unreadOnly, -1, -1, order,
|
||||
includeContent);
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getStatuses(List<FeedCategory> categories,
|
||||
public List<FeedEntryStatus> findByCategories(List<FeedCategory> categories,
|
||||
User user, boolean unreadOnly, int offset, int limit,
|
||||
ReadingOrder order, boolean includeContent) {
|
||||
|
||||
@@ -209,15 +205,6 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
private void limit(TypedQuery<FeedEntryStatus> query, int offset, int limit) {
|
||||
if (offset > -1) {
|
||||
query.setFirstResult(offset);
|
||||
}
|
||||
if (limit > -1) {
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
}
|
||||
|
||||
private void orderBy(CriteriaQuery<FeedEntryStatus> query,
|
||||
Root<FeedEntryStatus> root, ReadingOrder order) {
|
||||
Path<Date> orderPath = root.get(FeedEntryStatus_.entry).get(
|
||||
@@ -231,20 +218,20 @@ public class FeedEntryStatusService extends GenericDAO<FeedEntryStatus> {
|
||||
}
|
||||
|
||||
public void markFeedEntries(User user, Feed feed, Date olderThan) {
|
||||
List<FeedEntryStatus> statuses = getStatuses(feed, user, true,
|
||||
List<FeedEntryStatus> statuses = findByFeed(feed, user, true,
|
||||
ReadingOrder.desc, false);
|
||||
update(markList(statuses, olderThan));
|
||||
}
|
||||
|
||||
public void markCategoryEntries(User user, List<FeedCategory> categories,
|
||||
Date olderThan) {
|
||||
List<FeedEntryStatus> statuses = getStatuses(categories, user, true,
|
||||
List<FeedEntryStatus> statuses = findByCategories(categories, user, true,
|
||||
ReadingOrder.desc, false);
|
||||
update(markList(statuses, olderThan));
|
||||
}
|
||||
|
||||
public void markAllEntries(User user, Date olderThan) {
|
||||
List<FeedEntryStatus> statuses = getStatuses(user, true,
|
||||
List<FeedEntryStatus> statuses = findAll(user, true,
|
||||
ReadingOrder.desc, false);
|
||||
update(markList(statuses, olderThan));
|
||||
}
|
||||
@@ -3,72 +3,21 @@ package com.commafeed.backend.dao;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedCategory;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||
import com.google.api.client.util.Lists;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.uaihebert.factory.EasyCriteriaFactory;
|
||||
import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class FeedSubscriptionService extends GenericDAO<FeedSubscription> {
|
||||
public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
||||
|
||||
@Inject
|
||||
FeedCategoryService feedCategoryService;
|
||||
|
||||
@Inject
|
||||
FeedService feedService;
|
||||
|
||||
@Inject
|
||||
FeedEntryService feedEntryService;
|
||||
|
||||
@Inject
|
||||
FeedEntryStatusService feedEntryStatusService;
|
||||
|
||||
public void subscribe(User user, String url, String title,
|
||||
FeedCategory category) {
|
||||
|
||||
Feed feed = feedService.findByUrl(url);
|
||||
if (feed == null) {
|
||||
feed = new Feed();
|
||||
feed.setUrl(url);
|
||||
feedService.save(feed);
|
||||
}
|
||||
|
||||
FeedSubscription sub = findByFeed(user, feed);
|
||||
boolean newSubscription = false;
|
||||
if (sub == null) {
|
||||
sub = new FeedSubscription();
|
||||
sub.setFeed(feed);
|
||||
sub.setUser(user);
|
||||
newSubscription = true;
|
||||
}
|
||||
sub.setCategory(category);
|
||||
sub.setTitle(title);
|
||||
saveOrUpdate(sub);
|
||||
|
||||
if (newSubscription) {
|
||||
List<FeedEntryStatus> statuses = Lists.newArrayList();
|
||||
List<FeedEntry> allEntries = feedEntryService.findByFeed(feed, 0,
|
||||
10);
|
||||
for (FeedEntry entry : allEntries) {
|
||||
FeedEntryStatus status = new FeedEntryStatus();
|
||||
status.setEntry(entry);
|
||||
status.setRead(true);
|
||||
status.setSubscription(sub);
|
||||
statuses.add(status);
|
||||
}
|
||||
feedEntryStatusService.save(statuses);
|
||||
}
|
||||
}
|
||||
|
||||
public FeedSubscription findById(User user, Long id) {
|
||||
EasyCriteria<FeedSubscription> criteria = createCriteria();
|
||||
@@ -7,11 +7,13 @@ import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import com.commafeed.backend.model.AbstractModel;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.frontend.utils.ModelFactory.MF;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.uaihebert.factory.EasyCriteriaFactory;
|
||||
@@ -128,6 +130,16 @@ public abstract class GenericDAO<T extends AbstractModel> implements
|
||||
return criteria.getResultList();
|
||||
}
|
||||
|
||||
protected void limit(TypedQuery<FeedEntryStatus> query, int offset,
|
||||
int limit) {
|
||||
if (offset > -1) {
|
||||
query.setFirstResult(offset);
|
||||
}
|
||||
if (limit > -1) {
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<T> getType() {
|
||||
return (Class<T>) type.getRawType();
|
||||
|
||||
31
src/main/java/com/commafeed/backend/dao/UserDAO.java
Normal file
31
src/main/java/com/commafeed/backend/dao/UserDAO.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.services.PasswordEncryptionService;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class UserDAO extends GenericDAO<User> {
|
||||
|
||||
@Inject
|
||||
PasswordEncryptionService encryptionService;
|
||||
|
||||
public User findByName(String name) {
|
||||
TypedQuery<User> query = em.createNamedQuery("User.byName", User.class);
|
||||
query.setParameter("name", name.toLowerCase());
|
||||
|
||||
User user = null;
|
||||
try {
|
||||
user = query.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
user = null;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,13 +13,13 @@ import com.google.common.collect.Sets;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Stateless
|
||||
public class UserRoleService extends GenericDAO<UserRole> {
|
||||
public class UserRoleDAO extends GenericDAO<UserRole> {
|
||||
|
||||
public List<UserRole> findAll(User user) {
|
||||
return findByField(MF.i(MF.p(UserRole.class).getUser()), user);
|
||||
}
|
||||
|
||||
public Set<Role> getRoles(User user) {
|
||||
public Set<Role> findRoles(User user) {
|
||||
Set<Role> list = Sets.newHashSet();
|
||||
for (UserRole role : findByField(MF.i(proxy().getUser()), user)) {
|
||||
list.add(role.getRole());
|
||||
@@ -1,71 +0,0 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserRole;
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
import com.commafeed.backend.security.PasswordEncryptionService;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class UserService extends GenericDAO<User> {
|
||||
|
||||
@Inject
|
||||
PasswordEncryptionService encryptionService;
|
||||
|
||||
public User findByName(String name) {
|
||||
TypedQuery<User> query = em.createNamedQuery("User.byName", User.class);
|
||||
query.setParameter("name", name.toLowerCase());
|
||||
|
||||
User user = null;
|
||||
try {
|
||||
user = query.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
user = null;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public User login(String name, String password) {
|
||||
User user = findByName(name);
|
||||
if (user != null && !user.isDisabled()) {
|
||||
boolean authenticated = encryptionService.authenticate(password,
|
||||
user.getPassword(), user.getSalt());
|
||||
if (authenticated) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public User register(String name, String password, Collection<Role> roles) {
|
||||
return register(name, password, null, roles);
|
||||
}
|
||||
|
||||
public User register(String name, String password, String email,
|
||||
Collection<Role> roles) {
|
||||
if (findByName(name) != null) {
|
||||
return null;
|
||||
}
|
||||
User user = new User();
|
||||
byte[] salt = encryptionService.generateSalt();
|
||||
user.setName(name);
|
||||
user.setEmail(email);
|
||||
user.setSalt(salt);
|
||||
user.setPassword(encryptionService.getEncryptedPassword(password, salt));
|
||||
user.getRoles().add(new UserRole(user, Role.USER));
|
||||
for (Role role : roles) {
|
||||
user.getRoles().add(new UserRole(user, role));
|
||||
user.getRoles().add(new UserRole(user, role));
|
||||
}
|
||||
save(user);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import com.uaihebert.model.EasyCriteria;
|
||||
|
||||
@Stateless
|
||||
@SuppressWarnings("serial")
|
||||
public class UserSettingsService extends GenericDAO<UserSettings> {
|
||||
public class UserSettingsDAO extends GenericDAO<UserSettings> {
|
||||
|
||||
public UserSettings findByUser(User user) {
|
||||
|
||||
Reference in New Issue
Block a user