homepage_preference.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from homepagebuilder.interfaces import script, config, require
  2. from homepagebuilder.core.types import Context
  3. from homepagebuilder.core.formatter import format_code
  4. from typing import Type, TypeVar, Dict, List, Iterable, Optional
  5. from enum import Enum
  6. T = TypeVar('T')
  7. def is_true(obj:str):
  8. if isinstance(obj, bool):
  9. return obj
  10. if isinstance(obj, str):
  11. return obj.lower() == 'true' or obj == ''
  12. GET_DOMAIN_URL = require('domain').get_doamin_url
  13. class PrefenrenceEntry:
  14. __name:str
  15. __type:Type[T]
  16. __default:T
  17. def __init__(self, name:str, type:Type[T], default:T):
  18. self.__name = name
  19. self.__type = type
  20. self.__default = default
  21. @property
  22. def type(self):
  23. return self.__type
  24. @property
  25. def modify_method(self):
  26. return self.__method
  27. @property
  28. def name(self):
  29. return self.__name
  30. @property
  31. def default(self):
  32. return self.__default
  33. def get_element_names(self) -> List[str]:
  34. return []
  35. def get_element_name(cls) -> str:
  36. raise NotImplementedError()
  37. @classmethod
  38. def binding(cls, name) -> str:
  39. raise NotImplementedError()
  40. def get_value_from_save_page(self, settings):
  41. raise NotImplementedError()
  42. def convert_value(self, value):
  43. type = self.__type
  44. match type.__name__:
  45. case 'str':
  46. if isinstance(value, str):
  47. return value
  48. else:
  49. return str(value)
  50. case 'bool':
  51. if isinstance(value, str):
  52. return value.lower() == 'true' or value == ''
  53. else:
  54. return bool(value)
  55. case _:
  56. raise TypeError(type)
  57. class PrefenrenceHiddenEntry(PrefenrenceEntry):
  58. def get_element_names(self):
  59. return []
  60. def get_element_name(cls, name:str) -> str:
  61. raise NotImplementedError()
  62. @classmethod
  63. def binding(cls, name):
  64. raise NotImplementedError()
  65. def get_value_from_save_page(self, settings):
  66. return settings.get(self.name, self.default)
  67. class PrefenrenceChoiceEntry(PrefenrenceEntry):
  68. def __init__(self, name, type, default, values:List[T]):
  69. super().__init__(name, type, default)
  70. self.__values = values
  71. def get_element_names(self):
  72. return [self.get_element_name(value) for value in self.__values]
  73. def get_element_name(self, value):
  74. return self.get_element_name_by_value(self.name, value)
  75. @classmethod
  76. def get_element_name_by_value(cls, name, value):
  77. return name + value
  78. @classmethod
  79. def binding(cls, name):
  80. return f'<Binding Path="Checked" ElementName="{name}"/>'
  81. def get_value_from_save_page(self, settings):
  82. for value in self.__values:
  83. if is_true(settings.get(self.get_element_name(value))):
  84. return value
  85. return self.default
  86. class PrefenrenceBoolEntry(PrefenrenceEntry):
  87. def get_element_names(self):
  88. return [self.get_element_name()]
  89. def get_element_name(self):
  90. return self.get_element_name_by_value(self.name)
  91. @classmethod
  92. def binding(cls, name):
  93. return f'<Binding Path="Checked" ElementName="{name}"/>'
  94. @classmethod
  95. def get_element_name_by_value(cls, name):
  96. return name
  97. def get_value_from_save_page(self, settings):
  98. return is_true(settings.get(self.get_element_name(), self.default))
  99. class PrefenrenceResetEntry(PrefenrenceHiddenEntry):
  100. def __init__(self, name, type, default, reset_value):
  101. super().__init__(name, type, default)
  102. self.__reset_value = reset_value
  103. @property
  104. def reset_value(self):
  105. return self.__reset_value
  106. class PreferenceManager:
  107. __entries:Dict[str, PrefenrenceEntry] = {}
  108. @classmethod
  109. def add_entries(cls, entries:Iterable[PrefenrenceEntry]):
  110. for entry in entries:
  111. cls.__entries[entry.name] = entry
  112. @classmethod
  113. def has(cls, item):
  114. if isinstance(item, str):
  115. return item in cls.__entries
  116. raise TypeError()
  117. @classmethod
  118. def get(cls, key:str, default = None):
  119. return cls.__entries.get(key, default)
  120. @classmethod
  121. def is_using(cls, context:'Context', key, value) -> bool:
  122. entry = cls.get(key)
  123. if not entry:
  124. return False
  125. settings = context.setter.toProperties().get('args',{})
  126. current_value = settings.get(key)
  127. if current_value is not None:
  128. if value == True:
  129. return is_true(current_value)
  130. else:
  131. return current_value == value
  132. else:
  133. return entry.default == value
  134. @classmethod
  135. def pref_length(cls):
  136. return len(cls.__entries)
  137. @classmethod
  138. def get_entries(self):
  139. return self.__entries.values()
  140. PreferenceManager.add_entries([
  141. PrefenrenceChoiceEntry('Skin', str, 'basic',
  142. ['basic', 'newra', 'classic',]),
  143. PrefenrenceChoiceEntry('Edition', str, 'standard',
  144. ['standard', 'light']),
  145. PrefenrenceBoolEntry('HideWIP', bool, False),
  146. PrefenrenceBoolEntry('HideLaunchButton', bool, False),
  147. PrefenrenceBoolEntry('HideDownloadButton', bool, False),
  148. PrefenrenceBoolEntry('HideServerJarButton', bool, False),
  149. PrefenrenceResetEntry('mod', bool, False, True),
  150. PrefenrenceResetEntry('beta', bool, False, False)
  151. ])
  152. @script('IsUsingPreset')
  153. def get(content, context:'Context', *_args, **_kwargs):
  154. settings = context.setter.toProperties().get('args',{})
  155. if not is_true(settings.get('mod')):
  156. return content
  157. else:
  158. return ''
  159. @script('PreferenceUrl')
  160. def get_preferece_url(context:'Context', *_args, **_kwargs):
  161. settings = context.setter.toProperties().get('args',{})
  162. args = []
  163. url = GET_DOMAIN_URL(context)
  164. for entry in PreferenceManager.get_entries():
  165. value = entry.get_value_from_save_page(settings=settings)
  166. value = entry.convert_value(value)
  167. if isinstance(entry, PrefenrenceResetEntry):
  168. value = entry.reset_value
  169. if value != entry.default:
  170. if value == True:
  171. args.append(entry.name)
  172. else:
  173. args.append(entry.name + '=' + value)
  174. if len(args) > 0:
  175. url += '?' + '&amp;'.join(args)
  176. return url
  177. @script('PreferenceSavePageUrl')
  178. def preferece_save_page_url(context:'Context', *_args, **_kwargs):
  179. settings = context.setter.toProperties().get('args',{})
  180. string_format = '{}' + GET_DOMAIN_URL(context) + 'SaveChanges.json?'
  181. bindings = ''
  182. i = 0
  183. for entry in PreferenceManager.get_entries():
  184. if isinstance(entry, PrefenrenceHiddenEntry):
  185. value = settings.get(entry.name)
  186. if value is not None:
  187. value = entry.convert_value(value)
  188. string_format += f'{entry.name}={value}&amp;'
  189. continue
  190. for name in entry.get_element_names():
  191. string_format += f'{name}={{{i}}}&amp;'
  192. bindings += entry.binding(name)
  193. i += 1
  194. return f'<MultiBinding StringFormat="{string_format}">{bindings}</MultiBinding>'
  195. @script('PreferenceRadioBox')
  196. def preferece_radio(pref_key, pref_value, column, row, content, context:'Context', **_kwargs):
  197. data = {}
  198. data['column'] = column
  199. data['row'] = row
  200. data['content'] = content
  201. data['element_key'] = PrefenrenceChoiceEntry.get_element_name_by_value(pref_key, pref_value)
  202. data['check'] = PreferenceManager.is_using(context, pref_key, pref_value)
  203. return context.components['Preference/PreferenceRadioBox'].toxaml(data, context)
  204. @script('PreferenceCheckBox')
  205. def preferece_check(pref_key, content, context:'Context', **_kwargs):
  206. data = {}
  207. data['content'] = content
  208. data['element_key'] = PrefenrenceBoolEntry.get_element_name_by_value(pref_key)
  209. data['check'] = PreferenceManager.is_using(context, pref_key, True)
  210. return context.components['Preference/PreferenceCheckBox'].toxaml(data, context)