Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
solo-1
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
solo-1
Commits
bc29399f
Unverified
Commit
bc29399f
authored
Mar 29, 2019
by
Van
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/3.5.0-dev' into 3.5.0-dev
parents
cc7c1990
38711218
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
514 additions
and
269 deletions
+514
-269
src/main/java/org/b3log/solo/SoloServletListener.java
src/main/java/org/b3log/solo/SoloServletListener.java
+24
-25
src/main/java/org/b3log/solo/model/Option.java
src/main/java/org/b3log/solo/model/Option.java
+13
-8
src/main/java/org/b3log/solo/model/Skin.java
src/main/java/org/b3log/solo/model/Skin.java
+0
-53
src/main/java/org/b3log/solo/processor/IndexProcessor.java
src/main/java/org/b3log/solo/processor/IndexProcessor.java
+5
-3
src/main/java/org/b3log/solo/processor/console/AdminConsole.java
...n/java/org/b3log/solo/processor/console/AdminConsole.java
+2
-2
src/main/java/org/b3log/solo/processor/console/PreferenceConsole.java
...a/org/b3log/solo/processor/console/PreferenceConsole.java
+0
-14
src/main/java/org/b3log/solo/processor/console/SkinConsole.java
...in/java/org/b3log/solo/processor/console/SkinConsole.java
+273
-0
src/main/java/org/b3log/solo/service/DataModelService.java
src/main/java/org/b3log/solo/service/DataModelService.java
+1
-1
src/main/java/org/b3log/solo/service/InitService.java
src/main/java/org/b3log/solo/service/InitService.java
+11
-30
src/main/java/org/b3log/solo/service/OptionQueryService.java
src/main/java/org/b3log/solo/service/OptionQueryService.java
+23
-0
src/main/java/org/b3log/solo/service/PreferenceMgmtService.java
...in/java/org/b3log/solo/service/PreferenceMgmtService.java
+2
-107
src/main/java/org/b3log/solo/service/SkinMgmtService.java
src/main/java/org/b3log/solo/service/SkinMgmtService.java
+145
-0
src/main/java/org/b3log/solo/upgrade/V340_350.java
src/main/java/org/b3log/solo/upgrade/V340_350.java
+9
-0
src/main/java/org/b3log/solo/util/Skins.java
src/main/java/org/b3log/solo/util/Skins.java
+4
-9
src/main/java/org/b3log/solo/util/Solos.java
src/main/java/org/b3log/solo/util/Solos.java
+1
-14
src/main/resources/solo.properties
src/main/resources/solo.properties
+1
-3
No files found.
src/main/java/org/b3log/solo/SoloServletListener.java
View file @
bc29399f
...
...
@@ -39,7 +39,6 @@ import org.b3log.solo.event.B3ArticleUpdater;
import
org.b3log.solo.event.B3CommentSender
;
import
org.b3log.solo.event.PluginRefresher
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Skin
;
import
org.b3log.solo.processor.InitCheckHandler
;
import
org.b3log.solo.processor.PermalinkHandler
;
import
org.b3log.solo.processor.console.*
;
...
...
@@ -189,10 +188,9 @@ public final class SoloServletListener extends AbstractServletListener {
}
/**
* Loads
preference
.
* Loads
skin
.
* <p>
* Loads preference from repository, loads skins from skin directory then sets it into preference if the skins
* changed.
* Loads skin from repository, loads skins from skin directory then sets it into preference if the skins changed.
* </p>
*/
private
void
loadPreference
()
{
...
...
@@ -201,15 +199,15 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER
.
debug
(
"Loading preference...."
);
final
OptionQueryService
optionQueryService
=
beanManager
.
getReference
(
OptionQueryService
.
class
);
JSONObject
preference
;
JSONObject
skin
;
try
{
preference
=
optionQueryService
.
getPreference
();
if
(
null
==
preference
)
{
skin
=
optionQueryService
.
getSkin
();
if
(
null
==
skin
)
{
return
;
}
final
PreferenceMgmtService
preferenceMgmtService
=
beanManager
.
getReference
(
Preference
MgmtService
.
class
);
preferenceMgmtService
.
loadSkins
(
preference
);
final
SkinMgmtService
skinMgmtService
=
beanManager
.
getReference
(
Skin
MgmtService
.
class
);
skinMgmtService
.
loadSkins
(
skin
);
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
ERROR
,
e
.
getMessage
(),
e
);
...
...
@@ -256,25 +254,22 @@ public final class SoloServletListener extends AbstractServletListener {
private
void
resolveSkinDir
(
final
HttpServletRequest
httpServletRequest
)
{
String
skin
=
Skins
.
getSkinDirNameFromCookie
(
httpServletRequest
);
if
(
StringUtils
.
isBlank
(
skin
))
{
try
{
final
InitService
initService
=
beanManager
.
getReference
(
InitService
.
class
);
if
(
initService
.
isInited
())
{
final
OptionQueryService
optionQueryService
=
beanManager
.
getReference
(
OptionQueryService
.
class
);
final
JSONObject
preference
=
optionQueryService
.
getPreference
();
if
(
null
!=
preference
)
{
skin
=
preference
.
getString
(
Skin
.
SKIN_DIR_NAME
);
}
final
OptionQueryService
optionQueryService
=
beanManager
.
getReference
(
OptionQueryService
.
class
);
final
JSONObject
skinOpt
=
optionQueryService
.
getSkin
();
if
(
Solos
.
isMobile
(
httpServletRequest
))
{
if
(
null
!=
skinOpt
)
{
skin
=
skinOpt
.
optString
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
);
}
else
{
skin
=
Option
.
DefaultPreference
.
DEFAULT_MOBILE_SKIN_DIR_NAME
;
}
}
else
{
if
(
null
!=
skinOpt
)
{
skin
=
skinOpt
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
);
}
else
{
skin
=
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
;
}
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
ERROR
,
"Resolves skin failed"
,
e
);
}
}
if
(
StringUtils
.
isBlank
(
skin
))
{
skin
=
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
;
}
if
(
Solos
.
isMobile
(
httpServletRequest
))
{
skin
=
Solos
.
MOBILE_SKIN
;
}
httpServletRequest
.
setAttribute
(
Keys
.
TEMAPLTE_DIR_NAME
,
skin
);
}
...
...
@@ -399,6 +394,10 @@ public final class SoloServletListener extends AbstractServletListener {
DispatcherServlet
.
get
(
"/console/preference/"
,
preferenceConsole:
:
getPreference
);
DispatcherServlet
.
put
(
"/console/preference/"
,
preferenceConsole:
:
updatePreference
);
final
SkinConsole
skinConsole
=
beanManager
.
getReference
(
SkinConsole
.
class
);
DispatcherServlet
.
get
(
"/console/skin"
,
skinConsole:
:
getSkin
);
DispatcherServlet
.
put
(
"/console/skin"
,
skinConsole:
:
updateSkin
);
final
RepairConsole
repairConsole
=
beanManager
.
getReference
(
RepairConsole
.
class
);
DispatcherServlet
.
get
(
"/fix/restore-signs"
,
repairConsole:
:
restoreSigns
);
...
...
src/main/java/org/b3log/solo/model/Option.java
View file @
bc29399f
...
...
@@ -26,7 +26,7 @@ import org.json.JSONObject;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://github.com/hzchendou">hzchendou</a>
* @version 1.
5.0.6, Mar 20
, 2019
* @version 1.
6.0.0, Mar 29
, 2019
* @since 0.6.0
*/
public
final
class
Option
{
...
...
@@ -217,20 +217,15 @@ public final class Option {
*/
public
static
final
String
ID_C_FEED_OUTPUT_CNT
=
"feedOutputCnt"
;
/**
* Key of skins.
*/
public
static
final
String
ID_C_SKINS
=
"skins"
;
/**
* Key of skin dir name.
*/
public
static
final
String
ID_C_SKIN_DIR_NAME
=
"skinDirName"
;
/**
* Key of
skin
name.
* Key of
mobile skin dir
name.
*/
public
static
final
String
ID_C_
SKIN_NAME
=
"skin
Name"
;
public
static
final
String
ID_C_
MOBILE_SKIN_DIR_NAME
=
"mobileSkinDir
Name"
;
/**
* Key of footer content.
...
...
@@ -273,6 +268,11 @@ public final class Option {
*/
public
static
final
String
CATEGORY_C_HACPAI
=
"hacpai"
;
/**
* Category - Skin.
*/
public
static
final
String
CATEGORY_C_SKIN
=
"skin"
;
//// Transient ////
/**
* Key of statistic blog published article count.
...
...
@@ -359,6 +359,11 @@ public final class Option {
*/
public
static
final
String
DEFAULT_SKIN_DIR_NAME
=
"Pinghsu"
;
/**
* Default mobile skin directory name.
*/
public
static
final
String
DEFAULT_MOBILE_SKIN_DIR_NAME
=
"Pinghsu"
;
/**
* Default language.
*/
...
...
src/main/java/org/b3log/solo/model/Skin.java
deleted
100644 → 0
View file @
cc7c1990
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2019, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package
org
.
b3log
.
solo
.
model
;
/**
* This class defines all skin model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Aug 22, 2010
*/
public
final
class
Skin
{
/**
* Skin.
*/
public
static
final
String
SKIN
=
"skin"
;
/**
* Skins.
*/
public
static
final
String
SKINS
=
"skins"
;
/**
* Key of skin name, current selected skin name.
*/
public
static
final
String
SKIN_NAME
=
"skinName"
;
/**
* Key of skin directory name.
*/
public
static
final
String
SKIN_DIR_NAME
=
"skinDirName"
;
/**
* Private constructor.
*/
private
Skin
()
{
}
}
src/main/java/org/b3log/solo/processor/IndexProcessor.java
View file @
bc29399f
...
...
@@ -36,7 +36,6 @@ import org.b3log.latke.util.Paginator;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.model.Common
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Skin
;
import
org.b3log.solo.service.DataModelService
;
import
org.b3log.solo.service.InitService
;
import
org.b3log.solo.service.OptionQueryService
;
...
...
@@ -117,11 +116,14 @@ public class IndexProcessor {
// 前台皮肤切换 https://github.com/b3log/solo/issues/12060
String
specifiedSkin
=
Skins
.
getSkinDirName
(
context
);
if
(
StringUtils
.
isBlank
(
specifiedSkin
))
{
specifiedSkin
=
preference
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
);
final
JSONObject
skinOpt
=
optionQueryService
.
getSkin
();
specifiedSkin
=
Solos
.
isMobile
(
request
)
?
skinOpt
.
optString
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
)
:
skinOpt
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
);
}
request
.
setAttribute
(
Keys
.
TEMAPLTE_DIR_NAME
,
specifiedSkin
);
final
Cookie
cookie
=
new
Cookie
(
Skin
.
SKIN
,
specifiedSkin
);
final
Cookie
cookie
=
new
Cookie
(
Option
.
CATEGORY_C_
SKIN
,
specifiedSkin
);
cookie
.
setMaxAge
(
60
*
60
);
// 1 hour
cookie
.
setPath
(
"/"
);
response
.
addCookie
(
cookie
);
...
...
src/main/java/org/b3log/solo/processor/console/AdminConsole.java
View file @
bc29399f
...
...
@@ -42,7 +42,6 @@ import org.b3log.latke.util.Strings;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.model.Common
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Skin
;
import
org.b3log.solo.model.UserExt
;
import
org.b3log.solo.service.DataModelService
;
import
org.b3log.solo.service.ExportService
;
...
...
@@ -144,7 +143,8 @@ public class AdminConsole {
dataModel
.
put
(
Common
.
YEAR
,
String
.
valueOf
(
Calendar
.
getInstance
().
get
(
Calendar
.
YEAR
)));
dataModel
.
put
(
Option
.
ID_C_ARTICLE_LIST_DISPLAY_COUNT
,
preference
.
getInt
(
Option
.
ID_C_ARTICLE_LIST_DISPLAY_COUNT
));
dataModel
.
put
(
Option
.
ID_C_ARTICLE_LIST_PAGINATION_WINDOW_SIZE
,
preference
.
getInt
(
Option
.
ID_C_ARTICLE_LIST_PAGINATION_WINDOW_SIZE
));
dataModel
.
put
(
Skin
.
SKIN_DIR_NAME
,
preference
.
getString
(
Skin
.
SKIN_DIR_NAME
));
final
JSONObject
skin
=
optionQueryService
.
getSkin
();
dataModel
.
put
(
Option
.
CATEGORY_C_SKIN
,
skin
.
optString
(
Option
.
OPTION_VALUE
));
Keys
.
fillRuntime
(
dataModel
);
dataModelService
.
fillMinified
(
dataModel
);
// 使用 Marked 时代码高亮问题 https://github.com/b3log/solo/issues/12614
...
...
src/main/java/org/b3log/solo/processor/console/PreferenceConsole.java
View file @
bc29399f
...
...
@@ -29,16 +29,12 @@ import org.b3log.latke.servlet.annotation.RequestProcessor;
import
org.b3log.latke.servlet.renderer.JsonRenderer
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Sign
;
import
org.b3log.solo.model.Skin
;
import
org.b3log.solo.service.OptionMgmtService
;
import
org.b3log.solo.service.OptionQueryService
;
import
org.b3log.solo.service.PreferenceMgmtService
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
javax.servlet.http.Cookie
;
import
javax.servlet.http.HttpServletResponse
;
/**
* Preference console request processing.
*
...
...
@@ -145,10 +141,8 @@ public class PreferenceConsole {
* "blogSubtitle": "",
* "localeString": "",
* "timeZoneId": "",
* "skinName": "",
* "skinDirName": "",
* "skins": "[{
* "skinName": "",
* "skinDirName": ""
* }, ....]",
* "noticeBoard": "",
...
...
@@ -212,7 +206,6 @@ public class PreferenceConsole {
/**
* Updates the preference by the specified request.
* <p>
* <p>
* Request json:
* <pre>
* {
...
...
@@ -228,7 +221,6 @@ public class PreferenceConsole {
* "randomArticlesDisplayCount": int,
* "blogTitle": "",
* "blogSubtitle": "",
* "skinDirName": "",
* "localeString": "",
* "timeZoneId": "",
* "noticeBoard": "",
...
...
@@ -271,12 +263,6 @@ public class PreferenceConsole {
preferenceMgmtService
.
updatePreference
(
preference
);
final
HttpServletResponse
response
=
context
.
getResponse
();
final
Cookie
cookie
=
new
Cookie
(
Skin
.
SKIN
,
preference
.
getString
(
Skin
.
SKIN_DIR_NAME
));
cookie
.
setMaxAge
(
60
*
60
);
// 1 hour
cookie
.
setPath
(
"/"
);
response
.
addCookie
(
cookie
);
ret
.
put
(
Keys
.
STATUS_CODE
,
true
);
ret
.
put
(
Keys
.
MSG
,
langPropsService
.
get
(
"updateSuccLabel"
));
}
catch
(
final
ServiceException
e
)
{
...
...
src/main/java/org/b3log/solo/processor/console/SkinConsole.java
0 → 100644
View file @
bc29399f
This diff is collapsed.
Click to expand it.
src/main/java/org/b3log/solo/service/DataModelService.java
View file @
bc29399f
...
...
@@ -707,7 +707,7 @@ public class DataModelService {
final
JSONObject
admin
=
userRepository
.
getAdmin
();
dataModel
.
put
(
Common
.
ADMIN_USER
,
admin
);
final
String
skinDirName
=
(
String
)
context
.
attr
(
Keys
.
TEMAPLTE_DIR_NAME
);
dataModel
.
put
(
Skin
.
SKIN_DIR_NAME
,
skinDirName
);
dataModel
.
put
(
Option
.
ID_C_
SKIN_DIR_NAME
,
skinDirName
);
Keys
.
fillRuntime
(
dataModel
);
fillMinified
(
dataModel
);
fillPageNavigations
(
dataModel
);
...
...
src/main/java/org/b3log/solo/service/InitService.java
View file @
bc29399f
...
...
@@ -55,7 +55,7 @@ import java.util.Set;
* Solo initialization service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.5.2.3
1, Mar 23
, 2019
* @version 1.5.2.3
2, Mar 29
, 2019
* @since 0.4.0
*/
@Service
...
...
@@ -226,7 +226,7 @@ public class InitService {
final
Transaction
transaction
=
userRepository
.
beginTransaction
();
try
{
initStatistic
();
init
Preference
(
requestJSONObject
);
init
Options
(
requestJSONObject
);
initAdmin
(
requestJSONObject
);
initLink
();
helloWorld
();
...
...
@@ -466,12 +466,12 @@ public class InitService {
}
/**
* Initializes
preference
.
* Initializes
options
.
*
* @param requestJSONObject the specified json object
* @throws Exception exception
*/
private
void
init
Preference
(
final
JSONObject
requestJSONObject
)
throws
Exception
{
private
void
init
Options
(
final
JSONObject
requestJSONObject
)
throws
Exception
{
LOGGER
.
debug
(
"Initializing preference...."
);
final
JSONObject
hljsThemeOpt
=
new
JSONObject
();
...
...
@@ -660,36 +660,17 @@ public class InitService {
footerContentOpt
.
put
(
Option
.
OPTION_VALUE
,
DefaultPreference
.
DEFAULT_FOOTER_CONTENT
);
optionRepository
.
add
(
footerContentOpt
);
final
String
skinDirName
=
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
;
final
JSONObject
skinDirNameOpt
=
new
JSONObject
();
skinDirNameOpt
.
put
(
Keys
.
OBJECT_ID
,
Option
.
ID_C_SKIN_DIR_NAME
);
skinDirNameOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_
PREFERENCE
);
skinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
skinDirName
);
skinDirNameOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_
SKIN
);
skinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
);
optionRepository
.
add
(
skinDirNameOpt
);
final
String
skinName
=
Latkes
.
getSkinName
(
skinDirName
);
final
JSONObject
skinNameOpt
=
new
JSONObject
();
skinNameOpt
.
put
(
Keys
.
OBJECT_ID
,
Option
.
ID_C_SKIN_NAME
);
skinNameOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_PREFERENCE
);
skinNameOpt
.
put
(
Option
.
OPTION_VALUE
,
skinName
);
optionRepository
.
add
(
skinNameOpt
);
final
Set
<
String
>
skinDirNames
=
Skins
.
getSkinDirNames
();
final
JSONArray
skinArray
=
new
JSONArray
();
for
(
final
String
dirName
:
skinDirNames
)
{
final
JSONObject
skin
=
new
JSONObject
();
skinArray
.
put
(
skin
);
final
String
name
=
Latkes
.
getSkinName
(
dirName
);
skin
.
put
(
Skin
.
SKIN_NAME
,
name
);
skin
.
put
(
Skin
.
SKIN_DIR_NAME
,
dirName
);
}
final
JSONObject
skinsOpt
=
new
JSONObject
();
skinsOpt
.
put
(
Keys
.
OBJECT_ID
,
Option
.
ID_C_SKINS
);
skinsOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_PREFERENCE
);
skinsOpt
.
put
(
Option
.
OPTION_VALUE
,
skinArray
.
toString
());
optionRepository
.
add
(
skinsOpt
);
final
JSONObject
mobileSkinDirNameOpt
=
new
JSONObject
();
mobileSkinDirNameOpt
.
put
(
Keys
.
OBJECT_ID
,
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
);
mobileSkinDirNameOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_SKIN
);
mobileSkinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
DefaultPreference
.
DEFAULT_MOBILE_SKIN_DIR_NAME
);
optionRepository
.
add
(
mobileSkinDirNameOpt
);
LOGGER
.
info
(
"Initialized preference"
);
}
...
...
src/main/java/org/b3log/solo/service/OptionQueryService.java
View file @
bc29399f
...
...
@@ -47,6 +47,29 @@ public class OptionQueryService {
@Inject
private
OptionRepository
optionRepository
;
/**
* Gets the skin.
*
* @return skin, returns {@code null} if not found
*/
public
JSONObject
getSkin
()
{
try
{
JSONObject
ret
=
getOptions
(
Option
.
CATEGORY_C_SKIN
);
if
(
null
==
ret
)
{
// TODO: 在 v3.5.0 发布后可移除判空
ret
=
new
JSONObject
().
put
(
Option
.
ID_C_SKIN_DIR_NAME
,
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
).
put
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
,
Option
.
DefaultPreference
.
DEFAULT_MOBILE_SKIN_DIR_NAME
);
}
return
ret
;
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
ERROR
,
"Gets skin failed"
,
e
);
return
null
;
}
}
/**
* Gets the user preference.
*
...
...
src/main/java/org/b3log/solo/service/PreferenceMgmtService.java
View file @
bc29399f
...
...
@@ -27,26 +27,18 @@ import org.b3log.latke.service.LangPropsService;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.service.annotation.Service
;
import
org.b3log.latke.util.Locales
;
import
org.b3log.latke.util.Stopwatchs
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Skin
;
import
org.b3log.solo.repository.OptionRepository
;
import
org.b3log.solo.util.Skins
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
java.util.Iterator
;
import
java.util.Locale
;
import
java.util.Set
;
import
static
org
.
b3log
.
solo
.
model
.
Skin
.*;
import
static
org
.
b3log
.
solo
.
util
.
Skins
.
getSkinDirNames
;
/**
* Preference management service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.
3.2.18, Feb 6
, 2019
* @version 1.
4.0.0, Mar 29
, 2019
* @since 0.4.0
*/
@Service
...
...
@@ -75,72 +67,6 @@ public class PreferenceMgmtService {
@Inject
private
LangPropsService
langPropsService
;
/**
* Loads skins for the specified preference and initializes templates loading.
* <p>
* If the skins directory has been changed, persists the change into preference.
* </p>
*
* @param preference the specified preference
* @throws Exception exception
*/
public
void
loadSkins
(
final
JSONObject
preference
)
throws
Exception
{
Stopwatchs
.
start
(
"Load Skins"
);
LOGGER
.
debug
(
"Loading skins...."
);
final
Set
<
String
>
skinDirNames
=
getSkinDirNames
();
LOGGER
.
log
(
Level
.
DEBUG
,
"Loaded skins[dirNames={0}]"
,
skinDirNames
);
final
JSONArray
skinArray
=
new
JSONArray
();
for
(
final
String
dirName
:
skinDirNames
)
{
final
JSONObject
skin
=
new
JSONObject
();
final
String
name
=
Latkes
.
getSkinName
(
dirName
);
if
(
null
==
name
)
{
LOGGER
.
log
(
Level
.
WARN
,
"The directory [{0}] does not contain any skin, ignored it"
,
dirName
);
continue
;
}
skin
.
put
(
SKIN_NAME
,
name
);
skin
.
put
(
SKIN_DIR_NAME
,
dirName
);
skinArray
.
put
(
skin
);
}
final
String
currentSkinDirName
=
preference
.
optString
(
SKIN_DIR_NAME
);
final
String
skinName
=
preference
.
optString
(
SKIN_NAME
);
LOGGER
.
log
(
Level
.
DEBUG
,
"Current skin[name={0}]"
,
skinName
);
if
(!
skinDirNames
.
contains
(
currentSkinDirName
))
{
LOGGER
.
log
(
Level
.
WARN
,
"Configured skin [dirName={0}] can not find, try to use "
+
"default skin [dirName="
+
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
+
"] instead."
,
currentSkinDirName
);
if
(!
skinDirNames
.
contains
(
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
))
{
LOGGER
.
log
(
Level
.
ERROR
,
"Can not find default skin [dirName="
+
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
+
"], please redeploy your Solo and make sure contains the default skin. If you are using git, try to re-pull with 'git pull --recurse-submodules'"
);
System
.
exit
(-
1
);
}
preference
.
put
(
SKIN_DIR_NAME
,
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
);
preference
.
put
(
SKIN_NAME
,
Latkes
.
getSkinName
(
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
));
updatePreference
(
preference
);
}
final
String
skinsString
=
skinArray
.
toString
();
if
(!
skinsString
.
equals
(
preference
.
getString
(
SKINS
)))
{
LOGGER
.
debug
(
"The skins directory has been changed, persists the change into preference"
);
preference
.
put
(
SKINS
,
skinsString
);
updatePreference
(
preference
);
}
LOGGER
.
debug
(
"Loaded skins...."
);
Stopwatchs
.
end
();
}
/**
* Updates the preference with the specified preference.
*
...
...
@@ -151,33 +77,14 @@ public class PreferenceMgmtService {
final
Iterator
<
String
>
keys
=
preference
.
keys
();
while
(
keys
.
hasNext
())
{
final
String
key
=
keys
.
next
();
if
(
preference
.
isNull
(
key
))
{
throw
new
ServiceException
(
"A value is null of preference[key="
+
key
+
"]"
);
throw
new
ServiceException
(
"A value is null of preference
[key="
+
key
+
"]"
);
}
}
final
Transaction
transaction
=
optionRepository
.
beginTransaction
();
try
{
final
String
skinDirName
=
preference
.
getString
(
Skin
.
SKIN_DIR_NAME
);
final
String
skinName
=
Latkes
.
getSkinName
(
skinDirName
);
preference
.
put
(
Skin
.
SKIN_NAME
,
skinName
);
final
Set
<
String
>
skinDirNames
=
Skins
.
getSkinDirNames
();
final
JSONArray
skinArray
=
new
JSONArray
();
for
(
final
String
dirName
:
skinDirNames
)
{
final
JSONObject
skin
=
new
JSONObject
();
skinArray
.
put
(
skin
);
final
String
name
=
Latkes
.
getSkinName
(
dirName
);
skin
.
put
(
Skin
.
SKIN_NAME
,
name
);
skin
.
put
(
Skin
.
SKIN_DIR_NAME
,
dirName
);
}
preference
.
put
(
Skin
.
SKINS
,
skinArray
.
toString
());
preference
.
put
(
Option
.
ID_C_SIGNS
,
preference
.
get
(
Option
.
ID_C_SIGNS
).
toString
());
final
JSONObject
oldPreference
=
optionQueryService
.
getPreference
();
...
...
@@ -288,18 +195,6 @@ public class PreferenceMgmtService {
signsOpt
.
put
(
Option
.
OPTION_VALUE
,
preference
.
optString
(
Option
.
ID_C_SIGNS
));
optionRepository
.
update
(
Option
.
ID_C_SIGNS
,
signsOpt
);
final
JSONObject
skinDirNameOpt
=
optionRepository
.
get
(
Option
.
ID_C_SKIN_DIR_NAME
);
skinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
preference
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
));
optionRepository
.
update
(
Option
.
ID_C_SKIN_DIR_NAME
,
skinDirNameOpt
);
final
JSONObject
skinNameOpt
=
optionRepository
.
get
(
Option
.
ID_C_SKIN_NAME
);
skinNameOpt
.
put
(
Option
.
OPTION_VALUE
,
preference
.
optString
(
Option
.
ID_C_SKIN_NAME
));
optionRepository
.
update
(
Option
.
ID_C_SKIN_NAME
,
skinNameOpt
);
final
JSONObject
skinsOpt
=
optionRepository
.
get
(
Option
.
ID_C_SKINS
);
skinsOpt
.
put
(
Option
.
OPTION_VALUE
,
preference
.
optString
(
Option
.
ID_C_SKINS
));
optionRepository
.
update
(
Option
.
ID_C_SKINS
,
skinsOpt
);
final
JSONObject
timeZoneIdOpt
=
optionRepository
.
get
(
Option
.
ID_C_TIME_ZONE_ID
);
timeZoneIdOpt
.
put
(
Option
.
OPTION_VALUE
,
preference
.
optString
(
Option
.
ID_C_TIME_ZONE_ID
));
optionRepository
.
update
(
Option
.
ID_C_TIME_ZONE_ID
,
timeZoneIdOpt
);
...
...
src/main/java/org/b3log/solo/service/SkinMgmtService.java
0 → 100644
View file @
bc29399f
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2019, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package
org
.
b3log
.
solo
.
service
;
import
org.b3log.latke.Keys
;
import
org.b3log.latke.Latkes
;
import
org.b3log.latke.ioc.Inject
;
import
org.b3log.latke.logging.Level
;
import
org.b3log.latke.logging.Logger
;
import
org.b3log.latke.repository.Transaction
;
import
org.b3log.latke.service.LangPropsService
;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.service.annotation.Service
;
import
org.b3log.latke.util.Stopwatchs
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.repository.OptionRepository
;
import
org.b3log.solo.util.Skins
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
java.util.Set
;
/**
* Skin management service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Mar 29, 2019
* @since 3.5.0
*/
@Service
public
class
SkinMgmtService
{
/**
* Logger.
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
SkinMgmtService
.
class
);
/**
* Option query service.
*/
@Inject
private
OptionQueryService
optionQueryService
;
/**
* Option repository.
*/
@Inject
private
OptionRepository
optionRepository
;
/**
* Language service.
*/
@Inject
private
LangPropsService
langPropsService
;
/**
* Loads skins.
*
* @param skin the specified skin
* @throws Exception exception
*/
public
void
loadSkins
(
final
JSONObject
skin
)
throws
Exception
{
final
Set
<
String
>
skinDirNames
=
Skins
.
getSkinDirNames
();
LOGGER
.
log
(
Level
.
DEBUG
,
"Loaded skins [dirNames={0}]"
,
skinDirNames
);
final
JSONArray
skinArray
=
new
JSONArray
();
for
(
final
String
dirName
:
skinDirNames
)
{
final
JSONObject
s
=
new
JSONObject
();
final
String
name
=
Latkes
.
getSkinName
(
dirName
);
if
(
null
==
name
)
{
LOGGER
.
log
(
Level
.
WARN
,
"The directory [{0}] does not contain any skin, ignored it"
,
dirName
);
continue
;
}
s
.
put
(
Option
.
ID_C_SKIN_DIR_NAME
,
dirName
);
skinArray
.
put
(
s
);
}
final
String
currentSkinDirName
=
skin
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
);
if
(!
skinDirNames
.
contains
(
currentSkinDirName
))
{
LOGGER
.
log
(
Level
.
WARN
,
"Configured skin [dirName={0}] can not find, try to use "
+
"default skin [dirName="
+
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
+
"] instead."
,
currentSkinDirName
);
if
(!
skinDirNames
.
contains
(
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
))
{
LOGGER
.
log
(
Level
.
ERROR
,
"Can not find default skin [dirName="
+
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
+
"], please redeploy your Solo and make sure contains the default skin. If you are using git, try to re-pull with 'git pull --recurse-submodules'"
);
System
.
exit
(-
1
);
}
skin
.
put
(
Option
.
ID_C_SKIN_DIR_NAME
,
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
);
updateSkin
(
skin
);
}
}
/**
* Updates the skin with the specified skin.
*
* @param skin the specified skin
* @throws ServiceException service exception
*/
public
void
updateSkin
(
final
JSONObject
skin
)
throws
ServiceException
{
final
Transaction
transaction
=
optionRepository
.
beginTransaction
();
try
{
final
JSONObject
skinDirNameOpt
=
optionRepository
.
get
(
Option
.
ID_C_SKIN_DIR_NAME
);
skinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
skin
.
optString
(
Option
.
ID_C_SKIN_DIR_NAME
));
optionRepository
.
update
(
Option
.
ID_C_SKIN_DIR_NAME
,
skinDirNameOpt
);
JSONObject
mobileSkinDirNameOpt
=
optionRepository
.
get
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
);
// TODO: 在 v3.5.0 发布后可移除判空
if
(
null
==
mobileSkinDirNameOpt
)
{
mobileSkinDirNameOpt
=
new
JSONObject
();
mobileSkinDirNameOpt
.
put
(
Keys
.
OBJECT_ID
,
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
);
mobileSkinDirNameOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_SKIN
);
mobileSkinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
Option
.
DefaultPreference
.
DEFAULT_MOBILE_SKIN_DIR_NAME
);
optionRepository
.
add
(
mobileSkinDirNameOpt
);
}
else
{
mobileSkinDirNameOpt
.
put
(
Option
.
OPTION_VALUE
,
skin
.
optString
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
));
optionRepository
.
update
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
,
mobileSkinDirNameOpt
);
}
transaction
.
commit
();
}
catch
(
final
Exception
e
)
{
if
(
transaction
.
isActive
())
{
transaction
.
rollback
();
}
LOGGER
.
log
(
Level
.
ERROR
,
"Updates skin failed"
,
e
);
throw
new
ServiceException
(
langPropsService
.
get
(
"updateFailLabel"
));
}
}
}
src/main/java/org/b3log/solo/upgrade/V340_350.java
View file @
bc29399f
...
...
@@ -57,6 +57,15 @@ public final class V340_350 {
try
{
final
Transaction
transaction
=
optionRepository
.
beginTransaction
();
optionRepository
.
remove
(
"skinName"
);
optionRepository
.
remove
(
"skins"
);
final
JSONObject
skinOpt
=
optionRepository
.
get
(
Option
.
ID_C_SKIN_DIR_NAME
);
skinOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_SKIN
);
optionRepository
.
update
(
Option
.
ID_C_SKIN_DIR_NAME
,
skinOpt
);
final
JSONObject
mobileSkinOpt
=
optionRepository
.
get
(
Option
.
ID_C_MOBILE_SKIN_DIR_NAME
);
mobileSkinOpt
.
put
(
Option
.
OPTION_CATEGORY
,
Option
.
CATEGORY_C_SKIN
);
optionRepository
.
update
(
Option
.
ID_C_SKIN_DIR_NAME
,
mobileSkinOpt
);
JSONObject
hljsThemeOpt
=
optionRepository
.
get
(
Option
.
ID_C_HLJS_THEME
);
if
(
null
==
hljsThemeOpt
)
{
hljsThemeOpt
=
new
JSONObject
();
...
...
src/main/java/org/b3log/solo/util/Skins.java
View file @
bc29399f
...
...
@@ -33,7 +33,6 @@ import org.b3log.latke.util.Locales;
import
org.b3log.latke.util.Stopwatchs
;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.Skin
;
import
javax.servlet.ServletContext
;
import
javax.servlet.http.Cookie
;
...
...
@@ -48,7 +47,7 @@ import java.util.*;
* Skin utilities.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.6.
5, Feb 26
, 2019
* @version 1.1.6.
6, Mar 29
, 2019
* @since 0.3.1
*/
public
final
class
Skins
{
...
...
@@ -120,7 +119,7 @@ public final class Skins {
}
/**
* Fills the specified data model with the current skin
k's (WebRoot/skins/${skin
Name}/lang/lang_xx_XX.properties)
* Fills the specified data model with the current skin
's (WebRoot/skins/${skinDir
Name}/lang/lang_xx_XX.properties)
* and core language (WebRoot/WEB-INF/classes/lang_xx_XX.properties) configurations.
*
* @param localeString the specified locale string
...
...
@@ -218,12 +217,8 @@ public final class Skins {
* @return directory name, or {@code null} if not found
*/
public
static
String
getSkinDirName
(
final
RequestContext
context
)
{
if
(
Solos
.
isMobile
(
context
.
getRequest
()))
{
return
Solos
.
MOBILE_SKIN
;
}
// 1. Get skin from query
final
String
specifiedSkin
=
context
.
param
(
Skin
.
SKIN
);
final
String
specifiedSkin
=
context
.
param
(
Option
.
CATEGORY_C_
SKIN
);
if
(
StringUtils
.
isNotBlank
(
specifiedSkin
))
{
final
Set
<
String
>
skinDirNames
=
Skins
.
getSkinDirNames
();
if
(
skinDirNames
.
contains
(
specifiedSkin
))
{
...
...
@@ -247,7 +242,7 @@ public final class Skins {
final
Cookie
[]
cookies
=
request
.
getCookies
();
if
(
null
!=
cookies
)
{
for
(
final
Cookie
cookie
:
cookies
)
{
if
(
Skin
.
SKIN
.
equals
(
cookie
.
getName
()))
{
if
(
Option
.
CATEGORY_C_
SKIN
.
equals
(
cookie
.
getName
()))
{
final
String
skin
=
cookie
.
getValue
();
final
Set
<
String
>
skinDirNames
=
Skins
.
getSkinDirNames
();
...
...
src/main/java/org/b3log/solo/util/Solos.java
View file @
bc29399f
...
...
@@ -36,7 +36,6 @@ import org.b3log.latke.util.Strings;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.model.Article
;
import
org.b3log.solo.model.Common
;
import
org.b3log.solo.model.Option
;
import
org.b3log.solo.model.UserExt
;
import
org.b3log.solo.repository.UserRepository
;
import
org.json.JSONObject
;
...
...
@@ -54,7 +53,7 @@ import java.util.ResourceBundle;
* Solo utilities.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.8.0.
0, Mar 20
, 2019
* @version 1.8.0.
1, Mar 29
, 2019
* @since 2.8.0
*/
public
final
class
Solos
{
...
...
@@ -74,11 +73,6 @@ public final class Solos {
*/
public
static
final
String
GRAVATAR
;
/**
* Mobile skin.
*/
public
static
final
String
MOBILE_SKIN
;
/**
* Solo User-Agent.
*/
...
...
@@ -114,13 +108,6 @@ public final class Solos {
FAVICON_API
=
solo
.
getString
(
"faviconAPI"
);
GRAVATAR
=
solo
.
getString
(
"gravatar"
);
String
mobileSkin
=
Option
.
DefaultPreference
.
DEFAULT_SKIN_DIR_NAME
;
try
{
mobileSkin
=
solo
.
getString
(
"mobile.skin"
);
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
WARN
,
"Loads [mobile.skin] in solo.props failed ["
+
e
.
getMessage
()
+
"], using ["
+
mobileSkin
+
"] as the default mobile skin"
);
}
MOBILE_SKIN
=
mobileSkin
;
}
static
{
...
...
src/main/resources/solo.properties
View file @
bc29399f
...
...
@@ -18,11 +18,9 @@
#
# Description: Solo configurations.
# Version: 2.
4.0.5, Feb 28
, 2019
# Version: 2.
5.0.0, Mar 29
, 2019
# Author: Liang Ding
#
mobile.skin
=
Pinghsu
gravatar
=
https://secure.gravatar.com/avatar/
faviconAPI
=
https://api.byi.pw/favicon?url=
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment