MCPcopy
hub / github.com/1Panel-dev/MaxKB / File

Class File

apps/knowledge/models/knowledge.py:365–470  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

363
364
365class File(AppModelMixin):
366 id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
367 file_name = models.CharField(max_length=256, verbose_name="文件名称", default="")
368 file_size = models.IntegerField(verbose_name="文件大小", default=0)
369 sha256_hash = models.CharField(verbose_name="文件sha256_hash标识", default="")
370 source_type = models.CharField(
371 verbose_name="资源类型",
372 choices=FileSourceType,
373 default=FileSourceType.TEMPORARY_120_MINUTE.value,
374 db_index=True,
375 )
376 source_id = models.CharField(
377 verbose_name="资源id", default=FileSourceType.TEMPORARY_120_MINUTE.value, db_index=True
378 )
379 loid = models.IntegerField(verbose_name="loid")
380 meta = models.JSONField(verbose_name="文件关联数据", default=dict)
381
382 class Meta:
383 db_table = "file"
384
385 def save(self, bytea=None, force_insert=False, force_update=False, using=None, update_fields=None):
386 if bytea is None:
387 raise ValueError("bytea参数不能为空")
388
389 sha256_hash = get_sha256_hash(bytea)
390 self.sha256_hash = sha256_hash
391 existing_file = QuerySet(File).filter(sha256_hash=sha256_hash).first()
392 if existing_file:
393 self.loid = existing_file.loid
394 self.file_size = existing_file.file_size
395 return super().save()
396
397 compressed_data = self._compress_data(bytea)
398 self.file_size = len(compressed_data)
399
400 self.loid = self._create_large_object()
401
402 self._write_compressed_data(compressed_data)
403 # 调用父类保存
404 return super().save()
405
406 def _compress_data(self, data, compression_level=9):
407 """压缩数据到内存"""
408 buffer = io.BytesIO()
409 with zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
410 zipinfo = zipfile.ZipInfo(self.file_name)
411 zipinfo.compress_type = zipfile.ZIP_DEFLATED
412 zip_file.writestr(zipinfo, data, compresslevel=compression_level)
413
414 return buffer.getvalue()
415
416 def _create_large_object(self):
417 result = select_one("SELECT lo_creat(-1)::int8 as lo_id;", [])
418 return result["lo_id"]
419
420 def _write_compressed_data(self, data, block_size=64 * 1024):
421 buffer = io.BytesIO(data)
422 offset = 0

Callers 15

insertMethod · 0.90
to_toolMethod · 0.90
import_Method · 0.90
editMethod · 0.90
addMethod · 0.90
update_toolMethod · 0.90
uploadMethod · 0.90
uploadMethod · 0.90
_restore_source_fileMethod · 0.90
import_knowledgeMethod · 0.90
to_toolMethod · 0.90
parse_qa_fileMethod · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected