diff --git a/deploy/gdccloud/deploy.sh b/deploy/gdccloud/deploy.sh index de785fd..50d3d5c 100644 --- a/deploy/gdccloud/deploy.sh +++ b/deploy/gdccloud/deploy.sh @@ -18,6 +18,6 @@ fi ssh $USERSERVER "cd /tmp && rm -rf $ARTIFACT_NAME*.jar && echo `date` 'killed' >> log_$ARTIFACT_NAME" scp build/libs/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar $USERSERVER:/tmp/$ARTIFACT_NAME-0.1.0-SNAPSHOT.jar -ssh $USERSERVER -f "cd /tmp/ && /opt/jdk1.8.0_192/bin/java -jar $ARTIFACT_NAME-0.1.0-SNAPSHOT.jar -Xms 512m -Xmx 1024m --server.port=8443 --server.http.port=8080 --ng-tracker.base-url=http://193.110.3.124:8080 --ng-tracker.dev-mode=false >> /home/user/logfile_$ARTIFACT_NAME" & +ssh $USERSERVER -f "cd /tmp/ && /opt/jdk1.8.0_192/bin/java -jar $ARTIFACT_NAME-0.1.0-SNAPSHOT.jar -Xms 512m -Xmx 1024m --server.port=8443 --server.http.port=8080 --ng-tracker.base-url=http://193.110.3.124:8080 --ng-tracker.dev-mode=false --ng-tracker.driver-path=/home/user >> /home/user/logfile_$ARTIFACT_NAME" & sleep 10 echo "is deployed" \ No newline at end of file diff --git a/src/main/java/ru/ulstu/conference/model/Conference.java b/src/main/java/ru/ulstu/conference/model/Conference.java index 572921e..946b84a 100644 --- a/src/main/java/ru/ulstu/conference/model/Conference.java +++ b/src/main/java/ru/ulstu/conference/model/Conference.java @@ -6,6 +6,7 @@ import org.hibernate.validator.constraints.NotBlank; import org.springframework.format.annotation.DateTimeFormat; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.EventSource; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.paper.model.Paper; import ru.ulstu.timeline.model.Event; @@ -13,6 +14,7 @@ import ru.ulstu.user.model.User; import javax.persistence.CascadeType; import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; @@ -28,10 +30,13 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; @Entity @Table(name = "conference") -public class Conference extends BaseEntity implements EventSource { +@DiscriminatorValue("CONFERENCE") +public class Conference extends BaseEntity implements UserActivity, EventSource { @NotBlank private String title; @@ -163,4 +168,9 @@ public class Conference extends BaseEntity implements EventSource { .filter(d -> d.getDate().after(new Date())) .findFirst(); } + + @Override + public Set getActivityUsers() { + return getUsers().stream().map(ConferenceUser::getUser).collect(Collectors.toSet()); + } } diff --git a/src/main/java/ru/ulstu/conference/service/ConferenceService.java b/src/main/java/ru/ulstu/conference/service/ConferenceService.java index d877232..a3c4812 100644 --- a/src/main/java/ru/ulstu/conference/service/ConferenceService.java +++ b/src/main/java/ru/ulstu/conference/service/ConferenceService.java @@ -243,10 +243,9 @@ public class ConferenceService extends BaseService { } @Transactional - public Ping ping(ConferenceDto conferenceDto) throws IOException { - Ping ping = pingService.addPing(findOne(conferenceDto.getId())); + public void ping(ConferenceDto conferenceDto) throws IOException { + pingService.addPing(findOne(conferenceDto.getId())); conferenceRepository.updatePingConference(conferenceDto.getId()); - return ping; } private Conference findOne(Integer conferenceId) { diff --git a/src/main/java/ru/ulstu/configuration/ApplicationProperties.java b/src/main/java/ru/ulstu/configuration/ApplicationProperties.java index 49efac4..a1c0ba2 100644 --- a/src/main/java/ru/ulstu/configuration/ApplicationProperties.java +++ b/src/main/java/ru/ulstu/configuration/ApplicationProperties.java @@ -23,6 +23,8 @@ public class ApplicationProperties { private String debugEmail; + private String driverPath; + public boolean isUseHttps() { return useHttps; } @@ -70,4 +72,12 @@ public class ApplicationProperties { public void setDebugEmail(String debugEmail) { this.debugEmail = debugEmail; } + + public String getDriverPath() { + return driverPath; + } + + public void setDriverPath(String driverPath) { + this.driverPath = driverPath; + } } diff --git a/src/main/java/ru/ulstu/core/model/UserContainer.java b/src/main/java/ru/ulstu/core/model/UserActivity.java similarity index 50% rename from src/main/java/ru/ulstu/core/model/UserContainer.java rename to src/main/java/ru/ulstu/core/model/UserActivity.java index 7f83cd3..8e4e270 100644 --- a/src/main/java/ru/ulstu/core/model/UserContainer.java +++ b/src/main/java/ru/ulstu/core/model/UserActivity.java @@ -4,6 +4,7 @@ import ru.ulstu.user.model.User; import java.util.Set; -public interface UserContainer { - Set getUsers(); +public interface UserActivity { + String getTitle(); + Set getActivityUsers(); } diff --git a/src/main/java/ru/ulstu/grant/controller/GrantController.java b/src/main/java/ru/ulstu/grant/controller/GrantController.java index a9c01ed..1e28a33 100644 --- a/src/main/java/ru/ulstu/grant/controller/GrantController.java +++ b/src/main/java/ru/ulstu/grant/controller/GrantController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.grant.model.Grant; import ru.ulstu.grant.model.GrantDto; @@ -123,4 +124,10 @@ public class GrantController { public List getAllPapers() { return grantService.getAllUncompletedPapers(); } + + @ResponseBody + @PostMapping(value = "/ping") + public void ping(@RequestParam("grantId") int grantId) throws IOException { + grantService.ping(grantId); + } } diff --git a/src/main/java/ru/ulstu/grant/controller/GrantRestController.java b/src/main/java/ru/ulstu/grant/controller/GrantRestController.java new file mode 100644 index 0000000..9b90a4d --- /dev/null +++ b/src/main/java/ru/ulstu/grant/controller/GrantRestController.java @@ -0,0 +1,29 @@ +package ru.ulstu.grant.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.ulstu.configuration.Constants; +import ru.ulstu.grant.service.GrantService; + +import java.io.IOException; +import java.text.ParseException; + +import static ru.ulstu.paper.controller.PaperRestController.URL; + +@RestController +@RequestMapping(URL) +public class GrantRestController { + public static final String URL = Constants.API_1_0 + "grants"; + + private final GrantService grantService; + + public GrantRestController(GrantService grantService) { + this.grantService = grantService; + } + + @GetMapping("/grab") + public void grab() throws IOException, ParseException { + grantService.createFromKias(); + } +} diff --git a/src/main/java/ru/ulstu/grant/model/Grant.java b/src/main/java/ru/ulstu/grant/model/Grant.java index 78583c3..5b91453 100644 --- a/src/main/java/ru/ulstu/grant/model/Grant.java +++ b/src/main/java/ru/ulstu/grant/model/Grant.java @@ -5,7 +5,7 @@ import org.hibernate.annotations.FetchMode; import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.EventSource; -import ru.ulstu.core.model.UserContainer; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.paper.model.Paper; @@ -14,6 +14,7 @@ import ru.ulstu.timeline.model.Event; import ru.ulstu.user.model.User; import javax.persistence.CascadeType; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -37,7 +38,8 @@ import java.util.Set; @Entity @Table(name = "grants") -public class Grant extends BaseEntity implements UserContainer, EventSource { +@DiscriminatorValue("GRANT") +public class Grant extends BaseEntity implements UserActivity, EventSource { public enum GrantStatus { APPLICATION("Заявка"), ON_COMPETITION("Отправлен на конкурс"), @@ -167,7 +169,7 @@ public class Grant extends BaseEntity implements UserContainer, EventSource { } @Override - public Set getUsers() { + public Set getActivityUsers() { return getAuthors(); } diff --git a/src/main/java/ru/ulstu/grant/service/GrantService.java b/src/main/java/ru/ulstu/grant/service/GrantService.java index 542965a..03ae07f 100644 --- a/src/main/java/ru/ulstu/grant/service/GrantService.java +++ b/src/main/java/ru/ulstu/grant/service/GrantService.java @@ -16,6 +16,7 @@ import ru.ulstu.name.BaseService; import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.service.PaperService; +import ru.ulstu.ping.service.PingService; import ru.ulstu.project.model.Project; import ru.ulstu.project.model.ProjectDto; import ru.ulstu.project.service.ProjectService; @@ -51,6 +52,7 @@ public class GrantService extends BaseService { private final EventService eventService; private final GrantNotificationService grantNotificationService; private final KiasService kiasService; + private final PingService pingService; public GrantService(GrantRepository grantRepository, FileService fileService, @@ -60,7 +62,8 @@ public class GrantService extends BaseService { PaperService paperService, EventService eventService, GrantNotificationService grantNotificationService, - KiasService kiasService) { + KiasService kiasService, + PingService pingService) { this.grantRepository = grantRepository; this.kiasService = kiasService; this.baseRepository = grantRepository; @@ -71,6 +74,7 @@ public class GrantService extends BaseService { this.paperService = paperService; this.eventService = eventService; this.grantNotificationService = grantNotificationService; + this.pingService = pingService; } public List findAll() { @@ -334,6 +338,15 @@ public class GrantService extends BaseService { return grantRepository.findAllActive(); } + public Grant findById(Integer id) { + return grantRepository.findOne(id); + } + + @Transactional + public void ping(int grantId) throws IOException { + pingService.addPing(findById(grantId)); + } + public Grant findGrantById(Integer grantId) { return grantRepository.findOne(grantId); } diff --git a/src/main/java/ru/ulstu/grant/service/KiasService.java b/src/main/java/ru/ulstu/grant/service/KiasService.java index 618e83c..dbeacf5 100644 --- a/src/main/java/ru/ulstu/grant/service/KiasService.java +++ b/src/main/java/ru/ulstu/grant/service/KiasService.java @@ -5,16 +5,20 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.springframework.stereotype.Service; +import ru.ulstu.configuration.ApplicationProperties; import ru.ulstu.grant.model.GrantDto; import ru.ulstu.grant.page.KiasPage; import ru.ulstu.user.service.UserService; +import java.nio.file.Paths; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; +import static org.apache.commons.lang3.StringUtils.isEmpty; + @Service public class KiasService { private final static String BASE_URL = "https://www.rfbr.ru/rffi/ru/contest_search?CONTEST_STATUS_ID=%s&CONTEST_TYPE=%s&CONTEST_YEAR=%s"; @@ -27,9 +31,12 @@ public class KiasService { private final static String DRIVER_TYPE = "webdriver.chrome.driver"; private final UserService userService; + private final ApplicationProperties applicationProperties; - public KiasService(UserService userService) { + public KiasService(UserService userService, + ApplicationProperties applicationProperties) { this.userService = userService; + this.applicationProperties = applicationProperties; } public List getNewGrantsDto() throws ParseException { @@ -78,8 +85,10 @@ public class KiasService { } private String getDriverExecutablePath() { - return KiasService.class.getClassLoader().getResource( - String.format(DRIVER_LOCATION, getDriverExecutable(isWindows()))).getFile(); + return isEmpty(applicationProperties.getDriverPath()) + ? KiasService.class.getClassLoader() + .getResource(String.format(DRIVER_LOCATION, getDriverExecutable(isWindows()))).getFile() + : Paths.get(applicationProperties.getDriverPath(), getDriverExecutable(isWindows())).toString(); } private String getDriverExecutable(boolean isWindows) { diff --git a/src/main/java/ru/ulstu/paper/controller/PaperRestController.java b/src/main/java/ru/ulstu/paper/controller/PaperRestController.java index 6da009f..7c0d9c5 100644 --- a/src/main/java/ru/ulstu/paper/controller/PaperRestController.java +++ b/src/main/java/ru/ulstu/paper/controller/PaperRestController.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import ru.ulstu.configuration.Constants; import ru.ulstu.core.model.response.Response; @@ -72,4 +73,9 @@ public class PaperRestController { public Response getFormattedReference(@RequestBody @Valid ReferenceDto referenceDto) { return new Response<>(paperService.getFormattedReference(referenceDto)); } + + @PostMapping(value = "/ping") + public void ping(@RequestParam("paperId") int paperId) throws IOException { + paperService.ping(paperId); + } } diff --git a/src/main/java/ru/ulstu/paper/model/Paper.java b/src/main/java/ru/ulstu/paper/model/Paper.java index dbc9b52..32a1e5e 100644 --- a/src/main/java/ru/ulstu/paper/model/Paper.java +++ b/src/main/java/ru/ulstu/paper/model/Paper.java @@ -6,7 +6,7 @@ import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.conference.model.Conference; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.EventSource; -import ru.ulstu.core.model.UserContainer; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.grant.model.Grant; @@ -15,6 +15,7 @@ import ru.ulstu.user.model.User; import javax.persistence.CascadeType; import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -35,7 +36,8 @@ import java.util.Optional; import java.util.Set; @Entity -public class Paper extends BaseEntity implements UserContainer, EventSource { +@DiscriminatorValue("PAPER") +public class Paper extends BaseEntity implements UserActivity, EventSource { public enum PaperStatus { ATTENTION("Обратить внимание"), ON_PREPARATION("На подготовке"), @@ -260,7 +262,7 @@ public class Paper extends BaseEntity implements UserContainer, EventSource { } @Override - public Set getUsers() { + public Set getActivityUsers() { return getAuthors(); } diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 2393af4..3be9aee 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -15,6 +15,7 @@ import ru.ulstu.paper.model.Reference; import ru.ulstu.paper.model.ReferenceDto; import ru.ulstu.paper.repository.PaperRepository; import ru.ulstu.paper.repository.ReferenceRepository; +import ru.ulstu.ping.service.PingService; import ru.ulstu.timeline.service.EventService; import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; @@ -54,6 +55,7 @@ public class PaperService { private final FileService fileService; private final EventService eventService; private final ReferenceRepository referenceRepository; + private final PingService pingService; public PaperService(PaperRepository paperRepository, ReferenceRepository referenceRepository, @@ -61,7 +63,8 @@ public class PaperService { PaperNotificationService paperNotificationService, UserService userService, DeadlineService deadlineService, - EventService eventService) { + EventService eventService, + PingService pingService) { this.paperRepository = paperRepository; this.referenceRepository = referenceRepository; this.fileService = fileService; @@ -69,6 +72,7 @@ public class PaperService { this.userService = userService; this.deadlineService = deadlineService; this.eventService = eventService; + this.pingService = pingService; } public List findAll() { @@ -386,4 +390,9 @@ public class PaperService { autoCompleteData.setPublishers(referenceRepository.findDistinctPublishers()); return autoCompleteData; } + + @Transactional + public void ping(int paperId) throws IOException { + pingService.addPing(findPaperById(paperId)); + } } diff --git a/src/main/java/ru/ulstu/ping/model/Ping.java b/src/main/java/ru/ulstu/ping/model/Ping.java index c7e4c5e..7118c22 100644 --- a/src/main/java/ru/ulstu/ping/model/Ping.java +++ b/src/main/java/ru/ulstu/ping/model/Ping.java @@ -1,12 +1,20 @@ package ru.ulstu.ping.model; -import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.annotations.Any; +import org.hibernate.annotations.AnyMetaDef; +import org.hibernate.annotations.MetaValue; import org.springframework.format.annotation.DateTimeFormat; import ru.ulstu.conference.model.Conference; import ru.ulstu.core.model.BaseEntity; +import ru.ulstu.core.model.UserActivity; +import ru.ulstu.grant.model.Grant; +import ru.ulstu.paper.model.Paper; +import ru.ulstu.project.model.Project; import ru.ulstu.user.model.User; +import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @@ -25,9 +33,24 @@ public class Ping extends BaseEntity { @JoinColumn(name = "users_id") private User user; - @ManyToOne(optional = false) - @JoinColumn(name = "conference_id") - private Conference conference; + @Column(name = "activity_type", insertable = false, updatable = false) + private String activityType; + + @Any( + metaColumn = @Column(name = "activity_type"), + fetch = FetchType.LAZY + ) + @AnyMetaDef( + idType = "integer", metaType = "string", + metaValues = { + @MetaValue(targetEntity = Conference.class, value = "CONFERENCE"), + @MetaValue(targetEntity = Paper.class, value = "PAPER"), + @MetaValue(targetEntity = Project.class, value = "PROJECT"), + @MetaValue(targetEntity = Grant.class, value = "GRANT") + } + ) + @JoinColumn(name = "activity_id") + private UserActivity activity; public Ping() { } @@ -37,16 +60,6 @@ public class Ping extends BaseEntity { this.user = user; } - public Ping(@JsonProperty("id") Integer id, - @JsonProperty("date") Date date, - @JsonProperty("user") User user, - @JsonProperty("conference") Conference conference) { - setId(id); - this.date = date; - this.user = user; - this.conference = conference; - } - public Date getDate() { return date; } @@ -63,11 +76,11 @@ public class Ping extends BaseEntity { this.user = user; } - public Conference getConference() { - return conference; + public UserActivity getActivity() { + return this.activity; } - public void setConference(Conference conference) { - this.conference = conference; + public void setActivity(UserActivity activity) { + this.activity = activity; } } diff --git a/src/main/java/ru/ulstu/ping/model/PingInfo.java b/src/main/java/ru/ulstu/ping/model/PingInfo.java new file mode 100644 index 0000000..e8b943b --- /dev/null +++ b/src/main/java/ru/ulstu/ping/model/PingInfo.java @@ -0,0 +1,35 @@ +package ru.ulstu.ping.model; + +import ru.ulstu.user.model.User; + +import java.util.ArrayList; +import java.util.List; + +public class PingInfo { + private User user; + private List pings = new ArrayList<>(); + + public PingInfo(User user) { + this.user = user; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public List getPings() { + return pings; + } + + public void setPings(List pings) { + this.pings = pings; + } + + public void addPing(Ping ping) { + this.pings.add(ping); + } +} diff --git a/src/main/java/ru/ulstu/ping/repository/PingRepository.java b/src/main/java/ru/ulstu/ping/repository/PingRepository.java index de79dd7..cec24e7 100644 --- a/src/main/java/ru/ulstu/ping/repository/PingRepository.java +++ b/src/main/java/ru/ulstu/ping/repository/PingRepository.java @@ -6,8 +6,17 @@ import org.springframework.data.repository.query.Param; import ru.ulstu.conference.model.Conference; import ru.ulstu.ping.model.Ping; +import java.util.Date; +import java.util.List; + public interface PingRepository extends JpaRepository { - @Query("SELECT count(*) FROM Ping p WHERE (DAY(p.date) = :day) AND (MONTH(p.date) = :month) AND (YEAR(p.date) = :year) AND (p.conference = :conference)") + @Query("SELECT count(*) FROM Ping p WHERE (DAY(p.date) = :day) AND (MONTH(p.date) = :month) AND (YEAR(p.date) = :year) AND (p.activityType = 'conference') AND (p.activity = :conference)") long countByConferenceAndDate(@Param("conference") Conference conference, @Param("day") Integer day, @Param("month") Integer month, @Param("year") Integer year); + + @Query("SELECT p FROM Ping p WHERE (:activity = '' OR p.activityType = :activity)") + List getPings(@Param("activity") String activity); + + @Query("SELECT p FROM Ping p WHERE (:dateFrom < date)") + List findByDate(@Param("dateFrom") Date dateFrom); } diff --git a/src/main/java/ru/ulstu/ping/service/PingScheduler.java b/src/main/java/ru/ulstu/ping/service/PingScheduler.java new file mode 100644 index 0000000..239abbf --- /dev/null +++ b/src/main/java/ru/ulstu/ping/service/PingScheduler.java @@ -0,0 +1,58 @@ +package ru.ulstu.ping.service; + +import com.google.common.collect.ImmutableMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import ru.ulstu.core.model.UserActivity; +import ru.ulstu.ping.model.Ping; +import ru.ulstu.ping.model.PingInfo; +import ru.ulstu.ping.repository.PingRepository; +import ru.ulstu.user.model.User; +import ru.ulstu.user.service.MailService; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Service +public class PingScheduler { + private final Logger log = LoggerFactory.getLogger(PingScheduler.class); + private final PingRepository pingRepository; + private final MailService mailService; + private final static String PING_MAIL_SUBJECT = "Ping статистика"; + + public PingScheduler(PingRepository pingRepository, MailService mailService) { + this.pingRepository = pingRepository; + this.mailService = mailService; + } + + + @Scheduled(cron = "0 0 * * 1 ?") + public void sendPingsInfo() { + log.debug("Scheduler.sendPingsInfo started"); + + List pingInfos = new ArrayList<>(); + + for (Ping ping : pingRepository.findByDate(java.sql.Date.valueOf(LocalDate.now().minusWeeks(1)))) { + UserActivity pingActivity = ping.getActivity(); + Set users = pingActivity.getActivityUsers(); + + for (User user : users) { + PingInfo userPing = pingInfos.stream().filter(u -> u.getUser() == user).findFirst().orElse(null); + if (userPing == null) { + userPing = new PingInfo(user); + pingInfos.add(userPing); + } + userPing.addPing(ping); + } + } + + for (PingInfo pingInfo : pingInfos) { + mailService.sendEmailFromTemplate(ImmutableMap.of("pings", pingInfo.getPings()), + pingInfo.getUser(), "pingsInfoWeekEmail", PING_MAIL_SUBJECT); + } + } +} diff --git a/src/main/java/ru/ulstu/ping/service/PingService.java b/src/main/java/ru/ulstu/ping/service/PingService.java index 6666fdd..e1c0035 100644 --- a/src/main/java/ru/ulstu/ping/service/PingService.java +++ b/src/main/java/ru/ulstu/ping/service/PingService.java @@ -3,6 +3,7 @@ package ru.ulstu.ping.service; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.ulstu.conference.model.Conference; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.ping.model.Ping; import ru.ulstu.ping.repository.PingRepository; import ru.ulstu.user.service.UserService; @@ -10,22 +11,26 @@ import ru.ulstu.user.service.UserService; import java.io.IOException; import java.util.Calendar; import java.util.Date; +import java.util.List; @Service public class PingService { private final PingRepository pingRepository; private final UserService userService; + private final PingScheduler pingScheduler; public PingService(PingRepository pingRepository, - UserService userService) { + UserService userService, + PingScheduler pingScheduler) { this.pingRepository = pingRepository; this.userService = userService; + this.pingScheduler = pingScheduler; } @Transactional - public Ping addPing(Conference conference) throws IOException { + public Ping addPing(UserActivity activity) throws IOException { Ping newPing = new Ping(new Date(), userService.getCurrentUser()); - newPing.setConference(conference); + newPing.setActivity(activity); return pingRepository.save(newPing); } @@ -33,4 +38,8 @@ public class PingService { return Math.toIntExact(pingRepository.countByConferenceAndDate(conference, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR))); } + + public List getPings(String activity) { + return pingRepository.getPings(activity); + } } diff --git a/src/main/java/ru/ulstu/project/controller/ProjectController.java b/src/main/java/ru/ulstu/project/controller/ProjectController.java index a991e35..09438fd 100644 --- a/src/main/java/ru/ulstu/project/controller/ProjectController.java +++ b/src/main/java/ru/ulstu/project/controller/ProjectController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.grant.model.GrantDto; import ru.ulstu.project.model.Project; @@ -117,4 +118,10 @@ public class ProjectController { .filter(dto -> dto.getDate() != null || !isEmpty(dto.getDescription())) .collect(Collectors.toList())); } + + @ResponseBody + @PostMapping(value = "/ping") + public void ping(@RequestParam("projectId") int projectId) throws IOException { + projectService.ping(projectId); + } } diff --git a/src/main/java/ru/ulstu/project/model/Project.java b/src/main/java/ru/ulstu/project/model/Project.java index 6b5f925..6c60052 100644 --- a/src/main/java/ru/ulstu/project/model/Project.java +++ b/src/main/java/ru/ulstu/project/model/Project.java @@ -5,7 +5,7 @@ import org.hibernate.annotations.FetchMode; import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.EventSource; -import ru.ulstu.core.model.UserContainer; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.grant.model.Grant; @@ -13,6 +13,7 @@ import ru.ulstu.timeline.model.Event; import ru.ulstu.user.model.User; import javax.persistence.CascadeType; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -30,7 +31,8 @@ import java.util.List; import java.util.Set; @Entity -public class Project extends BaseEntity implements UserContainer, EventSource { +@DiscriminatorValue("PROJECT") +public class Project extends BaseEntity implements UserActivity, EventSource { public enum ProjectStatus { TECHNICAL_TASK("Техническое задание"), @@ -172,10 +174,13 @@ public class Project extends BaseEntity implements UserContainer, EventSource { this.executors = executors; } - @Override public Set getUsers() { - Set users = new HashSet(getExecutors()); - return users; + return new HashSet<>(getExecutors()); + } + + @Override + public Set getActivityUsers() { + return new HashSet<>(); } public List getGrants() { diff --git a/src/main/java/ru/ulstu/project/service/ProjectService.java b/src/main/java/ru/ulstu/project/service/ProjectService.java index 6491b04..699e241 100644 --- a/src/main/java/ru/ulstu/project/service/ProjectService.java +++ b/src/main/java/ru/ulstu/project/service/ProjectService.java @@ -8,6 +8,7 @@ import ru.ulstu.file.model.FileDataDto; import ru.ulstu.file.service.FileService; import ru.ulstu.grant.model.GrantDto; import ru.ulstu.grant.repository.GrantRepository; +import ru.ulstu.ping.service.PingService; import ru.ulstu.project.model.Project; import ru.ulstu.project.model.ProjectDto; import ru.ulstu.project.repository.ProjectRepository; @@ -35,19 +36,22 @@ public class ProjectService { private final FileService fileService; private final EventService eventService; private final UserService userService; + private final PingService pingService; public ProjectService(ProjectRepository projectRepository, DeadlineService deadlineService, GrantRepository grantRepository, FileService fileService, EventService eventService, - UserService userService) { + UserService userService, + PingService pingService) { this.projectRepository = projectRepository; this.deadlineService = deadlineService; this.grantRepository = grantRepository; this.fileService = fileService; this.eventService = eventService; this.userService = userService; + this.pingService = pingService; } public List findAll() { @@ -143,6 +147,11 @@ public class ProjectService { return users; } + @Transactional + public void ping(int projectId) throws IOException { + pingService.addPing(findById(projectId)); + } + public List getAllGrants() { List grants = convert(grantRepository.findAll(), GrantDto::new); return grants; diff --git a/src/main/java/ru/ulstu/strategy/api/EntityCreateStrategy.java b/src/main/java/ru/ulstu/strategy/api/EntityCreateStrategy.java index 8449e10..8a14399 100644 --- a/src/main/java/ru/ulstu/strategy/api/EntityCreateStrategy.java +++ b/src/main/java/ru/ulstu/strategy/api/EntityCreateStrategy.java @@ -1,21 +1,21 @@ package ru.ulstu.strategy.api; -import ru.ulstu.core.model.UserContainer; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.user.model.User; import java.util.List; import java.util.stream.Collectors; -public abstract class EntityCreateStrategy { +public abstract class EntityCreateStrategy { protected abstract List getActiveEntities(); protected abstract void createEntity(User user); - protected void createDefaultEntityIfNeed(List allUsers, List entities) { + protected void createDefaultEntityIfNeed(List allUsers, List entities) { allUsers.forEach(user -> { if (entities .stream() - .filter(entity -> entity.getUsers().contains(user)) + .filter(entity -> entity.getActivityUsers().contains(user)) .collect(Collectors.toSet()).isEmpty()) { createEntity(user); } diff --git a/src/main/java/ru/ulstu/user/controller/UserController.java b/src/main/java/ru/ulstu/user/controller/UserController.java index b57c1ac..d080d54 100644 --- a/src/main/java/ru/ulstu/user/controller/UserController.java +++ b/src/main/java/ru/ulstu/user/controller/UserController.java @@ -170,6 +170,12 @@ public class UserController extends OdinController { userService.inviteUser(email); } + @GetMapping("/activities/pings") + public Response> getActivitesStats(@RequestParam(value = "userId", required = false) Integer userId, + @RequestParam(value = "activity", required = false) String activity) { + return new Response<>(userService.getActivitiesPings(userId, activity)); + } + @PostMapping("/block") public void blockUser(@RequestParam("userId") Integer userId) { userService.blockUser(userId); diff --git a/src/main/java/ru/ulstu/user/controller/UserMvcController.java b/src/main/java/ru/ulstu/user/controller/UserMvcController.java index 7f1c1b8..f0a28d8 100644 --- a/src/main/java/ru/ulstu/user/controller/UserMvcController.java +++ b/src/main/java/ru/ulstu/user/controller/UserMvcController.java @@ -1,10 +1,12 @@ package ru.ulstu.user.controller; +import com.google.common.collect.ImmutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import ru.ulstu.configuration.Constants; @@ -17,6 +19,8 @@ import ru.ulstu.user.service.UserSessionService; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import java.util.List; +import java.util.Map; @Controller @RequestMapping(value = "/users") @@ -53,4 +57,21 @@ public class UserMvcController extends OdinController { public void getUsersDashboard(ModelMap modelMap) { modelMap.addAllAttributes(userService.getUsersInfo()); } + + @ModelAttribute("allUsers") + public List getAllUsers() { + return userService.findAll(); + } + + @ModelAttribute("allActivities") + public Map getAllActivites() { + return ImmutableMap.of("PAPER", "Статьи", + "GRANT", "Гранты", + "PROJECT", "Проекты", + "CONFERENCE", "Конференции"); + } + + @GetMapping("/pings") + public void getPings() { + } } diff --git a/src/main/java/ru/ulstu/user/service/UserService.java b/src/main/java/ru/ulstu/user/service/UserService.java index a58b6db..bbac124 100644 --- a/src/main/java/ru/ulstu/user/service/UserService.java +++ b/src/main/java/ru/ulstu/user/service/UserService.java @@ -14,14 +14,15 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.ExceptionHandler; import ru.ulstu.conference.service.ConferenceService; import ru.ulstu.configuration.ApplicationProperties; import ru.ulstu.core.error.EntityIdIsNullException; import ru.ulstu.core.jpa.OffsetablePageRequest; import ru.ulstu.core.model.BaseEntity; +import ru.ulstu.core.model.UserActivity; import ru.ulstu.core.model.response.PageableItems; -import ru.ulstu.core.model.response.Response; +import ru.ulstu.ping.model.Ping; +import ru.ulstu.ping.service.PingService; import ru.ulstu.user.error.UserActivationError; import ru.ulstu.user.error.UserBlockedException; import ru.ulstu.user.error.UserEmailExistsException; @@ -54,6 +55,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -76,6 +78,7 @@ public class UserService implements UserDetailsService { private final TimetableService timetableService; private final ConferenceService conferenceService; private final UserSessionService userSessionService; + private final PingService pingService; public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, @@ -83,6 +86,7 @@ public class UserService implements UserDetailsService { UserMapper userMapper, MailService mailService, ApplicationProperties applicationProperties, + @Lazy PingService pingService, @Lazy ConferenceService conferenceRepository, @Lazy UserSessionService userSessionService) throws ParseException { this.userRepository = userRepository; @@ -94,6 +98,7 @@ public class UserService implements UserDetailsService { this.conferenceService = conferenceRepository; this.timetableService = new TimetableService(); this.userSessionService = userSessionService; + this.pingService = pingService; } private User getUserByEmail(String email) { @@ -396,6 +401,31 @@ public class UserService implements UserDetailsService { return ImmutableMap.of("users", usersInfoNow, "error", err); } + public Map getActivitiesPings(Integer userId, + String activityName) { + User user = null; + if (userId != null) { + user = findById(userId); + } + Map activitiesPings = new HashMap<>(); + + for (Ping ping : pingService.getPings(activityName)) { + UserActivity activity = ping.getActivity(); + + if (user != null && !activity.getActivityUsers().contains(user)) { + continue; + } + + if (activitiesPings.containsKey(activity.getTitle())) { + activitiesPings.put(activity.getTitle(), activitiesPings.get(activity.getTitle()) + 1); + } else { + activitiesPings.put(activity.getTitle(), 1); + } + + } + return activitiesPings; + } + public void blockUser(int userId) { User userToBlock = findById(userId); userToBlock.setBlocker(getCurrentUser()); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f4be778..f4d9c36 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -37,4 +37,5 @@ ng-tracker.undead-user-login=admin ng-tracker.dev-mode=true ng-tracker.debug_email= ng-tracker.use-https=false -ng-tracker.check-run=false \ No newline at end of file +ng-tracker.check-run=false +ng-tracker.driver-path= diff --git a/src/main/resources/db/changelog-20190605_000000-schema.xml b/src/main/resources/db/changelog-20190605_000000-schema.xml new file mode 100644 index 0000000..c035b35 --- /dev/null +++ b/src/main/resources/db/changelog-20190605_000000-schema.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index 9150882..afcf8c9 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -52,5 +52,6 @@ - + + \ No newline at end of file diff --git a/src/main/resources/mail_templates/pingsInfoWeekEmail.html b/src/main/resources/mail_templates/pingsInfoWeekEmail.html new file mode 100644 index 0000000..180ef3b --- /dev/null +++ b/src/main/resources/mail_templates/pingsInfoWeekEmail.html @@ -0,0 +1,23 @@ + + + + Уведомление о создании статьи + + + + +

+ Уважаемый(ая) Ivan Ivanov +

+

+ Вы были отмечены в следующих задачах: +

+

+

+

+ Regards, +
+ NG-tracker. +

+ + diff --git a/src/main/resources/public/js/core.js b/src/main/resources/public/js/core.js index cc42258..d4eba0d 100644 --- a/src/main/resources/public/js/core.js +++ b/src/main/resources/public/js/core.js @@ -225,3 +225,19 @@ function getUrlVar(key) { var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search); return result && decodeURIComponent(result[1]) || ""; } + +function sendPing(field, url) { + id = document.getElementById(field).value + + $.ajax({ + url:url + `?${field}=` + id, + contentType: "application/json; charset=utf-8", + method: "POST", + success: function() { + showFeedbackMessage("Ping был отправлен", MessageTypesEnum.SUCCESS) + }, + error: function(errorData) { + showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING) + } + }) +} \ No newline at end of file diff --git a/src/main/resources/public/js/users.js b/src/main/resources/public/js/users.js index 68fbf55..0f8d1c0 100644 --- a/src/main/resources/public/js/users.js +++ b/src/main/resources/public/js/users.js @@ -138,4 +138,36 @@ function blockUser() { function isEmailValid(email) { re = /\S+@\S+\.\S+/; return re.test(email) +} + +function drawChart() { + userId = $('#author :selected').val() + activity = $('#activity :selected').val() + $.ajax({ + url:`/api/1.0/users/activities/pings?userId=${userId}&activity=${activity}`, + contentType: "application/json; charset=utf-8", + method: "GET", + success: function(response) { + if (response.data.length == 0) { + return; + } + array = [['Активности', 'Количество']] + + Object.keys(response.data).forEach(function(key) { + console.table('Key : ' + key + ', Value : ' + response.data[key]) + array.push([key, response.data[key]]) + }) + var data = google.visualization.arrayToDataTable(array); + var options = { + title: 'Активности', + is3D: true, + pieResidueSliceLabel: 'Остальное' + }; + var chart = new google.visualization.PieChart(document.getElementById('air')); + chart.draw(data, options); + }, + error: function(errorData) { + showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING) + } + }) } \ No newline at end of file diff --git a/src/main/resources/templates/grants/grant.html b/src/main/resources/templates/grants/grant.html index 04a86a7..ede1486 100644 --- a/src/main/resources/templates/grants/grant.html +++ b/src/main/resources/templates/grants/grant.html @@ -23,7 +23,7 @@ th:object="${grantDto}">
- +
--> +
+ +
diff --git a/src/main/resources/templates/papers/paper.html b/src/main/resources/templates/papers/paper.html index e77ccbb..062d9dc 100644 --- a/src/main/resources/templates/papers/paper.html +++ b/src/main/resources/templates/papers/paper.html @@ -43,7 +43,7 @@