/**
   * Markdowns.
   *
   * <p>Renders the response with a json object, for example,
   *
   * <pre>
   * {
   *     "html": ""
   * }
   * </pre>
   *
   * @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 = "/markdown", method = HTTPRequestMethod.POST)
  @Before(adviceClass = StopwatchStartAdvice.class)
  @After(adviceClass = StopwatchEndAdvice.class)
  public void markdown2HTML(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final HTTPRequestContext context)
      throws Exception {
    final JSONRenderer renderer = new JSONRenderer();
    context.setRenderer(renderer);
    final JSONObject result = new JSONObject();
    renderer.setJSONObject(result);

    result.put(Keys.STATUS_CODE, true);

    String markdownText = request.getParameter("markdownText");
    if (Strings.isEmptyOrNull(markdownText)) {
      result.put("html", "");

      return;
    }

    final JSONObject currentUser = userQueryService.getCurrentUser(request);
    if (null == currentUser) {
      response.sendError(HttpServletResponse.SC_FORBIDDEN);

      return;
    }

    final Set<String> userNames = userQueryService.getUserNames(markdownText);
    for (final String userName : userNames) {
      markdownText =
          markdownText.replace(
              '@' + userName,
              "@<a href='"
                  + Latkes.getServePath()
                  + "/member/"
                  + userName
                  + "'>"
                  + userName
                  + "</a>");
    }
    markdownText = shortLinkQueryService.linkArticle(markdownText);
    markdownText = shortLinkQueryService.linkTag(markdownText);
    markdownText = Emotions.convert(markdownText);
    markdownText = Markdowns.toHTML(markdownText);
    markdownText = Markdowns.clean(markdownText, "");

    result.put("html", markdownText);
  }
  /**
   * Processes the specified comment content.
   *
   * <ul>
   *   <li>Generates &#64;username home URL
   *   <li>Markdowns
   *   <li>Blocks comment if need
   *   <li>Generates emotion images
   *   <li>Generates article link with article id
   * </ul>
   *
   * @param comment the specified comment, for example,
   *     <pre>
   * {
   *     "commentContent": "",
   *     ....,
   *     "commenter": {}
   * }
   * </pre>
   */
  private void processCommentContent(final JSONObject comment) {
    final JSONObject commenter = comment.optJSONObject(Comment.COMMENT_T_COMMENTER);

    if (Comment.COMMENT_STATUS_C_INVALID == comment.optInt(Comment.COMMENT_STATUS)
        || UserExt.USER_STATUS_C_INVALID == commenter.optInt(UserExt.USER_STATUS)) {
      comment.put(Comment.COMMENT_CONTENT, langPropsService.get("commentContentBlockLabel"));

      return;
    }

    genCommentContentUserName(comment);

    String commentContent = comment.optString(Comment.COMMENT_CONTENT);

    commentContent = shortLinkQueryService.linkArticle(commentContent);
    commentContent = shortLinkQueryService.linkTag(commentContent);
    commentContent = Emotions.convert(commentContent);
    commentContent = Markdowns.toHTML(commentContent);
    commentContent = Markdowns.clean(commentContent, "");

    comment.put(Comment.COMMENT_CONTENT, commentContent);
  }
