package org.iatoki.judgels.raguel.forum.member; import com.google.common.collect.ImmutableList; import org.apache.commons.io.FileUtils; import org.iatoki.judgels.api.JudgelsAPIClientException; import org.iatoki.judgels.api.jophiel.JophielClientAPI; import org.iatoki.judgels.api.jophiel.JophielPublicAPI; import org.iatoki.judgels.api.jophiel.JophielUser; import org.iatoki.judgels.jophiel.avatar.BaseAvatarCacheService; import org.iatoki.judgels.jophiel.activity.UserActivityMessageService; import org.iatoki.judgels.play.Page; import org.iatoki.judgels.play.jid.BaseJidCacheService; import org.iatoki.judgels.play.template.HtmlTemplate; import org.iatoki.judgels.play.views.html.layouts.messageView; import org.iatoki.judgels.raguel.UploadResult; import org.iatoki.judgels.raguel.forum.AbstractForumController; import org.iatoki.judgels.raguel.forum.Forum; import org.iatoki.judgels.raguel.forum.ForumNotFoundException; import org.iatoki.judgels.raguel.forum.ForumService; import org.iatoki.judgels.raguel.forum.member.html.listAddMembersView; import org.iatoki.judgels.raguel.html.uploadResultView; import org.iatoki.judgels.raguel.user.UserService; import play.data.Form; import play.db.jpa.Transactional; import play.filters.csrf.AddCSRFToken; import play.filters.csrf.RequireCSRFCheck; import play.i18n.Messages; import play.mvc.Http; import play.mvc.Result; import play.twirl.api.Html; import javax.inject.Inject; import java.io.File; import java.io.IOException; import java.util.List; public final class ForumMemberController extends AbstractForumController { private static final long PAGE_SIZE = 1000; private final JophielPublicAPI jophielPublicAPI; private final ForumService forumService; private final ForumMemberService forumMemberService; private final UserService userService; @Inject public ForumMemberController(BaseJidCacheService jidCacheService, BaseAvatarCacheService avatarCacheService, JophielClientAPI jophielClientAPI, JophielPublicAPI jophielPublicAPI, UserActivityMessageService userActivityMessageService, ForumMemberService forumMemberService, ForumService forumService, UserService userService) { super(jidCacheService, avatarCacheService, jophielClientAPI, jophielPublicAPI, userActivityMessageService, forumMemberService); this.jophielPublicAPI = jophielPublicAPI; this.forumService = forumService; this.forumMemberService = forumMemberService; this.userService = userService; } @Transactional(readOnly = true) @AddCSRFToken public Result viewMembers(long forumId) throws ForumNotFoundException { return listAddMembers(forumId, 0, "id", "asc", ""); } @Transactional(readOnly = true) @AddCSRFToken public Result listAddMembers(long forumId, long pageIndex, String orderBy, String orderDir, String filterString) throws ForumNotFoundException { Forum forum = forumService.findForumById(forumId); if (!isCurrentUserModeratorOrAdmin()) { return redirect(org.iatoki.judgels.raguel.forum.routes.ForumController.viewForums(forumId)); } Page<ForumMember> forumMembers = forumMemberService.getPageOfMembersInForum(forum.getJid(), pageIndex, PAGE_SIZE, orderBy, orderDir, filterString); Form<ForumMemberAddForm> forumMemberCreateForm = Form.form(ForumMemberAddForm.class); Form<ForumMemberUploadForm> forumMemberUploadForm = Form.form(ForumMemberUploadForm.class); return showlistAddMember(forumMembers, pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forumMemberUploadForm, forum); } @Transactional @RequireCSRFCheck public Result postAddMember(long forumId, long pageIndex, String orderBy, String orderDir, String filterString) throws ForumNotFoundException { Forum forum = forumService.findForumById(forumId); if (!isCurrentUserModeratorOrAdmin()) { return redirect(org.iatoki.judgels.raguel.forum.routes.ForumController.viewForums(forumId)); } Form<ForumMemberAddForm> forumMemberCreateForm = Form.form(ForumMemberAddForm.class).bindFromRequest(); if (formHasErrors(forumMemberCreateForm)) { return showlistAddMemberWithMemberAddForm(pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forum); } ForumMemberAddForm forumMemberCreateData = forumMemberCreateForm.get(); JophielUser jophielUser; try { jophielUser = jophielPublicAPI.findUserByUsername(forumMemberCreateData.username); } catch (JudgelsAPIClientException e) { forumMemberCreateForm.reject("error.member.create.userNotExist"); return showlistAddMemberWithMemberAddForm(pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forum); } if (jophielUser == null) { forumMemberCreateForm.reject("error.member.create.userNotExist"); return showlistAddMemberWithMemberAddForm(pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forum); } if (forumMemberService.isMemberInForum(forum.getJid(), jophielUser.getJid())) { forumMemberCreateForm.reject("error.member.create.userIsAlreadyMember"); return showlistAddMemberWithMemberAddForm(pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forum); } userService.upsertUserFromJophielUser(jophielUser, getCurrentUserJid(), getCurrentUserIpAddress()); forumMemberService.createForumMember(forum.getJid(), jophielUser.getJid(), getCurrentUserJid(), getCurrentUserIpAddress()); return redirect(routes.ForumMemberController.viewMembers(forum.getId())); } @Transactional @RequireCSRFCheck public Result postUploadMember(long forumId) throws ForumNotFoundException { Forum forum = forumService.findForumById(forumId); if (!isCurrentUserModeratorOrAdmin()) { return redirect(org.iatoki.judgels.raguel.forum.routes.ForumController.viewForums(forumId)); } ImmutableList.Builder<UploadResult> failedUploadsBuilder = ImmutableList.builder(); Http.MultipartFormData body = request().body().asMultipartFormData(); Http.MultipartFormData.FilePart file; file = body.getFile("usernames"); if (file != null) { File userFile = file.getFile(); try { String[] usernames = FileUtils.readFileToString(userFile).split("\n"); for (String username : usernames) { try { JophielUser jophielUser = jophielPublicAPI.findUserByUsername(username); if (jophielUser != null) { if (!forumMemberService.isMemberInForum(forum.getJid(), jophielUser.getJid())) { userService.upsertUserFromJophielUser(jophielUser, getCurrentUserJid(), getCurrentUserIpAddress()); forumMemberService.createForumMember(forum.getJid(), jophielUser.getJid(), getCurrentUserJid(), getCurrentUserIpAddress()); } else { failedUploadsBuilder.add(new UploadResult(username, Messages.get("forum.member.new.error.registered"))); } } else { failedUploadsBuilder.add(new UploadResult(username, Messages.get("forum.member.new.error.invalid"))); } } catch (JudgelsAPIClientException e) { failedUploadsBuilder.add(new UploadResult(username, Messages.get("forum.member.new.error.invalid"))); } } } catch (IOException e) { throw new RuntimeException(e); } } List<UploadResult> failedUploads = failedUploadsBuilder.build(); return showUploadMemberResult(failedUploads, forum); } @Transactional public Result removeMember(long forumId, long forumMemberId) throws ForumNotFoundException, ForumMemberNotFoundException { Forum forum = forumService.findForumById(forumId); ForumMember forumMember = forumMemberService.findMemberInForumById(forumMemberId); if (!isCurrentUserModeratorOrAdmin()) { return redirect(org.iatoki.judgels.raguel.forum.routes.ForumController.viewForums(forumId)); } forumMemberService.deleteForumMember(forumMember.getId()); return redirect(routes.ForumMemberController.viewMembers(forum.getId())); } private Result showlistAddMemberWithMemberAddForm(long pageIndex, String orderBy, String orderDir, String filterString, Form<ForumMemberAddForm> forumMemberAddForm, Forum forum) { Form<ForumMemberUploadForm> forumMemberUploadForm = Form.form(ForumMemberUploadForm.class); Page<ForumMember> pageOfMembers = forumMemberService.getPageOfMembersInForum(forum.getJid(), pageIndex, PAGE_SIZE, orderBy, orderDir, filterString); return showlistAddMember(pageOfMembers, pageIndex, orderBy, orderDir, filterString, forumMemberAddForm, forumMemberUploadForm, forum); } private Result showlistAddMember(Page<ForumMember> forumMembers, long pageIndex, String orderBy, String orderDir, String filterString, Form<ForumMemberAddForm> forumMemberCreateForm, Form<ForumMemberUploadForm> forumMemberUploadForm, Forum forum) { HtmlTemplate htmlTemplate = getBaseHtmlTemplate(forum); Html content = listAddMembersView.render(forum.getId(), forumMembers, pageIndex, orderBy, orderDir, filterString, forumMemberCreateForm, forumMemberUploadForm, jophielPublicAPI.getUserAutocompleteAPIEndpoint()); htmlTemplate.setContent(content); htmlTemplate.markBreadcrumbLocation(Messages.get("forum.text.members"), routes.ForumMemberController.viewMembers(forum.getId())); return renderTemplate(htmlTemplate); } private Result showUploadMemberResult(List<UploadResult> failedUploads, Forum forum) { HtmlTemplate htmlTemplate = getBaseHtmlTemplate(forum); Html content; if (failedUploads.size() > 0) { content = uploadResultView.render(failedUploads); } else { content = messageView.render(Messages.get("forum.member.upload.text.success")); } htmlTemplate.setContent(content); htmlTemplate.setMainTitle(Messages.get("forum.member.upload.text.result")); htmlTemplate.markBreadcrumbLocation(Messages.get("forum.text.members"), routes.ForumMemberController.viewMembers(forum.getId())); return renderTemplate(htmlTemplate); } @Override protected HtmlTemplate getBaseHtmlTemplate(Forum forum) { HtmlTemplate htmlTemplate = super.getBaseHtmlTemplate(forum); htmlTemplate.markBreadcrumbLocation(Messages.get("forum.text.members"), org.iatoki.judgels.raguel.forum.routes.ForumController.jumpToMembers(forum.getId())); return htmlTemplate; } }