Example #1
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, CommentSender.class.getName()});
    try {
      if (data.optBoolean(Common.FROM_CLIENT)) {
        return;
      }

      final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);

      if (!originalArticle.optBoolean(Article.ARTICLE_SYNC_TO_CLIENT)) {
        return;
      }

      final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
      final UserQueryService userQueryService = beanManager.getReference(UserQueryService.class);

      final String authorId = originalArticle.optString(Article.ARTICLE_AUTHOR_ID);
      final JSONObject author = userQueryService.getUser(authorId);
      final String clientURL = author.optString(UserExt.USER_B3_CLIENT_ADD_COMMENT_URL);

      if (Strings.isEmptyOrNull(clientURL)) {
        return;
      }

      final JSONObject originalComment = data.getJSONObject(Comment.COMMENT);
      final String commenterId = originalComment.optString(Comment.COMMENT_AUTHOR_ID);
      final JSONObject commenter = userQueryService.getUser(commenterId);

      final HTTPRequest httpRequest = new HTTPRequest();
      httpRequest.setURL(new URL(clientURL));
      httpRequest.setRequestMethod(HTTPRequestMethod.PUT);
      final JSONObject requestJSONObject = new JSONObject();
      final JSONObject comment =
          new JSONObject(
              originalComment,
              new String[] {Comment.COMMENT_AUTHOR_EMAIL, Comment.COMMENT_CONTENT, Keys.OBJECT_ID});

      comment.put(Comment.COMMENT_T_AUTHOR_NAME, commenter.optString(User.USER_NAME));
      comment.put(UserExt.USER_B3_KEY, author.optString(UserExt.USER_B3_KEY));
      comment.put(Comment.COMMENT_T_AUTHOR_URL, commenter.optString(User.USER_URL));
      comment.put(
          Comment.COMMENT_ON_ARTICLE_ID,
          originalArticle.optString(Article.ARTICLE_CLIENT_ARTICLE_ID));
      comment.put(Comment.COMMENT_T_SYMPHONY_ID, originalArticle.optString(Keys.OBJECT_ID));

      requestJSONObject.put(Comment.COMMENT, comment);
      httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));

      urlFetchService.fetchAsync(httpRequest);
    } catch (final Exception e) {
      LOGGER.log(Level.ERROR, "Sends a comment to client error: {0}", e.getMessage());
    }

    LOGGER.log(Level.DEBUG, "Sent a comment to client");
  }
Example #2
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, ArticleNotifier.class.getName()});

    try {
      final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);
      final String articleId = originalArticle.optString(Keys.OBJECT_ID);

      final String articleAuthorId = originalArticle.optString(Article.ARTICLE_AUTHOR_ID);
      final JSONObject articleAuthor = userQueryService.getUser(articleAuthorId);
      final String articleAuthorName = articleAuthor.optString(User.USER_NAME);

      final String articleContent = originalArticle.optString(Article.ARTICLE_CONTENT);
      final Set<String> atUserNames = userQueryService.getUserNames(articleContent);
      atUserNames.remove(articleAuthorName); // Do not notify the author itself

      final Set<String> atedUserIds = new HashSet<String>();

      // 'At' Notification
      for (final String userName : atUserNames) {
        final JSONObject user = userQueryService.getUserByName(userName);

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

          continue;
        }

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

        notificationMgmtService.addAtNotification(requestJSONObject);

        atedUserIds.add(atedUserId);
      }

      // 'FollowingUser' Notification
      final JSONObject followerUsersResult =
          followQueryService.getFollowerUsers(articleAuthorId, 1, Integer.MAX_VALUE);
      @SuppressWarnings("unchecked")
      final List<JSONObject> followerUsers = (List) followerUsersResult.opt(Keys.RESULTS);
      for (final JSONObject followerUser : followerUsers) {
        final JSONObject requestJSONObject = new JSONObject();
        final String followerUserId = followerUser.optString(Keys.OBJECT_ID);

        if (atedUserIds.contains(followerUserId)) {
          continue;
        }

        requestJSONObject.put(Notification.NOTIFICATION_USER_ID, followerUserId);
        requestJSONObject.put(Notification.NOTIFICATION_DATA_ID, articleId);

        notificationMgmtService.addFollowingUserNotification(requestJSONObject);
      }

      // Timeline
      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, Article.ARTICLE);
      String content = langPropsService.get("timelineArticleLabel");
      content =
          content
              .replace(
                  "{user}",
                  "<a target='_blank' rel='nofollow' href='"
                      + Latkes.getServePath()
                      + "/member/"
                      + articleAuthorName
                      + "'>"
                      + articleAuthorName
                      + "</a>")
              .replace(
                  "{article}",
                  "<a target='_blank' rel='nofollow' href='"
                      + articlePermalink
                      + "'>"
                      + articleTitle
                      + "</a>");
      timeline.put(Common.CONTENT, content);

      timelineMgmtService.addTimeline(timeline);

      // 'Broadcast' Notification
      if (Article.ARTICLE_TYPE_C_CITY_BROADCAST == originalArticle.optInt(Article.ARTICLE_TYPE)) {
        final String city = originalArticle.optString(Article.ARTICLE_CITY);

        if (StringUtils.isNotBlank(city)) {
          final JSONObject requestJSONObject = new JSONObject();
          requestJSONObject.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, 1);
          requestJSONObject.put(Pagination.PAGINATION_PAGE_SIZE, Integer.MAX_VALUE);
          requestJSONObject.put(Pagination.PAGINATION_WINDOW_SIZE, Integer.MAX_VALUE);

          final long latestLoginTime = DateUtils.addDays(new Date(), -15).getTime();
          requestJSONObject.put(UserExt.USER_LATEST_LOGIN_TIME, latestLoginTime);
          requestJSONObject.put(UserExt.USER_CITY, city);

          final JSONObject result = userQueryService.getUsersByCity(requestJSONObject);
          final JSONArray users = result.optJSONArray(User.USERS);

          for (int i = 0; i < users.length(); i++) {
            final String userId = users.optJSONObject(i).optString(Keys.OBJECT_ID);

            if (userId.equals(articleAuthorId)) {
              continue;
            }

            final JSONObject notification = new JSONObject();
            notification.put(Notification.NOTIFICATION_USER_ID, userId);
            notification.put(Notification.NOTIFICATION_DATA_ID, articleId);

            notificationMgmtService.addBroadcastNotification(notification);
          }

          LOGGER.info("City broadcast [" + users.length() + "]");
        }
      }
    } catch (final Exception e) {
      LOGGER.log(Level.ERROR, "Sends the article notification failed", e);
    }
  }
