chats.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from pydantic import BaseModel
  2. from typing import List, Union, Optional
  3. from peewee import *
  4. from playhouse.shortcuts import model_to_dict
  5. import json
  6. import uuid
  7. import time
  8. from apps.web.internal.db import DB
  9. ####################
  10. # Chat DB Schema
  11. ####################
  12. class Chat(Model):
  13. id = CharField(unique=True)
  14. user_id = CharField()
  15. title = CharField()
  16. chat = TextField() # Save Chat JSON as Text
  17. timestamp = DateField()
  18. share_id = CharField(null=True, unique=True)
  19. class Meta:
  20. database = DB
  21. class ChatModel(BaseModel):
  22. id: str
  23. user_id: str
  24. title: str
  25. chat: str
  26. timestamp: int # timestamp in epoch
  27. share_id: Optional[str] = None
  28. ####################
  29. # Forms
  30. ####################
  31. class ChatForm(BaseModel):
  32. chat: dict
  33. class ChatTitleForm(BaseModel):
  34. title: str
  35. class ChatResponse(BaseModel):
  36. id: str
  37. user_id: str
  38. title: str
  39. chat: dict
  40. timestamp: int # timestamp in epoch
  41. share_id: Optional[str] = None # id of the chat to be shared
  42. class ChatTitleIdResponse(BaseModel):
  43. id: str
  44. title: str
  45. class ChatTable:
  46. def __init__(self, db):
  47. self.db = db
  48. db.create_tables([Chat])
  49. def insert_new_chat(self, user_id: str, form_data: ChatForm) -> Optional[ChatModel]:
  50. id = str(uuid.uuid4())
  51. chat = ChatModel(
  52. **{
  53. "id": id,
  54. "user_id": user_id,
  55. "title": (
  56. form_data.chat["title"] if "title" in form_data.chat else "New Chat"
  57. ),
  58. "chat": json.dumps(form_data.chat),
  59. "timestamp": int(time.time()),
  60. }
  61. )
  62. result = Chat.create(**chat.model_dump())
  63. return chat if result else None
  64. def update_chat_by_id(self, id: str, chat: dict) -> Optional[ChatModel]:
  65. try:
  66. query = Chat.update(
  67. chat=json.dumps(chat),
  68. title=chat["title"] if "title" in chat else "New Chat",
  69. timestamp=int(time.time()),
  70. ).where(Chat.id == id)
  71. query.execute()
  72. chat = Chat.get(Chat.id == id)
  73. return ChatModel(**model_to_dict(chat))
  74. except:
  75. return None
  76. def insert_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]:
  77. # Get the existing chat to share
  78. chat = Chat.get(Chat.id == chat_id)
  79. # Check if the chat is already shared
  80. if chat.share_id:
  81. return self.get_chat_by_id_and_user_id(chat.share_id, "shared")
  82. # Create a new chat with the same data, but with a new ID
  83. shared_chat = ChatModel(
  84. **{
  85. "id": str(uuid.uuid4()),
  86. "user_id": f"shared-{chat_id}",
  87. "title": chat.title,
  88. "chat": chat.chat,
  89. "timestamp": int(time.time()),
  90. }
  91. )
  92. shared_result = Chat.create(**shared_chat.model_dump())
  93. # Update the original chat with the share_id
  94. result = (
  95. Chat.update(share_id=shared_chat.id).where(Chat.id == chat_id).execute()
  96. )
  97. return shared_chat if (shared_result and result) else None
  98. def update_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]:
  99. try:
  100. print("update_shared_chat_by_id")
  101. chat = Chat.get(Chat.id == chat_id)
  102. print(chat)
  103. query = Chat.update(
  104. title=chat.title,
  105. chat=chat.chat,
  106. ).where(Chat.id == chat.share_id)
  107. query.execute()
  108. chat = Chat.get(Chat.id == chat.share_id)
  109. return ChatModel(**model_to_dict(chat))
  110. except:
  111. return None
  112. def delete_shared_chat_by_chat_id(self, chat_id: str) -> bool:
  113. try:
  114. query = Chat.delete().where(Chat.user_id == f"shared-{chat_id}")
  115. query.execute() # Remove the rows, return number of rows removed.
  116. return True
  117. except:
  118. return False
  119. def update_chat_share_id_by_id(
  120. self, id: str, share_id: Optional[str]
  121. ) -> Optional[ChatModel]:
  122. try:
  123. query = Chat.update(
  124. share_id=share_id,
  125. ).where(Chat.id == id)
  126. query.execute()
  127. chat = Chat.get(Chat.id == id)
  128. return ChatModel(**model_to_dict(chat))
  129. except:
  130. return None
  131. def get_chat_lists_by_user_id(
  132. self, user_id: str, skip: int = 0, limit: int = 50
  133. ) -> List[ChatModel]:
  134. return [
  135. ChatModel(**model_to_dict(chat))
  136. for chat in Chat.select()
  137. .where(Chat.user_id == user_id)
  138. .order_by(Chat.timestamp.desc())
  139. # .limit(limit)
  140. # .offset(skip)
  141. ]
  142. def get_chat_lists_by_chat_ids(
  143. self, chat_ids: List[str], skip: int = 0, limit: int = 50
  144. ) -> List[ChatModel]:
  145. return [
  146. ChatModel(**model_to_dict(chat))
  147. for chat in Chat.select()
  148. .where(Chat.id.in_(chat_ids))
  149. .order_by(Chat.timestamp.desc())
  150. ]
  151. def get_all_chats(self) -> List[ChatModel]:
  152. return [
  153. ChatModel(**model_to_dict(chat))
  154. for chat in Chat.select().order_by(Chat.timestamp.desc())
  155. ]
  156. def get_all_chats_by_user_id(self, user_id: str) -> List[ChatModel]:
  157. return [
  158. ChatModel(**model_to_dict(chat))
  159. for chat in Chat.select()
  160. .where(Chat.user_id == user_id)
  161. .order_by(Chat.timestamp.desc())
  162. ]
  163. def get_chat_by_id(self, id: str) -> Optional[ChatModel]:
  164. try:
  165. chat = Chat.get(Chat.id == id)
  166. return ChatModel(**model_to_dict(chat))
  167. except:
  168. return None
  169. def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]:
  170. try:
  171. chat = Chat.get(Chat.id == id, Chat.user_id == user_id)
  172. return ChatModel(**model_to_dict(chat))
  173. except:
  174. return None
  175. def get_chats(self, skip: int = 0, limit: int = 50) -> List[ChatModel]:
  176. return [
  177. ChatModel(**model_to_dict(chat))
  178. for chat in Chat.select().limit(limit).offset(skip)
  179. ]
  180. def delete_chat_by_id_and_user_id(self, id: str, user_id: str) -> bool:
  181. try:
  182. query = Chat.delete().where((Chat.id == id) & (Chat.user_id == user_id))
  183. query.execute() # Remove the rows, return number of rows removed.
  184. return True and self.delete_shared_chat_by_chat_id(id)
  185. except:
  186. return False
  187. def delete_chats_by_user_id(self, user_id: str) -> bool:
  188. try:
  189. self.delete_shared_chats_by_user_id(user_id)
  190. query = Chat.delete().where(Chat.user_id == user_id)
  191. query.execute() # Remove the rows, return number of rows removed.
  192. return True
  193. except:
  194. return False
  195. def delete_shared_chats_by_user_id(self, user_id: str) -> bool:
  196. try:
  197. shared_chat_ids = [
  198. f"shared-{chat.id}"
  199. for chat in Chat.select().where(Chat.user_id == user_id)
  200. ]
  201. query = Chat.delete().where(Chat.user_id << shared_chat_ids)
  202. query.execute() # Remove the rows, return number of rows removed.
  203. return True
  204. except:
  205. return False
  206. Chats = ChatTable(DB)