Commit c72aac50 authored by Liang Ding's avatar Liang Ding

Fix #12040

parent a37c0763
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: Solo POM. Description: Solo POM.
Version: 2.6.1.7, Oct 25, 2015 Version: 2.7.1.7, Nov 5, 2015
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<artifactId>solo</artifactId> <artifactId>solo</artifactId>
<packaging>war</packaging> <packaging>war</packaging>
<name>Solo</name> <name>Solo</name>
<version>1.1.0</version> <version>1.2.0</version>
<description> <description>
A Java blogging system, feel free to create your or your team own blog. A Java blogging system, feel free to create your or your team own blog.
</description> </description>
......
...@@ -47,6 +47,7 @@ import org.b3log.solo.repository.PreferenceRepository; ...@@ -47,6 +47,7 @@ import org.b3log.solo.repository.PreferenceRepository;
import org.b3log.solo.repository.impl.PreferenceRepositoryImpl; import org.b3log.solo.repository.impl.PreferenceRepositoryImpl;
import org.b3log.solo.service.PreferenceMgmtService; import org.b3log.solo.service.PreferenceMgmtService;
import org.b3log.solo.service.StatisticMgmtService; import org.b3log.solo.service.StatisticMgmtService;
import org.b3log.solo.service.UpgradeService;
import org.b3log.solo.util.Skins; import org.b3log.solo.util.Skins;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -54,7 +55,7 @@ import org.json.JSONObject; ...@@ -54,7 +55,7 @@ import org.json.JSONObject;
* Solo Servlet listener. * Solo Servlet listener.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.5.0.9, Oct 31, 2015 * @version 1.6.0.9, Nov 5, 2015
* @since 0.3.1 * @since 0.3.1
*/ */
public final class SoloServletListener extends AbstractServletListener { public final class SoloServletListener extends AbstractServletListener {
...@@ -62,7 +63,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -62,7 +63,7 @@ public final class SoloServletListener extends AbstractServletListener {
/** /**
* Solo version. * Solo version.
*/ */
public static final String VERSION = "1.1.0"; public static final String VERSION = "1.2.0";
/** /**
* Logger. * Logger.
...@@ -114,6 +115,10 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -114,6 +115,10 @@ public final class SoloServletListener extends AbstractServletListener {
beanManager = Lifecycle.getBeanManager(); beanManager = Lifecycle.getBeanManager();
Stopwatchs.start("Context Initialized"); Stopwatchs.start("Context Initialized");
// Upgrade check (https://github.com/b3log/solo/issues/12040)
final UpgradeService upgradeService = beanManager.getReference(UpgradeService.class);
upgradeService.upgrade();
// Set default skin, loads from preference later // Set default skin, loads from preference later
Skins.setDirectoryForTemplateLoading(Preference.Default.DEFAULT_SKIN_DIR_NAME); Skins.setDirectoryForTemplateLoading(Preference.Default.DEFAULT_SKIN_DIR_NAME);
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package org.b3log.solo.api.symphony; package org.b3log.solo.api.symphony;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Date; import java.util.Date;
...@@ -54,12 +53,11 @@ import org.b3log.solo.util.Comments; ...@@ -54,12 +53,11 @@ import org.b3log.solo.util.Comments;
import org.b3log.solo.util.QueryResults; import org.b3log.solo.util.QueryResults;
import org.json.JSONObject; import org.json.JSONObject;
/** /**
* Comment receiver (from B3log Symphony). * Comment receiver (from B3log Symphony).
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.8, Jul 10, 2014 * @version 1.1.0.9, Nov 5, 2015
* @since 0.5.5 * @since 0.5.5
*/ */
@RequestProcessor @RequestProcessor
...@@ -134,8 +132,7 @@ public class CommentReceiver { ...@@ -134,8 +132,7 @@ public class CommentReceiver {
* </pre> * </pre>
* </p> * </p>
* *
* @param request the specified http servlet request, for example, * @param request the specified http servlet request, for example, <pre>
* <pre>
* { * {
* "comment": { * "comment": {
* "userB3Key": "", * "userB3Key": "",
...@@ -157,7 +154,7 @@ public class CommentReceiver { ...@@ -157,7 +154,7 @@ public class CommentReceiver {
*/ */
@RequestProcessing(value = "/apis/symphony/comment", method = HTTPRequestMethod.PUT) @RequestProcessing(value = "/apis/symphony/comment", method = HTTPRequestMethod.PUT)
public void addComment(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context) public void addComment(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context)
throws Exception { throws Exception {
final JSONRenderer renderer = new JSONRenderer(); final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -210,8 +207,8 @@ public class CommentReceiver { ...@@ -210,8 +207,8 @@ public class CommentReceiver {
String commentContent = symphonyCmt.getString(Comment.COMMENT_CONTENT); String commentContent = symphonyCmt.getString(Comment.COMMENT_CONTENT);
commentContent += "<p class='cmtFromSym'><i>该评论同步自 <a href='" + SoloServletListener.B3LOG_SYMPHONY_SERVE_PATH commentContent += "<p class='cmtFromSym'><i>该评论同步自 <a href='" + SoloServletListener.B3LOG_SYMPHONY_SERVE_PATH
+ "/article/" + symphonyCmt.optString("commentSymphonyArticleId") + "#" + commentId + "/article/" + symphonyCmt.optString("commentSymphonyArticleId") + "#" + commentId
+ "' target='_blank'>黑客派</a></i></p>"; + "' target='_blank'>黑客派</a></i></p>";
final String originalCommentId = symphonyCmt.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID); final String originalCommentId = symphonyCmt.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
// Step 1: Add comment // Step 1: Add comment
final JSONObject comment = new JSONObject(); final JSONObject comment = new JSONObject();
...@@ -238,14 +235,14 @@ public class CommentReceiver { ...@@ -238,14 +235,14 @@ public class CommentReceiver {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, "");
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, "");
LOGGER.log(Level.WARN, "Not found orginal comment[id={0}] of reply[name={1}, content={2}]", LOGGER.log(Level.WARN, "Not found orginal comment[id={0}] of reply[name={1}, content={2}]",
new String[] {originalCommentId, commentName, commentContent}); new String[]{originalCommentId, commentName, commentContent});
} }
} else { } else {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, "");
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, "");
} }
CommentMgmtService.setCommentThumbnailURL(comment); commentMgmtService.setCommentThumbnailURL(comment);
ret.put(Comment.COMMENT_THUMBNAIL_URL, comment.getString(Comment.COMMENT_THUMBNAIL_URL)); ret.put(Comment.COMMENT_THUMBNAIL_URL, comment.getString(Comment.COMMENT_THUMBNAIL_URL));
// Sets comment on article.... // Sets comment on article....
comment.put(Comment.COMMENT_ON_ID, articleId); comment.put(Comment.COMMENT_ON_ID, articleId);
......
...@@ -44,6 +44,7 @@ import org.b3log.solo.model.*; ...@@ -44,6 +44,7 @@ import org.b3log.solo.model.*;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository; import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.util.Comments; import org.b3log.solo.util.Comments;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.json.JSONException; import org.json.JSONException;
...@@ -53,7 +54,7 @@ import org.json.JSONObject; ...@@ -53,7 +54,7 @@ import org.json.JSONObject;
* Comment management service. * Comment management service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.6, Oct 1, 2015 * @version 1.1.0.7, Nov 5, 2015
* @since 0.3.5 * @since 0.3.5
*/ */
@Service @Service
...@@ -82,6 +83,12 @@ public class CommentMgmtService { ...@@ -82,6 +83,12 @@ public class CommentMgmtService {
@Inject @Inject
private ArticleRepository articleRepository; private ArticleRepository articleRepository;
/**
* User repository.
*/
@Inject
private UserRepository userRepository;
/** /**
* Statistic management service. * Statistic management service.
*/ */
...@@ -709,15 +716,31 @@ public class CommentMgmtService { ...@@ -709,15 +716,31 @@ public class CommentMgmtService {
* Sets commenter thumbnail URL for the specified comment. * Sets commenter thumbnail URL for the specified comment.
* *
* <p> * <p>
* Try to set thumbnail URL using Gravatar service. * Try to set thumbnail URL using:
* <ol>
* <li>User avatar</li>
* <li>Gravatar service</li>
* <ol>
* </p> * </p>
* *
* @param comment the specified comment * @param comment the specified comment
* @throws Exception exception * @throws Exception exception
*/ */
public static void setCommentThumbnailURL(final JSONObject comment) throws Exception { public void setCommentThumbnailURL(final JSONObject comment) throws Exception {
final String commentEmail = comment.getString(Comment.COMMENT_EMAIL); final String commentEmail = comment.getString(Comment.COMMENT_EMAIL);
// 1. user avatar
final JSONObject user = userRepository.getByEmail(commentEmail);
if (null != user) {
final String avatar = user.optString(UserExt.USER_AVATAR);
if (!Strings.isEmptyOrNull(avatar)) {
comment.put(Comment.COMMENT_THUMBNAIL_URL, avatar);
return;
}
}
// 2. Gravatar
String thumbnailURL = Thumbnails.getGravatarURL(commentEmail.toLowerCase(), "60"); String thumbnailURL = Thumbnails.getGravatarURL(commentEmail.toLowerCase(), "60");
final URL gravatarURL = new URL(thumbnailURL); final URL gravatarURL = new URL(thumbnailURL);
......
...@@ -41,6 +41,7 @@ import org.b3log.solo.model.Page; ...@@ -41,6 +41,7 @@ import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository; import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.util.Thumbnails;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -49,7 +50,7 @@ import org.json.JSONObject; ...@@ -49,7 +50,7 @@ import org.json.JSONObject;
* Comment query service. * Comment query service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.5, Feb 28, 2014 * @version 1.0.0.6, Nov 5, 2015
* @since 0.3.5 * @since 0.3.5
*/ */
@Service @Service
...@@ -242,6 +243,10 @@ public class CommentQueryService { ...@@ -242,6 +243,10 @@ public class CommentQueryService {
comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME))); comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME)));
comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL))); comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL)));
comment.put(Common.IS_REPLY, false); // Assumes this comment is not a reply comment.put(Common.IS_REPLY, false); // Assumes this comment is not a reply
final String email = comment.optString(Comment.COMMENT_EMAIL);
comment.put(Comment.COMMENT_THUMBNAIL_URL, Thumbnails.getGravatarURL(email, "60"));
if (!Strings.isEmptyOrNull(comment.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID))) { if (!Strings.isEmptyOrNull(comment.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID))) {
// This comment is a reply // This comment is a reply
......
...@@ -13,48 +13,47 @@ ...@@ -13,48 +13,47 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.processor; package org.b3log.solo.service;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService; import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailServiceFactory; import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.*; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.jdbc.util.Connections;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.service.annotation.Service;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.TextHTMLRenderer;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*; import org.b3log.solo.model.*;
import org.b3log.solo.repository.*; import org.b3log.solo.repository.*;
import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
/** /**
* Upgrader. * Upgrade service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a> * @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.5.1.14, Oct 17, 2015 * @version 1.0.0.0, Nov 5, 2015
* @since 0.3.1 * @since 1.2.0
*/ */
@RequestProcessor @Service
public class UpgradeProcessor { public class UpgradeService {
/** /**
* Logger. * Logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(UpgradeProcessor.class.getName()); private static final Logger LOGGER = Logger.getLogger(UpgradeService.class.getName());
/** /**
* Article repository. * Article repository.
...@@ -104,7 +103,7 @@ public class UpgradeProcessor { ...@@ -104,7 +103,7 @@ public class UpgradeProcessor {
/** /**
* Old version. * Old version.
*/ */
private static final String FROM_VER = "1.0.0"; private static final String FROM_VER = "1.1.0";
/** /**
* New version. * New version.
...@@ -113,27 +112,17 @@ public class UpgradeProcessor { ...@@ -113,27 +112,17 @@ public class UpgradeProcessor {
/** /**
* Checks upgrade. * Checks upgrade.
*
* @param context the specified context
*/ */
@RequestProcessing(value = "/upgrade/checker.do", method = HTTPRequestMethod.GET) public void upgrade() {
public void upgrade(final HTTPRequestContext context) {
final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer);
try { try {
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE); final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
if (null == preference) { if (null == preference) {
LOGGER.log(Level.INFO, "Not init yet"); LOGGER.log(Level.INFO, "Not init yet");
renderer.setContent("Not init yet");
return; return;
} }
renderer.setContent("Upgrade successfully ;-)");
final String currentVer = preference.getString(Preference.VERSION); final String currentVer = preference.getString(Preference.VERSION);
if (SoloServletListener.VERSION.equals(currentVer)) { if (SoloServletListener.VERSION.equals(currentVer)) {
...@@ -141,7 +130,7 @@ public class UpgradeProcessor { ...@@ -141,7 +130,7 @@ public class UpgradeProcessor {
} }
if (FROM_VER.equals(currentVer)) { if (FROM_VER.equals(currentVer)) {
upgrade(); perform();
return; return;
} }
...@@ -154,11 +143,9 @@ public class UpgradeProcessor { ...@@ -154,11 +143,9 @@ public class UpgradeProcessor {
sent = true; sent = true;
} }
renderer.setContent(langPropsService.get("skipVersionAlert"));
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
LOGGER.log(Level.ERROR,
renderer.setContent(
"Upgrade failed [" + e.getMessage() + "], please contact the Solo developers or reports this " "Upgrade failed [" + e.getMessage() + "], please contact the Solo developers or reports this "
+ "issue directly (<a href='https://github.com/b3log/solo/issues/new'>" + "issue directly (<a href='https://github.com/b3log/solo/issues/new'>"
+ "https://github.com/b3log/solo/issues/new</a>) "); + "https://github.com/b3log/solo/issues/new</a>) ");
...@@ -166,20 +153,29 @@ public class UpgradeProcessor { ...@@ -166,20 +153,29 @@ public class UpgradeProcessor {
} }
/** /**
* Upgrades. * Performs upgrade.
* *
* @throws Exception upgrade fails * @throws Exception upgrade fails
*/ */
private void upgrade() throws Exception { private void perform() throws Exception {
LOGGER.log(Level.INFO, "Upgrading from version [{0}] to version [{1}]....", FROM_VER, TO_VER); LOGGER.log(Level.INFO, "Upgrading from version [{0}] to version [{1}]....", FROM_VER, TO_VER);
Transaction transaction = null; Transaction transaction = null;
try { try {
final Connection connection = Connections.getConnection();
final Statement statement = connection.createStatement();
final String tablePrefix = Latkes.getLocalProperty("jdbc.tablePrefix") + "_";
statement.execute("ALTER TABLE `" + tablePrefix + "user` ADD COLUMN `userAvatar` varchar(255)");
statement.close();
connection.commit();
connection.close();
transaction = userRepository.beginTransaction(); transaction = userRepository.beginTransaction();
upgradeUsers(); upgradeUsers();
// Upgrades preference model // Upgrades preference model
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE); final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
...@@ -221,7 +217,7 @@ public class UpgradeProcessor { ...@@ -221,7 +217,7 @@ public class UpgradeProcessor {
userRepository.update(user.optString(Keys.OBJECT_ID), user); userRepository.update(user.optString(Keys.OBJECT_ID), user);
LOGGER.log(Level.INFO, "Updated user[name={0}]"); LOGGER.log(Level.INFO, "Updated user[email={0}]", email);
} }
} }
......
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
# #
# Description: B3log configurations. # Description: B3log configurations.
# Version: 1.2.0.0, May 19, 2015 # Version: 1.2.0.0, Nov 5, 2015
# Author: Liang Ding # Author: Liang Ding
# #
rhythm.servePath=http://rhythm.b3log.org:80 rhythm.servePath=http://rhythm.b3log.org:80
symphony.servePath=http://hacpai.com:80 symphony.servePath=http://hacpai.com:80
gravatar=http://gravatar.duoshuo.com/avatar/ gravatar=https://secure.gravatar.com/avatar/
faviconAPI=http://api.byi.pw/favicon?url= faviconAPI=http://api.byi.pw/favicon?url=
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: Solo logging configurations. # Description: Solo logging configurations.
# Version: 1.1.0.3, Oct 31, 2015 # Version: 1.1.0.4, Nov 5, 2015
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -34,3 +34,4 @@ log4j.logger.org.b3log.latke.util.freemarker.Templates=ERROR ...@@ -34,3 +34,4 @@ log4j.logger.org.b3log.latke.util.freemarker.Templates=ERROR
log4j.logger.org.eclipse.jetty=WARN log4j.logger.org.eclipse.jetty=WARN
log4j.logger.freemarker=WARN log4j.logger.freemarker=WARN
log4j.logger.com.mchange=WARN
...@@ -20,12 +20,12 @@ ...@@ -20,12 +20,12 @@
Description: Web deployment descriptor on GAE. See Description: Web deployment descriptor on GAE. See
http://code.google.com/intl/en/appengine/docs/java/config/appconfig.html http://code.google.com/intl/en/appengine/docs/java/config/appconfig.html
for more details. for more details.
Version: 1.4.5.6, Oct 1, 2015 Version: 1.5.5.6, Nov 5, 2015
Author: Liang Ding Author: Liang Ding
--> -->
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>solo-demo</application> <application>solo-demo</application>
<version>110</version> <version>120</version>
<sessions-enabled>true</sessions-enabled> <sessions-enabled>true</sessions-enabled>
......
...@@ -18,17 +18,11 @@ ...@@ -18,17 +18,11 @@
--> -->
<!-- <!--
Description: Cron job configurations. Description: Cron job configurations.
Version: 1.0.1.4, Feb 11, 2015 Version: 1.0.1.5, Nov 5, 2015
Author: Liang Ding Author: Liang Ding
--> -->
<cronentries> <cronentries>
<cron>
<url>/upgrade/checker.do</url>
<description>Upgrade checker, see issue 257 (http://code.google.com/p/b3log-solo/issues/detail?id=257).</description>
<schedule>every 60 minutes</schedule>
</cron>
<cron> <cron>
<url>/console/stat/onlineVisitorRefresh</url> <url>/console/stat/onlineVisitorRefresh</url>
<description>Online Visitor Refresher</description> <description>Online Visitor Refresher</description>
...@@ -40,12 +34,5 @@ ...@@ -40,12 +34,5 @@
<description>Sync user to http://hacpai.com</description> <description>Sync user to http://hacpai.com</description>
<schedule>every 24 hours</schedule> <schedule>every 24 hours</schedule>
</cron> </cron>
<!-- http://code.google.com/p/b3log-solo/issues/detail?id=308#c4
<cron>
<url>/article-random-double-gen.do?cnt=10</url>
<description>Regenerate article random double.</description>
<schedule>every 1 hours</schedule>
</cron>
-->
</cronentries> </cronentries>
var Page=function(tips){this.currentCommentId="";this.tips=tips};$.extend(Page.prototype,{insertEmotions:function(name){var _it=this;if(name===undefined){name=""}$("#emotions"+name+" span").click(function(){var $comment=$("#comment"+name);var endPosition=_it._getCursorEndPosition($comment[0]);var key="["+this.className+"]",textValue=$comment[0].value;textValue=textValue.substring(0,endPosition)+key+textValue.substring(endPosition,textValue.length);$("#comment"+name).val(textValue);if($.browser.msie){endPosition-=textValue.split("\n").length-1;var oR=$comment[0].createTextRange();oR.collapse(true);oR.moveStart("character",endPosition+6);oR.select()}else{$comment[0].setSelectionRange(endPosition+6,endPosition+6)}})},_getCursorEndPosition:function(textarea){textarea.focus();if(textarea.setSelectionRange){return textarea.selectionEnd}else{if(document.selection){var i=0,oS=document.selection.createRange(),oR=document.body.createTextRange();oR.moveToElementText(textarea);oS.getBookmark();for(i=0;oR.compareEndPoints("StartToStart",oS)<0&&oS.moveStart("character",-1)!==0;i++){if(textarea.value.charAt(i)==="\n"){i++}}return i}}},validateComment:function(state){if(Util.isLoggedIn()){var commenterContent=$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"");if(2>commenterContent.length||commenterContent.length>500){$("#commentErrorTip"+state).html(this.tips.commentContentCannotEmptyLabel);$("#comment"+state).focus()}else{return true}$("#commentErrorTip"+state).show();return false}var commentName=$("#commentName"+state).val().replace(/(^\s*)|(\s*$)/g,""),commenterContent=$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"");if(2>commentName.length||commentName.length>20){$("#commentErrorTip"+state).html(this.tips.nameTooLongLabel);$("#commentName"+state).focus()}else{if($("#commentEmail"+state).val().replace(/\s/g,"")===""){$("#commentErrorTip"+state).html(this.tips.mailCannotEmptyLabel);$("#commentEmail"+state).focus()}else{if(!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#commentEmail"+state).val())){$("#commentErrorTip"+state).html(this.tips.mailInvalidLabel);$("#commentEmail"+state).focus()}else{if(2>commenterContent.length||commenterContent.length>500){$("#commentErrorTip"+state).html(this.tips.commentContentCannotEmptyLabel);$("#comment"+state).focus()}else{if($("#commentValidate"+state).val().replace(/\s/g,"")===""){$("#commentErrorTip"+state).html(this.tips.captchaCannotEmptyLabel);$("#commentValidate"+state).focus()}else{return true}}}}}$("#commentErrorTip"+state).show();return false},replaceCommentsEm:function(selector){var $commentContents=$(selector);for(var i=0;i<$commentContents.length;i++){var str=$commentContents[i].innerHTML;$commentContents[i].innerHTML=Util.replaceEmString(str)}},_initSyntaxHighlighter:function(languages){for(var i=0;i<languages.length;i++){switch(languages[i]){case"groovy":languages[i]="groovy "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushGroovy.js";break;case"java":languages[i]="java "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJava.js";break;case"php":languages[i]="php "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPhp.js";break;case"scala":languages[i]="scala "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushScala.js";break;case"sql":languages[i]="sql "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushSql.js";break;case"applescript":languages[i]="applescript "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushAppleScript.js";break;case"as3":case"actionscript3":languages[i]="actionscript3 as3 "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushAS3.js";break;case"bash":case"shell":languages[i]="bash shell "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushBash.js";break;case"coldfusion":case"cf":languages[i]="coldfusion cf "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushColdFusion.js";break;case"c#":case"c-sharp":case"csharp":languages[i]="c# c-sharp csharp "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCSharp.js";break;case"cpp":case"c":languages[i]="cpp c "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCpp.js";break;case"css":languages[i]="css "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCss.js";break;case"delphi":case"pascal":languages[i]="delphi pascal "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushDelphi.js";break;case"diff":case"patch":case"pas":languages[i]="diff patch pas "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushDiff.js";break;case"erl":case"erlang":languages[i]="erl erlang "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushErlang.js";break;case"js":case"jscript":case"javascript":languages[i]="js jscript javascript "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJScript.js";break;case"jfx":case"javafx":languages[i]="jfx javafx "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJavaFX.js";break;case"perl":case"pl":languages[i]="perl pl "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPerl.js";break;case"plain":case"text":languages[i]="text plain "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPlain.js";break;case"ps":case"powershell":languages[i]="ps powershell "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPowerShell.js";break;case"py":case"python":languages[i]="py python "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPython.js";break;case"rails":case"ror":case"ruby":case"rb":languages[i]="ruby rails ror rb "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushRuby.js";break;case"sass":case"scss":languages[i]="sass scss "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushSass.js";break;case"vb":case"vbnet":languages[i]="vb vbnet "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushVb.js";break;case"xml":case"xhtml":case"xslt":case"html":languages[i]="xml xhtml xslt html "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushXml.js";break;default:break}}SyntaxHighlighter.autoloader.apply(null,languages);SyntaxHighlighter.config.stripBrs=true;SyntaxHighlighter.all()},_loadSyntaxHighlighter:function(SHTheme){var cssName=SHTheme?SHTheme:"shCoreEclipse",that=this;if(document.createStyleSheet){document.createStyleSheet(latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/styles/"+cssName+".css")}else{$("head").append($("<link rel='stylesheet' href='"+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/styles/"+cssName+".css' type='text/css' charset='utf-8' />"))}$.ajax({url:latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shCore.js",dataType:"script",cache:true,success:function(){var languages=[],isScrip=false;$(".article-body pre, .code-highlight pre").each(function(){var name=this.className.split(";")[0];var language=name.substr(7,name.length-1);if(this.className.indexOf("html-script: true")>-1&&(language!=="xml"&&language!=="xhtml"&&language!=="xslt"&&language!="html")){isScrip=true}languages.push(language)});if(isScrip){$.ajax({url:latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushXml.js",dataType:"script",cache:true,success:function(){that._initSyntaxHighlighter(languages)}})}else{that._initSyntaxHighlighter(languages)}}})},parseLanguage:function(obj){var isPrettify=false,isSH=false;$(".article-body pre, .code-highlight pre").each(function(){if(this.className.indexOf("brush")>-1){isSH=true}if(this.className.indexOf("prettyprint")>-1){isPrettify=true}});if(isSH){this._loadSyntaxHighlighter(obj?(obj.SHTheme?obj.SHTheme:undefined):undefined)}if(isPrettify){if(document.createStyleSheet){document.createStyleSheet(latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.css")}else{$("head").append($("<link rel='stylesheet' href='"+latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.css'>"))}$.ajax({url:latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.js",dataType:"script",cache:true,success:function(){prettyPrint()}})}},load:function(obj){var that=this;that.insertEmotions();that.parseLanguage(obj?(obj.language?obj.language:undefined):undefined);$("#commentValidate").keypress(function(event){if(event.keyCode===13){that.submitComment()}});$("#comment").keypress(function(event){if(event.keyCode===13&&event.ctrlKey){that.submitComment()}});$("#captcha").click(function(){$(this).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())});if(!Util.isLoggedIn()){$("#commentEmail").val(Cookie.readCookie("commentEmail"));$("#commentURL").val(Cookie.readCookie("commentURL"));$("#commentName").val(Cookie.readCookie("commentName"))}try{JSON}catch(e){document.write('<script src="'+latkeConfig.staticServePath+'/js/lib/json2.js"><\/script>')}},loadRandomArticles:function(headTitle){var randomArticles1Label=this.tips.randomArticles1Label;$.ajax({url:latkeConfig.servePath+"/get-random-articles.do",type:"POST",success:function(result,textStatus){var randomArticles=result.randomArticles;if(!randomArticles||0===randomArticles.length){$("#randomArticles").remove();return}var listHtml="";for(var i=0;i<randomArticles.length;i++){var article=randomArticles[i];var title=article.articleTitle;var randomArticleLiHtml="<li><a rel='nofollow' title='"+title+"' href='"+latkeConfig.servePath+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=randomArticleLiHtml}var titleHTML=headTitle?headTitle:"<h4>"+randomArticles1Label+"</h4>";var randomArticleListHtml=titleHTML+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#randomArticles").append(randomArticleListHtml)}})},loadRelevantArticles:function(id,headTitle){$.ajax({url:latkeConfig.servePath+"/article/id/"+id+"/relevant/articles",type:"GET",success:function(data,textStatus){var articles=data.relevantArticles;if(!articles||0===articles.length){$("#relevantArticles").remove();return}var listHtml="";for(var i=0;i<articles.length;i++){var article=articles[i];var title=article.articleTitle;var articleLiHtml="<li><a rel='nofollow' title='"+title+"' href='"+latkeConfig.servePath+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=articleLiHtml}var relevantArticleListHtml=headTitle+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#relevantArticles").append(relevantArticleListHtml)},error:function(){$("#relevantArticles").remove()}})},loadExternalRelevantArticles:function(tags,headTitle){var tips=this.tips;try{$.ajax({url:"http://rhythm.b3log.org:80/get-articles-by-tags.do?tags="+tags+"&blogHost="+tips.blogHost+"&paginationPageSize="+tips.externalRelevantArticlesDisplayCount,type:"GET",cache:true,dataType:"jsonp",error:function(){$("#externalRelevantArticles").remove()},success:function(data,textStatus){var articles=data.articles;if(!articles||0===articles.length){$("#externalRelevantArticles").remove();return}var listHtml="";for(var i=0;i<articles.length;i++){var article=articles[i];var title=article.articleTitle;var articleLiHtml="<li><a rel='nofollow' title='"+title+"' target='_blank' href='"+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=articleLiHtml}var titleHTML=headTitle?headTitle:"<h4>"+tips.externalRelevantArticles1Label+"</h4>";var randomArticleListHtml=titleHTML+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#externalRelevantArticles").append(randomArticleListHtml)}})}catch(e){}},submitComment:function(commentId,state){if(!state){state=""}var that=this,tips=this.tips,type="article";if(tips.externalRelevantArticlesDisplayCount===undefined){type="page"}if(this.validateComment(state)){$("#submitCommentButton"+state).attr("disabled","disabled");$("#commentErrorTip"+state).show().html(this.tips.loadingLabel);var requestJSONObject={oId:tips.oId,commentContent:$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"")};if(!Util.isLoggedIn()){requestJSONObject={oId:tips.oId,commentContent:$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,""),commentEmail:$("#commentEmail"+state).val(),commentURL:Util.proessURL($("#commentURL"+state).val().replace(/(^\s*)|(\s*$)/g,"")),commentName:$("#commentName"+state).val().replace(/(^\s*)|(\s*$)/g,""),captcha:$("#commentValidate"+state).val()};Cookie.createCookie("commentName",requestJSONObject.commentName,365);Cookie.createCookie("commentEmail",requestJSONObject.commentEmail,365);Cookie.createCookie("commentURL",$("#commentURL"+state).val().replace(/(^\s*)|(\s*$)/g,""),365)}if(state==="Reply"){requestJSONObject.commentOriginalCommentId=commentId}$.ajax({type:"POST",url:latkeConfig.servePath+"/add-"+type+"-comment.do",cache:false,contentType:"application/json",data:JSON.stringify(requestJSONObject),success:function(result){if(!result.sc){$("#commentErrorTip"+state).html(result.msg);$("#comment"+state).val("").focus();$("#submitCommentButton"+state).removeAttr("disabled");if(!Util.isLoggedIn()){$("#captcha"+state).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())}return}result.replyNameHTML="";if(!Util.isLoggedIn()){$("#captcha"+state).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random());if($("#commentURL"+state).val().replace(/\s/g,"")===""){result.replyNameHTML="<a>"+$("#commentName"+state).val()+"</a>"}else{result.replyNameHTML='<a href="'+Util.proessURL($("#commentURL"+state).val())+'" target="_blank">'+$("#commentName"+state).val()+"</a>"}result.userName=$("#commentName"+state).val()}else{result.replyNameHTML='<a href="'+window.location.host+'" target="_blank">'+Util.getUserName()+"</a>";result.userName=Util.getUserName()}that.addCommentAjax(addComment(result,state),state);$("#submitCommentButton"+state).removeAttr("disabled")}})}},addReplyForm:function(id,commentFormHTML,endHTML){var that=this;if(id===this.currentCommentId){if($("#commentNameReply").val()===""){$("#commentNameReply").focus()}else{if($("#commentEmailReply").val()===""){$("#commentEmailReply").focus()}else{$("#commentReply").focus()}}return}$("#replyForm").remove();endHTML=endHTML?endHTML:"";if(endHTML==="</div>"){$("#"+id).append(commentFormHTML+$("#commentForm").html()+endHTML)}else{$("#"+id).append(commentFormHTML+$("#commentForm").html()+"</table>"+endHTML)}$("#replyForm input, #replyForm textarea").each(function(){this.id=this.id+"Reply"});$("#commentNameReply").val(Cookie.readCookie("commentName"));$("#commentEmailReply").val(Cookie.readCookie("commentEmail"));var $label=$("#replyForm #commentURLLabel");if($label.length===1){$label.attr("id","commentURLLabelReply")}$("#commentURLReply").val(Cookie.readCookie("commentURL"));$("#replyForm #emotions").attr("id","emotionsReply");this.insertEmotions("Reply");$("#commentReply").unbind().keypress(function(event){if(event.keyCode===13&&event.ctrlKey){that.submitComment(id,"Reply");event.preventDefault()}});$("#commentValidateReply").unbind().keypress(function(event){if(event.keyCode===13){that.submitComment(id,"Reply");event.preventDefault()}});$("#replyForm #captcha").attr("id","captchaReply").attr("src",latkeConfig.servePath+"/captcha.do?"+new Date().getTime()).click(function(){$(this).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())});$("#replyForm #commentErrorTip").attr("id","commentErrorTipReply").html("").hide();$("#replyForm #submitCommentButton").attr("id","submitCommentButtonReply");$("#replyForm #submitCommentButtonReply").unbind("click").removeAttr("onclick").click(function(){that.submitComment(id,"Reply")});if($("#commentNameReply").val()===""){$("#commentNameReply").focus()}else{if($("#commentEmailReply").val()===""){$("#commentEmailReply").focus()}else{$("#commentReply").focus()}}this.currentCommentId=id},hideComment:function(id){$("#commentRef"+id).hide()},showComment:function(it,id,top,parentTag){var positionTop=parseInt($(it).position().top);if(parentTag){positionTop=parseInt($(it).parents(parentTag).position().top)}if($("#commentRef"+id).length>0){$("#commentRef"+id).show().css("top",(positionTop+top)+"px")}else{var $refComment=$("#"+id).clone();$refComment.addClass("comment-body-ref").attr("id","commentRef"+id);$refComment.find("#replyForm").remove();$("#comments").append($refComment);$("#commentRef"+id).css("top",(positionTop+top)+"px")}},addCommentAjax:function(commentHTML,state){if($("#comments").children().length>0){$($("#comments").children()[0]).before(commentHTML)}else{$("#comments").html(commentHTML)}if(state===""){$("#commentErrorTip").html("").hide();$("#comment").val("");$("#commentValidate").val("");$("#captcha").attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())}else{$("#replyForm").remove()}window.location.hash="#comments"}}); var Page=function(tips){this.currentCommentId="";this.tips=tips};$.extend(Page.prototype,{insertEmotions:function(name){var _it=this;if(name===undefined){name=""}$("#emotions"+name+" span").click(function(){var $comment=$("#comment"+name);var endPosition=_it._getCursorEndPosition($comment[0]);var key="["+this.className+"]",textValue=$comment[0].value;textValue=textValue.substring(0,endPosition)+key+textValue.substring(endPosition,textValue.length);$("#comment"+name).val(textValue);if($.browser.msie){endPosition-=textValue.split("\n").length-1;var oR=$comment[0].createTextRange();oR.collapse(true);oR.moveStart("character",endPosition+6);oR.select()}else{$comment[0].setSelectionRange(endPosition+6,endPosition+6)}})},_getCursorEndPosition:function(textarea){textarea.focus();if(textarea.setSelectionRange){return textarea.selectionEnd}else{if(document.selection){var i=0,oS=document.selection.createRange(),oR=document.body.createTextRange();oR.moveToElementText(textarea);oS.getBookmark();for(i=0;oR.compareEndPoints("StartToStart",oS)<0&&oS.moveStart("character",-1)!==0;i++){if(textarea.value.charAt(i)==="\n"){i++}}return i}}},validateComment:function(state){if(Util.isLoggedIn()){var commenterContent=$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"");if(2>commenterContent.length||commenterContent.length>500){$("#commentErrorTip"+state).html(this.tips.commentContentCannotEmptyLabel);$("#comment"+state).focus()}else{return true}$("#commentErrorTip"+state).show();return false}var commentName=$("#commentName"+state).val().replace(/(^\s*)|(\s*$)/g,""),commenterContent=$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"");if(2>commentName.length||commentName.length>20){$("#commentErrorTip"+state).html(this.tips.nameTooLongLabel);$("#commentName"+state).focus()}else{if($("#commentEmail"+state).val().replace(/\s/g,"")===""){$("#commentErrorTip"+state).html(this.tips.mailCannotEmptyLabel);$("#commentEmail"+state).focus()}else{if(!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#commentEmail"+state).val())){$("#commentErrorTip"+state).html(this.tips.mailInvalidLabel);$("#commentEmail"+state).focus()}else{if(2>commenterContent.length||commenterContent.length>500){$("#commentErrorTip"+state).html(this.tips.commentContentCannotEmptyLabel);$("#comment"+state).focus()}else{if($("#commentValidate"+state).val().replace(/\s/g,"")===""){$("#commentErrorTip"+state).html(this.tips.captchaCannotEmptyLabel);$("#commentValidate"+state).focus()}else{return true}}}}}$("#commentErrorTip"+state).show();return false},replaceCommentsEm:function(selector){var $commentContents=$(selector);for(var i=0;i<$commentContents.length;i++){var str=$commentContents[i].innerHTML;$commentContents[i].innerHTML=Util.replaceEmString(str)}},_initSyntaxHighlighter:function(languages){for(var i=0;i<languages.length;i++){switch(languages[i]){case"groovy":languages[i]="groovy "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushGroovy.js";break;case"java":languages[i]="java "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJava.js";break;case"php":languages[i]="php "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPhp.js";break;case"scala":languages[i]="scala "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushScala.js";break;case"sql":languages[i]="sql "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushSql.js";break;case"applescript":languages[i]="applescript "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushAppleScript.js";break;case"as3":case"actionscript3":languages[i]="actionscript3 as3 "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushAS3.js";break;case"bash":case"shell":languages[i]="bash shell "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushBash.js";break;case"coldfusion":case"cf":languages[i]="coldfusion cf "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushColdFusion.js";break;case"c#":case"c-sharp":case"csharp":languages[i]="c# c-sharp csharp "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCSharp.js";break;case"cpp":case"c":languages[i]="cpp c "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCpp.js";break;case"css":languages[i]="css "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushCss.js";break;case"delphi":case"pascal":languages[i]="delphi pascal "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushDelphi.js";break;case"diff":case"patch":case"pas":languages[i]="diff patch pas "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushDiff.js";break;case"erl":case"erlang":languages[i]="erl erlang "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushErlang.js";break;case"js":case"jscript":case"javascript":languages[i]="js jscript javascript "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJScript.js";break;case"jfx":case"javafx":languages[i]="jfx javafx "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushJavaFX.js";break;case"perl":case"pl":languages[i]="perl pl "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPerl.js";break;case"plain":case"text":languages[i]="text plain "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPlain.js";break;case"ps":case"powershell":languages[i]="ps powershell "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPowerShell.js";break;case"py":case"python":languages[i]="py python "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushPython.js";break;case"rails":case"ror":case"ruby":case"rb":languages[i]="ruby rails ror rb "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushRuby.js";break;case"sass":case"scss":languages[i]="sass scss "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushSass.js";break;case"vb":case"vbnet":languages[i]="vb vbnet "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushVb.js";break;case"xml":case"xhtml":case"xslt":case"html":languages[i]="xml xhtml xslt html "+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushXml.js";break;default:break}}SyntaxHighlighter.autoloader.apply(null,languages);SyntaxHighlighter.config.stripBrs=true;SyntaxHighlighter.all()},_loadSyntaxHighlighter:function(SHTheme){var cssName=SHTheme?SHTheme:"shCoreEclipse",that=this;if(document.createStyleSheet){document.createStyleSheet(latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/styles/"+cssName+".css")}else{$("head").append($("<link rel='stylesheet' href='"+latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/styles/"+cssName+".css' type='text/css' charset='utf-8' />"))}$.ajax({url:latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shCore.js",dataType:"script",cache:true,success:function(){var languages=[],isScrip=false;$(".article-body pre, .code-highlight pre").each(function(){var name=this.className.split(";")[0];var language=name.substr(7,name.length-1);if(this.className.indexOf("html-script: true")>-1&&(language!=="xml"&&language!=="xhtml"&&language!=="xslt"&&language!="html")){isScrip=true}languages.push(language)});if(isScrip){$.ajax({url:latkeConfig.staticServePath+"/js/lib/SyntaxHighlighter/scripts/shBrushXml.js",dataType:"script",cache:true,success:function(){that._initSyntaxHighlighter(languages)}})}else{that._initSyntaxHighlighter(languages)}}})},parseLanguage:function(obj){var isPrettify=false,isSH=false;$(".article-body pre, .code-highlight pre").each(function(){if(this.className.indexOf("brush")>-1){isSH=true}if(this.className.indexOf("prettyprint")>-1){isPrettify=true}});if(isSH){this._loadSyntaxHighlighter(obj?(obj.SHTheme?obj.SHTheme:undefined):undefined);return false}if(isPrettify){if(document.createStyleSheet){document.createStyleSheet(latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.css")}else{$("head").append($("<link rel='stylesheet' href='"+latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.css'>"))}$.ajax({url:latkeConfig.staticServePath+"/js/lib/google-code-prettify/prettify.js",dataType:"script",cache:true,success:function(){prettyPrint()}});return false}if(document.createStyleSheet){document.createStyleSheet(latkeConfig.staticServePath+"/js/lib/highlight/styles/default.css")}else{$("head").append($("<link rel='stylesheet' href='"+latkeConfig.staticServePath+"/js/lib/highlight/styles/github.css'>"))}$.ajax({url:latkeConfig.staticServePath+"/js/lib/highlight/highlight.pack.js",dataType:"script",cache:true,success:function(){hljs.initHighlightingOnLoad()}})},load:function(obj){var that=this;that.insertEmotions();that.parseLanguage(obj?(obj.language?obj.language:undefined):undefined);$("#commentValidate").keypress(function(event){if(event.keyCode===13){that.submitComment()}});$("#comment").keypress(function(event){if(event.keyCode===13&&event.ctrlKey){that.submitComment()}});$("#captcha").click(function(){$(this).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())});if(!Util.isLoggedIn()){$("#commentEmail").val(Cookie.readCookie("commentEmail"));$("#commentURL").val(Cookie.readCookie("commentURL"));$("#commentName").val(Cookie.readCookie("commentName"))}try{JSON}catch(e){document.write('<script src="'+latkeConfig.staticServePath+'/js/lib/json2.js"><\/script>')}},loadRandomArticles:function(headTitle){var randomArticles1Label=this.tips.randomArticles1Label;$.ajax({url:latkeConfig.servePath+"/get-random-articles.do",type:"POST",success:function(result,textStatus){var randomArticles=result.randomArticles;if(!randomArticles||0===randomArticles.length){$("#randomArticles").remove();return}var listHtml="";for(var i=0;i<randomArticles.length;i++){var article=randomArticles[i];var title=article.articleTitle;var randomArticleLiHtml="<li><a rel='nofollow' title='"+title+"' href='"+latkeConfig.servePath+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=randomArticleLiHtml}var titleHTML=headTitle?headTitle:"<h4>"+randomArticles1Label+"</h4>";var randomArticleListHtml=titleHTML+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#randomArticles").append(randomArticleListHtml)}})},loadRelevantArticles:function(id,headTitle){$.ajax({url:latkeConfig.servePath+"/article/id/"+id+"/relevant/articles",type:"GET",success:function(data,textStatus){var articles=data.relevantArticles;if(!articles||0===articles.length){$("#relevantArticles").remove();return}var listHtml="";for(var i=0;i<articles.length;i++){var article=articles[i];var title=article.articleTitle;var articleLiHtml="<li><a rel='nofollow' title='"+title+"' href='"+latkeConfig.servePath+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=articleLiHtml}var relevantArticleListHtml=headTitle+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#relevantArticles").append(relevantArticleListHtml)},error:function(){$("#relevantArticles").remove()}})},loadExternalRelevantArticles:function(tags,headTitle){var tips=this.tips;try{$.ajax({url:"http://rhythm.b3log.org:80/get-articles-by-tags.do?tags="+tags+"&blogHost="+tips.blogHost+"&paginationPageSize="+tips.externalRelevantArticlesDisplayCount,type:"GET",cache:true,dataType:"jsonp",error:function(){$("#externalRelevantArticles").remove()},success:function(data,textStatus){var articles=data.articles;if(!articles||0===articles.length){$("#externalRelevantArticles").remove();return}var listHtml="";for(var i=0;i<articles.length;i++){var article=articles[i];var title=article.articleTitle;var articleLiHtml="<li><a rel='nofollow' title='"+title+"' target='_blank' href='"+article.articlePermalink+"'>"+title+"</a></li>";listHtml+=articleLiHtml}var titleHTML=headTitle?headTitle:"<h4>"+tips.externalRelevantArticles1Label+"</h4>";var randomArticleListHtml=titleHTML+"<ul class='marginLeft12'>"+listHtml+"</ul>";$("#externalRelevantArticles").append(randomArticleListHtml)}})}catch(e){}},submitComment:function(commentId,state){if(!state){state=""}var that=this,tips=this.tips,type="article";if(tips.externalRelevantArticlesDisplayCount===undefined){type="page"}if(this.validateComment(state)){$("#submitCommentButton"+state).attr("disabled","disabled");$("#commentErrorTip"+state).show().html(this.tips.loadingLabel);var requestJSONObject={oId:tips.oId,commentContent:$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,"")};if(!Util.isLoggedIn()){requestJSONObject={oId:tips.oId,commentContent:$("#comment"+state).val().replace(/(^\s*)|(\s*$)/g,""),commentEmail:$("#commentEmail"+state).val(),commentURL:Util.proessURL($("#commentURL"+state).val().replace(/(^\s*)|(\s*$)/g,"")),commentName:$("#commentName"+state).val().replace(/(^\s*)|(\s*$)/g,""),captcha:$("#commentValidate"+state).val()};Cookie.createCookie("commentName",requestJSONObject.commentName,365);Cookie.createCookie("commentEmail",requestJSONObject.commentEmail,365);Cookie.createCookie("commentURL",$("#commentURL"+state).val().replace(/(^\s*)|(\s*$)/g,""),365)}if(state==="Reply"){requestJSONObject.commentOriginalCommentId=commentId}$.ajax({type:"POST",url:latkeConfig.servePath+"/add-"+type+"-comment.do",cache:false,contentType:"application/json",data:JSON.stringify(requestJSONObject),success:function(result){if(!result.sc){$("#commentErrorTip"+state).html(result.msg);$("#comment"+state).val("").focus();$("#submitCommentButton"+state).removeAttr("disabled");if(!Util.isLoggedIn()){$("#captcha"+state).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())}return}result.replyNameHTML="";if(!Util.isLoggedIn()){$("#captcha"+state).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random());if($("#commentURL"+state).val().replace(/\s/g,"")===""){result.replyNameHTML="<a>"+$("#commentName"+state).val()+"</a>"}else{result.replyNameHTML='<a href="'+Util.proessURL($("#commentURL"+state).val())+'" target="_blank">'+$("#commentName"+state).val()+"</a>"}result.userName=$("#commentName"+state).val()}else{result.replyNameHTML='<a href="'+window.location.host+'" target="_blank">'+Util.getUserName()+"</a>";result.userName=Util.getUserName()}that.addCommentAjax(addComment(result,state),state);$("#submitCommentButton"+state).removeAttr("disabled")}})}},addReplyForm:function(id,commentFormHTML,endHTML){var that=this;if(id===this.currentCommentId){if($("#commentNameReply").val()===""){$("#commentNameReply").focus()}else{if($("#commentEmailReply").val()===""){$("#commentEmailReply").focus()}else{$("#commentReply").focus()}}return}$("#replyForm").remove();endHTML=endHTML?endHTML:"";if(endHTML==="</div>"){$("#"+id).append(commentFormHTML+$("#commentForm").html()+endHTML)}else{$("#"+id).append(commentFormHTML+$("#commentForm").html()+"</table>"+endHTML)}$("#replyForm input, #replyForm textarea").each(function(){this.id=this.id+"Reply"});$("#commentNameReply").val(Cookie.readCookie("commentName"));$("#commentEmailReply").val(Cookie.readCookie("commentEmail"));var $label=$("#replyForm #commentURLLabel");if($label.length===1){$label.attr("id","commentURLLabelReply")}$("#commentURLReply").val(Cookie.readCookie("commentURL"));$("#replyForm #emotions").attr("id","emotionsReply");this.insertEmotions("Reply");$("#commentReply").unbind().keypress(function(event){if(event.keyCode===13&&event.ctrlKey){that.submitComment(id,"Reply");event.preventDefault()}});$("#commentValidateReply").unbind().keypress(function(event){if(event.keyCode===13){that.submitComment(id,"Reply");event.preventDefault()}});$("#replyForm #captcha").attr("id","captchaReply").attr("src",latkeConfig.servePath+"/captcha.do?"+new Date().getTime()).click(function(){$(this).attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())});$("#replyForm #commentErrorTip").attr("id","commentErrorTipReply").html("").hide();$("#replyForm #submitCommentButton").attr("id","submitCommentButtonReply");$("#replyForm #submitCommentButtonReply").unbind("click").removeAttr("onclick").click(function(){that.submitComment(id,"Reply")});if($("#commentNameReply").val()===""){$("#commentNameReply").focus()}else{if($("#commentEmailReply").val()===""){$("#commentEmailReply").focus()}else{$("#commentReply").focus()}}this.currentCommentId=id},hideComment:function(id){$("#commentRef"+id).hide()},showComment:function(it,id,top,parentTag){var positionTop=parseInt($(it).position().top);if(parentTag){positionTop=parseInt($(it).parents(parentTag).position().top)}if($("#commentRef"+id).length>0){$("#commentRef"+id).show().css("top",(positionTop+top)+"px")}else{var $refComment=$("#"+id).clone();$refComment.addClass("comment-body-ref").attr("id","commentRef"+id);$refComment.find("#replyForm").remove();$("#comments").append($refComment);$("#commentRef"+id).css("top",(positionTop+top)+"px")}},addCommentAjax:function(commentHTML,state){if($("#comments").children().length>0){$($("#comments").children()[0]).before(commentHTML)}else{$("#comments").html(commentHTML)}if(state===""){$("#commentErrorTip").html("").hide();$("#comment").val("");$("#commentValidate").val("");$("#captcha").attr("src",latkeConfig.servePath+"/captcha.do?code="+Math.random())}else{$("#replyForm").remove()}window.location.hash="#comments"}});
\ No newline at end of file \ No newline at end of file
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