/* * Symphony - A modern community (forum/SNS/blog) platform written in Java. * Copyright (C) 2012-2017, b3log.org & hacpai.com * * This program 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. * * This program 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 org.b3log.symphony.processor; import org.b3log.latke.Keys; import org.b3log.latke.Latkes; import org.b3log.latke.ioc.inject.Inject; import org.b3log.latke.model.Pagination; import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.annotation.After; import org.b3log.latke.servlet.annotation.Before; import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.util.Strings; import org.b3log.symphony.cache.DomainCache; import org.b3log.symphony.model.*; import org.b3log.symphony.processor.advice.AnonymousViewCheck; import org.b3log.symphony.processor.advice.PermissionGrant; import org.b3log.symphony.processor.advice.stopwatch.StopwatchEndAdvice; import org.b3log.symphony.processor.advice.stopwatch.StopwatchStartAdvice; import org.b3log.symphony.service.*; import org.b3log.symphony.util.Symphonys; import org.json.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; /** * Domain processor. * <p> * <ul> * <li>Shows domains (/domains), GET</li> * <li>Shows domain article (/{domainURI}), GET</li> * </ul> * </p> * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @version 1.1.0.8, Dec 24, 2016 * @since 1.4.0 */ @RequestProcessor public class DomainProcessor { /** * Article query service. */ @Inject private ArticleQueryService articleQueryService; /** * Domain query service. */ @Inject private DomainQueryService domainQueryService; /** * Option query service. */ @Inject private OptionQueryService optionQueryService; /** * User query service. */ @Inject private UserQueryService userQueryService; /** * Data model service. */ @Inject private DataModelService dataModelService; /** * Domain cache. */ @Inject private DomainCache domainCache; /** * Caches domains. * * @param request the specified HTTP servlet request * @param response the specified HTTP servlet response * @param context the specified HTTP request context * @throws Exception exception */ @RequestProcessing(value = "/cron/domain/cache-domains", method = HTTPRequestMethod.GET) @Before(adviceClass = StopwatchStartAdvice.class) @After(adviceClass = StopwatchEndAdvice.class) public void cacheDomains(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context) throws Exception { final String key = Symphonys.get("keyOfSymphony"); if (!key.equals(request.getParameter("key"))) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } domainCache.loadDomains(); context.renderJSON().renderTrueResult(); } /** * Shows domain articles. * * @param context the specified context * @param request the specified request * @param response the specified response * @param domainURI the specified domain URI * @throws Exception exception */ @RequestProcessing(value = "/domain/{domainURI}", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, AnonymousViewCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showDomainArticles(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response, final String domainURI) throws Exception { final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("domain-articles.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); int pageSize = Symphonys.getInt("indexArticlesCnt"); final JSONObject user = userQueryService.getCurrentUser(request); if (null != user) { pageSize = user.optInt(UserExt.USER_LIST_PAGE_SIZE); if (!UserExt.finshedGuide(user)) { response.sendRedirect(Latkes.getServePath() + "/guide"); return; } } final JSONObject domain = domainQueryService.getByURI(domainURI); if (null == domain) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } final List<JSONObject> tags = domainQueryService.getTags(domain.optString(Keys.OBJECT_ID)); domain.put(Domain.DOMAIN_T_TAGS, (Object) tags); dataModel.put(Domain.DOMAIN, domain); dataModel.put(Common.SELECTED, domain.optString(Domain.DOMAIN_URI)); final String domainId = domain.optString(Keys.OBJECT_ID); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = articleQueryService.getDomainArticles(avatarViewMode, domainId, pageNum, pageSize); final List<JSONObject> latestArticles = (List<JSONObject>) result.opt(Article.ARTICLES); dataModel.put(Common.LATEST_ARTICLES, latestArticles); final JSONObject pagination = result.optJSONObject(Pagination.PAGINATION); final int pageCount = pagination.optInt(Pagination.PAGINATION_PAGE_COUNT); final List<Integer> pageNums = (List<Integer>) pagination.opt(Pagination.PAGINATION_PAGE_NUMS); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); dataModelService.fillRandomArticles(avatarViewMode, dataModel); dataModelService.fillSideHotArticles(avatarViewMode, dataModel); dataModelService.fillSideTags(dataModel); dataModelService.fillLatestCmts(dataModel); } /** * Shows domains. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/domains", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, AnonymousViewCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showDomains(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("domains.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final JSONObject statistic = optionQueryService.getStatistic(); final int tagCnt = statistic.optInt(Option.ID_C_STATISTIC_TAG_COUNT); dataModel.put(Tag.TAG_T_COUNT, tagCnt); final int domainCnt = statistic.optInt(Option.ID_C_STATISTIC_DOMAIN_COUNT); dataModel.put(Domain.DOMAIN_T_COUNT, domainCnt); dataModelService.fillHeaderAndFooter(request, response, dataModel); } }