Example #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);
    }
  }
Example #4
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, ArticleSender.class.getName()});
    try {
      final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);

      if (!originalArticle.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
        LOGGER.log(
            Level.DEBUG,
            "Ignores post article[title={0}] to Rhythm",
            originalArticle.getString(Article.ARTICLE_TITLE));

        return;
      }

      final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
      final PreferenceQueryService preferenceQueryService =
          beanManager.getReference(PreferenceQueryService.class);

      final JSONObject preference = preferenceQueryService.getPreference();

      if (null == preference) {
        throw new EventException("Not found preference");
      }

      if (!Strings.isEmptyOrNull(originalArticle.optString(Article.ARTICLE_VIEW_PWD))) {
        return;
      }

      if (Latkes.getServePath().contains("localhost")) {
        LOGGER.log(
            Level.INFO,
            "Solo runs on local server, so should not send this article[id={0}, title={1}] to Rhythm",
            new Object[] {
              originalArticle.getString(Keys.OBJECT_ID),
              originalArticle.getString(Article.ARTICLE_TITLE)
            });
        return;
      }

      final HTTPRequest httpRequest = new HTTPRequest();

      httpRequest.setURL(ADD_ARTICLE_URL);
      httpRequest.setRequestMethod(HTTPRequestMethod.POST);
      final JSONObject requestJSONObject = new JSONObject();
      final JSONObject article = new JSONObject();

      article.put(Keys.OBJECT_ID, originalArticle.getString(Keys.OBJECT_ID));
      article.put(Article.ARTICLE_TITLE, originalArticle.getString(Article.ARTICLE_TITLE));
      article.put(Article.ARTICLE_PERMALINK, originalArticle.getString(Article.ARTICLE_PERMALINK));
      article.put(Article.ARTICLE_TAGS_REF, originalArticle.getString(Article.ARTICLE_TAGS_REF));
      article.put(
          Article.ARTICLE_AUTHOR_EMAIL, originalArticle.getString(Article.ARTICLE_AUTHOR_EMAIL));
      article.put(Article.ARTICLE_CONTENT, originalArticle.getString(Article.ARTICLE_CONTENT));
      article.put(
          Article.ARTICLE_CREATE_DATE,
          ((Date) originalArticle.get(Article.ARTICLE_CREATE_DATE)).getTime());
      article.put(Common.POST_TO_COMMUNITY, originalArticle.getBoolean(Common.POST_TO_COMMUNITY));

      // Removes this property avoid to persist
      originalArticle.remove(Common.POST_TO_COMMUNITY);

      requestJSONObject.put(Article.ARTICLE, article);
      requestJSONObject.put(Common.BLOG_VERSION, SoloServletListener.VERSION);
      requestJSONObject.put(Common.BLOG, "B3log Solo");
      requestJSONObject.put(Option.ID_C_BLOG_TITLE, preference.getString(Option.ID_C_BLOG_TITLE));
      requestJSONObject.put("blogHost", Latkes.getServePath());
      requestJSONObject.put("userB3Key", preference.optString(Option.ID_C_KEY_OF_SOLO));
      requestJSONObject.put("clientAdminEmail", preference.optString(Option.ID_C_ADMIN_EMAIL));
      requestJSONObject.put("clientRuntimeEnv", Latkes.getRuntimeEnv().name());

      httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));

      urlFetchService.fetchAsync(httpRequest);
    } catch (final Exception e) {
      LOGGER.log(Level.ERROR, "Sends an article to Rhythm error: {0}", e.getMessage());
    }

    LOGGER.log(Level.DEBUG, "Sent an article to Rhythm");
  }