profiles.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import timetable_calendar as calendar
  2. from PyQt5.QtCore import *
  3. from PyQt5.QtGui import *
  4. from copy import copy
  5. from typing import *
  6. import random
  7. import json
  8. import os
  9. """
  10. Формат хранения профилей в файле JSON:
  11. [
  12. {
  13. "id": 123,
  14. "name": "Name",
  15. "color": <int color value>
  16. "timetable": {
  17. "11:55": "melody.wav",
  18. "11:55": "melody.wav",
  19. "11:55": "melody.wav",
  20. ...
  21. }
  22. },
  23. {
  24. "id": 123,
  25. "name": "Name",
  26. "color": <int color value>
  27. "timetable": {
  28. "11:55": "melody.wav",
  29. "11:55": "melody.wav",
  30. "11:55": "melody.wav",
  31. ...
  32. }
  33. },
  34. ...
  35. ]
  36. """
  37. _file_path = 'profiles.json'
  38. _profiles_loaded = False
  39. _profiles: List[Dict[str, Union[str, QColor, Dict[QTime, str]]]]
  40. def _is_unique_id(id: int) -> bool:
  41. global _profiles
  42. for profile in _profiles:
  43. if profile['id'] == id:
  44. return False
  45. return True
  46. def _generate_unique_id() -> int:
  47. id = random.randint(0, 1001)
  48. while True:
  49. if _is_unique_id(id):
  50. return id
  51. id = random.randint(0, 1001)
  52. def _deserialize_timetable(timetable: Dict[str, str]) -> Dict[QTime, str]:
  53. new_timetable = { }
  54. for key, value in timetable.items():
  55. key_parts = [int(x) for x in key.split(':')]
  56. new_key = QTime(key_parts[0], key_parts[1], 0)
  57. new_timetable[new_key] = value
  58. return new_timetable
  59. def _serialize_timetable(timetable: Dict[QTime, str]) -> Dict[str, str]:
  60. new_timetable = { }
  61. for key, value in timetable.items():
  62. new_key = f'{key.hour():02d}:{key.minute():02d}'
  63. new_timetable[new_key] = value
  64. return new_timetable
  65. def _load_profiles() -> None:
  66. global _file_path, _profiles, _profiles_loaded
  67. if _profiles_loaded:
  68. return
  69. _profiles = []
  70. _profiles_loaded = True
  71. if not os.path.exists(_file_path):
  72. return
  73. try:
  74. file = open(_file_path, 'r', encoding='utf-8')
  75. loaded_profiles = json.load(file)
  76. file.close()
  77. except Exception as exception:
  78. print('Ошибка загрузки файла профилей!')
  79. print(exception.with_traceback(None))
  80. return
  81. # Конвертация из формата хранения в формат объект
  82. _profiles = []
  83. for profile in loaded_profiles:
  84. new_profile = { }
  85. new_profile['id'] = int(profile['id'])
  86. new_profile['name'] = str(profile['name'])
  87. new_profile['color'] = QColor(int(profile['color']))
  88. new_profile['timetable'] = _deserialize_timetable(profile['timetable'])
  89. _profiles.append(new_profile)
  90. def _save_profiles() -> None:
  91. global _file_path, _profiles
  92. serialized_profiles = []
  93. for profile in _profiles:
  94. serialized = { }
  95. serialized['id'] = profile['id']
  96. serialized['name'] = profile['name']
  97. serialized['color'] = profile['color'].rgb()
  98. serialized['timetable'] = _serialize_timetable(profile['timetable'])
  99. serialized_profiles.append(serialized)
  100. try:
  101. file = open(_file_path, 'w+', encoding='utf-8')
  102. json.dump(serialized_profiles, file, ensure_ascii=False, sort_keys=True, indent=4)
  103. file.close()
  104. print('Профили успешно сохранены!')
  105. # print(json.dumps(serialized_profiles, ensure_ascii=False, sort_keys=True, indent=4))
  106. except Exception as exception:
  107. print('Ошибка сохранения профилей!')
  108. print(exception.with_traceback(None))
  109. def add_profile(name: str, color: QColor, timetable: Dict[QTime, str]) -> int:
  110. global _profiles
  111. _load_profiles()
  112. color.setAlpha(255)
  113. profile_id = _generate_unique_id()
  114. profile = {
  115. 'id': profile_id,
  116. 'name': name,
  117. 'color': color,
  118. 'timetable': timetable
  119. }
  120. _profiles.append(profile)
  121. _save_profiles()
  122. return profile_id
  123. def get_all() -> List[Dict[str, Union[str, QColor, Dict[QTime, str]]]]:
  124. global _profiles
  125. _load_profiles()
  126. return copy(_profiles)
  127. def get(profile_id: int) -> Union[Dict[str, Union[str, QColor, Dict[QTime, str]]], None]:
  128. global _profiles
  129. _load_profiles()
  130. for profile in _profiles:
  131. if profile['id'] == profile_id:
  132. return copy(profile)
  133. return None
  134. def replace(
  135. value_from: Dict[str, Union[str, QColor, Dict[QTime, str]]],
  136. value_to: Dict[str, Union[str, QColor, Dict[QTime, str]]]
  137. ) -> None:
  138. global _profiles
  139. _load_profiles()
  140. index = _profiles.index(value_from)
  141. _profiles[index] = value_to
  142. _save_profiles()
  143. def remove(profile: Dict[str, Union[str, QColor, Dict[QTime, str]]]) -> None:
  144. global _profiles
  145. _load_profiles()
  146. _profiles.remove(profile)
  147. _save_profiles()
  148. calendar.notify_profile_removal(profile['id'])