serializer.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. from dataclasses import dataclass
  2. from arrow import Arrow
  3. from sqlalchemy import or_, func, case
  4. from app.config import PAGE_LIMIT
  5. from app.extensions import db
  6. from app.models import Alias, Contact, EmailLog, Mailbox
  7. @dataclass
  8. class AliasInfo:
  9. alias: Alias
  10. nb_forward: int
  11. nb_blocked: int
  12. nb_reply: int
  13. latest_email_log: EmailLog = None
  14. latest_contact: Contact = None
  15. def serialize_alias_info(alias_info: AliasInfo) -> dict:
  16. return {
  17. # Alias field
  18. "id": alias_info.alias.id,
  19. "email": alias_info.alias.email,
  20. "creation_date": alias_info.alias.created_at.format(),
  21. "creation_timestamp": alias_info.alias.created_at.timestamp,
  22. "enabled": alias_info.alias.enabled,
  23. "note": alias_info.alias.note,
  24. # activity
  25. "nb_forward": alias_info.nb_forward,
  26. "nb_block": alias_info.nb_blocked,
  27. "nb_reply": alias_info.nb_reply,
  28. }
  29. def serialize_alias_info_v2(alias_info: AliasInfo) -> dict:
  30. res = {
  31. # Alias field
  32. "id": alias_info.alias.id,
  33. "email": alias_info.alias.email,
  34. "creation_date": alias_info.alias.created_at.format(),
  35. "creation_timestamp": alias_info.alias.created_at.timestamp,
  36. "enabled": alias_info.alias.enabled,
  37. "note": alias_info.alias.note,
  38. # activity
  39. "nb_forward": alias_info.nb_forward,
  40. "nb_block": alias_info.nb_blocked,
  41. "nb_reply": alias_info.nb_reply,
  42. }
  43. if alias_info.latest_email_log:
  44. email_log = alias_info.latest_email_log
  45. contact = alias_info.latest_contact
  46. # latest activity
  47. res["latest_activity"] = {
  48. "timestamp": email_log.created_at.timestamp,
  49. "action": email_log.get_action(),
  50. "contact": {
  51. "email": contact.website_email,
  52. "name": contact.name,
  53. "reverse_alias": contact.website_send_to(),
  54. },
  55. }
  56. return res
  57. def serialize_contact(contact: Contact) -> dict:
  58. res = {
  59. "id": contact.id,
  60. "creation_date": contact.created_at.format(),
  61. "creation_timestamp": contact.created_at.timestamp,
  62. "last_email_sent_date": None,
  63. "last_email_sent_timestamp": None,
  64. "contact": contact.website_email,
  65. "reverse_alias": contact.website_send_to(),
  66. }
  67. email_log: EmailLog = contact.last_reply()
  68. if email_log:
  69. res["last_email_sent_date"] = email_log.created_at.format()
  70. res["last_email_sent_timestamp"] = email_log.created_at.timestamp
  71. return res
  72. def get_alias_infos_with_pagination(user, page_id=0, query=None) -> [AliasInfo]:
  73. ret = []
  74. q = (
  75. db.session.query(Alias)
  76. .filter(Alias.user_id == user.id)
  77. .order_by(Alias.created_at.desc())
  78. )
  79. if query:
  80. q = q.filter(
  81. or_(Alias.email.ilike(f"%{query}%"), Alias.note.ilike(f"%{query}%"))
  82. )
  83. q = q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT)
  84. for alias in q:
  85. ret.append(get_alias_info(alias))
  86. return ret
  87. def get_alias_infos_with_pagination_v2(user, page_id=0, query=None) -> [AliasInfo]:
  88. ret = []
  89. latest_activity = func.max(
  90. case(
  91. [
  92. (Alias.created_at > EmailLog.created_at, Alias.created_at),
  93. (Alias.created_at < EmailLog.created_at, EmailLog.created_at),
  94. ],
  95. else_=Alias.created_at,
  96. )
  97. ).label("latest")
  98. q = (
  99. db.session.query(Alias, latest_activity)
  100. .join(Contact, Alias.id == Contact.alias_id, isouter=True)
  101. .join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
  102. .filter(Alias.user_id == user.id)
  103. .group_by(Alias.id)
  104. .order_by(latest_activity.desc())
  105. )
  106. if query:
  107. q = q.filter(
  108. or_(Alias.email.ilike(f"%{query}%"), Alias.note.ilike(f"%{query}%"))
  109. )
  110. q = q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT)
  111. for alias, latest_activity in q:
  112. ret.append(get_alias_info_v2(alias))
  113. return ret
  114. def get_alias_info(alias: Alias) -> AliasInfo:
  115. q = (
  116. db.session.query(Contact, EmailLog)
  117. .filter(Contact.alias_id == alias.id)
  118. .filter(EmailLog.contact_id == Contact.id)
  119. )
  120. alias_info = AliasInfo(alias=alias, nb_blocked=0, nb_forward=0, nb_reply=0,)
  121. for _, el in q:
  122. if el.is_reply:
  123. alias_info.nb_reply += 1
  124. elif el.blocked:
  125. alias_info.nb_blocked += 1
  126. else:
  127. alias_info.nb_forward += 1
  128. return alias_info
  129. def get_alias_info_v2(alias: Alias) -> AliasInfo:
  130. q = (
  131. db.session.query(Contact, EmailLog)
  132. .filter(Contact.alias_id == alias.id)
  133. .filter(EmailLog.contact_id == Contact.id)
  134. )
  135. latest_activity: Arrow = alias.created_at
  136. latest_email_log = None
  137. latest_contact = None
  138. alias_info = AliasInfo(alias=alias, nb_blocked=0, nb_forward=0, nb_reply=0,)
  139. for contact, email_log in q:
  140. if email_log.is_reply:
  141. alias_info.nb_reply += 1
  142. elif email_log.blocked:
  143. alias_info.nb_blocked += 1
  144. else:
  145. alias_info.nb_forward += 1
  146. if email_log.created_at > latest_activity:
  147. latest_activity = email_log.created_at
  148. latest_email_log = email_log
  149. latest_contact = contact
  150. alias_info.latest_contact = latest_contact
  151. alias_info.latest_email_log = latest_email_log
  152. return alias_info
  153. def get_alias_contacts(alias, page_id: int) -> [dict]:
  154. q = (
  155. Contact.query.filter_by(alias_id=alias.id)
  156. .order_by(Contact.id.desc())
  157. .limit(PAGE_LIMIT)
  158. .offset(page_id * PAGE_LIMIT)
  159. )
  160. res = []
  161. for fe in q.all():
  162. res.append(serialize_contact(fe))
  163. return res