/web_hook/events.py

https://github.com/lordfriend/Albireo · Python · 238 lines · 162 code · 34 blank · 42 comment · 15 complexity · 9f8b4025afac3a41056c6b4ddee9a2c8 MD5 · raw file

  1. from datetime import datetime
  2. from utils.http import DateTimeEncoder, is_absolute_url
  3. from utils.SessionManager import SessionManager
  4. from domain.WebHook import WebHook
  5. from domain.WebHookToken import WebHookToken
  6. import json
  7. import yaml
  8. import logging
  9. logger = logging.getLogger(__name__)
  10. def get_config(key):
  11. __fr = open('./config/config.yml', 'r')
  12. __config = yaml.load(__fr)
  13. return __config[key] if key in __config else None
  14. site_obj = get_config('site')
  15. class EventType:
  16. def __init__(self):
  17. pass
  18. TYPE_EPISODE_DOWNLOADED = 'EPISODE_DOWNLOADED'
  19. TYPE_USER_FAVORITE = 'USER_FAVORITE_CHANGED'
  20. TYPE_KEEP_ALIVE = 'KEEP_ALIVE'
  21. TYPE_INITIAL = 'INITIAL'
  22. TYPE_TOKEN_ADDED = 'TOKEN_ADDED'
  23. TYPE_TOKEN_REMOVED = 'TOKEN_REMOVED'
  24. TYPE_USER_EMAIL = 'USER_EMAIL_CHANGED'
  25. # noinspection PyMethodMayBeStatic
  26. class Event(object):
  27. """
  28. Base class for event
  29. """
  30. def __init__(self, event_type, payload):
  31. self.event_type = event_type
  32. self.payload = payload
  33. self.event_time = datetime.utcnow()
  34. def _get_all_web_hook(self):
  35. """
  36. Get all web_hook that is not dead.
  37. :return: an list of tuples which are (web_hook_id, web_hook_url, shared_secret)
  38. """
  39. session = SessionManager.Session()
  40. try:
  41. web_hook_list = session.query(WebHook). \
  42. filter(WebHook.status != WebHook.STATUS_IS_DEAD). \
  43. all()
  44. return [(str(web_hook.id), web_hook.url, web_hook.shared_secret) for web_hook in web_hook_list]
  45. finally:
  46. SessionManager.Session.remove()
  47. def to_json(self):
  48. return json.dumps(self.payload, cls=DateTimeEncoder)
  49. def get_web_hooks(self):
  50. """
  51. :return: an list of tuples which are (web_hook_id, web_hook_url, shared_secret)
  52. """
  53. return self._get_all_web_hook()
  54. # noinspection PyOldStyleClasses
  55. class EpisodeEvent(Event):
  56. """
  57. When an episode is downloaded
  58. """
  59. def __init__(self, **kwargs):
  60. episode_dict = kwargs.get('episode')
  61. episode_dict_tiny = {
  62. 'id': episode_dict['id'],
  63. 'url': '{0}://{1}/play/{2}'.format(site_obj['protocol'], site_obj['host'], episode_dict['id']),
  64. 'bgm_eps_id': episode_dict['bgm_eps_id'],
  65. 'name': episode_dict.get('name'),
  66. 'name_cn': episode_dict.get('name_cn'),
  67. 'episode_no': episode_dict['episode_no'],
  68. 'status': episode_dict['status'],
  69. 'airdate': episode_dict.get('airdate'),
  70. 'thumbnail_image': episode_dict['thumbnail_image'],
  71. 'bangumi': {
  72. 'id': episode_dict['bangumi']['id'],
  73. 'bgm_id': episode_dict['bangumi']['bgm_id'],
  74. 'name': episode_dict['bangumi']['name'],
  75. 'name_cn': episode_dict['bangumi'].get('name_cn'),
  76. 'summary': episode_dict['bangumi'].get('summary'),
  77. 'image': episode_dict['bangumi']['image'],
  78. 'cover_image': episode_dict['bangumi']['cover_image'],
  79. 'status': episode_dict['bangumi']['status'],
  80. 'air_date': episode_dict['bangumi'].get('air_date'),
  81. 'air_weekday': episode_dict['bangumi'].get('air_weekday'),
  82. 'eps': episode_dict['bangumi']['eps'],
  83. 'type': episode_dict['bangumi']['type']
  84. }
  85. }
  86. try:
  87. host_part = '{0}://{1}'.format(site_obj['protocol'], site_obj['host'])
  88. thumbnail_url = episode_dict_tiny['thumbnail_image']['url']
  89. bangumi_cover_url = episode_dict_tiny['bangumi']['cover_image']['url']
  90. if not is_absolute_url(thumbnail_url):
  91. # relative url stars with slash
  92. episode_dict_tiny['thumbnail_image']['url'] = '{0}{1}'.format(host_part, thumbnail_url)
  93. if not is_absolute_url(bangumi_cover_url):
  94. episode_dict_tiny['bangumi']['cover_image']['url'] = '{0}{1}'.format(host_part, bangumi_cover_url)
  95. except Exception as error:
  96. logger.error(error)
  97. super(self.__class__, self).__init__(EventType.TYPE_EPISODE_DOWNLOADED, {
  98. 'episode': episode_dict_tiny
  99. })
  100. # noinspection PyOldStyleClasses
  101. class UserFavoriteEvent(Event):
  102. """
  103. When a user favorite changes
  104. payload content;
  105. favorites: the same structure with Favorite except that user_id is replaced with token_id
  106. """
  107. def __init__(self, **kwargs):
  108. super(self.__class__, self).__init__(EventType.TYPE_USER_FAVORITE, {
  109. 'favorites': kwargs.get('favorites')})
  110. self.token = kwargs.get('token')
  111. def get_web_hooks(self):
  112. """
  113. return the web hook for certain token
  114. :return: a list of tuples which are (web_hook_id, web_hook_url)
  115. """
  116. session = SessionManager.Session()
  117. try:
  118. result = session.query(WebHookToken, WebHook).\
  119. join(WebHook).\
  120. filter(WebHookToken.token_id == self.token).\
  121. filter(WebHookToken.web_hook_id == WebHook.id).\
  122. filter(WebHook.status != WebHook.STATUS_IS_DEAD).\
  123. all()
  124. print result
  125. if len(result) == 0:
  126. logger.error('no web hook found for this token', exc_info=True)
  127. return []
  128. web_hooks = []
  129. for (web_hook_token, web_hook) in result:
  130. web_hooks.append((str(web_hook.id), web_hook.url, web_hook.shared_secret))
  131. return web_hooks
  132. finally:
  133. SessionManager.Session.remove()
  134. class KeepAliveEvent(Event):
  135. """
  136. As the name indicates, this is a event to ensure the web hook is alive.
  137. """
  138. def __init__(self, **kwargs):
  139. super(self.__class__, self).__init__(EventType.TYPE_KEEP_ALIVE, {
  140. 'status': kwargs.get('status')
  141. })
  142. self.web_hook_id = kwargs.get('web_hook_id')
  143. self.url = kwargs.get('url')
  144. self.shared_secret = kwargs.get('shared_secret')
  145. def get_web_hooks(self):
  146. return [(self.web_hook_id, self.url, self.shared_secret)]
  147. class TokenAddedEvent(Event):
  148. """
  149. When user add a token of web hook. The payload is very similar to UserFavoriteEvent
  150. """
  151. def __init__(self, **kwargs):
  152. super(self.__class__, self).__init__(EventType.TYPE_TOKEN_ADDED, {
  153. 'favorites': kwargs.get('favorites'),
  154. 'email': kwargs.get('email'),
  155. 'token_id': kwargs.get('token_id')
  156. })
  157. self.web_hook_id = kwargs.get('web_hook_id')
  158. def get_web_hooks(self):
  159. session = SessionManager.Session()
  160. try:
  161. web_hook = session.query(WebHook).\
  162. filter(WebHook.id == self.web_hook_id).\
  163. one()
  164. return [(self.web_hook_id, web_hook.url, web_hook.shared_secret)]
  165. finally:
  166. SessionManager.Session.remove()
  167. class TokenRemovedEvent(Event):
  168. """
  169. When user remove a token of web hook.
  170. """
  171. def __init__(self, **kwargs):
  172. super(self.__class__, self).__init__(EventType.TYPE_TOKEN_REMOVED, {
  173. 'token_id': kwargs.get('token_id')
  174. })
  175. self.web_hook_id = kwargs.get('web_hook_id')
  176. class InitialEvent(Event):
  177. """
  178. When register a web hook, this event will emit once
  179. """
  180. def __init__(self, **kwargs):
  181. super(self.__class__, self).__init__(EventType.TYPE_INITIAL, {
  182. 'web_hook_id': kwargs.get('web_hook_id'),
  183. 'url': kwargs.get('url')
  184. })
  185. self.web_hook_id = kwargs.get('web_hook_id')
  186. self.url = kwargs.get('url')
  187. self.shared_secret = kwargs.get('shared_secret')
  188. def get_web_hooks(self):
  189. return [(self.web_hook_id, self.url, self.shared_secret)]
  190. class UserEmailChangeEvent(Event):
  191. """
  192. When a user's registered email is changed.
  193. """
  194. def __init__(self, **kwargs):
  195. super(self.__class__, self).__init__(EventType.TYPE_USER_EMAIL, {
  196. 'email': kwargs.get('email'),
  197. 'token': kwargs.get('token_id')
  198. })
  199. self.web_hook_id = kwargs.get('web_hook_id')
  200. self.web_hook_url = kwargs.get('web_hook_url')
  201. self.shared_secret = kwargs.get('shared_secret')
  202. def get_web_hooks(self):
  203. return [(self.web_hook_id, self.web_hook_url, self.shared_secret)]