homepage_preference.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 PreferenceEntry:
  14. def __init__(self, name:str, value_type:Type[T], default:T):
  15. self.__name = name
  16. self.__value_type = value_type
  17. self.__default = default
  18. @property
  19. def value_type(self):
  20. """返回值类型"""
  21. return self.__value_type
  22. @property
  23. def name(self):
  24. """名称"""
  25. return self.__name
  26. @property
  27. def default(self):
  28. """默认值"""
  29. return self.__default
  30. def get_element_names(self) -> List[str]:
  31. return []
  32. @classmethod
  33. def get_element_name(cls, *args, **kwargs) -> str:
  34. """返回设置该项的元素名称"""
  35. raise NotImplementedError()
  36. @classmethod
  37. def binding(cls, name) -> str:
  38. """返回绑定代码"""
  39. raise NotImplementedError()
  40. def get_value_from_save_page(self, settings):
  41. raise NotImplementedError()
  42. def convert_value(self, value):
  43. value_type = self.__value_type
  44. match value_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(value_type)
  57. class PreferenceHiddenEntry(PreferenceEntry):
  58. def get_element_names(self):
  59. return []
  60. @classmethod
  61. def get_element_name(cls, name:str) -> str:
  62. raise NotImplementedError()
  63. @classmethod
  64. def binding(cls, name):
  65. raise NotImplementedError()
  66. def get_value_from_save_page(self, settings):
  67. return settings.get(self.name, self.default)
  68. class PreferenceChoiceEntry(PreferenceEntry):
  69. def __init__(self, name, value_type, default, values:List[T]):
  70. super().__init__(name, value_type, default)
  71. self.__values = values
  72. def get_element_names(self):
  73. return [self.get_element_name(value) for value in self.__values]
  74. def get_element_name(self, value):
  75. return self.get_element_name_by_value(self.name, value)
  76. @classmethod
  77. def get_element_name_by_value(cls, name, value):
  78. return name + value
  79. @classmethod
  80. def binding(cls, name):
  81. return f'<Binding Path="Checked" ElementName="{name}"/>'
  82. def get_value_from_save_page(self, settings):
  83. for value in self.__values:
  84. if is_true(settings.get(self.get_element_name(value))):
  85. return value
  86. return self.default
  87. class PreferenceBoolEntry(PreferenceEntry):
  88. def get_element_names(self):
  89. return [self.get_element_name()]
  90. def get_element_name(self):
  91. return self.get_element_name_by_value(self.name)
  92. @classmethod
  93. def binding(cls, name):
  94. return f'<Binding Path="Checked" ElementName="{name}"/>'
  95. @classmethod
  96. def get_element_name_by_value(cls, name):
  97. return name
  98. def get_value_from_save_page(self, settings):
  99. return is_true(settings.get(self.get_element_name(), self.default))
  100. class PreferenceResetEntry(PreferenceHiddenEntry):
  101. def __init__(self, name, value_type, default, reset_value):
  102. super().__init__(name, value_type, default)
  103. self.__reset_value = reset_value
  104. @property
  105. def reset_value(self):
  106. return self.__reset_value
  107. class PreferenceManager:
  108. __entries:Dict[str, PreferenceEntry] = {}
  109. @classmethod
  110. def add_entries(cls, entries:Iterable[PreferenceEntry]):
  111. for entry in entries:
  112. cls.__entries[entry.name] = entry
  113. @classmethod
  114. def has(cls, item):
  115. if isinstance(item, str):
  116. return item in cls.__entries
  117. raise TypeError()
  118. @classmethod
  119. def get(cls, key:str, default = None):
  120. return cls.__entries.get(key, default)
  121. @classmethod
  122. def is_using(cls, context:'Context', key, value) -> bool:
  123. entry = cls.get(key)
  124. if not entry:
  125. return False
  126. settings = context.setter.toProperties().get('args',{})
  127. current_value = settings.get(key)
  128. if current_value is not None:
  129. if value == True:
  130. return is_true(current_value)
  131. else:
  132. return current_value == value
  133. else:
  134. return entry.default == value
  135. @classmethod
  136. def pref_length(cls):
  137. return len(cls.__entries)
  138. @classmethod
  139. def get_entries(cls):
  140. return cls.__entries.values()
  141. PreferenceManager.add_entries([
  142. PreferenceHiddenEntry('debug', bool, False),
  143. PreferenceChoiceEntry('Skin', str, 'basic',
  144. ['basic', 'newra', 'classic',]),
  145. PreferenceChoiceEntry('Edition', str, 'standard',
  146. ['standard', 'light']),
  147. PreferenceBoolEntry('HideWIP', bool, False),
  148. PreferenceBoolEntry('HideLaunchButton', bool, False),
  149. PreferenceBoolEntry('HideDownloadButton', bool, False),
  150. PreferenceBoolEntry('HideServerJarButton', bool, False),
  151. PreferenceResetEntry('mod', bool, False, True),
  152. PreferenceResetEntry('beta', bool, False, False)
  153. ])
  154. @script('IsUsingPreset')
  155. def get(content, context:'Context', *_args, **_kwargs):
  156. settings = context.setter.toProperties().get('args',{})
  157. if not is_true(settings.get('mod')):
  158. return content
  159. else:
  160. return ''
  161. @script('PreferenceUrl')
  162. def get_preferece_url(context:'Context', *_args, **_kwargs):
  163. settings = context.setter.toProperties().get('args',{})
  164. args = []
  165. url = GET_DOMAIN_URL(context)
  166. for entry in PreferenceManager.get_entries():
  167. value = entry.get_value_from_save_page(settings=settings)
  168. value = entry.convert_value(value)
  169. if isinstance(entry, PreferenceResetEntry):
  170. value = entry.reset_value
  171. if value != entry.default:
  172. if value == True:
  173. args.append(entry.name)
  174. else:
  175. args.append(entry.name + '=' + value)
  176. if len(args) > 0:
  177. url += '?' + '&amp;'.join(args)
  178. return url
  179. @script('PreferenceSavePageUrl')
  180. def preferece_save_page_url(context:'Context', *_args, **_kwargs):
  181. settings = context.setter.toProperties().get('args',{})
  182. string_format = '{}' + GET_DOMAIN_URL(context) + 'SaveChanges.json?'
  183. bindings = ''
  184. i = 0
  185. for entry in PreferenceManager.get_entries():
  186. if isinstance(entry, PreferenceHiddenEntry):
  187. value = settings.get(entry.name)
  188. if value is not None:
  189. value = entry.convert_value(value)
  190. string_format += f'{entry.name}={value}&amp;'
  191. continue
  192. for name in entry.get_element_names():
  193. string_format += f'{name}={{{i}}}&amp;'
  194. bindings += entry.binding(name)
  195. i += 1
  196. return f'<MultiBinding StringFormat="{string_format}">{bindings}</MultiBinding>'
  197. @script('PreferenceRadioBox')
  198. def preferece_radio(pref_key, pref_value, column, row, content, context:'Context', **_kwargs):
  199. data = {}
  200. data['column'] = column
  201. data['row'] = row
  202. data['content'] = content
  203. data['element_key'] = PreferenceChoiceEntry.get_element_name_by_value(pref_key, pref_value)
  204. data['check'] = PreferenceManager.is_using(context, pref_key, pref_value)
  205. return context.components['Preference/PreferenceRadioBox'].toxaml(data, context)
  206. @script('PreferenceCheckBox')
  207. def preferece_check(pref_key, content, context:'Context', **_kwargs):
  208. data = {}
  209. data['content'] = content
  210. data['element_key'] = PreferenceBoolEntry.get_element_name_by_value(pref_key)
  211. data['check'] = PreferenceManager.is_using(context, pref_key, True)
  212. return context.components['Preference/PreferenceCheckBox'].toxaml(data, context)