mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-03-31 16:00:39 +08:00
Improved some project stats (#95)
* The actual stars and watchers can now be displayed when the home_projects view is refreshed. * views are now also kept track on, it will only change if you refresh the home_projects view. * Changed V1ApiService a little bit, The mapping of the result from the db calls to a bit cleaner and a little bit efficienter way (O(2n) -> O(n)) (not that it should matter that much. Changed ApiV1Controller by adding a default by the recommended tag (in case some project or plugin didnt have one but you still want to request the users information) * Fix for the upsert statement, it complained about null values * Made the fix for NPE in apiv4controller less hacky and added spaces between `//` and the message * Refresh on count
This commit is contained in:
parent
c99ea8de06
commit
719ada906b
@ -806,12 +806,12 @@ alter table project_views_individual owner to hangar;
|
||||
|
||||
create table project_views
|
||||
(
|
||||
day date not null,
|
||||
day date not null default current_date,
|
||||
project_id bigint not null
|
||||
constraint project_views_project_id_fkey
|
||||
references projects
|
||||
on delete cascade,
|
||||
views integer not null,
|
||||
views integer not null default 1,
|
||||
constraint project_views_pkey
|
||||
primary key (project_id, day)
|
||||
);
|
||||
@ -935,12 +935,12 @@ FROM projects p
|
||||
LEFT JOIN project_versions lv ON p.id = lv.project_id
|
||||
JOIN project_members_all pm ON p.id = pm.id
|
||||
LEFT JOIN (SELECT p_1.id,
|
||||
count(*) AS stars
|
||||
COUNT(ps_1.user_id) AS stars
|
||||
FROM projects p_1
|
||||
LEFT JOIN project_stars ps_1 ON p_1.id = ps_1.project_id
|
||||
GROUP BY p_1.id) ps ON p.id = ps.id
|
||||
LEFT JOIN (SELECT p_1.id,
|
||||
count(*) AS watchers
|
||||
count(pw_1.user_id) AS watchers
|
||||
FROM projects p_1
|
||||
LEFT JOIN project_watchers pw_1 ON p_1.id = pw_1.project_id
|
||||
GROUP BY p_1.id) pw ON p.id = pw.id
|
||||
|
@ -216,7 +216,7 @@ public class Apiv1Controller extends HangarController {
|
||||
projectObj.set("href", mapper.valueToTree(project.getOwnerName() + "/" + project.getSlug()));
|
||||
projectObj.set("members", writeMembers(members.getOrDefault(project.getId(), new ArrayList<>())));
|
||||
projectObj.set("channels", mapper.valueToTree( projectChannels.getOrDefault(project.getId(), new ArrayList<>())));
|
||||
projectObj.set("recommended", writeVersion(recommendedVersions.get(project.getId()), project, recommendedVersionChannels.get(project.getId()), vTags.getOrDefault(recommendedVersions.get(project.getId()).getId(), new ArrayList<>())));
|
||||
projectObj.set("recommended", writeVersion(project, recommendedVersions, recommendedVersionChannels, vTags));
|
||||
ObjectNode projectCategoryObj = mapper.createObjectNode();
|
||||
projectCategoryObj.set("title", mapper.valueToTree(project.getCategory().getTitle()));
|
||||
projectCategoryObj.set("icon", mapper.valueToTree(project.getCategory().getIcon()));
|
||||
@ -229,9 +229,12 @@ public class Apiv1Controller extends HangarController {
|
||||
return projectsArray;
|
||||
}
|
||||
|
||||
private ObjectNode writeVersion(ProjectVersionsTable version, ProjectsTable project, ProjectChannelsTable channel, List<ProjectVersionTagsTable> tags) {
|
||||
private ObjectNode writeVersion(ProjectsTable project, Map<Long, ProjectVersionsTable> recommendedVersions, Map<Long, ProjectChannelsTable> recommendedVersionChannels, Map<Long, List<ProjectVersionTagsTable>> vTags) {
|
||||
ProjectVersionsTable version = recommendedVersions.get(project.getId());
|
||||
ObjectNode objectNode = mapper.createObjectNode();
|
||||
if (version == null) return objectNode;
|
||||
ProjectChannelsTable channel = recommendedVersionChannels.get(project.getId());
|
||||
List<ProjectVersionTagsTable> tags = vTags.getOrDefault(version.getId(), new ArrayList<>());
|
||||
|
||||
objectNode.set("id", mapper.valueToTree(version.getId()));
|
||||
objectNode.set("createdAt", mapper.valueToTree(version.getCreatedAt().toString()));
|
||||
|
31
src/main/java/io/papermc/hangar/db/dao/ProjectViewDao.java
Normal file
31
src/main/java/io/papermc/hangar/db/dao/ProjectViewDao.java
Normal file
@ -0,0 +1,31 @@
|
||||
package io.papermc.hangar.db.dao;
|
||||
|
||||
|
||||
import io.papermc.hangar.db.model.ProjectViewsTable;
|
||||
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Repository
|
||||
@RegisterBeanMapper(ProjectViewsTable.class)
|
||||
// TODO: decide where we do count it as a view and where we don't
|
||||
public interface ProjectViewDao {
|
||||
|
||||
// The db will automatically get the current_date from itself (if you dont provide any date)
|
||||
@SqlUpdate("insert into project_views (day, project_id, views) values (current_date , :projectId, 1)" +
|
||||
"on conflict (day, project_id) " +
|
||||
"do update set views = project_views.views + 1 ")
|
||||
void increaseView(long projectId);
|
||||
|
||||
@SqlQuery("select views from project_views " +
|
||||
"where day = :day and project_id = :projectId ")
|
||||
long getViewsFromDate(LocalDate day, long projectId);
|
||||
|
||||
@SqlQuery("select day, project_id, views from project_views " +
|
||||
"where day = :day and project_id = :projectId ")
|
||||
ProjectViewsTable getViewsTable(LocalDate day, long projectId);
|
||||
|
||||
}
|
@ -12,6 +12,8 @@ import io.papermc.hangar.model.Role;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -35,44 +37,29 @@ public class V1ApiService {
|
||||
return v1ApiDao.get().getUsers(offset, limit);
|
||||
}
|
||||
|
||||
public <V> Map<Long, List<V>> mapListToMap(List<Map.Entry<Long, V>> map){
|
||||
Map<Long, List<V>> returnMap = new HashMap<>();
|
||||
map.forEach(entry -> {
|
||||
returnMap.computeIfAbsent(entry.getKey(), userId ->new ArrayList<>()).add(entry.getValue());
|
||||
});
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
// TODO better way for this?
|
||||
public Map<Long, List<String>> getStarredPlugins(List<Long> userIds) {
|
||||
return v1ApiDao.get().getStarredPlugins(userIds).stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(Entry::getKey)
|
||||
).entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Entry::getKey,
|
||||
longListEntry -> longListEntry.getValue().stream().map(Entry::getValue).collect(Collectors.toList()))
|
||||
);
|
||||
return mapListToMap(v1ApiDao.get().getStarredPlugins(userIds));
|
||||
}
|
||||
|
||||
public Map<Long, List<Role>> getUsersGlobalRoles(List<Long> userIds) {
|
||||
return v1ApiDao.get().getUsersGlobalRoles(userIds).stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(Entry::getKey)
|
||||
).entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Entry::getKey,
|
||||
listEntry -> listEntry.getValue().stream().map(entry -> Role.fromId(entry.getValue().getId())).collect(Collectors.toList())
|
||||
)
|
||||
);
|
||||
Map<Long, List<Role>> returnMap = new HashMap<>();
|
||||
v1ApiDao.get().getUsersGlobalRoles(userIds).forEach(entry -> {
|
||||
returnMap.computeIfAbsent(entry.getKey(), userId -> new ArrayList<>())
|
||||
.add(Role.fromId(entry.getValue().getId()));
|
||||
});
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
public Map<Long, List<ProjectChannelsTable>> getProjectsChannels(List<Long> projectIds) {
|
||||
return v1ApiDao.get().getProjectsChannels(projectIds).stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(Entry::getKey)
|
||||
).entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Entry::getKey,
|
||||
listEntry -> listEntry.getValue().stream().map(Entry::getValue).collect(Collectors.toList())
|
||||
)
|
||||
);
|
||||
return mapListToMap(v1ApiDao.get().getProjectsChannels(projectIds));
|
||||
}
|
||||
|
||||
public Map<Long, ProjectVersionsTable> getProjectsRecommendedVersion(List<Long> projectIds) {
|
||||
@ -91,15 +78,6 @@ public class V1ApiService {
|
||||
}
|
||||
|
||||
public Map<Long, List<ProjectVersionTagsTable>> getVersionsTags(List<Long> versionIds) {
|
||||
return v1ApiDao.get().getVersionsTags(versionIds).stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(Entry::getKey)
|
||||
).entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Entry::getKey,
|
||||
listEntry -> listEntry.getValue().stream().map(Entry::getValue).collect(Collectors.toList())
|
||||
)
|
||||
);
|
||||
return mapListToMap(v1ApiDao.get().getVersionsTags(versionIds));
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package io.papermc.hangar.service.project;
|
||||
|
||||
import io.papermc.hangar.config.hangar.HangarConfig;
|
||||
import io.papermc.hangar.db.dao.GeneralDao;
|
||||
import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.dao.ProjectDao;
|
||||
import io.papermc.hangar.db.dao.UserDao;
|
||||
import io.papermc.hangar.db.dao.ProjectViewDao;
|
||||
import io.papermc.hangar.db.dao.api.ProjectApiDao;
|
||||
import io.papermc.hangar.db.model.ProjectVersionsTable;
|
||||
import io.papermc.hangar.db.model.ProjectVisibilityChangesTable;
|
||||
@ -46,16 +48,20 @@ public class ProjectService {
|
||||
private final HangarDao<UserDao> userDao;
|
||||
private final HangarDao<VisibilityDao> visibilityDao;
|
||||
private final HangarDao<ProjectApiDao> projectApiDao;
|
||||
private final HangarDao<ProjectViewDao> projectViewDao;
|
||||
private final HangarDao<GeneralDao> generalDao;
|
||||
private final UserService userService;
|
||||
private final FlagService flagService;
|
||||
|
||||
@Autowired
|
||||
public ProjectService(HangarConfig hangarConfig, HangarDao<ProjectDao> projectDao, HangarDao<UserDao> userDao, HangarDao<VisibilityDao> visibilityDao, HangarDao<ProjectApiDao> projectApiDao, UserService userService, FlagService flagService) {
|
||||
public ProjectService(HangarConfig hangarConfig, HangarDao<ProjectDao> projectDao, HangarDao<UserDao> userDao, HangarDao<VisibilityDao> visibilityDao, HangarDao<ProjectApiDao> projectApiDao, HangarDao<ProjectViewDao> projectViewDao, HangarDao<GeneralDao> generalDao, UserService userService, FlagService flagService) {
|
||||
this.hangarConfig = hangarConfig;
|
||||
this.projectDao = projectDao;
|
||||
this.userDao = userDao;
|
||||
this.visibilityDao = visibilityDao;
|
||||
this.projectApiDao = projectApiDao;
|
||||
this.projectViewDao = projectViewDao;
|
||||
this.generalDao = generalDao;
|
||||
this.userService = userService;
|
||||
this.flagService = flagService;
|
||||
}
|
||||
@ -155,6 +161,10 @@ public class ProjectService {
|
||||
public Project getProjectApi(String pluginId) { // TODO still probably have to work out a standard for how to handle the api models
|
||||
ProjectsTable projectsTable = projectDao.get().getByPluginId(pluginId);
|
||||
if (projectsTable == null) return null;
|
||||
|
||||
projectViewDao.get().increaseView(projectsTable.getId()); //TODO don't increase every time here
|
||||
generalDao.get().refreshHomeProjects();
|
||||
|
||||
Project project = new Project();
|
||||
project.setCreatedAt(projectsTable.getCreatedAt());
|
||||
project.setPluginId(projectsTable.getPluginId());
|
||||
@ -222,7 +232,7 @@ public class ProjectService {
|
||||
case RECENT_DOWNLOADS : orderingFirstHalf ="p.recent_views *"; break;
|
||||
case RECENT_VIEWS: orderingFirstHalf ="p.recent_downloads*"; break;
|
||||
default:
|
||||
orderingFirstHalf = " "; //Just in case and so that the ide doesnt complain
|
||||
orderingFirstHalf = " "; // Just in case and so that the ide doesnt complain
|
||||
}
|
||||
ordering = orderingFirstHalf + relevance;
|
||||
}
|
||||
@ -236,7 +246,7 @@ public class ProjectService {
|
||||
private String trimQuery(String query){
|
||||
String trimmedQuery = null;
|
||||
if(query != null && !query.isBlank()) {
|
||||
trimmedQuery = query.trim(); //Ore#APIV2Queries line 169 && 200
|
||||
trimmedQuery = query.trim(); // Ore#APIV2Queries line 169 && 200
|
||||
}
|
||||
return trimmedQuery;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user