homepage_preference.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 modify_method(self):
  23. return self.__method
  24. @property
  25. def name(self):
  26. return self.__name
  27. @property
  28. def default(self):
  29. return self.__default
  30. def get_element_names(self) -> List[str]:
  31. return []
  32. def get_element_name(cls) -> str:
  33. raise NotImplementedError()
  34. @classmethod
  35. def binding(cls, name) -> str:
  36. raise NotImplementedError()
  37. def get_value_from_save_page(self, settings):
  38. raise NotImplementedError()
  39. class PrefenrenceHiddenEntry(PrefenrenceEntry):
  40. def get_element_names(self):
  41. return []
  42. def get_element_name(cls, name:str) -> str:
  43. raise NotImplementedError()
  44. @classmethod
  45. def binding(cls, name):
  46. raise NotImplementedError()
  47. def get_value_from_save_page(self, settings):
  48. return settings.get(self.name, self.default)
  49. class PrefenrenceChoiceEntry(PrefenrenceEntry):
  50. def __init__(self, name, type, default, values:List[T]):
  51. super().__init__(name, type, default)
  52. self.__values = values
  53. def get_element_names(self):
  54. return [self.get_element_name(value) for value in self.__values]
  55. def get_element_name(self, value):
  56. return self.get_element_name_by_value(self.name, value)
  57. @classmethod
  58. def get_element_name_by_value(cls, name, value):
  59. return name + value
  60. @classmethod
  61. def binding(cls, name):
  62. return f'<Binding Path="Checked" ElementName="{name}"/>'
  63. def get_value_from_save_page(self, settings):
  64. for value in self.__values:
  65. if is_true(settings.get(self.get_element_name(value))):
  66. return value
  67. return self.default
  68. class PrefenrenceBoolEntry(PrefenrenceEntry):
  69. def get_element_names(self):
  70. return [self.get_element_name()]
  71. def get_element_name(self):
  72. return self.get_element_name_by_value(self.name)
  73. @classmethod
  74. def binding(cls, name):
  75. return f'<Binding Path="Checked" ElementName="{name}"/>'
  76. @classmethod
  77. def get_element_name_by_value(cls, name):
  78. return name
  79. def get_value_from_save_page(self, settings):
  80. return is_true(settings.get(self.get_element_name(), self.default))
  81. class PreferenceManager:
  82. __entries:Dict[str, PrefenrenceEntry] = {}
  83. @classmethod
  84. def add_entries(cls, entries:Iterable[PrefenrenceEntry]):
  85. for entry in entries:
  86. cls.__entries[entry.name] = entry
  87. @classmethod
  88. def has(cls, item):
  89. if isinstance(item, str):
  90. return item in cls.__entries
  91. raise TypeError()
  92. @classmethod
  93. def get(cls, key:str, default = None):
  94. return cls.__entries.get(key, default)
  95. @classmethod
  96. def is_using(cls, context:'Context', key, value) -> bool:
  97. entry = cls.get(key)
  98. if not entry:
  99. return False
  100. settings = context.setter.toProperties().get('args',{})
  101. current_value = settings.get(key)
  102. if current_value is not None:
  103. return current_value == value
  104. else:
  105. return entry.default == value
  106. @classmethod
  107. def pref_length(cls):
  108. return len(cls.__entries)
  109. @classmethod
  110. def get_entries(self):
  111. return self.__entries.values()
  112. PreferenceManager.add_entries([
  113. PrefenrenceChoiceEntry('skin', str, 'basic',
  114. ['basic', 'newra']),
  115. PrefenrenceChoiceEntry('edition', str, 'standard',
  116. ['standard', 'light']),
  117. PrefenrenceBoolEntry('hidewip', bool, False),
  118. PrefenrenceHiddenEntry('mod', bool, False),
  119. PrefenrenceHiddenEntry('beta', bool, False)
  120. ])
  121. @script('PreferenceUrl')
  122. def get_preferece_url(context:'Context', *_args, **_kwargs):
  123. settings = context.setter.toProperties().get('args',{})
  124. args = []
  125. url = GET_DOMAIN_URL(context)
  126. for entry in PreferenceManager.get_entries():
  127. value = entry.get_value_from_save_page(settings=settings)
  128. if value != entry.default:
  129. if is_true(value):
  130. args.append(entry.name)
  131. else:
  132. args.append(entry.name + '=' + value)
  133. if len(args) > 0:
  134. url += '?' + '&amp;'.join(args)
  135. return url
  136. @script('PreferenceSavePageUrl')
  137. def preferece_save_page_url(context:'Context', *_args, **_kwargs):
  138. settings = context.setter.toProperties().get('args',{})
  139. string_format = '{}' + GET_DOMAIN_URL(context) + 'SaveChanges.json?'
  140. bindings = ''
  141. i = 0
  142. for entry in PreferenceManager.get_entries():
  143. if isinstance(entry, PrefenrenceHiddenEntry):
  144. value = settings.get(entry.name)
  145. if value is not None:
  146. string_format += f'{entry.name}={value}'
  147. continue
  148. for name in entry.get_element_names():
  149. string_format += f'{name}={{{i}}}&amp;'
  150. bindings += entry.binding(name)
  151. i += 1
  152. return f'<MultiBinding StringFormat="{string_format}">{bindings}</MultiBinding>'
  153. @script('PreferenceRadioBox')
  154. def preferece_radio(pref_key, pref_value, column, row, content, context:'Context', **_kwargs):
  155. data = {}
  156. data['column'] = column
  157. data['row'] = row
  158. data['content'] = content
  159. data['element_key'] = PrefenrenceChoiceEntry.get_element_name_by_value(pref_key, pref_value)
  160. data['check'] = PreferenceManager.is_using(context, pref_key, pref_value)
  161. return context.components['Preference/PreferenceRadioBox'].toxaml(data, context)
  162. @script('PreferenceCheckBox')
  163. def preferece_check(pref_key, content, context:'Context', **_kwargs):
  164. data = {}
  165. data['content'] = content
  166. data['element_key'] = PrefenrenceBoolEntry.get_element_name_by_value(pref_key)
  167. data['check'] = PreferenceManager.is_using(context, pref_key, True)
  168. return context.components['Preference/PreferenceCheckBox'].toxaml(data, context)