2018-10-28 09:10:56 +01:00
/ *
* This file is part of Player Analytics ( Plan ) .
*
* Plan is free software : you can redistribute it and / or modify
2018-11-11 19:55:11 +01:00
* it under the terms of the GNU Lesser General Public License v3 as published by
2018-10-28 09:10:56 +01:00
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Plan 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
2018-11-11 19:55:11 +01:00
* GNU Lesser General Public License for more details .
2018-10-28 09:10:56 +01:00
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan . If not , see < https : //www.gnu.org/licenses/>.
* /
2019-08-30 22:14:54 +02:00
package com.djrapitops.plan.settings.locale ;
2018-07-28 17:31:07 +02:00
2019-08-30 22:14:54 +02:00
import com.djrapitops.plan.SubSystem ;
2023-08-20 10:56:13 +02:00
import com.djrapitops.plan.delivery.domain.auth.WebPermission ;
2022-08-28 09:21:46 +02:00
import com.djrapitops.plan.delivery.web.AssetVersions ;
2019-08-30 22:14:54 +02:00
import com.djrapitops.plan.delivery.webserver.auth.FailReason ;
import com.djrapitops.plan.settings.config.PlanConfig ;
import com.djrapitops.plan.settings.config.paths.PluginSettings ;
import com.djrapitops.plan.settings.locale.lang.* ;
2022-04-06 16:37:23 +02:00
import com.djrapitops.plan.storage.file.FileResource ;
2019-08-30 22:14:54 +02:00
import com.djrapitops.plan.storage.file.PlanFiles ;
2020-05-15 11:20:29 +02:00
import com.djrapitops.plan.utilities.logging.ErrorContext ;
2020-05-14 15:57:29 +02:00
import com.djrapitops.plan.utilities.logging.ErrorLogger ;
2021-03-09 10:36:07 +01:00
import net.playeranalytics.plugin.server.PluginLogger ;
2018-07-28 17:31:07 +02:00
2018-08-23 09:20:58 +02:00
import javax.inject.Inject ;
import javax.inject.Singleton ;
2018-07-28 17:31:07 +02:00
import java.io.File ;
import java.io.IOException ;
import java.util.Arrays ;
import java.util.Map ;
2018-08-23 09:20:58 +02:00
import java.util.Optional ;
2018-07-28 17:31:07 +02:00
import java.util.function.Function ;
import java.util.stream.Collectors ;
/ * *
* System in charge of { @link Locale } .
*
2021-02-13 14:16:03 +01:00
* @author AuroraLS3
2018-07-28 17:31:07 +02:00
* /
2018-08-23 09:20:58 +02:00
@Singleton
2018-07-28 17:31:07 +02:00
public class LocaleSystem implements SubSystem {
2018-09-29 11:44:56 +02:00
private final PlanFiles files ;
2018-08-23 09:20:58 +02:00
private final PlanConfig config ;
2022-08-28 09:21:46 +02:00
private final AssetVersions assetVersions ;
2018-08-23 09:20:58 +02:00
private final PluginLogger logger ;
2020-05-14 15:57:29 +02:00
private final ErrorLogger errorLogger ;
2018-07-28 17:31:07 +02:00
2018-08-23 09:20:58 +02:00
private final Locale locale ;
@Inject
public LocaleSystem (
2018-09-29 11:44:56 +02:00
PlanFiles files ,
2018-08-23 09:20:58 +02:00
PlanConfig config ,
2022-08-28 09:21:46 +02:00
AssetVersions assetVersions ,
2018-08-23 09:20:58 +02:00
PluginLogger logger ,
2020-05-14 15:57:29 +02:00
ErrorLogger errorLogger
2018-08-23 09:20:58 +02:00
) {
2018-09-29 11:44:56 +02:00
this . files = files ;
2018-08-23 09:20:58 +02:00
this . config = config ;
2022-08-28 09:21:46 +02:00
this . assetVersions = assetVersions ;
2018-08-23 09:20:58 +02:00
this . logger = logger ;
2020-05-14 15:57:29 +02:00
this . errorLogger = errorLogger ;
2018-07-28 23:16:42 +02:00
this . locale = new Locale ( ) ;
}
2022-08-28 09:11:37 +02:00
/ * *
* Get the txt keys of all Lang entries ( legacy locale files that need yml conversion ) .
*
* @return Map of txt key ( eg { @code " HTML - LOGIN_CREATE_ACCOUNT " } ) - Lang ( eg . { @link HtmlLang # LOGIN_CREATE_ACCOUNT } )
* /
2018-07-28 17:31:07 +02:00
public static Map < String , Lang > getIdentifiers ( ) {
2022-04-06 16:37:23 +02:00
return Arrays . stream ( getValuesArray ( ) )
. flatMap ( Arrays : : stream )
. collect ( Collectors . toMap ( Lang : : getIdentifier , Function . identity ( ) ) ) ;
}
2022-08-28 09:11:37 +02:00
/ * *
* Get the yml keys of all Lang entries .
*
* @return Map of yml key ( eg . { @code " html.login.register " } ) - Lang ( eg . { @link HtmlLang # LOGIN_CREATE_ACCOUNT } )
* /
2022-04-06 16:37:23 +02:00
public static Map < String , Lang > getKeys ( ) {
return Arrays . stream ( getValuesArray ( ) )
. flatMap ( Arrays : : stream )
. collect ( Collectors . toMap ( Lang : : getKey , Function . identity ( ) ) ) ;
}
private static Lang [ ] [ ] getValuesArray ( ) {
return new Lang [ ] [ ] {
2018-07-29 09:58:00 +02:00
CommandLang . values ( ) ,
2018-07-28 21:53:11 +02:00
DeepHelpLang . values ( ) ,
2018-07-30 09:26:48 +02:00
ErrorPageLang . values ( ) ,
2019-09-28 09:34:34 +02:00
FailReason . values ( ) ,
2021-01-30 12:38:41 +01:00
FilterLang . values ( ) ,
GenericLang . values ( ) ,
HelpLang . values ( ) ,
HtmlLang . values ( ) ,
2019-09-28 09:34:34 +02:00
JSLang . values ( ) ,
2021-01-30 12:38:41 +01:00
PluginLang . values ( ) ,
2023-08-20 10:56:13 +02:00
WebPermission . values ( ) ,
2018-07-28 17:31:07 +02:00
} ;
}
@Override
2018-08-23 09:20:58 +02:00
public void enable ( ) {
2022-04-06 16:37:23 +02:00
convertFromLegacyFormat ( ) ;
2018-09-29 11:44:56 +02:00
File localeFile = files . getLocaleFile ( ) ;
2018-07-28 17:31:07 +02:00
2018-12-08 10:44:10 +01:00
if ( config . isTrue ( PluginSettings . WRITE_NEW_LOCALE ) ) {
2018-07-28 17:31:07 +02:00
writeNewDefaultLocale ( localeFile ) ;
}
2018-08-23 09:20:58 +02:00
Optional < Locale > loaded ;
2018-07-28 17:31:07 +02:00
if ( localeFile . exists ( ) ) {
2023-04-07 13:31:24 +02:00
writeNewDefaultLocale ( localeFile ) ;
2018-08-23 09:20:58 +02:00
loaded = loadFromFile ( localeFile ) ;
2018-07-28 17:31:07 +02:00
} else {
2018-08-23 09:20:58 +02:00
loaded = loadSettingLocale ( ) ;
2018-07-28 17:31:07 +02:00
}
2018-08-23 09:20:58 +02:00
loaded . ifPresent ( locale : : loadFromAnotherLocale ) ;
2019-04-20 11:04:07 +02:00
LangCode langCode = locale . getLangCode ( ) ;
logger . info ( " Locale: ' " + langCode . getName ( ) + " ' by " + langCode . getAuthors ( ) ) ;
2018-07-28 17:31:07 +02:00
}
private void writeNewDefaultLocale ( File localeFile ) {
try {
2019-09-09 16:28:00 +02:00
Locale writing = loadSettingLocale ( ) . orElse ( locale ) ;
if ( localeFile . exists ( ) ) {
writing . putAll ( Locale . fromFile ( localeFile ) ) ;
}
new LocaleFileWriter ( writing ) . writeToFile ( localeFile ) ;
2018-07-29 12:15:31 +02:00
} catch ( IOException | IllegalStateException e ) {
2021-03-09 10:36:07 +01:00
errorLogger . error ( e , ErrorContext . builder ( ) . whatToDo ( " Fix write permissions to " + localeFile . getAbsolutePath ( ) ) . build ( ) ) ;
2018-08-23 09:20:58 +02:00
}
resetWriteConfigSetting ( ) ;
}
private void resetWriteConfigSetting ( ) {
try {
2018-12-08 10:44:10 +01:00
config . set ( PluginSettings . WRITE_NEW_LOCALE , false ) ;
2018-08-23 09:20:58 +02:00
config . save ( ) ;
} catch ( IOException | IllegalStateException e ) {
2021-03-09 10:36:07 +01:00
errorLogger . error ( e , ErrorContext . builder ( ) . whatToDo ( " Fix write permissions to " + config . getConfigFilePath ( ) ) . build ( ) ) ;
2018-07-28 17:31:07 +02:00
}
}
2022-04-06 16:37:23 +02:00
private void convertFromLegacyFormat ( ) {
File oldCustomFile = files . getFileFromPluginFolder ( " locale.txt " ) ;
if ( ! files . getLocaleFile ( ) . exists ( ) & & oldCustomFile . exists ( ) ) {
try {
logger . info ( " Converting locale.txt to yml... " ) ;
Locale loaded = new LocaleFileReader ( new FileResource ( " locale.txt " , oldCustomFile ) ) . loadLegacy ( LangCode . CUSTOM ) ;
new LocaleFileWriter ( loaded ) . writeToFile ( files . getLocaleFile ( ) ) ;
} catch ( IOException e ) {
errorLogger . error ( e , ErrorContext . builder ( ) . whatToDo ( " Fix write permissions to " + files . getLocaleFile ( ) . toString ( ) ) . build ( ) ) ;
}
}
for ( LangCode code : LangCode . values ( ) ) {
if ( code = = LangCode . CUSTOM ) continue ;
File oldFile = files . getFileFromPluginFolder ( " locale_ " + code + " .txt " ) ;
if ( ! files . getFileFromPluginFolder ( code . getFileName ( ) ) . exists ( ) & & oldFile . exists ( ) ) {
try {
logger . info ( " Converting " + oldFile . getName ( ) + " to yml... " ) ;
Locale loaded = new LocaleFileReader ( new FileResource ( oldFile . getName ( ) , oldFile ) ) . loadLegacy ( LangCode . CUSTOM ) ;
new LocaleFileWriter ( loaded ) . writeToFile ( files . getFileFromPluginFolder ( code . getFileName ( ) ) ) ;
} catch ( IOException e ) {
errorLogger . error ( e , ErrorContext . builder ( ) . whatToDo ( " Fix write permissions to " + files . getFileFromPluginFolder ( code . getFileName ( ) ) . toString ( ) ) . build ( ) ) ;
}
}
}
}
2018-08-23 09:20:58 +02:00
private Optional < Locale > loadSettingLocale ( ) {
2018-07-28 17:31:07 +02:00
try {
2018-12-16 13:37:38 +01:00
String setting = config . get ( PluginSettings . LOCALE ) ;
2020-10-11 14:04:10 +02:00
if ( " write-all " . equalsIgnoreCase ( setting ) ) {
for ( LangCode code : LangCode . values ( ) ) {
if ( code = = LangCode . CUSTOM ) continue ;
2020-11-05 22:16:01 +01:00
Locale writing = Locale . forLangCode ( code , files ) ;
new LocaleFileWriter ( writing ) . writeToFile (
2022-04-06 16:37:23 +02:00
files . getDataDirectory ( ) . resolve ( " locale_ " + code . name ( ) + " .yml " ) . toFile ( )
2020-10-11 14:04:10 +02:00
) ;
}
return Optional . empty ( ) ;
}
2019-01-03 13:04:26 +01:00
if ( ! " default " . equalsIgnoreCase ( setting ) ) {
2019-04-03 18:24:19 +02:00
return Optional . of ( Locale . forLangCodeString ( files , setting ) ) ;
2018-08-23 09:20:58 +02:00
}
2018-07-28 17:31:07 +02:00
} catch ( IOException e ) {
2022-04-06 16:37:23 +02:00
logger . warn ( " Failed to read locale from jar: " + config . get ( PluginSettings . LOCALE ) + " , " + e ) ;
2018-08-23 09:20:58 +02:00
logger . warn ( " Using Default Locale as a fallback (EN) " ) ;
2018-07-28 17:31:07 +02:00
}
2018-08-23 09:20:58 +02:00
return Optional . empty ( ) ;
2018-07-28 17:31:07 +02:00
}
2018-08-23 09:20:58 +02:00
private Optional < Locale > loadFromFile ( File localeFile ) {
2018-07-28 17:31:07 +02:00
try {
2018-08-23 09:20:58 +02:00
return Optional . of ( Locale . fromFile ( localeFile ) ) ;
2018-07-28 17:31:07 +02:00
} catch ( IOException e ) {
2022-04-06 16:37:23 +02:00
logger . warn ( " Failed to read locale file at " + localeFile . getAbsolutePath ( ) + " , " + e ) ;
2018-08-23 09:20:58 +02:00
logger . warn ( " Using Default Locale as a fallback (EN) " ) ;
2018-07-28 17:31:07 +02:00
}
2018-08-23 09:20:58 +02:00
return Optional . empty ( ) ;
2018-07-28 17:31:07 +02:00
}
@Override
public void disable ( ) {
// No action necessary on disable.
}
public Locale getLocale ( ) {
return locale ;
}
2022-04-06 16:37:23 +02:00
2022-08-28 09:21:46 +02:00
public long getMaxLocaleVersion ( ) {
return assetVersions . getLatestWebAssetVersion ( ) . orElse ( 0L ) ;
}
public Optional < Long > getLocaleVersion ( LangCode langCode ) {
return assetVersions . getAssetVersion ( langCode . getFileName ( ) ) ;
2022-04-06 16:37:23 +02:00
}
public Optional < Long > getCustomLocaleVersion ( ) {
File localeFile = files . getLocaleFile ( ) ;
if ( ! localeFile . exists ( ) ) {
return Optional . empty ( ) ;
}
return Optional . of ( localeFile . lastModified ( ) ) ;
}
2018-07-28 17:31:07 +02:00
}