diff --git a/src/main/java/de/thm/arsnova/controller/QuestionController.java b/src/main/java/de/thm/arsnova/controller/QuestionController.java index d6f7098313de9cb136926fb03fdb92de20e5376b..3a8adf80c12d94307f092fedcca929c3fd0fff7a 100644 --- a/src/main/java/de/thm/arsnova/controller/QuestionController.java +++ b/src/main/java/de/thm/arsnova/controller/QuestionController.java @@ -35,6 +35,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.Question; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.IQuestionService; @@ -106,6 +107,12 @@ public class QuestionController extends AbstractController { return questions; } + @RequestMapping(value = "/session/{sessionkey}/skillquestioncount", method = RequestMethod.GET) + @ResponseBody + public final int getSkillQuestionCount(@PathVariable final String sessionkey, final HttpServletResponse response) { + return questionService.getSkillQuestionCount(sessionkey); + } + @RequestMapping(value = "/session/{sessionKey}/questionids", method = RequestMethod.GET) @ResponseBody public final List<String> getQuestionIds( @@ -264,6 +271,15 @@ public class QuestionController extends AbstractController { return questionService.getInterposedCount(sessionKey); } + @RequestMapping(value = "/session/{sessionKey}/interposedreadingcount", method = RequestMethod.GET) + @ResponseBody + public final InterposedReadingCount getUnreadInterposedCount( + @PathVariable final String sessionKey, + final HttpServletResponse response + ) { + return questionService.getInterposedReadingCount(sessionKey); + } + @RequestMapping(value = "/session/{sessionKey}/interposed", method = RequestMethod.GET) @ResponseBody public final List<InterposedQuestion> getInterposedQuestions( diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java index ca5d55565072eb4ed1b636f410fd0c35d5b5cee6..dd79faa7549ee1cb20c127c29652eeee510caced 100644 --- a/src/main/java/de/thm/arsnova/controller/SessionController.java +++ b/src/main/java/de/thm/arsnova/controller/SessionController.java @@ -142,4 +142,15 @@ public class SessionController extends AbstractController { } return sessions; } + + @RequestMapping(value = "/session/visitedsessions", method = RequestMethod.GET) + @ResponseBody + public final List<Session> getMyVisitedSession(final HttpServletResponse response) { + List<Session> sessions = sessionService.getMyVisitedSessions(userService.getCurrentUser()); + if (sessions == null || sessions.isEmpty()) { + response.setStatus(HttpStatus.NO_CONTENT.value()); + return null; + } + return sessions; + } } diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index 2fcaf7846c2018bf259b7ca1d61af8fdd05ee348..32b618940dd778eb96f787ed825d5913e2ef7521 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -58,6 +58,7 @@ import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.PossibleAnswer; import de.thm.arsnova.entities.Question; @@ -1009,7 +1010,7 @@ public class CouchDBDao implements IDatabaseDao { View view = new View("skill_question/count_answers_by_session"); view.setKey(URLEncoder.encode("\"" + s.get_id() + "\"", "UTF-8")); ViewResults results = this.getDatabase().view(view); - if (results.size() == 0) { + if (results.getResults().size() == 0) { return 0; } return results.getJSONArray("rows").optJSONObject(0).optInt("value"); @@ -1041,6 +1042,26 @@ public class CouchDBDao implements IDatabaseDao { return 0; } + @Override + public InterposedReadingCount getInterposedReadingCount(Session session) { + try { + View view = new View("interposed_question/count_by_session_reading"); + view.setStartKey(URLEncoder.encode("[\"" + session.get_id() + "\"]", "UTF-8")); + view.setEndKey(URLEncoder.encode("[\"" + session.get_id() + "\", {}]", "UTF-8")); + view.setGroup(true); + ViewResults results = this.getDatabase().view(view); + if (results.size() == 0 || results.getResults().size() == 0) { + return new InterposedReadingCount(); + } + int read = results.getJSONArray("rows").optJSONObject(0).optInt("value"); + int unread = results.getJSONArray("rows").optJSONObject(1).optInt("value"); + return new InterposedReadingCount(read, unread); + } catch (UnsupportedEncodingException e) { + LOGGER.error("Error while retrieving interposed question count", e); + } + return new InterposedReadingCount(); + } + @Override public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { Session s = this.getSessionFromKeyword(sessionKey); @@ -1237,4 +1258,33 @@ public class CouchDBDao implements IDatabaseDao { document.put("read", question.isRead()); this.getDatabase().saveDocument(document); } + + @Override + public List<Session> getMyVisitedSessions(User user) { + try { + View view = new View("logged_in/visited_sessions_by_user"); + view.setKey(URLEncoder.encode("\"" + user.getUsername() + "\"", "UTF-8")); + ViewResults sessions = this.getDatabase().view(view); + List<Session> allSessions = new ArrayList<Session>(); + for (Document d : sessions.getResults()) { + @SuppressWarnings("unchecked") + Collection<Session> visitedSessions = JSONArray.toCollection( + d.getJSONObject().getJSONArray("value"), + Session.class + ); + allSessions.addAll(visitedSessions); + } + // Do these sessions still exist? + List<Session> result = new ArrayList<Session>(); + for (Session s : allSessions) { + Session session = this.getSessionFromKeyword(s.getKeyword()); + if (session != null) { + result.add(session); + } + } + return result; + } catch (UnsupportedEncodingException e) { + return null; + } + } } diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index b8837942e505cef3556d2607520afdbc05046b37..7e55ec088d9648b3f7eabafcf21bf9d35ae8fcc3 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -28,6 +28,7 @@ import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; @@ -90,6 +91,8 @@ public interface IDatabaseDao { int getInterposedCount(String sessionKey); + InterposedReadingCount getInterposedReadingCount(Session session); + List<InterposedQuestion> getInterposedQuestions(String sessionKey); void vote(String menu); @@ -111,4 +114,6 @@ public interface IDatabaseDao { InterposedQuestion getInterposedQuestion(String questionId) throws IOException; void markInterposedQuestionAsRead(InterposedQuestion question) throws IOException; + + List<Session> getMyVisitedSessions(User user); } diff --git a/src/main/java/de/thm/arsnova/entities/InterposedReadingCount.java b/src/main/java/de/thm/arsnova/entities/InterposedReadingCount.java new file mode 100644 index 0000000000000000000000000000000000000000..5620f834de4d3d9e917ee5003065b6b9d8691932 --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/InterposedReadingCount.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 THM webMedia + * + * This file is part of ARSnova. + * + * ARSnova is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ARSnova is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.thm.arsnova.entities; + +public class InterposedReadingCount { + + private int read; + private int unread; + + public InterposedReadingCount(int readCount, int unreadCount) { + this.read = readCount; + this.unread = unreadCount; + } + + public InterposedReadingCount() { + this.read = 0; + this.unread = 0; + } + + public int getRead() { + return read; + } + + public void setRead(int read) { + this.read = read; + } + + public int getUnread() { + return unread; + } + + public void setUnread(int unread) { + this.unread = unread; + } + + public int getTotal() { + return getRead() + getUnread(); + } +} diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java index 3bacde60e5a1c6ed972f014bffbf3d51e8943ce1..9f40c1f5cf84546c34d03f08c32b792d8b04f5c0 100644 --- a/src/main/java/de/thm/arsnova/services/IQuestionService.java +++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java @@ -23,6 +23,7 @@ import java.util.List; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.Question; public interface IQuestionService { @@ -56,6 +57,8 @@ public interface IQuestionService { int getInterposedCount(String sessionKey); + InterposedReadingCount getInterposedReadingCount(String sessionKey); + List<InterposedQuestion> getInterposedQuestions(String sessionKey); InterposedQuestion readInterposedQuestion(String sessionKey, String questionId); diff --git a/src/main/java/de/thm/arsnova/services/ISessionService.java b/src/main/java/de/thm/arsnova/services/ISessionService.java index 865fc2fcba651a786505d545ae484e56a2f8ed3b..7175464fa71de1eba6b68481d45208f312562403 100644 --- a/src/main/java/de/thm/arsnova/services/ISessionService.java +++ b/src/main/java/de/thm/arsnova/services/ISessionService.java @@ -36,7 +36,10 @@ public interface ISessionService { List<Session> getMySessions(String username); + List<Session> getMyVisitedSessions(User currentUser); + LoggedIn registerAsOnlineUser(User user, String sessionkey); int countActiveUsers(String sessionkey); + } diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index 3bc18f7c9f74d3fee42384c609a251af278a92b5..73eb5cd268e92721970f7dd34c77b02cd778c6f6 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -31,6 +31,7 @@ import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; @@ -146,6 +147,13 @@ public class QuestionService implements IQuestionService { return databaseDao.getInterposedCount(sessionKey); } + @Override + @Authenticated + public InterposedReadingCount getInterposedReadingCount(String sessionKey) { + Session session = this.databaseDao.getSessionFromKeyword(sessionKey); + return databaseDao.getInterposedReadingCount(session); + } + @Override @Authenticated public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java index c99377734bd47ae2a6dadfd3812f839244d94075..23f6f881bcd2c8243018f22b327f1516f9772a2d 100644 --- a/src/main/java/de/thm/arsnova/services/SessionService.java +++ b/src/main/java/de/thm/arsnova/services/SessionService.java @@ -57,6 +57,11 @@ public class SessionService implements ISessionService { return databaseDao.getMySessions(username); } + @Override + public final List<Session> getMyVisitedSessions(final User user) { + return databaseDao.getMyVisitedSessions(user); + } + @Override @Authenticated public final Session saveSession(final Session session) { diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 79f2902018014f07f0794b457d9e7726fd7e2c71..b64f8c892b1e9503e8068786fb229c9b5ddf68a6 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -31,6 +31,7 @@ import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; @@ -363,4 +364,16 @@ public class StubDatabaseDao implements IDatabaseDao { public void markInterposedQuestionAsRead(InterposedQuestion question) throws IOException { this.interposedQuestion.setRead(true); } + + @Override + public List<Session> getMyVisitedSessions(User user) { + // TODO Auto-generated method stub + return null; + } + + @Override + public InterposedReadingCount getInterposedReadingCount(Session session) { + // TODO Auto-generated method stub + return null; + } }