from homepagebuilder.interfaces import script, config, require
from homepagebuilder.core.types import Context
from homepagebuilder.core.formatter import format_code
from typing import Type, TypeVar, Dict, List, Iterable, Optional
from enum import Enum
T = TypeVar('T')
def is_true(obj:str):
if isinstance(obj, bool):
return obj
if isinstance(obj, str):
return obj.lower() == 'true' or obj == ''
GET_DOMAIN_URL = require('domain').get_doamin_url
class PreferenceEntry:
def __init__(self, name:str, value_type:Type[T], default:T):
self.__name = name
self.__value_type = value_type
self.__default = default
@property
def value_type(self):
"""返回值类型"""
return self.__value_type
@property
def name(self):
"""名称"""
return self.__name
@property
def default(self):
"""默认值"""
return self.__default
def get_element_names(self) -> List[str]:
return []
@classmethod
def get_element_name(cls, *args, **kwargs) -> str:
"""返回设置该项的元素名称"""
raise NotImplementedError()
@classmethod
def binding(cls, name) -> str:
"""返回绑定代码"""
raise NotImplementedError()
def get_value_from_save_page(self, settings):
raise NotImplementedError()
def convert_value(self, value):
value_type = self.__value_type
match value_type.__name__:
case 'str':
if isinstance(value, str):
return value
else:
return str(value)
case 'bool':
if isinstance(value, str):
return value.lower() == 'true' or value == ''
else:
return bool(value)
case _:
raise TypeError(value_type)
class PreferenceHiddenEntry(PreferenceEntry):
def get_element_names(self):
return []
@classmethod
def get_element_name(cls, name:str) -> str:
raise NotImplementedError()
@classmethod
def binding(cls, name):
raise NotImplementedError()
def get_value_from_save_page(self, settings):
return settings.get(self.name, self.default)
class PreferenceChoiceEntry(PreferenceEntry):
def __init__(self, name, value_type, default, values:List[T]):
super().__init__(name, value_type, default)
self.__values = values
def get_element_names(self):
return [self.get_element_name(value) for value in self.__values]
def get_element_name(self, value):
return self.get_element_name_by_value(self.name, value)
@classmethod
def get_element_name_by_value(cls, name, value):
return name + value
@classmethod
def binding(cls, name):
return f''
def get_value_from_save_page(self, settings):
for value in self.__values:
if is_true(settings.get(self.get_element_name(value))):
return value
return self.default
class PreferenceBoolEntry(PreferenceEntry):
def get_element_names(self):
return [self.get_element_name()]
def get_element_name(self):
return self.get_element_name_by_value(self.name)
@classmethod
def binding(cls, name):
return f''
@classmethod
def get_element_name_by_value(cls, name):
return name
def get_value_from_save_page(self, settings):
return is_true(settings.get(self.get_element_name(), self.default))
class PreferenceResetEntry(PreferenceHiddenEntry):
def __init__(self, name, value_type, default, reset_value):
super().__init__(name, value_type, default)
self.__reset_value = reset_value
@property
def reset_value(self):
return self.__reset_value
class PreferenceManager:
__entries:Dict[str, PreferenceEntry] = {}
@classmethod
def add_entries(cls, entries:Iterable[PreferenceEntry]):
for entry in entries:
cls.__entries[entry.name] = entry
@classmethod
def has(cls, item):
if isinstance(item, str):
return item in cls.__entries
raise TypeError()
@classmethod
def get(cls, key:str, default = None):
return cls.__entries.get(key, default)
@classmethod
def is_using(cls, context:'Context', key, value) -> bool:
entry = cls.get(key)
if not entry:
return False
settings = context.setter.toProperties().get('args',{})
current_value = settings.get(key)
if current_value is not None:
if value == True:
return is_true(current_value)
else:
return current_value == value
else:
return entry.default == value
@classmethod
def pref_length(cls):
return len(cls.__entries)
@classmethod
def get_entries(cls):
return cls.__entries.values()
PreferenceManager.add_entries([
PreferenceHiddenEntry('debug', bool, False),
PreferenceChoiceEntry('Skin', str, 'basic',
['basic', 'newra', 'classic',]),
PreferenceChoiceEntry('Edition', str, 'standard',
['standard', 'light']),
PreferenceBoolEntry('HideWIP', bool, False),
PreferenceBoolEntry('HideLaunchButton', bool, False),
PreferenceBoolEntry('HideDownloadButton', bool, False),
PreferenceBoolEntry('HideServerJarButton', bool, False),
PreferenceResetEntry('mod', bool, False, True),
PreferenceResetEntry('beta', bool, False, False)
])
@script('IsUsingPreset')
def get(content, context:'Context', *_args, **_kwargs):
settings = context.setter.toProperties().get('args',{})
if not is_true(settings.get('mod')):
return content
else:
return ''
@script('PreferenceUrl')
def get_preferece_url(context:'Context', *_args, **_kwargs):
settings = context.setter.toProperties().get('args',{})
args = []
url = GET_DOMAIN_URL(context)
for entry in PreferenceManager.get_entries():
value = entry.get_value_from_save_page(settings=settings)
value = entry.convert_value(value)
if isinstance(entry, PreferenceResetEntry):
value = entry.reset_value
if value != entry.default:
if value == True:
args.append(entry.name)
else:
args.append(entry.name + '=' + value)
if len(args) > 0:
url += '?' + '&'.join(args)
return url
@script('PreferenceSavePageUrl')
def preferece_save_page_url(context:'Context', *_args, **_kwargs):
settings = context.setter.toProperties().get('args',{})
string_format = '{}' + GET_DOMAIN_URL(context) + 'SaveChanges.json?'
bindings = ''
i = 0
for entry in PreferenceManager.get_entries():
if isinstance(entry, PreferenceHiddenEntry):
value = settings.get(entry.name)
if value is not None:
value = entry.convert_value(value)
string_format += f'{entry.name}={value}&'
continue
for name in entry.get_element_names():
string_format += f'{name}={{{i}}}&'
bindings += entry.binding(name)
i += 1
return f'{bindings}'
@script('PreferenceRadioBox')
def preferece_radio(pref_key, pref_value, column, row, content, context:'Context', **_kwargs):
data = {}
data['column'] = column
data['row'] = row
data['content'] = content
data['element_key'] = PreferenceChoiceEntry.get_element_name_by_value(pref_key, pref_value)
data['check'] = PreferenceManager.is_using(context, pref_key, pref_value)
return context.components['Preference/PreferenceRadioBox'].toxaml(data, context)
@script('PreferenceCheckBox')
def preferece_check(pref_key, content, context:'Context', **_kwargs):
data = {}
data['content'] = content
data['element_key'] = PreferenceBoolEntry.get_element_name_by_value(pref_key)
data['check'] = PreferenceManager.is_using(context, pref_key, True)
return context.components['Preference/PreferenceCheckBox'].toxaml(data, context)