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 PrefenrenceEntry:
__name:str
__type:Type[T]
__default:T
def __init__(self, name:str, type:Type[T], default:T):
self.__name = name
self.__type = type
self.__default = default
@property
def type(self):
return self.__type
@property
def modify_method(self):
return self.__method
@property
def name(self):
return self.__name
@property
def default(self):
return self.__default
def get_element_names(self) -> List[str]:
return []
def get_element_name(cls) -> 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):
type = self.__type
match 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(type)
class PrefenrenceHiddenEntry(PrefenrenceEntry):
def get_element_names(self):
return []
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 PrefenrenceChoiceEntry(PrefenrenceEntry):
def __init__(self, name, type, default, values:List[T]):
super().__init__(name, 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 PrefenrenceBoolEntry(PrefenrenceEntry):
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 PrefenrenceResetEntry(PrefenrenceHiddenEntry):
def __init__(self, name, type, default, reset_value):
super().__init__(name, type, default)
self.__reset_value = reset_value
@property
def reset_value(self):
return self.__reset_value
class PreferenceManager:
__entries:Dict[str, PrefenrenceEntry] = {}
@classmethod
def add_entries(cls, entries:Iterable[PrefenrenceEntry]):
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(self):
return self.__entries.values()
PreferenceManager.add_entries([
PrefenrenceChoiceEntry('Skin', str, 'basic',
['basic', 'newra', 'classic',]),
PrefenrenceChoiceEntry('Edition', str, 'standard',
['standard', 'light']),
PrefenrenceBoolEntry('HideWIP', bool, False),
PrefenrenceBoolEntry('HideLaunchButton', bool, False),
PrefenrenceBoolEntry('HideDownloadButton', bool, False),
PrefenrenceBoolEntry('HideServerJarButton', bool, False),
PrefenrenceResetEntry('mod', bool, False, True),
PrefenrenceResetEntry('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, PrefenrenceResetEntry):
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, PrefenrenceHiddenEntry):
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'] = PrefenrenceChoiceEntry.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'] = PrefenrenceBoolEntry.get_element_name_by_value(pref_key)
data['check'] = PreferenceManager.is_using(context, pref_key, True)
return context.components['Preference/PreferenceCheckBox'].toxaml(data, context)