Commit e5ec2661 authored by Liang Ding's avatar Liang Ding

🚧 #12256 填充侧边栏分类模型

parent 183ba177
......@@ -20,7 +20,7 @@ package org.b3log.solo.model;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.4.5.1, Nov 1, 2015
* @version 1.5.5.1, Apr 8, 2017
* @since 0.3.1
*/
public final class Common {
......@@ -35,6 +35,11 @@ public final class Common {
*/
public static final String MOST_USED_TAGS = "mostUsedTags";
/**
* Most used categories.
*/
public static final String MOST_USED_CATEGORIES = "mostUsedCategories";
/**
* Most comment count articles.
*/
......@@ -174,7 +179,7 @@ public final class Common {
* Key of current user.
*/
public static final String CURRENT_USER = "currentUser";
/**
* Key of admin user.
*/
......
......@@ -16,15 +16,6 @@
package org.b3log.solo.processor.util;
import freemarker.template.Template;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
......@@ -47,30 +38,26 @@ import org.b3log.latke.util.*;
import org.b3log.latke.util.freemarker.Templates;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*;
import static org.b3log.solo.model.Article.ARTICLE_CONTENT;
import org.b3log.solo.repository.ArchiveDateRepository;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.LinkRepository;
import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.service.OptionQueryService;
import org.b3log.solo.service.StatisticQueryService;
import org.b3log.solo.service.TagQueryService;
import org.b3log.solo.service.UserQueryService;
import org.b3log.solo.repository.*;
import org.b3log.solo.service.*;
import org.b3log.solo.util.Thumbnails;
import org.b3log.solo.util.comparator.Comparators;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import static org.b3log.solo.model.Article.ARTICLE_CONTENT;
/**
* Filler utilities.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.5.11.13, Feb 26, 2017
* @version 1.6.11.13, Apr 8, 2017
* @since 0.3.1
*/
@Service
......@@ -80,101 +67,89 @@ public class Filler {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(Filler.class.getName());
/**
* {@code true} for published.
*/
private static final boolean PUBLISHED = true;
/**
* User service.
*/
private static UserService userService = UserServiceFactory.getUserService();
/**
* Topbar utilities.
*/
@Inject
private TopBars topBars;
/**
* Article repository.
*/
@Inject
private ArticleRepository articleRepository;
/**
* Comment repository.
*/
@Inject
private CommentRepository commentRepository;
/**
* Archive date repository.
*/
@Inject
private ArchiveDateRepository archiveDateRepository;
/**
* Category repository.
*/
@Inject
private CategoryRepository categoryRepository;
/**
* Tag repository.
*/
@Inject
private TagRepository tagRepository;
/**
* Link repository.
*/
@Inject
private LinkRepository linkRepository;
/**
* Page repository.
*/
@Inject
private PageRepository pageRepository;
/**
* Statistic query service.
*/
@Inject
private StatisticQueryService statisticQueryService;
/**
* User repository.
*/
@Inject
private UserRepository userRepository;
/**
* Option query service..
*/
@Inject
private OptionQueryService optionQueryService;
/**
* Article query service.
*/
@Inject
private ArticleQueryService articleQueryService;
/**
* {@code true} for published.
*/
private static final boolean PUBLISHED = true;
/**
* Tag query service.
*/
@Inject
private TagQueryService tagQueryService;
/**
* User query service.
*/
@Inject
private UserQueryService userQueryService;
/**
* Fill tag article..
*/
@Inject
private FillTagArticles fillTagArticles;
/**
* User service.
*/
private static UserService userService = UserServiceFactory.getUserService();
/**
* Event manager.
*/
......@@ -190,14 +165,14 @@ public class Filler {
/**
* Fills articles in index.ftl.
*
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param currentPageNum current page number
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
*/
public void fillIndexArticles(final HttpServletRequest request,
final Map<String, Object> dataModel, final int currentPageNum, final JSONObject preference)
final Map<String, Object> dataModel, final int currentPageNum, final JSONObject preference)
throws ServiceException {
Stopwatchs.start("Fill Index Articles");
......@@ -219,19 +194,19 @@ public class Filler {
if (null == template) {
LOGGER.debug("The skin dose not contain [index.ftl] template");
} else // See https://github.com/b3log/solo/issues/179 for more details
if (Templates.hasExpression(template, "<#list articles1 as article>")) {
isArticles1 = true;
query.addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
LOGGER.trace("Query ${articles1} in index.ftl");
} else { // <#list articles as article>
query.addSort(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING);
if (preference.getBoolean(Option.ID_C_ENABLE_ARTICLE_UPDATE_HINT)) {
query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING);
} else {
if (Templates.hasExpression(template, "<#list articles1 as article>")) {
isArticles1 = true;
query.addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
LOGGER.trace("Query ${articles1} in index.ftl");
} else { // <#list articles as article>
query.addSort(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING);
if (preference.getBoolean(Option.ID_C_ENABLE_ARTICLE_UPDATE_HINT)) {
query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING);
} else {
query.addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
}
}
}
query.index(Article.ARTICLE_PERMALINK);
......@@ -331,10 +306,35 @@ public class Filler {
Stopwatchs.end();
}
/**
* Fills most used categories.
*
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
public void fillMostUsedCategories(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill Most Used Categories");
try {
LOGGER.debug("Filling most used categories....");
final int mostUsedCategoryDisplayCnt = Integer.MAX_VALUE; // XXX: preference instead
final List<JSONObject> categories = categoryRepository.getMostUsedCategories(mostUsedCategoryDisplayCnt);
dataModel.put(Common.MOST_USED_CATEGORIES, categories);
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Fills most used categories failed", e);
throw new ServiceException(e);
} finally {
Stopwatchs.end();
}
}
/**
* Fills most used tags.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -364,7 +364,7 @@ public class Filler {
/**
* Fills archive dates.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -437,7 +437,7 @@ public class Filler {
/**
* Fills most view count articles.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -461,7 +461,7 @@ public class Filler {
/**
* Fills most comments articles.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -485,7 +485,7 @@ public class Filler {
/**
* Fills post articles recently.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -513,7 +513,7 @@ public class Filler {
/**
* Fills post comments recently.
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -550,8 +550,8 @@ public class Filler {
/**
* Fills footer.ftl.
*
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -621,14 +621,14 @@ public class Filler {
/**
* Fills header.ftl.
*
* @param request the specified HTTP servlet request
* @param response the specified HTTP servlet response
* @param dataModel data model
* @param request the specified HTTP servlet request
* @param response the specified HTTP servlet response
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
public void fillBlogHeader(final HttpServletRequest request, final HttpServletResponse response,
final Map<String, Object> dataModel, final JSONObject preference)
final Map<String, Object> dataModel, final JSONObject preference)
throws ServiceException {
Stopwatchs.start("Fill Header");
try {
......@@ -718,8 +718,8 @@ public class Filler {
/**
* Fills side.ftl.
*
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
......@@ -755,6 +755,10 @@ public class Filler {
fillRecentComments(dataModel, preference);
}
if (Templates.hasExpression(template, "<#list mostUsedCategories as tag>")) {
fillMostUsedCategories(dataModel, preference);
}
if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) {
fillMostUsedTags(dataModel, preference);
}
......@@ -782,14 +786,14 @@ public class Filler {
/**
* Fills the specified template.
*
* @param request the specified HTTP servlet request
* @param template the specified template
* @param dataModel data model
* @param request the specified HTTP servlet request
* @param template the specified template
* @param dataModel data model
* @param preference the specified preference
* @throws ServiceException service exception
*/
public void fillUserTemplate(final HttpServletRequest request, final Template template,
final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill User Template[name=" + template.getName() + "]");
try {
LOGGER.log(Level.DEBUG, "Filling user template[name{0}]", template.getName());
......@@ -806,6 +810,10 @@ public class Filler {
fillRecentComments(dataModel, preference);
}
if (Templates.hasExpression(template, "<#list mostUsedCategories as tag>")) {
fillMostUsedCategories(dataModel, preference);
}
if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) {
fillMostUsedTags(dataModel, preference);
}
......@@ -890,7 +898,7 @@ public class Filler {
/**
* Sets some extra properties into the specified article with the specified author and preference, performs content
* and abstract editor processing.
*
* <p>
* <p>
* Article ext properties:
* <pre>
......@@ -903,15 +911,15 @@ public class Filler {
* }
* </pre> </p>
*
* @param request the specified HTTP servlet request
* @param article the specified article
* @param author the specified author
* @param request the specified HTTP servlet request
* @param article the specified article
* @param author the specified author
* @param preference the specified preference
* @throws ServiceException service exception
* @see #setArticlesExProperties(HttpServletRequest, List, JSONObject, JSONObject)
*/
private void setArticleExProperties(final HttpServletRequest request,
final JSONObject article, final JSONObject author, final JSONObject preference)
final JSONObject article, final JSONObject author, final JSONObject preference)
throws ServiceException {
try {
final String authorName = author.getString(User.USER_NAME);
......@@ -953,7 +961,7 @@ public class Filler {
/**
* Sets some extra properties into the specified article with the specified preference, performs content and
* abstract editor processing.
*
* <p>
* <p>
* Article ext properties:
* <pre>
......@@ -966,14 +974,14 @@ public class Filler {
* }
* </pre> </p>
*
* @param request the specified HTTP servlet request
* @param article the specified article
* @param request the specified HTTP servlet request
* @param article the specified article
* @param preference the specified preference
* @throws ServiceException service exception
* @see #setArticlesExProperties(HttpServletRequest, List, JSONObject)
*/
private void setArticleExProperties(final HttpServletRequest request,
final JSONObject article, final JSONObject preference) throws ServiceException {
final JSONObject article, final JSONObject preference) throws ServiceException {
try {
final JSONObject author = articleQueryService.getAuthor(article);
final String authorName = author.getString(User.USER_NAME);
......@@ -1014,11 +1022,11 @@ public class Filler {
/**
* Sets some extra properties into the specified article with the specified author and preference.
*
* <p>
* <p>
* The batch version of method {@linkplain #setArticleExProperties(HttpServletRequest, JSONObject, JSONObject, JSONObject)}.
* </p>
*
* <p>
* <p>
* Article ext properties:
* <pre>
......@@ -1030,15 +1038,15 @@ public class Filler {
* }
* </pre> </p>
*
* @param request the specified HTTP servlet request
* @param articles the specified articles
* @param author the specified author
* @param request the specified HTTP servlet request
* @param articles the specified articles
* @param author the specified author
* @param preference the specified preference
* @throws ServiceException service exception
* @see #setArticleExProperties(HttpServletRequest, JSONObject, JSONObject, JSONObject)
*/
public void setArticlesExProperties(final HttpServletRequest request,
final List<JSONObject> articles, final JSONObject author, final JSONObject preference)
final List<JSONObject> articles, final JSONObject author, final JSONObject preference)
throws ServiceException {
for (final JSONObject article : articles) {
setArticleExProperties(request, article, author, preference);
......@@ -1047,11 +1055,11 @@ public class Filler {
/**
* Sets some extra properties into the specified article with the specified preference.
*
* <p>
* <p>
* The batch version of method {@linkplain #setArticleExProperties(HttpServletRequest, JSONObject, JSONObject)}.
* </p>
*
* <p>
* <p>
* Article ext properties:
* <pre>
......@@ -1063,14 +1071,14 @@ public class Filler {
* }
* </pre> </p>
*
* @param request the specified HTTP servlet request
* @param articles the specified articles
* @param request the specified HTTP servlet request
* @param articles the specified articles
* @param preference the specified preference
* @throws ServiceException service exception
* @see #setArticleExProperties(HttpServletRequest, JSONObject, JSONObject)
*/
public void setArticlesExProperties(final HttpServletRequest request,
final List<JSONObject> articles, final JSONObject preference)
final List<JSONObject> articles, final JSONObject preference)
throws ServiceException {
for (final JSONObject article : articles) {
setArticleExProperties(request, article, preference);
......@@ -1079,7 +1087,7 @@ public class Filler {
/**
* Processes the abstract of the specified article with the specified preference.
*
* <p>
* <p>
* <ul>
* <li>If the abstract is {@code null}, sets it with ""</li>
......@@ -1089,7 +1097,7 @@ public class Filler {
* </p>
*
* @param preference the specified preference
* @param article the specified article
* @param article the specified article
*/
private void processArticleAbstract(final JSONObject preference, final JSONObject article) {
final String articleAbstract = article.optString(Article.ARTICLE_ABSTRACT, null);
......
......@@ -19,11 +19,13 @@ import org.b3log.latke.repository.Repository;
import org.b3log.latke.repository.RepositoryException;
import org.json.JSONObject;
import java.util.List;
/**
* Category repository.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.1, Apr 1, 2017
* @version 1.2.0.1, Apr 8, 2017
* @since 2.0.0
*/
public interface CategoryRepository extends Repository {
......@@ -80,4 +82,13 @@ public interface CategoryRepository extends Repository {
* @throws RepositoryException repository exception
*/
JSONObject getByOrder(final int order) throws RepositoryException;
/**
* Gets most used categories (contains the most tags) with the specified number.
*
* @param num the specified number
* @return a list of most used categories, returns an empty list if not found
* @throws RepositoryException repository exception
*/
List<JSONObject> getMostUsedCategories(final int num) throws RepositoryException;
}
......@@ -18,16 +18,23 @@ package org.b3log.solo.repository.impl;
import org.b3log.latke.Keys;
import org.b3log.latke.repository.*;
import org.b3log.latke.repository.annotation.Repository;
import org.b3log.latke.util.CollectionUtils;
import org.b3log.solo.model.Category;
import org.b3log.solo.model.Tag;
import org.b3log.solo.repository.CategoryRepository;
import org.json.JSONArray;
import org.json.JSONObject;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Category repository.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.0, Apr 1, 2017
* @version 1.1.0.1, Apr 8, 2017
* @since 2.0.0
*/
@Repository
......@@ -104,6 +111,20 @@ public class CategoryRepositoryImpl extends AbstractRepository implements Catego
return array.optJSONObject(0);
}
@Override
public List<JSONObject> getMostUsedCategories(final int num) throws RepositoryException {
final Query query = new Query().addSort(Category.CATEGORY_TAG_CNT, SortDirection.DESCENDING).
setCurrentPageNum(1).setPageSize(num).setPageCount(1);
final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final List<JSONObject> ret = CollectionUtils.jsonArrayToList(array);
sortJSONCategoryList(ret);
return ret;
}
@Override
public JSONObject getUpper(final String id) throws RepositoryException {
final JSONObject category = get(id);
......@@ -153,4 +174,14 @@ public class CategoryRepositoryImpl extends AbstractRepository implements Catego
return array.optJSONObject(0);
}
private void sortJSONCategoryList(final List<JSONObject> tagJoList) {
Collections.sort(tagJoList, new Comparator<JSONObject>() {
@Override
public int compare(final JSONObject o1, final JSONObject o2) {
return Collator.getInstance(java.util.Locale.CHINA).
compare(o1.optString(Tag.TAG_TITLE), o2.optString(Tag.TAG_TITLE));
}
});
}
}
......@@ -142,9 +142,8 @@ public class ArticleQueryService {
pagination.put(Pagination.PAGINATION_PAGE_NUMS, (Object) Collections.emptyList());
try {
final JSONArray categoryTags =
categoryTagRepository.getByCategoryId(categoryId, 1, Integer.MAX_VALUE)
.optJSONArray(Keys.RESULTS);
final JSONArray categoryTags = categoryTagRepository.getByCategoryId(
categoryId, 1, Integer.MAX_VALUE).optJSONArray(Keys.RESULTS);
if (categoryTags.length() <= 0) {
return ret;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment