tamar-file-hub-client 0.1.6__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tamar-file-hub-client might be problematic. Click here for more details.
- file_hub_client/rpc/gen/file_service_pb2.py +19 -5
- file_hub_client/rpc/gen/file_service_pb2_grpc.py +44 -0
- file_hub_client/rpc/protos/file_service.proto +81 -0
- file_hub_client/schemas/__init__.py +14 -0
- file_hub_client/schemas/context.py +171 -171
- file_hub_client/schemas/file.py +65 -0
- file_hub_client/services/file/async_blob_service.py +141 -9
- file_hub_client/services/file/sync_blob_service.py +141 -9
- {tamar_file_hub_client-0.1.6.dist-info → tamar_file_hub_client-0.1.8.dist-info}/METADATA +1 -1
- {tamar_file_hub_client-0.1.6.dist-info → tamar_file_hub_client-0.1.8.dist-info}/RECORD +12 -12
- {tamar_file_hub_client-0.1.6.dist-info → tamar_file_hub_client-0.1.8.dist-info}/WHEEL +0 -0
- {tamar_file_hub_client-0.1.6.dist-info → tamar_file_hub_client-0.1.8.dist-info}/top_level.txt +0 -0
|
@@ -26,13 +26,19 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
|
|
|
26
26
|
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x66ile_service.proto\x12\x04\x66ile\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xab\x01\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x11\n\tfile_name\x18\x03 \x01(\t\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12.\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb7\x02\n\nUploadFile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x0f\n\x07\x66ile_id\x18\x03 \x01(\t\x12\x14\n\x0cstorage_type\x18\x04 \x01(\t\x12\x13\n\x0bstored_name\x18\x05 \x01(\t\x12\x13\n\x0bstored_path\x18\x06 \x01(\t\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x11\n\tfile_size\x18\x08 \x01(\x03\x12\x10\n\x08\x66ile_ext\x18\t \x01(\t\x12\x11\n\tmime_type\x18\n \x01(\t\x12\x0e\n\x06status\x18\x0b \x01(\t\x12.\n\ncreated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x9f\x02\n\x11UploadFileRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12\x11\n\tmime_type\x18\x05 \x01(\t\x12\x19\n\x0cis_temporary\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x07 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\"\xb3\x02\n\x10UploadUrlRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x11\n\tfile_type\x18\x03 \x01(\t\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x11\n\tfile_size\x18\x05 \x01(\x03\x12\x11\n\tfile_hash\x18\x06 \x01(\t\x12\x19\n\x0cis_temporary\x18\x07 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x08 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\t \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\")\n\x16UploadCompletedRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"u\n\x12\x44ownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x13\n\x06is_cdn\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x02 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"\xd4\x01\n\x10ShareLinkRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x11\n\tis_public\x18\x02 \x01(\x08\x12\x14\n\x0c\x61\x63\x63\x65ss_scope\x18\x03 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12\x17\n\nmax_access\x18\x05 \x01(\x05H\x01\x88\x01\x01\x12\x1b\n\x0eshare_password\x18\x06 \x01(\tH\x02\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\r\n\x0b_max_accessB\x11\n\x0f_share_password\"\x82\x01\n\x10\x46ileVisitRequest\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ss_type\x18\x02 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ss_duration\x18\x03 \x01(\x05\x12)\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"!\n\x0eGetFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"6\n\x11RenameFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\"$\n\x11\x44\x65leteFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x8d\x02\n\x10ListFilesRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tfile_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tfile_type\x18\x03 \x03(\t\x12\x1c\n\x0f\x63reated_by_role\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x17\n\ncreated_by\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpage_size\x18\x06 \x01(\x05H\x04\x88\x01\x01\x12\x11\n\x04page\x18\x07 \x01(\x05H\x05\x88\x01\x01\x42\x0c\n\n_folder_idB\x0c\n\n_file_nameB\x12\n\x10_created_by_roleB\r\n\x0b_created_byB\x0c\n\n_page_sizeB\x07\n\x05_page\"{\n\x17\x42\x61tchDownloadUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x13\n\x06is_cdn\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"#\n\x10GetGcsUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\")\n\x15\x42\x61tchGetGcsUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\"U\n\x12UploadFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\"a\n\x11UploadUrlResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\x12\x0b\n\x03url\x18\x03 \x01(\t\"\"\n\x13\x44ownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\"*\n\x11ShareLinkResponse\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\"-\n\x10\x46ileListResponse\x12\x19\n\x05\x66iles\x18\x01 \x03(\x0b\x32\n.file.File\"g\n\x0fGetFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12*\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFileH\x00\x88\x01\x01\x42\x0e\n\x0c_upload_file\"H\n\x18\x42\x61tchDownloadUrlResponse\x12,\n\rdownload_urls\x18\x01 \x03(\x0b\x32\x15.file.DownloadUrlInfo\"`\n\x0f\x44ownloadUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"7\n\x11GetGcsUrlResponse\x12\x0f\n\x07gcs_url\x18\x01 \x01(\t\x12\x11\n\tmime_type\x18\x02 \x01(\t\"<\n\x16\x42\x61tchGetGcsUrlResponse\x12\"\n\x08gcs_urls\x18\x01 \x03(\x0b\x32\x10.file.GcsUrlInfo\"_\n\nGcsUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0f\n\x07gcs_url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"+\n\x18\x43ompressionStatusRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x84\x01\n\x19\x43ompressionStatusResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x1a\n\rerror_message\x18\x02 \x01(\tH\x00\x88\x01\x01\x12)\n\x08variants\x18\x03 \x03(\x0b\x32\x17.file.CompressedVariantB\x10\n\x0e_error_message\"Q\n\x12GetVariantsRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x19\n\x0cvariant_type\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_variant_type\"@\n\x13GetVariantsResponse\x12)\n\x08variants\x18\x01 \x03(\x0b\x32\x17.file.CompressedVariant\"\xc7\x02\n\x11\x43ompressedVariant\x12\x14\n\x0cvariant_name\x18\x01 \x01(\t\x12\x14\n\x0cvariant_type\x18\x02 \x01(\t\x12\x12\n\nmedia_type\x18\x03 \x01(\t\x12\r\n\x05width\x18\x04 \x01(\x05\x12\x0e\n\x06height\x18\x05 \x01(\x05\x12\x11\n\tfile_size\x18\x06 \x01(\x03\x12\x0e\n\x06\x66ormat\x18\x07 \x01(\t\x12\x14\n\x07quality\x18\x08 \x01(\x05H\x00\x88\x01\x01\x12\x15\n\x08\x64uration\x18\t \x01(\x01H\x01\x88\x01\x01\x12\x14\n\x07\x62itrate\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x10\n\x03\x66ps\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12\x19\n\x11\x63ompression_ratio\x18\x0c \x01(\x01\x12\x13\n\x0bstored_path\x18\r \x01(\tB\n\n\x08_qualityB\x0b\n\t_durationB\n\n\x08_bitrateB\x06\n\x04_fps\"Y\n\x14RecompressionRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x1c\n\x0f\x66orce_reprocess\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_force_reprocess\"8\n\x15RecompressionResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\"\x92\x01\n\x19VariantDownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x14\n\x0cvariant_name\x18\x02 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x13\n\x06is_cdn\x18\x04 \x01(\x08H\x01\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\t\n\x07_is_cdn\"\x8c\x01\n\x1aVariantDownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x32\n\x0cvariant_info\x18\x03 \x01(\x0b\x32\x17.file.CompressedVariantH\x01\x88\x01\x01\x42\x08\n\x06_errorB\x0f\n\r_variant_info\"\x07\n\x05\x45mpty2\x87\n\n\x0b\x46ileService\x12?\n\nUploadFile\x12\x17.file.UploadFileRequest\x1a\x18.file.UploadFileResponse\x12\x44\n\x11GenerateUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12M\n\x1aGenerateResumableUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12\x43\n\x16\x43onfirmUploadCompleted\x12\x1c.file.UploadCompletedRequest\x1a\x0b.file.Empty\x12J\n\x13GenerateDownloadUrl\x12\x18.file.DownloadUrlRequest\x1a\x19.file.DownloadUrlResponse\x12Y\n\x18\x42\x61tchGenerateDownloadUrl\x12\x1d.file.BatchDownloadUrlRequest\x1a\x1e.file.BatchDownloadUrlResponse\x12<\n\tGetGcsUrl\x12\x16.file.GetGcsUrlRequest\x1a\x17.file.GetGcsUrlResponse\x12K\n\x0e\x42\x61tchGetGcsUrl\x12\x1b.file.BatchGetGcsUrlRequest\x1a\x1c.file.BatchGetGcsUrlResponse\x12\x44\n\x11GenerateShareLink\x12\x16.file.ShareLinkRequest\x1a\x17.file.ShareLinkResponse\x12\x30\n\tVisitFile\x12\x16.file.FileVisitRequest\x1a\x0b.file.Empty\x12\x36\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\x15.file.GetFileResponse\x12\x31\n\nRenameFile\x12\x17.file.RenameFileRequest\x1a\n.file.File\x12\x32\n\nDeleteFile\x12\x17.file.DeleteFileRequest\x1a\x0b.file.Empty\x12;\n\tListFiles\x12\x16.file.ListFilesRequest\x1a\x16.file.FileListResponse\x12W\n\x14GetCompressionStatus\x12\x1e.file.CompressionStatusRequest\x1a\x1f.file.CompressionStatusResponse\x12L\n\x15GetCompressedVariants\x12\x18.file.GetVariantsRequest\x1a\x19.file.GetVariantsResponse\x12O\n\x14TriggerRecompression\x12\x1a.file.RecompressionRequest\x1a\x1b.file.RecompressionResponse\x12_\n\x1aGenerateVariantDownloadUrl\x12\x1f.file.VariantDownloadUrlRequest\x1a .file.VariantDownloadUrlResponseb\x06proto3')
|
|
29
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x66ile_service.proto\x12\x04\x66ile\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xab\x01\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x11\n\tfile_name\x18\x03 \x01(\t\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12.\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb7\x02\n\nUploadFile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x0f\n\x07\x66ile_id\x18\x03 \x01(\t\x12\x14\n\x0cstorage_type\x18\x04 \x01(\t\x12\x13\n\x0bstored_name\x18\x05 \x01(\t\x12\x13\n\x0bstored_path\x18\x06 \x01(\t\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x11\n\tfile_size\x18\x08 \x01(\x03\x12\x10\n\x08\x66ile_ext\x18\t \x01(\t\x12\x11\n\tmime_type\x18\n \x01(\t\x12\x0e\n\x06status\x18\x0b \x01(\t\x12.\n\ncreated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x9f\x02\n\x11UploadFileRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12\x11\n\tmime_type\x18\x05 \x01(\t\x12\x19\n\x0cis_temporary\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x07 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\"\xb3\x02\n\x10UploadUrlRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x11\n\tfile_type\x18\x03 \x01(\t\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x11\n\tfile_size\x18\x05 \x01(\x03\x12\x11\n\tfile_hash\x18\x06 \x01(\t\x12\x19\n\x0cis_temporary\x18\x07 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x08 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\t \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\")\n\x16UploadCompletedRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"u\n\x12\x44ownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x13\n\x06is_cdn\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x02 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"\xd4\x01\n\x10ShareLinkRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x11\n\tis_public\x18\x02 \x01(\x08\x12\x14\n\x0c\x61\x63\x63\x65ss_scope\x18\x03 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12\x17\n\nmax_access\x18\x05 \x01(\x05H\x01\x88\x01\x01\x12\x1b\n\x0eshare_password\x18\x06 \x01(\tH\x02\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\r\n\x0b_max_accessB\x11\n\x0f_share_password\"\x82\x01\n\x10\x46ileVisitRequest\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ss_type\x18\x02 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ss_duration\x18\x03 \x01(\x05\x12)\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"!\n\x0eGetFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"6\n\x11RenameFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\"$\n\x11\x44\x65leteFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x8d\x02\n\x10ListFilesRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tfile_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tfile_type\x18\x03 \x03(\t\x12\x1c\n\x0f\x63reated_by_role\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x17\n\ncreated_by\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpage_size\x18\x06 \x01(\x05H\x04\x88\x01\x01\x12\x11\n\x04page\x18\x07 \x01(\x05H\x05\x88\x01\x01\x42\x0c\n\n_folder_idB\x0c\n\n_file_nameB\x12\n\x10_created_by_roleB\r\n\x0b_created_byB\x0c\n\n_page_sizeB\x07\n\x05_page\"{\n\x17\x42\x61tchDownloadUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x13\n\x06is_cdn\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"#\n\x10GetGcsUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\")\n\x15\x42\x61tchGetGcsUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\"U\n\x12UploadFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\"a\n\x11UploadUrlResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\x12\x0b\n\x03url\x18\x03 \x01(\t\"\"\n\x13\x44ownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\"*\n\x11ShareLinkResponse\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\"-\n\x10\x46ileListResponse\x12\x19\n\x05\x66iles\x18\x01 \x03(\x0b\x32\n.file.File\"g\n\x0fGetFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12*\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFileH\x00\x88\x01\x01\x42\x0e\n\x0c_upload_file\"H\n\x18\x42\x61tchDownloadUrlResponse\x12,\n\rdownload_urls\x18\x01 \x03(\x0b\x32\x15.file.DownloadUrlInfo\"`\n\x0f\x44ownloadUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"7\n\x11GetGcsUrlResponse\x12\x0f\n\x07gcs_url\x18\x01 \x01(\t\x12\x11\n\tmime_type\x18\x02 \x01(\t\"<\n\x16\x42\x61tchGetGcsUrlResponse\x12\"\n\x08gcs_urls\x18\x01 \x03(\x0b\x32\x10.file.GcsUrlInfo\"_\n\nGcsUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0f\n\x07gcs_url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"+\n\x18\x43ompressionStatusRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x84\x01\n\x19\x43ompressionStatusResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x1a\n\rerror_message\x18\x02 \x01(\tH\x00\x88\x01\x01\x12)\n\x08variants\x18\x03 \x03(\x0b\x32\x17.file.CompressedVariantB\x10\n\x0e_error_message\"Q\n\x12GetVariantsRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x19\n\x0cvariant_type\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_variant_type\"@\n\x13GetVariantsResponse\x12)\n\x08variants\x18\x01 \x03(\x0b\x32\x17.file.CompressedVariant\"\xc7\x02\n\x11\x43ompressedVariant\x12\x14\n\x0cvariant_name\x18\x01 \x01(\t\x12\x14\n\x0cvariant_type\x18\x02 \x01(\t\x12\x12\n\nmedia_type\x18\x03 \x01(\t\x12\r\n\x05width\x18\x04 \x01(\x05\x12\x0e\n\x06height\x18\x05 \x01(\x05\x12\x11\n\tfile_size\x18\x06 \x01(\x03\x12\x0e\n\x06\x66ormat\x18\x07 \x01(\t\x12\x14\n\x07quality\x18\x08 \x01(\x05H\x00\x88\x01\x01\x12\x15\n\x08\x64uration\x18\t \x01(\x01H\x01\x88\x01\x01\x12\x14\n\x07\x62itrate\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x10\n\x03\x66ps\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12\x19\n\x11\x63ompression_ratio\x18\x0c \x01(\x01\x12\x13\n\x0bstored_path\x18\r \x01(\tB\n\n\x08_qualityB\x0b\n\t_durationB\n\n\x08_bitrateB\x06\n\x04_fps\"Y\n\x14RecompressionRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x1c\n\x0f\x66orce_reprocess\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_force_reprocess\"8\n\x15RecompressionResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\"\x92\x01\n\x19VariantDownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x14\n\x0cvariant_name\x18\x02 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x13\n\x06is_cdn\x18\x04 \x01(\x08H\x01\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\t\n\x07_is_cdn\"\x8c\x01\n\x1aVariantDownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x32\n\x0cvariant_info\x18\x03 \x01(\x0b\x32\x17.file.CompressedVariantH\x01\x88\x01\x01\x42\x08\n\x06_errorB\x0f\n\r_variant_info\"\x82\x01\n\x16\x42\x61tchFileStatusRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x16\n\tcache_key\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x1c\n\x0finclude_details\x18\x03 \x01(\x08H\x01\x88\x01\x01\x42\x0c\n\n_cache_keyB\x12\n\x10_include_details\"\x95\x01\n\x17\x42\x61tchFileStatusResponse\x12&\n\x08statuses\x18\x01 \x03(\x0b\x32\x14.file.FileStatusInfo\x12\x16\n\tcache_key\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12\x19\n\x11\x63\x61\x63he_ttl_seconds\x18\x04 \x01(\x05\x42\x0c\n\n_cache_key\"\x9d\x02\n\x0e\x46ileStatusInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12-\n\rupload_status\x18\x02 \x01(\x0e\x32\x16.file.FileUploadStatus\x12\x37\n\x12\x63ompression_status\x18\x03 \x01(\x0e\x32\x1b.file.FileCompressionStatus\x12)\n\x0bsync_status\x18\x04 \x01(\x0e\x32\x14.file.FileSyncStatus\x12-\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x17.file.FileStatusDetailsH\x00\x88\x01\x01\x12\x1a\n\rerror_message\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_detailsB\x10\n\x0e_error_message\"\xe9\x03\n\x11\x46ileStatusDetails\x12\x16\n\tfile_size\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x19\n\x0cstorage_type\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0estorage_region\x18\x03 \x01(\tH\x02\x88\x01\x01\x12 \n\x13\x63ompression_task_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\'\n\x1a\x63ompression_variants_count\x18\x05 \x01(\x05H\x04\x88\x01\x01\x12!\n\x14\x63ompression_progress\x18\x06 \x01(\x01H\x05\x88\x01\x01\x12\x1f\n\x12sync_regions_total\x18\x07 \x01(\x05H\x06\x88\x01\x01\x12#\n\x16sync_regions_completed\x18\x08 \x01(\x05H\x07\x88\x01\x01\x12\x1c\n\x14sync_pending_regions\x18\t \x03(\tB\x0c\n\n_file_sizeB\x0f\n\r_storage_typeB\x11\n\x0f_storage_regionB\x16\n\x14_compression_task_idB\x1d\n\x1b_compression_variants_countB\x17\n\x15_compression_progressB\x15\n\x13_sync_regions_totalB\x19\n\x17_sync_regions_completed\"\x07\n\x05\x45mpty*z\n\x10\x46ileUploadStatus\x12\x12\n\x0eUPLOAD_UNKNOWN\x10\x00\x12\x12\n\x0eUPLOAD_PENDING\x10\x01\x12\x15\n\x11UPLOAD_PROCESSING\x10\x02\x12\x14\n\x10UPLOAD_COMPLETED\x10\x03\x12\x11\n\rUPLOAD_FAILED\x10\x04*\xd1\x01\n\x15\x46ileCompressionStatus\x12\x17\n\x13\x43OMPRESSION_UNKNOWN\x10\x00\x12\x1e\n\x1a\x43OMPRESSION_NOT_APPLICABLE\x10\x01\x12\x17\n\x13\x43OMPRESSION_PENDING\x10\x02\x12\x1a\n\x16\x43OMPRESSION_PROCESSING\x10\x03\x12\x19\n\x15\x43OMPRESSION_COMPLETED\x10\x04\x12\x16\n\x12\x43OMPRESSION_FAILED\x10\x05\x12\x17\n\x13\x43OMPRESSION_SKIPPED\x10\x06*\x97\x01\n\x0e\x46ileSyncStatus\x12\x10\n\x0cSYNC_UNKNOWN\x10\x00\x12\x15\n\x11SYNC_NOT_REQUIRED\x10\x01\x12\x10\n\x0cSYNC_PENDING\x10\x02\x12\x13\n\x0fSYNC_PROCESSING\x10\x03\x12\x10\n\x0cSYNC_PARTIAL\x10\x04\x12\x12\n\x0eSYNC_COMPLETED\x10\x05\x12\x0f\n\x0bSYNC_FAILED\x10\x06\x32\xda\n\n\x0b\x46ileService\x12?\n\nUploadFile\x12\x17.file.UploadFileRequest\x1a\x18.file.UploadFileResponse\x12\x44\n\x11GenerateUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12M\n\x1aGenerateResumableUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12\x43\n\x16\x43onfirmUploadCompleted\x12\x1c.file.UploadCompletedRequest\x1a\x0b.file.Empty\x12J\n\x13GenerateDownloadUrl\x12\x18.file.DownloadUrlRequest\x1a\x19.file.DownloadUrlResponse\x12Y\n\x18\x42\x61tchGenerateDownloadUrl\x12\x1d.file.BatchDownloadUrlRequest\x1a\x1e.file.BatchDownloadUrlResponse\x12<\n\tGetGcsUrl\x12\x16.file.GetGcsUrlRequest\x1a\x17.file.GetGcsUrlResponse\x12K\n\x0e\x42\x61tchGetGcsUrl\x12\x1b.file.BatchGetGcsUrlRequest\x1a\x1c.file.BatchGetGcsUrlResponse\x12\x44\n\x11GenerateShareLink\x12\x16.file.ShareLinkRequest\x1a\x17.file.ShareLinkResponse\x12\x30\n\tVisitFile\x12\x16.file.FileVisitRequest\x1a\x0b.file.Empty\x12\x36\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\x15.file.GetFileResponse\x12\x31\n\nRenameFile\x12\x17.file.RenameFileRequest\x1a\n.file.File\x12\x32\n\nDeleteFile\x12\x17.file.DeleteFileRequest\x1a\x0b.file.Empty\x12;\n\tListFiles\x12\x16.file.ListFilesRequest\x1a\x16.file.FileListResponse\x12W\n\x14GetCompressionStatus\x12\x1e.file.CompressionStatusRequest\x1a\x1f.file.CompressionStatusResponse\x12L\n\x15GetCompressedVariants\x12\x18.file.GetVariantsRequest\x1a\x19.file.GetVariantsResponse\x12O\n\x14TriggerRecompression\x12\x1a.file.RecompressionRequest\x1a\x1b.file.RecompressionResponse\x12_\n\x1aGenerateVariantDownloadUrl\x12\x1f.file.VariantDownloadUrlRequest\x1a .file.VariantDownloadUrlResponse\x12Q\n\x12\x42\x61tchGetFileStatus\x12\x1c.file.BatchFileStatusRequest\x1a\x1d.file.BatchFileStatusResponseb\x06proto3')
|
|
30
30
|
|
|
31
31
|
_globals = globals()
|
|
32
32
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
33
33
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'file_service_pb2', _globals)
|
|
34
34
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
35
35
|
DESCRIPTOR._loaded_options = None
|
|
36
|
+
_globals['_FILEUPLOADSTATUS']._serialized_start=5275
|
|
37
|
+
_globals['_FILEUPLOADSTATUS']._serialized_end=5397
|
|
38
|
+
_globals['_FILECOMPRESSIONSTATUS']._serialized_start=5400
|
|
39
|
+
_globals['_FILECOMPRESSIONSTATUS']._serialized_end=5609
|
|
40
|
+
_globals['_FILESYNCSTATUS']._serialized_start=5612
|
|
41
|
+
_globals['_FILESYNCSTATUS']._serialized_end=5763
|
|
36
42
|
_globals['_FILE']._serialized_start=92
|
|
37
43
|
_globals['_FILE']._serialized_end=263
|
|
38
44
|
_globals['_UPLOADFILE']._serialized_start=266
|
|
@@ -103,8 +109,16 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
103
109
|
_globals['_VARIANTDOWNLOADURLREQUEST']._serialized_end=4056
|
|
104
110
|
_globals['_VARIANTDOWNLOADURLRESPONSE']._serialized_start=4059
|
|
105
111
|
_globals['_VARIANTDOWNLOADURLRESPONSE']._serialized_end=4199
|
|
106
|
-
_globals['
|
|
107
|
-
_globals['
|
|
108
|
-
_globals['
|
|
109
|
-
_globals['
|
|
112
|
+
_globals['_BATCHFILESTATUSREQUEST']._serialized_start=4202
|
|
113
|
+
_globals['_BATCHFILESTATUSREQUEST']._serialized_end=4332
|
|
114
|
+
_globals['_BATCHFILESTATUSRESPONSE']._serialized_start=4335
|
|
115
|
+
_globals['_BATCHFILESTATUSRESPONSE']._serialized_end=4484
|
|
116
|
+
_globals['_FILESTATUSINFO']._serialized_start=4487
|
|
117
|
+
_globals['_FILESTATUSINFO']._serialized_end=4772
|
|
118
|
+
_globals['_FILESTATUSDETAILS']._serialized_start=4775
|
|
119
|
+
_globals['_FILESTATUSDETAILS']._serialized_end=5264
|
|
120
|
+
_globals['_EMPTY']._serialized_start=5266
|
|
121
|
+
_globals['_EMPTY']._serialized_end=5273
|
|
122
|
+
_globals['_FILESERVICE']._serialized_start=5766
|
|
123
|
+
_globals['_FILESERVICE']._serialized_end=7136
|
|
110
124
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -126,6 +126,11 @@ class FileServiceStub(object):
|
|
|
126
126
|
request_serializer=file__service__pb2.VariantDownloadUrlRequest.SerializeToString,
|
|
127
127
|
response_deserializer=file__service__pb2.VariantDownloadUrlResponse.FromString,
|
|
128
128
|
_registered_method=True)
|
|
129
|
+
self.BatchGetFileStatus = channel.unary_unary(
|
|
130
|
+
'/file.FileService/BatchGetFileStatus',
|
|
131
|
+
request_serializer=file__service__pb2.BatchFileStatusRequest.SerializeToString,
|
|
132
|
+
response_deserializer=file__service__pb2.BatchFileStatusResponse.FromString,
|
|
133
|
+
_registered_method=True)
|
|
129
134
|
|
|
130
135
|
|
|
131
136
|
class FileServiceServicer(object):
|
|
@@ -242,6 +247,13 @@ class FileServiceServicer(object):
|
|
|
242
247
|
context.set_details('Method not implemented!')
|
|
243
248
|
raise NotImplementedError('Method not implemented!')
|
|
244
249
|
|
|
250
|
+
def BatchGetFileStatus(self, request, context):
|
|
251
|
+
"""批量文件状态查询API
|
|
252
|
+
"""
|
|
253
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
254
|
+
context.set_details('Method not implemented!')
|
|
255
|
+
raise NotImplementedError('Method not implemented!')
|
|
256
|
+
|
|
245
257
|
|
|
246
258
|
def add_FileServiceServicer_to_server(servicer, server):
|
|
247
259
|
rpc_method_handlers = {
|
|
@@ -335,6 +347,11 @@ def add_FileServiceServicer_to_server(servicer, server):
|
|
|
335
347
|
request_deserializer=file__service__pb2.VariantDownloadUrlRequest.FromString,
|
|
336
348
|
response_serializer=file__service__pb2.VariantDownloadUrlResponse.SerializeToString,
|
|
337
349
|
),
|
|
350
|
+
'BatchGetFileStatus': grpc.unary_unary_rpc_method_handler(
|
|
351
|
+
servicer.BatchGetFileStatus,
|
|
352
|
+
request_deserializer=file__service__pb2.BatchFileStatusRequest.FromString,
|
|
353
|
+
response_serializer=file__service__pb2.BatchFileStatusResponse.SerializeToString,
|
|
354
|
+
),
|
|
338
355
|
}
|
|
339
356
|
generic_handler = grpc.method_handlers_generic_handler(
|
|
340
357
|
'file.FileService', rpc_method_handlers)
|
|
@@ -833,3 +850,30 @@ class FileService(object):
|
|
|
833
850
|
timeout,
|
|
834
851
|
metadata,
|
|
835
852
|
_registered_method=True)
|
|
853
|
+
|
|
854
|
+
@staticmethod
|
|
855
|
+
def BatchGetFileStatus(request,
|
|
856
|
+
target,
|
|
857
|
+
options=(),
|
|
858
|
+
channel_credentials=None,
|
|
859
|
+
call_credentials=None,
|
|
860
|
+
insecure=False,
|
|
861
|
+
compression=None,
|
|
862
|
+
wait_for_ready=None,
|
|
863
|
+
timeout=None,
|
|
864
|
+
metadata=None):
|
|
865
|
+
return grpc.experimental.unary_unary(
|
|
866
|
+
request,
|
|
867
|
+
target,
|
|
868
|
+
'/file.FileService/BatchGetFileStatus',
|
|
869
|
+
file__service__pb2.BatchFileStatusRequest.SerializeToString,
|
|
870
|
+
file__service__pb2.BatchFileStatusResponse.FromString,
|
|
871
|
+
options,
|
|
872
|
+
channel_credentials,
|
|
873
|
+
insecure,
|
|
874
|
+
call_credentials,
|
|
875
|
+
compression,
|
|
876
|
+
wait_for_ready,
|
|
877
|
+
timeout,
|
|
878
|
+
metadata,
|
|
879
|
+
_registered_method=True)
|
|
@@ -28,6 +28,9 @@ service FileService {
|
|
|
28
28
|
rpc GetCompressedVariants (GetVariantsRequest) returns (GetVariantsResponse);
|
|
29
29
|
rpc TriggerRecompression (RecompressionRequest) returns (RecompressionResponse);
|
|
30
30
|
rpc GenerateVariantDownloadUrl (VariantDownloadUrlRequest) returns (VariantDownloadUrlResponse);
|
|
31
|
+
|
|
32
|
+
// 批量文件状态查询API
|
|
33
|
+
rpc BatchGetFileStatus (BatchFileStatusRequest) returns (BatchFileStatusResponse);
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
// ========= 数据结构定义 =========
|
|
@@ -262,4 +265,82 @@ message VariantDownloadUrlResponse {
|
|
|
262
265
|
optional CompressedVariant variant_info = 3; // 返回变体详细信息
|
|
263
266
|
}
|
|
264
267
|
|
|
268
|
+
// ========= 批量文件状态查询相关结构 =========
|
|
269
|
+
|
|
270
|
+
message BatchFileStatusRequest {
|
|
271
|
+
repeated string file_ids = 1; // 批量查询的文件ID列表(最多100个)
|
|
272
|
+
optional string cache_key = 2; // 客户端缓存标识
|
|
273
|
+
optional bool include_details = 3; // 是否返回详细信息,默认false
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
message BatchFileStatusResponse {
|
|
277
|
+
repeated FileStatusInfo statuses = 1; // 文件状态信息
|
|
278
|
+
optional string cache_key = 2; // 服务端缓存标识
|
|
279
|
+
int64 timestamp = 3; // 缓存时间戳
|
|
280
|
+
int32 cache_ttl_seconds = 4; // 缓存TTL秒数
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
message FileStatusInfo {
|
|
284
|
+
string file_id = 1;
|
|
285
|
+
|
|
286
|
+
// 三大状态
|
|
287
|
+
FileUploadStatus upload_status = 2; // 上传状态
|
|
288
|
+
FileCompressionStatus compression_status = 3; // 压缩状态
|
|
289
|
+
FileSyncStatus sync_status = 4; // 备份同步状态
|
|
290
|
+
|
|
291
|
+
// 扩展信息(当include_details=true时返回)
|
|
292
|
+
optional FileStatusDetails details = 5;
|
|
293
|
+
|
|
294
|
+
// 错误信息
|
|
295
|
+
optional string error_message = 6;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
message FileStatusDetails {
|
|
299
|
+
// 上传详情
|
|
300
|
+
optional int64 file_size = 1;
|
|
301
|
+
optional string storage_type = 2; // gcs, oss
|
|
302
|
+
optional string storage_region = 3;
|
|
303
|
+
|
|
304
|
+
// 压缩详情
|
|
305
|
+
optional string compression_task_id = 4;
|
|
306
|
+
optional int32 compression_variants_count = 5;
|
|
307
|
+
optional double compression_progress = 6; // 0.0-1.0
|
|
308
|
+
|
|
309
|
+
// 同步详情
|
|
310
|
+
optional int32 sync_regions_total = 7;
|
|
311
|
+
optional int32 sync_regions_completed = 8;
|
|
312
|
+
repeated string sync_pending_regions = 9;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 文件上传状态枚举
|
|
316
|
+
enum FileUploadStatus {
|
|
317
|
+
UPLOAD_UNKNOWN = 0;
|
|
318
|
+
UPLOAD_PENDING = 1; // 待上传
|
|
319
|
+
UPLOAD_PROCESSING = 2; // 上传中
|
|
320
|
+
UPLOAD_COMPLETED = 3; // 已完成
|
|
321
|
+
UPLOAD_FAILED = 4; // 失败
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 文件压缩状态枚举
|
|
325
|
+
enum FileCompressionStatus {
|
|
326
|
+
COMPRESSION_UNKNOWN = 0;
|
|
327
|
+
COMPRESSION_NOT_APPLICABLE = 1; // 不需要压缩
|
|
328
|
+
COMPRESSION_PENDING = 2; // 等待压缩
|
|
329
|
+
COMPRESSION_PROCESSING = 3; // 压缩中
|
|
330
|
+
COMPRESSION_COMPLETED = 4; // 已完成
|
|
331
|
+
COMPRESSION_FAILED = 5; // 失败
|
|
332
|
+
COMPRESSION_SKIPPED = 6; // 跳过压缩
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// 文件同步状态枚举
|
|
336
|
+
enum FileSyncStatus {
|
|
337
|
+
SYNC_UNKNOWN = 0;
|
|
338
|
+
SYNC_NOT_REQUIRED = 1; // 不需要同步
|
|
339
|
+
SYNC_PENDING = 2; // 等待同步
|
|
340
|
+
SYNC_PROCESSING = 3; // 同步中
|
|
341
|
+
SYNC_PARTIAL = 4; // 部分完成
|
|
342
|
+
SYNC_COMPLETED = 5; // 全部完成
|
|
343
|
+
SYNC_FAILED = 6; // 同步失败
|
|
344
|
+
}
|
|
345
|
+
|
|
265
346
|
message Empty {}
|
|
@@ -21,6 +21,13 @@ from .file import (
|
|
|
21
21
|
GetVariantsResponse,
|
|
22
22
|
RecompressionResponse,
|
|
23
23
|
VariantDownloadUrlResponse,
|
|
24
|
+
# 文件状态相关
|
|
25
|
+
FileUploadStatus,
|
|
26
|
+
FileCompressionStatus,
|
|
27
|
+
FileSyncStatus,
|
|
28
|
+
FileStatusDetails,
|
|
29
|
+
FileStatusInfo,
|
|
30
|
+
BatchFileStatusResponse,
|
|
24
31
|
)
|
|
25
32
|
from .folder import (
|
|
26
33
|
FolderInfo,
|
|
@@ -83,6 +90,13 @@ __all__ = [
|
|
|
83
90
|
"GetVariantsResponse",
|
|
84
91
|
"RecompressionResponse",
|
|
85
92
|
"VariantDownloadUrlResponse",
|
|
93
|
+
# 文件状态相关
|
|
94
|
+
"FileUploadStatus",
|
|
95
|
+
"FileCompressionStatus",
|
|
96
|
+
"FileSyncStatus",
|
|
97
|
+
"FileStatusDetails",
|
|
98
|
+
"FileStatusInfo",
|
|
99
|
+
"BatchFileStatusResponse",
|
|
86
100
|
|
|
87
101
|
# 文件夹相关
|
|
88
102
|
"FolderInfo",
|
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
"""
|
|
2
|
-
用户上下文和请求上下文相关的Schema定义
|
|
3
|
-
"""
|
|
4
|
-
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Optional, Dict, Any
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
|
|
8
|
-
from file_hub_client.enums import Role
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@dataclass
|
|
12
|
-
class UserContext:
|
|
13
|
-
"""
|
|
14
|
-
用户上下文信息
|
|
15
|
-
|
|
16
|
-
包含两大类信息:
|
|
17
|
-
1. ownership(所有权): org_id, user_id - 表示资源归属
|
|
18
|
-
2. operator(操作者): actor_id, role - 表示实际操作者(可能是用户、agent或系统)
|
|
19
|
-
3. request info(请求信息): user_ip - 表示请求来源IP(用于审计和安全)
|
|
20
|
-
"""
|
|
21
|
-
# Ownership - 资源所有权信息
|
|
22
|
-
org_id: str # 组织ID
|
|
23
|
-
user_id: str # 用户ID
|
|
24
|
-
|
|
25
|
-
# Operator - 操作者信息
|
|
26
|
-
actor_id: Optional[str] = None # 实际操作者ID(如果为空,默认使用user_id)
|
|
27
|
-
role: Role = Role.ACCOUNT # 操作者角色(ACCOUNT, AGENT, SYSTEM等)
|
|
28
|
-
|
|
29
|
-
# Request info - 请求信息
|
|
30
|
-
user_ip: Optional[str] = None # 用户IP地址(请求来源IP)
|
|
31
|
-
|
|
32
|
-
def __post_init__(self):
|
|
33
|
-
"""初始化后处理,如果actor_id为空,默认使用user_id"""
|
|
34
|
-
if self.actor_id is None:
|
|
35
|
-
self.actor_id = self.user_id
|
|
36
|
-
|
|
37
|
-
def to_metadata(self) -> Dict[str, str]:
|
|
38
|
-
"""转换为gRPC metadata格式"""
|
|
39
|
-
metadata = {
|
|
40
|
-
'x-org-id': self.org_id,
|
|
41
|
-
'x-user-id': self.user_id,
|
|
42
|
-
'x-actor-id': self.actor_id,
|
|
43
|
-
'x-role': self.role,
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
# 只有当user_ip不为None时才添加x-user-ip
|
|
47
|
-
if self.user_ip is not None:
|
|
48
|
-
metadata['x-user-ip'] = self.user_ip
|
|
49
|
-
|
|
50
|
-
return metadata
|
|
51
|
-
|
|
52
|
-
@classmethod
|
|
53
|
-
def from_metadata(cls, metadata: Dict[str, str]) -> Optional['UserContext']:
|
|
54
|
-
"""从metadata中解析用户上下文"""
|
|
55
|
-
org_id = metadata.get('x-org-id')
|
|
56
|
-
user_id = metadata.get('x-user-id')
|
|
57
|
-
|
|
58
|
-
if not org_id or not user_id:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
return cls(
|
|
62
|
-
org_id=org_id,
|
|
63
|
-
user_id=user_id,
|
|
64
|
-
actor_id=metadata.get('x-actor-id'),
|
|
65
|
-
role=Role(metadata.get('x-role', Role.ACCOUNT)),
|
|
66
|
-
user_ip=metadata.get('x-user-ip')
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@dataclass
|
|
71
|
-
class RequestContext:
|
|
72
|
-
"""
|
|
73
|
-
请求上下文信息
|
|
74
|
-
|
|
75
|
-
包含请求相关的元数据,如客户端信息、请求追踪等
|
|
76
|
-
"""
|
|
77
|
-
request_id: Optional[str] = None # 请求ID,用于追踪
|
|
78
|
-
client_ip: Optional[str] = None # 客户端IP地址
|
|
79
|
-
client_version: Optional[str] = None # 客户端版本
|
|
80
|
-
client_type: Optional[str] = None # 客户端类型(web, mobile, desktop, cli等)
|
|
81
|
-
user_agent: Optional[str] = None # User-Agent信息
|
|
82
|
-
timestamp: Optional[datetime] = field(default_factory=datetime.now) # 请求时间戳
|
|
83
|
-
extra: Dict[str, Any] = field(default_factory=dict) # 其他扩展信息
|
|
84
|
-
|
|
85
|
-
def to_metadata(self) -> Dict[str, str]:
|
|
86
|
-
"""转换为gRPC metadata格式"""
|
|
87
|
-
metadata = {}
|
|
88
|
-
|
|
89
|
-
if self.request_id:
|
|
90
|
-
metadata['x-request-id'] = self.request_id
|
|
91
|
-
if self.client_ip:
|
|
92
|
-
metadata['x-client-ip'] = self.client_ip
|
|
93
|
-
if self.client_version:
|
|
94
|
-
metadata['x-client-version'] = self.client_version
|
|
95
|
-
if self.client_type:
|
|
96
|
-
metadata['x-client-type'] = self.client_type
|
|
97
|
-
if self.user_agent:
|
|
98
|
-
metadata['x-user-agent'] = self.user_agent
|
|
99
|
-
if self.timestamp:
|
|
100
|
-
metadata['x-timestamp'] = self.timestamp.isoformat()
|
|
101
|
-
|
|
102
|
-
# 添加扩展信息
|
|
103
|
-
for key, value in self.extra.items():
|
|
104
|
-
metadata[f'x-{key}'] = str(value)
|
|
105
|
-
|
|
106
|
-
return metadata
|
|
107
|
-
|
|
108
|
-
@classmethod
|
|
109
|
-
def from_metadata(cls, metadata: Dict[str, str]) -> 'RequestContext':
|
|
110
|
-
"""从metadata中解析请求上下文"""
|
|
111
|
-
# 提取标准字段
|
|
112
|
-
request_id = metadata.get('x-request-id')
|
|
113
|
-
client_ip = metadata.get('x-client-ip')
|
|
114
|
-
client_version = metadata.get('x-client-version')
|
|
115
|
-
client_type = metadata.get('x-client-type')
|
|
116
|
-
user_agent = metadata.get('x-user-agent')
|
|
117
|
-
|
|
118
|
-
# 解析时间戳
|
|
119
|
-
timestamp = None
|
|
120
|
-
if 'x-timestamp' in metadata:
|
|
121
|
-
try:
|
|
122
|
-
timestamp = datetime.fromisoformat(metadata['x-timestamp'])
|
|
123
|
-
except:
|
|
124
|
-
pass
|
|
125
|
-
|
|
126
|
-
# 提取扩展字段
|
|
127
|
-
extra = {}
|
|
128
|
-
for key, value in metadata.items():
|
|
129
|
-
if key.startswith('x-') and key not in [
|
|
130
|
-
'x-request-id', 'x-client-ip', 'x-client-version',
|
|
131
|
-
'x-client-type', 'x-user-agent', 'x-timestamp',
|
|
132
|
-
'x-org-id', 'x-user-id', 'x-actor-id', 'x-role'
|
|
133
|
-
]:
|
|
134
|
-
extra[key[2:]] = value # 去掉 'x-' 前缀
|
|
135
|
-
|
|
136
|
-
return cls(
|
|
137
|
-
request_id=request_id,
|
|
138
|
-
client_ip=client_ip,
|
|
139
|
-
client_version=client_version,
|
|
140
|
-
client_type=client_type,
|
|
141
|
-
user_agent=user_agent,
|
|
142
|
-
timestamp=timestamp,
|
|
143
|
-
extra=extra
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@dataclass
|
|
148
|
-
class FullContext:
|
|
149
|
-
"""完整的上下文信息,包含用户上下文和请求上下文"""
|
|
150
|
-
user_context: Optional[UserContext] = None
|
|
151
|
-
request_context: Optional[RequestContext] = None
|
|
152
|
-
|
|
153
|
-
def to_metadata(self) -> Dict[str, str]:
|
|
154
|
-
"""转换为gRPC metadata格式"""
|
|
155
|
-
metadata = {}
|
|
156
|
-
|
|
157
|
-
if self.user_context:
|
|
158
|
-
metadata.update(self.user_context.to_metadata())
|
|
159
|
-
|
|
160
|
-
if self.request_context:
|
|
161
|
-
metadata.update(self.request_context.to_metadata())
|
|
162
|
-
|
|
163
|
-
return metadata
|
|
164
|
-
|
|
165
|
-
@classmethod
|
|
166
|
-
def from_metadata(cls, metadata: Dict[str, str]) -> 'FullContext':
|
|
167
|
-
"""从metadata中解析完整上下文"""
|
|
168
|
-
return cls(
|
|
169
|
-
user_context=UserContext.from_metadata(metadata),
|
|
170
|
-
request_context=RequestContext.from_metadata(metadata)
|
|
171
|
-
)
|
|
1
|
+
"""
|
|
2
|
+
用户上下文和请求上下文相关的Schema定义
|
|
3
|
+
"""
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Optional, Dict, Any
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
from file_hub_client.enums import Role
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class UserContext:
|
|
13
|
+
"""
|
|
14
|
+
用户上下文信息
|
|
15
|
+
|
|
16
|
+
包含两大类信息:
|
|
17
|
+
1. ownership(所有权): org_id, user_id - 表示资源归属
|
|
18
|
+
2. operator(操作者): actor_id, role - 表示实际操作者(可能是用户、agent或系统)
|
|
19
|
+
3. request info(请求信息): user_ip - 表示请求来源IP(用于审计和安全)
|
|
20
|
+
"""
|
|
21
|
+
# Ownership - 资源所有权信息
|
|
22
|
+
org_id: str # 组织ID
|
|
23
|
+
user_id: str # 用户ID
|
|
24
|
+
|
|
25
|
+
# Operator - 操作者信息
|
|
26
|
+
actor_id: Optional[str] = None # 实际操作者ID(如果为空,默认使用user_id)
|
|
27
|
+
role: Role = Role.ACCOUNT # 操作者角色(ACCOUNT, AGENT, SYSTEM等)
|
|
28
|
+
|
|
29
|
+
# Request info - 请求信息
|
|
30
|
+
user_ip: Optional[str] = None # 用户IP地址(请求来源IP)
|
|
31
|
+
|
|
32
|
+
def __post_init__(self):
|
|
33
|
+
"""初始化后处理,如果actor_id为空,默认使用user_id"""
|
|
34
|
+
if self.actor_id is None:
|
|
35
|
+
self.actor_id = self.user_id
|
|
36
|
+
|
|
37
|
+
def to_metadata(self) -> Dict[str, str]:
|
|
38
|
+
"""转换为gRPC metadata格式"""
|
|
39
|
+
metadata = {
|
|
40
|
+
'x-org-id': self.org_id,
|
|
41
|
+
'x-user-id': self.user_id,
|
|
42
|
+
'x-actor-id': self.actor_id,
|
|
43
|
+
'x-role': self.role,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# 只有当user_ip不为None时才添加x-user-ip
|
|
47
|
+
if self.user_ip is not None:
|
|
48
|
+
metadata['x-user-ip'] = self.user_ip
|
|
49
|
+
|
|
50
|
+
return metadata
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_metadata(cls, metadata: Dict[str, str]) -> Optional['UserContext']:
|
|
54
|
+
"""从metadata中解析用户上下文"""
|
|
55
|
+
org_id = metadata.get('x-org-id')
|
|
56
|
+
user_id = metadata.get('x-user-id')
|
|
57
|
+
|
|
58
|
+
if not org_id or not user_id:
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
return cls(
|
|
62
|
+
org_id=org_id,
|
|
63
|
+
user_id=user_id,
|
|
64
|
+
actor_id=metadata.get('x-actor-id'),
|
|
65
|
+
role=Role(metadata.get('x-role', Role.ACCOUNT)),
|
|
66
|
+
user_ip=metadata.get('x-user-ip')
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class RequestContext:
|
|
72
|
+
"""
|
|
73
|
+
请求上下文信息
|
|
74
|
+
|
|
75
|
+
包含请求相关的元数据,如客户端信息、请求追踪等
|
|
76
|
+
"""
|
|
77
|
+
request_id: Optional[str] = None # 请求ID,用于追踪
|
|
78
|
+
client_ip: Optional[str] = None # 客户端IP地址
|
|
79
|
+
client_version: Optional[str] = None # 客户端版本
|
|
80
|
+
client_type: Optional[str] = None # 客户端类型(web, mobile, desktop, cli等)
|
|
81
|
+
user_agent: Optional[str] = None # User-Agent信息
|
|
82
|
+
timestamp: Optional[datetime] = field(default_factory=datetime.now) # 请求时间戳
|
|
83
|
+
extra: Dict[str, Any] = field(default_factory=dict) # 其他扩展信息
|
|
84
|
+
|
|
85
|
+
def to_metadata(self) -> Dict[str, str]:
|
|
86
|
+
"""转换为gRPC metadata格式"""
|
|
87
|
+
metadata = {}
|
|
88
|
+
|
|
89
|
+
if self.request_id:
|
|
90
|
+
metadata['x-request-id'] = self.request_id
|
|
91
|
+
if self.client_ip:
|
|
92
|
+
metadata['x-client-ip'] = self.client_ip
|
|
93
|
+
if self.client_version:
|
|
94
|
+
metadata['x-client-version'] = self.client_version
|
|
95
|
+
if self.client_type:
|
|
96
|
+
metadata['x-client-type'] = self.client_type
|
|
97
|
+
if self.user_agent:
|
|
98
|
+
metadata['x-user-agent'] = self.user_agent
|
|
99
|
+
if self.timestamp:
|
|
100
|
+
metadata['x-timestamp'] = self.timestamp.isoformat()
|
|
101
|
+
|
|
102
|
+
# 添加扩展信息
|
|
103
|
+
for key, value in self.extra.items():
|
|
104
|
+
metadata[f'x-{key}'] = str(value)
|
|
105
|
+
|
|
106
|
+
return metadata
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def from_metadata(cls, metadata: Dict[str, str]) -> 'RequestContext':
|
|
110
|
+
"""从metadata中解析请求上下文"""
|
|
111
|
+
# 提取标准字段
|
|
112
|
+
request_id = metadata.get('x-request-id')
|
|
113
|
+
client_ip = metadata.get('x-client-ip')
|
|
114
|
+
client_version = metadata.get('x-client-version')
|
|
115
|
+
client_type = metadata.get('x-client-type')
|
|
116
|
+
user_agent = metadata.get('x-user-agent')
|
|
117
|
+
|
|
118
|
+
# 解析时间戳
|
|
119
|
+
timestamp = None
|
|
120
|
+
if 'x-timestamp' in metadata:
|
|
121
|
+
try:
|
|
122
|
+
timestamp = datetime.fromisoformat(metadata['x-timestamp'])
|
|
123
|
+
except:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
# 提取扩展字段
|
|
127
|
+
extra = {}
|
|
128
|
+
for key, value in metadata.items():
|
|
129
|
+
if key.startswith('x-') and key not in [
|
|
130
|
+
'x-request-id', 'x-client-ip', 'x-client-version',
|
|
131
|
+
'x-client-type', 'x-user-agent', 'x-timestamp',
|
|
132
|
+
'x-org-id', 'x-user-id', 'x-actor-id', 'x-role'
|
|
133
|
+
]:
|
|
134
|
+
extra[key[2:]] = value # 去掉 'x-' 前缀
|
|
135
|
+
|
|
136
|
+
return cls(
|
|
137
|
+
request_id=request_id,
|
|
138
|
+
client_ip=client_ip,
|
|
139
|
+
client_version=client_version,
|
|
140
|
+
client_type=client_type,
|
|
141
|
+
user_agent=user_agent,
|
|
142
|
+
timestamp=timestamp,
|
|
143
|
+
extra=extra
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class FullContext:
|
|
149
|
+
"""完整的上下文信息,包含用户上下文和请求上下文"""
|
|
150
|
+
user_context: Optional[UserContext] = None
|
|
151
|
+
request_context: Optional[RequestContext] = None
|
|
152
|
+
|
|
153
|
+
def to_metadata(self) -> Dict[str, str]:
|
|
154
|
+
"""转换为gRPC metadata格式"""
|
|
155
|
+
metadata = {}
|
|
156
|
+
|
|
157
|
+
if self.user_context:
|
|
158
|
+
metadata.update(self.user_context.to_metadata())
|
|
159
|
+
|
|
160
|
+
if self.request_context:
|
|
161
|
+
metadata.update(self.request_context.to_metadata())
|
|
162
|
+
|
|
163
|
+
return metadata
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def from_metadata(cls, metadata: Dict[str, str]) -> 'FullContext':
|
|
167
|
+
"""从metadata中解析完整上下文"""
|
|
168
|
+
return cls(
|
|
169
|
+
user_context=UserContext.from_metadata(metadata),
|
|
170
|
+
request_context=RequestContext.from_metadata(metadata)
|
|
171
|
+
)
|
file_hub_client/schemas/file.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from typing import Optional, Dict, List, Any
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
|
+
from enum import Enum
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class File(BaseModel):
|
|
@@ -169,3 +170,67 @@ class VariantDownloadUrlResponse(BaseModel):
|
|
|
169
170
|
url: str = Field(..., description="下载URL")
|
|
170
171
|
error: Optional[str] = Field(None, description="错误信息")
|
|
171
172
|
variant_info: Optional[CompressedVariant] = Field(None, description="变体详细信息")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# ========= 文件状态服务相关模型 =========
|
|
176
|
+
|
|
177
|
+
class FileUploadStatus(str, Enum):
|
|
178
|
+
"""文件上传状态枚举"""
|
|
179
|
+
UPLOAD_UNKNOWN = "UPLOAD_UNKNOWN"
|
|
180
|
+
UPLOAD_PENDING = "UPLOAD_PENDING"
|
|
181
|
+
UPLOAD_PROCESSING = "UPLOAD_PROCESSING"
|
|
182
|
+
UPLOAD_COMPLETED = "UPLOAD_COMPLETED"
|
|
183
|
+
UPLOAD_FAILED = "UPLOAD_FAILED"
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class FileCompressionStatus(str, Enum):
|
|
187
|
+
"""文件压缩状态枚举"""
|
|
188
|
+
COMPRESSION_UNKNOWN = "COMPRESSION_UNKNOWN"
|
|
189
|
+
COMPRESSION_NOT_APPLICABLE = "COMPRESSION_NOT_APPLICABLE"
|
|
190
|
+
COMPRESSION_PENDING = "COMPRESSION_PENDING"
|
|
191
|
+
COMPRESSION_PROCESSING = "COMPRESSION_PROCESSING"
|
|
192
|
+
COMPRESSION_COMPLETED = "COMPRESSION_COMPLETED"
|
|
193
|
+
COMPRESSION_FAILED = "COMPRESSION_FAILED"
|
|
194
|
+
COMPRESSION_SKIPPED = "COMPRESSION_SKIPPED"
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class FileSyncStatus(str, Enum):
|
|
198
|
+
"""文件同步状态枚举"""
|
|
199
|
+
SYNC_UNKNOWN = "SYNC_UNKNOWN"
|
|
200
|
+
SYNC_NOT_REQUIRED = "SYNC_NOT_REQUIRED"
|
|
201
|
+
SYNC_PENDING = "SYNC_PENDING"
|
|
202
|
+
SYNC_PROCESSING = "SYNC_PROCESSING"
|
|
203
|
+
SYNC_PARTIAL = "SYNC_PARTIAL"
|
|
204
|
+
SYNC_COMPLETED = "SYNC_COMPLETED"
|
|
205
|
+
SYNC_FAILED = "SYNC_FAILED"
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class FileStatusDetails(BaseModel):
|
|
209
|
+
"""文件状态详情"""
|
|
210
|
+
file_size: Optional[int] = Field(None, description="文件大小")
|
|
211
|
+
storage_type: Optional[str] = Field(None, description="存储类型")
|
|
212
|
+
storage_region: Optional[str] = Field(None, description="存储区域")
|
|
213
|
+
compression_task_id: Optional[str] = Field(None, description="压缩任务ID")
|
|
214
|
+
compression_variants_count: Optional[int] = Field(None, description="压缩变体数量")
|
|
215
|
+
compression_progress: Optional[float] = Field(None, description="压缩进度")
|
|
216
|
+
sync_regions_total: Optional[int] = Field(None, description="同步区域总数")
|
|
217
|
+
sync_regions_completed: Optional[int] = Field(None, description="已完成同步区域数")
|
|
218
|
+
sync_pending_regions: List[str] = Field(default_factory=list, description="待同步区域列表")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class FileStatusInfo(BaseModel):
|
|
222
|
+
"""文件状态信息"""
|
|
223
|
+
file_id: str = Field(..., description="文件ID")
|
|
224
|
+
upload_status: FileUploadStatus = Field(..., description="上传状态")
|
|
225
|
+
compression_status: FileCompressionStatus = Field(..., description="压缩状态")
|
|
226
|
+
sync_status: FileSyncStatus = Field(..., description="同步状态")
|
|
227
|
+
details: Optional[FileStatusDetails] = Field(None, description="状态详情")
|
|
228
|
+
error_message: Optional[str] = Field(None, description="错误信息")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class BatchFileStatusResponse(BaseModel):
|
|
232
|
+
"""批量文件状态响应"""
|
|
233
|
+
statuses: List[FileStatusInfo] = Field(default_factory=list, description="文件状态列表")
|
|
234
|
+
cache_key: Optional[str] = Field(None, description="缓存键")
|
|
235
|
+
timestamp: int = Field(..., description="时间戳")
|
|
236
|
+
cache_ttl_seconds: int = Field(..., description="缓存TTL(秒)")
|
|
@@ -11,7 +11,7 @@ from .base_file_service import BaseFileService
|
|
|
11
11
|
from ...enums import UploadMode
|
|
12
12
|
from ...errors import ValidationError
|
|
13
13
|
from ...rpc import AsyncGrpcClient
|
|
14
|
-
from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, GetGcsUrlResponse, BatchGcsUrlResponse, CompressionStatusResponse, GetVariantsResponse, RecompressionResponse, VariantDownloadUrlResponse, CompressedVariant
|
|
14
|
+
from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, GetGcsUrlResponse, BatchGcsUrlResponse, CompressionStatusResponse, GetVariantsResponse, RecompressionResponse, VariantDownloadUrlResponse, CompressedVariant, BatchFileStatusResponse, FileStatusInfo, FileStatusDetails, FileUploadStatus, FileCompressionStatus, FileSyncStatus
|
|
15
15
|
from ...utils import AsyncHttpUploader, AsyncHttpDownloader, retry_with_backoff, get_file_mime_type
|
|
16
16
|
|
|
17
17
|
|
|
@@ -453,18 +453,33 @@ class AsyncBlobService(BaseFileService):
|
|
|
453
453
|
# 使用下载的内容作为file参数
|
|
454
454
|
file = downloaded_content
|
|
455
455
|
|
|
456
|
-
#
|
|
457
|
-
mime_type
|
|
456
|
+
# MIME类型优先级:用户指定 > 内容检测 > URL文件名推断
|
|
457
|
+
if mime_type:
|
|
458
|
+
# 用户明确提供的MIME类型优先级最高,无需进行内容检测
|
|
459
|
+
final_mime_type = mime_type
|
|
460
|
+
else:
|
|
461
|
+
# 用户未提供MIME类型,进行内容检测和文件名推断
|
|
462
|
+
content_detected_mime = self._detect_mime_from_content(downloaded_content)
|
|
463
|
+
url_filename_mime = get_file_mime_type(Path(file_name))
|
|
464
|
+
|
|
465
|
+
if content_detected_mime != "application/octet-stream":
|
|
466
|
+
# 内容检测到了具体的MIME类型,使用内容检测的
|
|
467
|
+
final_mime_type = content_detected_mime
|
|
468
|
+
else:
|
|
469
|
+
# 内容检测失败,使用从URL文件名推断的MIME类型
|
|
470
|
+
final_mime_type = url_filename_mime
|
|
458
471
|
|
|
459
|
-
#
|
|
460
|
-
_, content, file_size,
|
|
472
|
+
# 提取文件信息,传入最终确定的MIME类型
|
|
473
|
+
_, content, file_size, extract_mime_type, extract_file_type, file_hash = self._extract_file_info(file, final_mime_type)
|
|
461
474
|
|
|
462
475
|
# file_name已经在上面设置了(要么是用户指定的,要么是从URL提取的)
|
|
463
476
|
extracted_file_name = file_name
|
|
477
|
+
|
|
478
|
+
# 使用最终确定的MIME类型
|
|
479
|
+
mime_type = final_mime_type
|
|
464
480
|
|
|
465
|
-
#
|
|
466
|
-
file_type =
|
|
467
|
-
extracted_file_name).suffix else 'dat'
|
|
481
|
+
# 基于最终MIME类型计算文件扩展名
|
|
482
|
+
file_type = extract_file_type
|
|
468
483
|
else:
|
|
469
484
|
# 解析文件参数,提取文件信息
|
|
470
485
|
# 如果用户指定了文件名,先从文件名推断MIME类型,然后传给_extract_file_info
|
|
@@ -485,7 +500,9 @@ class AsyncBlobService(BaseFileService):
|
|
|
485
500
|
# 没有指定文件名,传入用户提供的MIME类型(如果有)
|
|
486
501
|
extracted_file_name, content, file_size, extract_mime_type, extract_file_type, file_hash = self._extract_file_info(
|
|
487
502
|
file, mime_type)
|
|
488
|
-
|
|
503
|
+
# 如果用户指定了MIME类型,使用用户指定的,否则使用检测的
|
|
504
|
+
if not mime_type:
|
|
505
|
+
mime_type = extract_mime_type
|
|
489
506
|
file_type = extract_file_type
|
|
490
507
|
|
|
491
508
|
# 根据文件大小自动选择上传模式
|
|
@@ -978,3 +995,118 @@ class AsyncBlobService(BaseFileService):
|
|
|
978
995
|
error=response.error if response.error else None,
|
|
979
996
|
variant_info=variant_info
|
|
980
997
|
)
|
|
998
|
+
|
|
999
|
+
async def batch_get_file_status(
|
|
1000
|
+
self,
|
|
1001
|
+
file_ids: List[str],
|
|
1002
|
+
*,
|
|
1003
|
+
cache_key: Optional[str] = None,
|
|
1004
|
+
include_details: Optional[bool] = False,
|
|
1005
|
+
request_id: Optional[str] = None,
|
|
1006
|
+
**metadata
|
|
1007
|
+
) -> BatchFileStatusResponse:
|
|
1008
|
+
"""
|
|
1009
|
+
批量获取文件状态(异步版本)
|
|
1010
|
+
|
|
1011
|
+
Args:
|
|
1012
|
+
file_ids: 文件ID列表
|
|
1013
|
+
cache_key: 缓存键(可选)
|
|
1014
|
+
include_details: 是否包含详细状态信息(默认False)
|
|
1015
|
+
request_id: 请求ID,用于追踪
|
|
1016
|
+
**metadata: 额外的gRPC元数据
|
|
1017
|
+
|
|
1018
|
+
Returns:
|
|
1019
|
+
BatchFileStatusResponse: 批量文件状态响应
|
|
1020
|
+
"""
|
|
1021
|
+
from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
|
|
1022
|
+
|
|
1023
|
+
stub = await self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
|
|
1024
|
+
|
|
1025
|
+
request = file_service_pb2.BatchFileStatusRequest(
|
|
1026
|
+
file_ids=file_ids,
|
|
1027
|
+
include_details=include_details if include_details is not None else False
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
if cache_key:
|
|
1031
|
+
request.cache_key = cache_key
|
|
1032
|
+
|
|
1033
|
+
# 构建元数据
|
|
1034
|
+
grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
|
|
1035
|
+
|
|
1036
|
+
response = await stub.BatchGetFileStatus(request, metadata=grpc_metadata)
|
|
1037
|
+
|
|
1038
|
+
# 转换文件状态信息
|
|
1039
|
+
statuses = []
|
|
1040
|
+
for status_info in response.statuses:
|
|
1041
|
+
# 转换状态详情(如果存在)
|
|
1042
|
+
details = None
|
|
1043
|
+
if status_info.HasField('details'):
|
|
1044
|
+
details = FileStatusDetails(
|
|
1045
|
+
file_size=status_info.details.file_size if status_info.details.HasField('file_size') else None,
|
|
1046
|
+
storage_type=status_info.details.storage_type if status_info.details.HasField('storage_type') else None,
|
|
1047
|
+
storage_region=status_info.details.storage_region if status_info.details.HasField('storage_region') else None,
|
|
1048
|
+
compression_task_id=status_info.details.compression_task_id if status_info.details.HasField('compression_task_id') else None,
|
|
1049
|
+
compression_variants_count=status_info.details.compression_variants_count if status_info.details.HasField('compression_variants_count') else None,
|
|
1050
|
+
compression_progress=status_info.details.compression_progress if status_info.details.HasField('compression_progress') else None,
|
|
1051
|
+
sync_regions_total=status_info.details.sync_regions_total if status_info.details.HasField('sync_regions_total') else None,
|
|
1052
|
+
sync_regions_completed=status_info.details.sync_regions_completed if status_info.details.HasField('sync_regions_completed') else None,
|
|
1053
|
+
sync_pending_regions=list(status_info.details.sync_pending_regions)
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1056
|
+
# 转换枚举值
|
|
1057
|
+
upload_status = self._convert_upload_status(status_info.upload_status)
|
|
1058
|
+
compression_status = self._convert_compression_status(status_info.compression_status)
|
|
1059
|
+
sync_status = self._convert_sync_status(status_info.sync_status)
|
|
1060
|
+
|
|
1061
|
+
statuses.append(FileStatusInfo(
|
|
1062
|
+
file_id=status_info.file_id,
|
|
1063
|
+
upload_status=upload_status,
|
|
1064
|
+
compression_status=compression_status,
|
|
1065
|
+
sync_status=sync_status,
|
|
1066
|
+
details=details,
|
|
1067
|
+
error_message=status_info.error_message if status_info.HasField('error_message') else None
|
|
1068
|
+
))
|
|
1069
|
+
|
|
1070
|
+
return BatchFileStatusResponse(
|
|
1071
|
+
statuses=statuses,
|
|
1072
|
+
cache_key=response.cache_key if response.HasField('cache_key') else None,
|
|
1073
|
+
timestamp=response.timestamp,
|
|
1074
|
+
cache_ttl_seconds=response.cache_ttl_seconds
|
|
1075
|
+
)
|
|
1076
|
+
|
|
1077
|
+
def _convert_upload_status(self, proto_status: int) -> FileUploadStatus:
|
|
1078
|
+
"""转换上传状态枚举"""
|
|
1079
|
+
status_map = {
|
|
1080
|
+
0: FileUploadStatus.UPLOAD_UNKNOWN,
|
|
1081
|
+
1: FileUploadStatus.UPLOAD_PENDING,
|
|
1082
|
+
2: FileUploadStatus.UPLOAD_PROCESSING,
|
|
1083
|
+
3: FileUploadStatus.UPLOAD_COMPLETED,
|
|
1084
|
+
4: FileUploadStatus.UPLOAD_FAILED,
|
|
1085
|
+
}
|
|
1086
|
+
return status_map.get(proto_status, FileUploadStatus.UPLOAD_UNKNOWN)
|
|
1087
|
+
|
|
1088
|
+
def _convert_compression_status(self, proto_status: int) -> FileCompressionStatus:
|
|
1089
|
+
"""转换压缩状态枚举"""
|
|
1090
|
+
status_map = {
|
|
1091
|
+
0: FileCompressionStatus.COMPRESSION_UNKNOWN,
|
|
1092
|
+
1: FileCompressionStatus.COMPRESSION_NOT_APPLICABLE,
|
|
1093
|
+
2: FileCompressionStatus.COMPRESSION_PENDING,
|
|
1094
|
+
3: FileCompressionStatus.COMPRESSION_PROCESSING,
|
|
1095
|
+
4: FileCompressionStatus.COMPRESSION_COMPLETED,
|
|
1096
|
+
5: FileCompressionStatus.COMPRESSION_FAILED,
|
|
1097
|
+
6: FileCompressionStatus.COMPRESSION_SKIPPED,
|
|
1098
|
+
}
|
|
1099
|
+
return status_map.get(proto_status, FileCompressionStatus.COMPRESSION_UNKNOWN)
|
|
1100
|
+
|
|
1101
|
+
def _convert_sync_status(self, proto_status: int) -> FileSyncStatus:
|
|
1102
|
+
"""转换同步状态枚举"""
|
|
1103
|
+
status_map = {
|
|
1104
|
+
0: FileSyncStatus.SYNC_UNKNOWN,
|
|
1105
|
+
1: FileSyncStatus.SYNC_NOT_REQUIRED,
|
|
1106
|
+
2: FileSyncStatus.SYNC_PENDING,
|
|
1107
|
+
3: FileSyncStatus.SYNC_PROCESSING,
|
|
1108
|
+
4: FileSyncStatus.SYNC_PARTIAL,
|
|
1109
|
+
5: FileSyncStatus.SYNC_COMPLETED,
|
|
1110
|
+
6: FileSyncStatus.SYNC_FAILED,
|
|
1111
|
+
}
|
|
1112
|
+
return status_map.get(proto_status, FileSyncStatus.SYNC_UNKNOWN)
|
|
@@ -9,7 +9,7 @@ from .base_file_service import BaseFileService
|
|
|
9
9
|
from ...enums import UploadMode
|
|
10
10
|
from ...errors import ValidationError
|
|
11
11
|
from ...rpc import SyncGrpcClient
|
|
12
|
-
from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, GetGcsUrlResponse, BatchGcsUrlResponse, CompressionStatusResponse, GetVariantsResponse, RecompressionResponse, VariantDownloadUrlResponse, CompressedVariant
|
|
12
|
+
from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, GetGcsUrlResponse, BatchGcsUrlResponse, CompressionStatusResponse, GetVariantsResponse, RecompressionResponse, VariantDownloadUrlResponse, CompressedVariant, BatchFileStatusResponse, FileStatusInfo, FileStatusDetails, FileUploadStatus, FileCompressionStatus, FileSyncStatus
|
|
13
13
|
from ...utils import HttpUploader, HttpDownloader, retry_with_backoff, get_file_mime_type
|
|
14
14
|
|
|
15
15
|
|
|
@@ -452,18 +452,33 @@ class SyncBlobService(BaseFileService):
|
|
|
452
452
|
# 使用下载的内容作为file参数
|
|
453
453
|
file = downloaded_content
|
|
454
454
|
|
|
455
|
-
#
|
|
456
|
-
mime_type
|
|
455
|
+
# MIME类型优先级:用户指定 > 内容检测 > URL文件名推断
|
|
456
|
+
if mime_type:
|
|
457
|
+
# 用户明确提供的MIME类型优先级最高,无需进行内容检测
|
|
458
|
+
final_mime_type = mime_type
|
|
459
|
+
else:
|
|
460
|
+
# 用户未提供MIME类型,进行内容检测和文件名推断
|
|
461
|
+
content_detected_mime = self._detect_mime_from_content(downloaded_content)
|
|
462
|
+
url_filename_mime = get_file_mime_type(Path(file_name))
|
|
463
|
+
|
|
464
|
+
if content_detected_mime != "application/octet-stream":
|
|
465
|
+
# 内容检测到了具体的MIME类型,使用内容检测的
|
|
466
|
+
final_mime_type = content_detected_mime
|
|
467
|
+
else:
|
|
468
|
+
# 内容检测失败,使用从URL文件名推断的MIME类型
|
|
469
|
+
final_mime_type = url_filename_mime
|
|
457
470
|
|
|
458
|
-
#
|
|
459
|
-
_, content, file_size,
|
|
471
|
+
# 提取文件信息,传入最终确定的MIME类型
|
|
472
|
+
_, content, file_size, extract_mime_type, extract_file_type, file_hash = self._extract_file_info(file, final_mime_type)
|
|
460
473
|
|
|
461
474
|
# file_name已经在上面设置了(要么是用户指定的,要么是从URL提取的)
|
|
462
475
|
extracted_file_name = file_name
|
|
476
|
+
|
|
477
|
+
# 使用最终确定的MIME类型
|
|
478
|
+
mime_type = final_mime_type
|
|
463
479
|
|
|
464
|
-
#
|
|
465
|
-
file_type =
|
|
466
|
-
extracted_file_name).suffix else 'dat'
|
|
480
|
+
# 基于最终MIME类型计算文件扩展名
|
|
481
|
+
file_type = extract_file_type
|
|
467
482
|
else:
|
|
468
483
|
# 解析文件参数,提取文件信息
|
|
469
484
|
# 如果用户指定了文件名,先从文件名推断MIME类型,然后传给_extract_file_info
|
|
@@ -484,7 +499,9 @@ class SyncBlobService(BaseFileService):
|
|
|
484
499
|
# 没有指定文件名,传入用户提供的MIME类型(如果有)
|
|
485
500
|
extracted_file_name, content, file_size, extract_mime_type, extract_file_type, file_hash = self._extract_file_info(
|
|
486
501
|
file, mime_type)
|
|
487
|
-
|
|
502
|
+
# 如果用户指定了MIME类型,使用用户指定的,否则使用检测的
|
|
503
|
+
if not mime_type:
|
|
504
|
+
mime_type = extract_mime_type
|
|
488
505
|
file_type = extract_file_type
|
|
489
506
|
|
|
490
507
|
# 根据文件大小自动选择上传模式
|
|
@@ -976,3 +993,118 @@ class SyncBlobService(BaseFileService):
|
|
|
976
993
|
error=response.error if response.error else None,
|
|
977
994
|
variant_info=variant_info
|
|
978
995
|
)
|
|
996
|
+
|
|
997
|
+
def batch_get_file_status(
|
|
998
|
+
self,
|
|
999
|
+
file_ids: List[str],
|
|
1000
|
+
*,
|
|
1001
|
+
cache_key: Optional[str] = None,
|
|
1002
|
+
include_details: Optional[bool] = False,
|
|
1003
|
+
request_id: Optional[str] = None,
|
|
1004
|
+
**metadata
|
|
1005
|
+
) -> BatchFileStatusResponse:
|
|
1006
|
+
"""
|
|
1007
|
+
批量获取文件状态
|
|
1008
|
+
|
|
1009
|
+
Args:
|
|
1010
|
+
file_ids: 文件ID列表
|
|
1011
|
+
cache_key: 缓存键(可选)
|
|
1012
|
+
include_details: 是否包含详细状态信息(默认False)
|
|
1013
|
+
request_id: 请求ID,用于追踪
|
|
1014
|
+
**metadata: 额外的gRPC元数据
|
|
1015
|
+
|
|
1016
|
+
Returns:
|
|
1017
|
+
BatchFileStatusResponse: 批量文件状态响应
|
|
1018
|
+
"""
|
|
1019
|
+
from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
|
|
1020
|
+
|
|
1021
|
+
stub = self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
|
|
1022
|
+
|
|
1023
|
+
request = file_service_pb2.BatchFileStatusRequest(
|
|
1024
|
+
file_ids=file_ids,
|
|
1025
|
+
include_details=include_details if include_details is not None else False
|
|
1026
|
+
)
|
|
1027
|
+
|
|
1028
|
+
if cache_key:
|
|
1029
|
+
request.cache_key = cache_key
|
|
1030
|
+
|
|
1031
|
+
# 构建元数据
|
|
1032
|
+
grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
|
|
1033
|
+
|
|
1034
|
+
response = stub.BatchGetFileStatus(request, metadata=grpc_metadata)
|
|
1035
|
+
|
|
1036
|
+
# 转换文件状态信息
|
|
1037
|
+
statuses = []
|
|
1038
|
+
for status_info in response.statuses:
|
|
1039
|
+
# 转换状态详情(如果存在)
|
|
1040
|
+
details = None
|
|
1041
|
+
if status_info.HasField('details'):
|
|
1042
|
+
details = FileStatusDetails(
|
|
1043
|
+
file_size=status_info.details.file_size if status_info.details.HasField('file_size') else None,
|
|
1044
|
+
storage_type=status_info.details.storage_type if status_info.details.HasField('storage_type') else None,
|
|
1045
|
+
storage_region=status_info.details.storage_region if status_info.details.HasField('storage_region') else None,
|
|
1046
|
+
compression_task_id=status_info.details.compression_task_id if status_info.details.HasField('compression_task_id') else None,
|
|
1047
|
+
compression_variants_count=status_info.details.compression_variants_count if status_info.details.HasField('compression_variants_count') else None,
|
|
1048
|
+
compression_progress=status_info.details.compression_progress if status_info.details.HasField('compression_progress') else None,
|
|
1049
|
+
sync_regions_total=status_info.details.sync_regions_total if status_info.details.HasField('sync_regions_total') else None,
|
|
1050
|
+
sync_regions_completed=status_info.details.sync_regions_completed if status_info.details.HasField('sync_regions_completed') else None,
|
|
1051
|
+
sync_pending_regions=list(status_info.details.sync_pending_regions)
|
|
1052
|
+
)
|
|
1053
|
+
|
|
1054
|
+
# 转换枚举值
|
|
1055
|
+
upload_status = self._convert_upload_status(status_info.upload_status)
|
|
1056
|
+
compression_status = self._convert_compression_status(status_info.compression_status)
|
|
1057
|
+
sync_status = self._convert_sync_status(status_info.sync_status)
|
|
1058
|
+
|
|
1059
|
+
statuses.append(FileStatusInfo(
|
|
1060
|
+
file_id=status_info.file_id,
|
|
1061
|
+
upload_status=upload_status,
|
|
1062
|
+
compression_status=compression_status,
|
|
1063
|
+
sync_status=sync_status,
|
|
1064
|
+
details=details,
|
|
1065
|
+
error_message=status_info.error_message if status_info.HasField('error_message') else None
|
|
1066
|
+
))
|
|
1067
|
+
|
|
1068
|
+
return BatchFileStatusResponse(
|
|
1069
|
+
statuses=statuses,
|
|
1070
|
+
cache_key=response.cache_key if response.HasField('cache_key') else None,
|
|
1071
|
+
timestamp=response.timestamp,
|
|
1072
|
+
cache_ttl_seconds=response.cache_ttl_seconds
|
|
1073
|
+
)
|
|
1074
|
+
|
|
1075
|
+
def _convert_upload_status(self, proto_status: int) -> FileUploadStatus:
|
|
1076
|
+
"""转换上传状态枚举"""
|
|
1077
|
+
status_map = {
|
|
1078
|
+
0: FileUploadStatus.UPLOAD_UNKNOWN,
|
|
1079
|
+
1: FileUploadStatus.UPLOAD_PENDING,
|
|
1080
|
+
2: FileUploadStatus.UPLOAD_PROCESSING,
|
|
1081
|
+
3: FileUploadStatus.UPLOAD_COMPLETED,
|
|
1082
|
+
4: FileUploadStatus.UPLOAD_FAILED,
|
|
1083
|
+
}
|
|
1084
|
+
return status_map.get(proto_status, FileUploadStatus.UPLOAD_UNKNOWN)
|
|
1085
|
+
|
|
1086
|
+
def _convert_compression_status(self, proto_status: int) -> FileCompressionStatus:
|
|
1087
|
+
"""转换压缩状态枚举"""
|
|
1088
|
+
status_map = {
|
|
1089
|
+
0: FileCompressionStatus.COMPRESSION_UNKNOWN,
|
|
1090
|
+
1: FileCompressionStatus.COMPRESSION_NOT_APPLICABLE,
|
|
1091
|
+
2: FileCompressionStatus.COMPRESSION_PENDING,
|
|
1092
|
+
3: FileCompressionStatus.COMPRESSION_PROCESSING,
|
|
1093
|
+
4: FileCompressionStatus.COMPRESSION_COMPLETED,
|
|
1094
|
+
5: FileCompressionStatus.COMPRESSION_FAILED,
|
|
1095
|
+
6: FileCompressionStatus.COMPRESSION_SKIPPED,
|
|
1096
|
+
}
|
|
1097
|
+
return status_map.get(proto_status, FileCompressionStatus.COMPRESSION_UNKNOWN)
|
|
1098
|
+
|
|
1099
|
+
def _convert_sync_status(self, proto_status: int) -> FileSyncStatus:
|
|
1100
|
+
"""转换同步状态枚举"""
|
|
1101
|
+
status_map = {
|
|
1102
|
+
0: FileSyncStatus.SYNC_UNKNOWN,
|
|
1103
|
+
1: FileSyncStatus.SYNC_NOT_REQUIRED,
|
|
1104
|
+
2: FileSyncStatus.SYNC_PENDING,
|
|
1105
|
+
3: FileSyncStatus.SYNC_PROCESSING,
|
|
1106
|
+
4: FileSyncStatus.SYNC_PARTIAL,
|
|
1107
|
+
5: FileSyncStatus.SYNC_COMPLETED,
|
|
1108
|
+
6: FileSyncStatus.SYNC_FAILED,
|
|
1109
|
+
}
|
|
1110
|
+
return status_map.get(proto_status, FileSyncStatus.SYNC_UNKNOWN)
|
|
@@ -13,26 +13,26 @@ file_hub_client/rpc/generate_grpc.py,sha256=opzstxWdW7vqR9OxrgUCSUkZe8IqgcOdruqW
|
|
|
13
13
|
file_hub_client/rpc/interceptors.py,sha256=cFLKziOZMO5oKZfElLXctLKo08BJCFHFiuCrvtYSGaw,21627
|
|
14
14
|
file_hub_client/rpc/sync_client.py,sha256=iaow1Lpi0moq9kwlUVNP0p4ucgHKCP8y5cvmP32dkQU,15364
|
|
15
15
|
file_hub_client/rpc/gen/__init__.py,sha256=NJLqr9ezUXeOyy1J0sMPn3Kl_8IyGw7GAzzzewO3MIw,45
|
|
16
|
-
file_hub_client/rpc/gen/file_service_pb2.py,sha256=
|
|
17
|
-
file_hub_client/rpc/gen/file_service_pb2_grpc.py,sha256=
|
|
16
|
+
file_hub_client/rpc/gen/file_service_pb2.py,sha256=xDtV7K78rtq1QqKaO2_DiPbb8ClAWqKOzHG3C5VEdSg,18415
|
|
17
|
+
file_hub_client/rpc/gen/file_service_pb2_grpc.py,sha256=uDh4WOwjgBNrx-njCjF_7tzeQqK8gKwfCR9bjMiMGZc,35156
|
|
18
18
|
file_hub_client/rpc/gen/folder_service_pb2.py,sha256=OPNYHThmL1k2KH1ll2L_Gj76oWBWqcymXKHu8mk1Zvk,4126
|
|
19
19
|
file_hub_client/rpc/gen/folder_service_pb2_grpc.py,sha256=pOHFsVThdAu5DAKd8QK3_zQvUmFgGlh4KBqIYnYDZ_U,10411
|
|
20
20
|
file_hub_client/rpc/gen/taple_service_pb2.py,sha256=8BJCFRFJ_khl_Uaw-5jWCabljWJo6zaqOYWe1368xEw,48254
|
|
21
21
|
file_hub_client/rpc/gen/taple_service_pb2_grpc.py,sha256=DCL-45PlEZ0guLz1u2fFH_sDIT_awuSvp9Ak6fa2GO8,64773
|
|
22
|
-
file_hub_client/rpc/protos/file_service.proto,sha256=
|
|
22
|
+
file_hub_client/rpc/protos/file_service.proto,sha256=R4AUEHNvixMi-kIkTXKeAZFMTI6lJVolC1hBBoF59Jg,9792
|
|
23
23
|
file_hub_client/rpc/protos/folder_service.proto,sha256=cgIbJT2slXMMRGrtrzN3kjae9-4CB1zXCmceiUgE6fI,1542
|
|
24
24
|
file_hub_client/rpc/protos/taple_service.proto,sha256=0mwhyBwD3yvFhMiiSA6J3Ni6pyHc369iD4oDXXl7DIU,29765
|
|
25
|
-
file_hub_client/schemas/__init__.py,sha256=
|
|
26
|
-
file_hub_client/schemas/context.py,sha256=
|
|
27
|
-
file_hub_client/schemas/file.py,sha256=
|
|
25
|
+
file_hub_client/schemas/__init__.py,sha256=tIHq7bmurBNDdz8iPuz-_bt9SiIDaGSffxD1Y6ae3CA,3050
|
|
26
|
+
file_hub_client/schemas/context.py,sha256=tSbzb7ESLqc323h4GBiel38hXc6dxTAWLpJDzxAaz6g,5976
|
|
27
|
+
file_hub_client/schemas/file.py,sha256=rM9KDcOQRi1vfbHzFD_BGL9_A9wbh9BJRmUK3szlkfU,9540
|
|
28
28
|
file_hub_client/schemas/folder.py,sha256=D7UFsLCou-7CCXCQvuRObaBQEGmETsm1cgGOG1ceSrk,1026
|
|
29
29
|
file_hub_client/schemas/taple.py,sha256=LYsECsDbcioPXcvjRBcCEbh083iEB-eFCapJrGMJ8w0,17790
|
|
30
30
|
file_hub_client/services/__init__.py,sha256=yh5mir0dKB_LtJMk2hTpQI9WSlguaxtVD2KomMnzxdM,514
|
|
31
31
|
file_hub_client/services/file/__init__.py,sha256=aJygo_AzYk5NN-ezp-a9YlugJ82wVIP9e5e54fl0UsI,342
|
|
32
|
-
file_hub_client/services/file/async_blob_service.py,sha256=
|
|
32
|
+
file_hub_client/services/file/async_blob_service.py,sha256=67n3cGROM8CIHqiraCaXyBukMK4Rh7hRdl5R-UkrSMI,43112
|
|
33
33
|
file_hub_client/services/file/async_file_service.py,sha256=lFMfnHKsbTIOpMAdFvER4B2JqVGz9SNzgxlmA1kY3Js,17197
|
|
34
34
|
file_hub_client/services/file/base_file_service.py,sha256=21C-z8zU2ooZp31YBTOAzvUJKbC5zUQ7T0pSmFA8iRs,16144
|
|
35
|
-
file_hub_client/services/file/sync_blob_service.py,sha256=
|
|
35
|
+
file_hub_client/services/file/sync_blob_service.py,sha256=cYH92aIwYy0Q44cFJ5qGJY4jIHTx5zEU62XKaSAUyXY,42723
|
|
36
36
|
file_hub_client/services/file/sync_file_service.py,sha256=3VEgFiWYfoWD4iZObJ8uylUtNmK08snXWUaVEosUPDo,16979
|
|
37
37
|
file_hub_client/services/folder/__init__.py,sha256=vGbMOlNiEBdnWZB1xE74RJtoroI28hKHCWfQV1GqKQc,210
|
|
38
38
|
file_hub_client/services/folder/async_folder_service.py,sha256=uFEmtW8EXYvaKYT2JCitWbdTGR1EtHlx_eBN5P3JUZg,7293
|
|
@@ -53,7 +53,7 @@ file_hub_client/utils/mime_extension_mapper.py,sha256=jZhgKJcp-xFVDtaFBgUYaGcY4-
|
|
|
53
53
|
file_hub_client/utils/retry.py,sha256=A2MBdJCEY-Ks0guq8dd5wXX22sD27N30Qy3nQIW1B_s,18019
|
|
54
54
|
file_hub_client/utils/smart_retry.py,sha256=RjBhyG6SNDfMXxNxKU_qayWDD6Ihp7ow6_BPjhgflM0,16465
|
|
55
55
|
file_hub_client/utils/upload_helper.py,sha256=mOnb_FGn-JLS-1uiC_LvDMOH0Y9-xvVo9QAJxid-GvI,23071
|
|
56
|
-
tamar_file_hub_client-0.1.
|
|
57
|
-
tamar_file_hub_client-0.1.
|
|
58
|
-
tamar_file_hub_client-0.1.
|
|
59
|
-
tamar_file_hub_client-0.1.
|
|
56
|
+
tamar_file_hub_client-0.1.8.dist-info/METADATA,sha256=MPeMi7avNV-xb93Wfh0MENm5kZG3Tp1sOofpvbVNBw8,80363
|
|
57
|
+
tamar_file_hub_client-0.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
58
|
+
tamar_file_hub_client-0.1.8.dist-info/top_level.txt,sha256=9wcR7hyAJQdJg_kuH6WR3nmpJ8O-j8aJNK8f_kcFy6U,16
|
|
59
|
+
tamar_file_hub_client-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
{tamar_file_hub_client-0.1.6.dist-info → tamar_file_hub_client-0.1.8.dist-info}/top_level.txt
RENAMED
|
File without changes
|