Exemple #3
0
  @Override
  public void action(final Event<JSONObject> event) throws EventException {
    final JSONObject data = event.getData();
    LOGGER.log(
        Level.DEBUG,
        "Processing an event[type={0}, data={1}] in listener[className={2}]",
        new Object[] {event.getType(), data, CommentNotifier.class.getName()});

    try {
      final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);
      final JSONObject originalComment = data.getJSONObject(Comment.COMMENT);
      final String commentContent = originalComment.optString(Comment.COMMENT_CONTENT);
      final JSONObject commenter =
          userQueryService.getUser(originalComment.optString(Comment.COMMENT_AUTHOR_ID));
      final String commenterName = commenter.optString(User.USER_NAME);

      // 0. Data channel (WebSocket)
      final JSONObject chData = new JSONObject();
      chData.put(Article.ARTICLE_T_ID, originalArticle.optString(Keys.OBJECT_ID));
      chData.put(Comment.COMMENT_T_ID, originalComment.optString(Keys.OBJECT_ID));
      chData.put(Comment.COMMENT_T_AUTHOR_NAME, commenterName);

      final String userEmail = commenter.optString(User.USER_EMAIL);
      chData.put(
          Comment.COMMENT_T_AUTHOR_THUMBNAIL_URL, avatarQueryService.getAvatarURL(userEmail));
      chData.put(Common.THUMBNAIL_UPDATE_TIME, commenter.optLong(UserExt.USER_UPDATE_TIME));

      chData.put(
          Comment.COMMENT_CREATE_TIME,
          DateFormatUtils.format(
              new Date(originalComment.optLong(Comment.COMMENT_CREATE_TIME)), "yyyy-MM-dd HH:mm"));
      String cc = shortLinkQueryService.linkArticle(commentContent);
      cc = shortLinkQueryService.linkTag(cc);
      cc = Emotions.convert(cc);
      cc = Markdowns.toHTML(cc);
      cc = Markdowns.clean(cc, "");
      try {
        final Set<String> userNames = userQueryService.getUserNames(commentContent);
        for (final String userName : userNames) {
          cc =
              cc.replace(
                  '@' + userName,
                  "@<a href='"
                      + Latkes.getServePath()
                      + "/member/"
                      + userName
                      + "'>"
                      + userName
                      + "</a>");
        }
      } catch (final ServiceException e) {
        LOGGER.log(Level.ERROR, "Generates @username home URL for comment content failed", e);
      }
      chData.put(Comment.COMMENT_CONTENT, cc);

      ArticleChannel.notifyComment(chData);

      // + Article Heat
      final JSONObject articleHeat = new JSONObject();
      articleHeat.put(Article.ARTICLE_T_ID, originalArticle.optString(Keys.OBJECT_ID));
      articleHeat.put(Common.OPERATION, "+");
      ArticleListChannel.notifyHeat(articleHeat);

      final boolean isDiscussion =
          originalArticle.optInt(Article.ARTICLE_TYPE) == Article.ARTICLE_TYPE_C_DISCUSSION;

      // Timeline
      if (!isDiscussion) {
        final String articleTitle =
            StringUtils.substring(
                Jsoup.parse(originalArticle.optString(Article.ARTICLE_TITLE)).text(), 0, 28);
        final String articlePermalink =
            Latkes.getServePath() + originalArticle.optString(Article.ARTICLE_PERMALINK);

        final JSONObject timeline = new JSONObject();
        timeline.put(Common.TYPE, Comment.COMMENT);
        String content = langPropsService.get("timelineCommentLabel");
        content =
            content
                .replace(
                    "{user}",
                    "<a target='_blank' rel='nofollow' href='"
                        + Latkes.getServePath()
                        + "/member/"
                        + commenterName
                        + "'>"
                        + commenterName
                        + "</a>")
                .replace(
                    "{article}",
                    "<a target='_blank' rel='nofollow' href='"
                        + articlePermalink
                        + "'>"
                        + articleTitle
                        + "</a>")
                .replace("{comment}", StringUtils.substring(Jsoup.parse(cc).text(), 0, 28));
        timeline.put(Common.CONTENT, content);

        timelineMgmtService.addTimeline(timeline);
      }

      // 1. 'Commented' Notification
      final String articleAuthorId = originalArticle.optString(Article.ARTICLE_AUTHOR_ID);
      final Set<String> atUserNames = userQueryService.getUserNames(commentContent);
      final boolean commenterIsArticleAuthor =
          articleAuthorId.equals(originalComment.optString(Comment.COMMENT_AUTHOR_ID));
      if (commenterIsArticleAuthor && atUserNames.isEmpty()) {
        return;
      }

      atUserNames.remove(commenterName); // Do not notify commenter itself

      if (!commenterIsArticleAuthor) {
        final JSONObject requestJSONObject = new JSONObject();
        requestJSONObject.put(Notification.NOTIFICATION_USER_ID, articleAuthorId);
        requestJSONObject.put(
            Notification.NOTIFICATION_DATA_ID, originalComment.optString(Keys.OBJECT_ID));

        notificationMgmtService.addCommentedNotification(requestJSONObject);
      }

      final String articleContent = originalArticle.optString(Article.ARTICLE_CONTENT);
      final Set<String> articleContentAtUserNames = userQueryService.getUserNames(articleContent);

      // 2. 'At' Notification
      for (final String userName : atUserNames) {
        if (isDiscussion && !articleContentAtUserNames.contains(userName)) {
          continue;
        }

        final JSONObject user = userQueryService.getUserByName(userName);

        if (null == user) {
          LOGGER.log(Level.WARN, "Not found user by name [{0}]", userName);

          continue;
        }

        if (user.optString(Keys.OBJECT_ID).equals(articleAuthorId)) {
          continue; // Has added in step 1
        }

        final JSONObject requestJSONObject = new JSONObject();
        requestJSONObject.put(Notification.NOTIFICATION_USER_ID, user.optString(Keys.OBJECT_ID));
        requestJSONObject.put(
            Notification.NOTIFICATION_DATA_ID, originalComment.optString(Keys.OBJECT_ID));

        notificationMgmtService.addAtNotification(requestJSONObject);
      }
    } catch (final Exception e) {
      LOGGER.log(Level.ERROR, "Sends the comment notification failed", e);
    }
  }