Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

file_service.py 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #
  2. # Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. from flask_login import current_user
  17. from peewee import fn
  18. from api.db import FileType
  19. from api.db.db_models import DB, File2Document, Knowledgebase
  20. from api.db.db_models import File, Document
  21. from api.db.services.common_service import CommonService
  22. from api.utils import get_uuid
  23. from rag.utils import MINIO
  24. class FileService(CommonService):
  25. model = File
  26. @classmethod
  27. @DB.connection_context()
  28. def get_by_pf_id(cls, tenant_id, pf_id, page_number, items_per_page,
  29. orderby, desc, keywords):
  30. if keywords:
  31. files = cls.model.select().where(
  32. (cls.model.tenant_id == tenant_id)
  33. & (cls.model.parent_id == pf_id), (fn.LOWER(cls.model.name).like(f"%%{keywords.lower()}%%")))
  34. else:
  35. files = cls.model.select().where((cls.model.tenant_id == tenant_id)
  36. & (cls.model.parent_id == pf_id))
  37. count = files.count()
  38. if desc:
  39. files = files.order_by(cls.model.getter_by(orderby).desc())
  40. else:
  41. files = files.order_by(cls.model.getter_by(orderby).asc())
  42. files = files.paginate(page_number, items_per_page)
  43. res_files = list(files.dicts())
  44. for file in res_files:
  45. if file["type"] == FileType.FOLDER.value:
  46. file["size"] = cls.get_folder_size(file["id"])
  47. file['kbs_info'] = []
  48. continue
  49. kbs_info = cls.get_kb_id_by_file_id(file['id'])
  50. file['kbs_info'] = kbs_info
  51. return res_files, count
  52. @classmethod
  53. @DB.connection_context()
  54. def get_kb_id_by_file_id(cls, file_id):
  55. kbs = (cls.model.select(*[Knowledgebase.id, Knowledgebase.name])
  56. .join(File2Document, on=(File2Document.file_id == file_id))
  57. .join(Document, on=(File2Document.document_id == Document.id))
  58. .join(Knowledgebase, on=(Knowledgebase.id == Document.kb_id))
  59. .where(cls.model.id == file_id))
  60. if not kbs: return []
  61. kbs_info_list = []
  62. for kb in list(kbs.dicts()):
  63. kbs_info_list.append({"kb_id": kb['id'], "kb_name": kb['name']})
  64. return kbs_info_list
  65. @classmethod
  66. @DB.connection_context()
  67. def get_by_pf_id_name(cls, id, name):
  68. file = cls.model.select().where((cls.model.parent_id == id) & (cls.model.name == name))
  69. if file.count():
  70. e, file = cls.get_by_id(file[0].id)
  71. if not e:
  72. raise RuntimeError("Database error (File retrieval)!")
  73. return file
  74. return None
  75. @classmethod
  76. @DB.connection_context()
  77. def get_id_list_by_id(cls, id, name, count, res):
  78. if count < len(name):
  79. file = cls.get_by_pf_id_name(id, name[count])
  80. if file:
  81. res.append(file.id)
  82. return cls.get_id_list_by_id(file.id, name, count + 1, res)
  83. else:
  84. return res
  85. else:
  86. return res
  87. @classmethod
  88. @DB.connection_context()
  89. def get_all_innermost_file_ids(cls, folder_id, result_ids):
  90. subfolders = cls.model.select().where(cls.model.parent_id == folder_id)
  91. if subfolders.exists():
  92. for subfolder in subfolders:
  93. cls.get_all_innermost_file_ids(subfolder.id, result_ids)
  94. else:
  95. result_ids.append(folder_id)
  96. return result_ids
  97. @classmethod
  98. @DB.connection_context()
  99. def create_folder(cls, file, parent_id, name, count):
  100. if count > len(name) - 2:
  101. return file
  102. else:
  103. file = cls.insert({
  104. "id": get_uuid(),
  105. "parent_id": parent_id,
  106. "tenant_id": current_user.id,
  107. "created_by": current_user.id,
  108. "name": name[count],
  109. "location": "",
  110. "size": 0,
  111. "type": FileType.FOLDER.value
  112. })
  113. return cls.create_folder(file, file.id, name, count + 1)
  114. @classmethod
  115. @DB.connection_context()
  116. def is_parent_folder_exist(cls, parent_id):
  117. parent_files = cls.model.select().where(cls.model.id == parent_id)
  118. if parent_files.count():
  119. return True
  120. cls.delete_folder_by_pf_id(parent_id)
  121. return False
  122. @classmethod
  123. @DB.connection_context()
  124. def get_root_folder(cls, tenant_id):
  125. file = cls.model.select().where(cls.model.tenant_id == tenant_id and
  126. cls.model.parent_id == cls.model.id)
  127. if not file:
  128. file_id = get_uuid()
  129. file = {
  130. "id": file_id,
  131. "parent_id": file_id,
  132. "tenant_id": tenant_id,
  133. "created_by": tenant_id,
  134. "name": "/",
  135. "type": FileType.FOLDER.value,
  136. "size": 0,
  137. "location": "",
  138. }
  139. cls.save(**file)
  140. else:
  141. file_id = file[0].id
  142. e, file = cls.get_by_id(file_id)
  143. if not e:
  144. raise RuntimeError("Database error (File retrieval)!")
  145. return file
  146. @classmethod
  147. @DB.connection_context()
  148. def get_parent_folder(cls, file_id):
  149. file = cls.model.select().where(cls.model.id == file_id)
  150. if file.count():
  151. e, file = cls.get_by_id(file[0].parent_id)
  152. if not e:
  153. raise RuntimeError("Database error (File retrieval)!")
  154. else:
  155. raise RuntimeError("Database error (File doesn't exist)!")
  156. return file
  157. @classmethod
  158. @DB.connection_context()
  159. def get_all_parent_folders(cls, start_id):
  160. parent_folders = []
  161. current_id = start_id
  162. while current_id:
  163. e, file = cls.get_by_id(current_id)
  164. if file.parent_id != file.id and e:
  165. parent_folders.append(file)
  166. current_id = file.parent_id
  167. else:
  168. parent_folders.append(file)
  169. break
  170. return parent_folders
  171. @classmethod
  172. @DB.connection_context()
  173. def insert(cls, file):
  174. if not cls.save(**file):
  175. raise RuntimeError("Database error (File)!")
  176. e, file = cls.get_by_id(file["id"])
  177. if not e:
  178. raise RuntimeError("Database error (File retrieval)!")
  179. return file
  180. @classmethod
  181. @DB.connection_context()
  182. def delete(cls, file):
  183. return cls.delete_by_id(file.id)
  184. @classmethod
  185. @DB.connection_context()
  186. def delete_by_pf_id(cls, folder_id):
  187. return cls.model.delete().where(cls.model.parent_id == folder_id).execute()
  188. @classmethod
  189. @DB.connection_context()
  190. def delete_folder_by_pf_id(cls, user_id, folder_id):
  191. try:
  192. files = cls.model.select().where((cls.model.tenant_id == user_id)
  193. & (cls.model.parent_id == folder_id))
  194. for file in files:
  195. cls.delete_folder_by_pf_id(user_id, file.id)
  196. return cls.model.delete().where((cls.model.tenant_id == user_id)
  197. & (cls.model.id == folder_id)).execute(),
  198. except Exception as e:
  199. print(e)
  200. raise RuntimeError("Database error (File retrieval)!")
  201. @classmethod
  202. @DB.connection_context()
  203. def get_file_count(cls, tenant_id):
  204. files = cls.model.select(cls.model.id).where(cls.model.tenant_id == tenant_id)
  205. return len(files)
  206. @classmethod
  207. @DB.connection_context()
  208. def get_folder_size(cls, folder_id):
  209. size = 0
  210. def dfs(parent_id):
  211. nonlocal size
  212. for f in cls.model.select(*[cls.model.id, cls.model.size, cls.model.type]).where(
  213. cls.model.parent_id == parent_id, cls.model.id != parent_id):
  214. size += f.size
  215. if f.type == FileType.FOLDER.value:
  216. dfs(f.id)
  217. dfs(folder_id)
  218. return size