@@ -56,177 +56,89 @@ class CompressionLib:
5656
5757class Chunk (Object ):
5858
59- def __init__ (self , offset , url , length ):
59+ def __init__ (self , number , offset , url , length ):
6060 """
6161 Initialize a Chunk.
6262
63+ :param int number: Chunk number.
6364 :param int offset: Chunk offset.
6465 :param str url: Signed URL.
6566 :param int length: Object length.
6667 """
6768 super ().__init__ (
69+ number = number ,
6870 offset = offset ,
6971 url = url ,
7072 length = length
7173 )
7274
7375
74- class MetadataPart (Object ):
76+ class Metadata (Object ):
7577 """
76- CTERA Direct I/O File Metadata Part
77-
78- :ivar int start: Starting offset.
79- :ivar int end: Ending offset.
80- :ivar int length: Length of the range in bytes.
81- :ivar bool encrypted: Indicates whether the range data is encrypted.
82- :ivar str encryption_key: Encryption key used for the range data.
83- :ivar bool compressed: Indicates whether the range data is compressed.
84- :ivar str compression_alg: Compression algorithm used for the range data.
85- :ivar list[cterasdk.common.object.Object] chunks: List of Chunk Objects.
78+ CTERA Direct IO File Metadata
8679 """
87- def __init__ (self , offset , end , encrypted , encryption_key , compressed , compression_alg , chunks ):
80+
81+ def __init__ (self , file_id , server_object ):
8882 """
8983 Initialize a Direct IO metadata response object.
9084
91- :param int offset: Starting offset.
92- :param int end: Ending offset.
93- :param bool encrypted: Indicates whether the file is encrypted.
94- :param str encryption_key: Encryption key used for the file.
95- :param bool compressed: Indicates whether the file is compressed.
96- :param str compression_alg: Compression algorithm used for the file.
97- :param list[cterasdk.common.object.Object] chunks: List of Chunk Objects.
85+ :param int file_id: File ID.
86+ :param cterasdk.common.object.Object server_object: Response Object.
9887 """
9988 super ().__init__ (
100- start = offset ,
101- end = end ,
102- length = (end - offset ) + 1 ,
103- encrypted = encrypted ,
104- encryption_key = encryption_key ,
105- compressed = compressed ,
106- compression_alg = compression_alg
89+ file_id = file_id ,
90+ encrypted = server_object .encrypt_info .data_encrypted ,
91+ compressed = server_object .compression_type != CompressionLib .Off ,
92+ chunks = Metadata ._format_chunks (server_object .chunks )
10793 )
108- for chunk in chunks :
109- self .chunks .append (Chunk (offset , chunk .url , chunk .len ))
110- offset = offset + chunk .len
94+ self .encryption_key = server_object .encrypt_info .wrapped_key if self .encrypted else None
95+ self .compression_library = server_object .compression_type if self .compressed else None
96+ last_chunk = self .chunks [- 1 ]
97+ self .size = last_chunk .offset + last_chunk .length
11198
11299 @staticmethod
113- def from_server_object (server_object ):
114- compressed = server_object .compression_type != CompressionLib .Off
115- start , end = map (int , server_object .actual_blocks_range .range .split ('-' ))
116- return MetadataPart (
117- start ,
118- end ,
119- server_object .encrypt_info .data_encrypted ,
120- server_object .encrypt_info .wrapped_key if server_object .encrypt_info .data_encrypted else None ,
121- compressed ,
122- server_object .compression_type if compressed else None
123- )
124-
125- def __repr__ (self ):
126- return str (self )
127-
128- def __str__ (self ):
129- return (
130- f"{ self .__class__ .__name__ } ("
131- f"{{'start': { self .start } , "
132- f"'end': { self .end } , "
133- f"'encrypted': { self .encrypted } , "
134- f"'compressed': { self .compressed } , "
135- f"'length': { self .length } , "
136- f"'chunks': { len (self .chunks )} }})"
137- )
138-
139-
140- class Metadata (Object ):
141- """
142- CTERA Direct I/O File Metadata
143-
144- :ivar int file_id: File ID.
145- :ivar int file_size: File Size.
146- :ivar list[cterasdk.direct.types.MetadataPart] parts: List of Metadata Parts.
147- :ivar bool encrypted: Indicates whether the range data is encrypted.
148- :ivar str encryption_key: Encryption key used for the range data.
149- :ivar bool compressed: Indicates whether the range data is compressed.
150- :ivar str compression_alg: Compression algorithm used for the range data.
151- """
152- def __init__ (self , file_id , * parts ):
100+ def _format_chunks (server_object ):
153101 """
154- Initialize a Direct IO metadata response object .
102+ Create Chunks .
155103
156104 :param int file_id: File ID.
157- :param list[cterasdk.direct.types.MetadataPart] parts: List of Metadata Parts.
105+ :param cterasdk.common.object.Object server_object: Server response.
106+ :param list[int] blocks: List of block numbers to retrieve.
107+ :returns: Chunk objects
108+ :rtype: list[cterasdk.direct.types.Chunk]
158109 """
159- super ().__init__ (file_id = file_id , parts = parts )
160-
161- @property
162- def size (self ):
163- return self .parts [0 ].actual_blocks_range .file_size
164-
165- @property
166- def encrypted (self ):
167- return self .parts [0 ].encrypted
168-
169- @property
170- def encryption_key (self ):
171- return self .parts [0 ].encryption_key
172-
173- @property
174- def compressed (self ):
175- return self .parts [0 ].compressed
176-
177- @property
178- def compression_alg (self ):
179- return self .parts [0 ].compression_alg
180-
181- @property
182- def start (self ):
183- return self .parts [0 ].start
184-
185- @property
186- def end (self ):
187- return self .parts [- 1 ].end
110+ offset = 0
111+ chunks = []
112+ for number , chunk in enumerate (server_object , 1 ):
113+ chunks .append (Chunk (number , offset , chunk .url , chunk .len ))
114+ offset = offset + chunk .len
115+ return chunks
188116
189117 def serialize (self ):
190118 """
191- Serialize Direct I/O metadata to a dictionary.
119+ Serialize Direct IO metadata to a dictionary.
192120 """
193- chunks = []
194- for part in self .parts :
195- chunks .extend (part .chunks )
196-
197- return {
198- 'file_id' : self .file_id ,
199- 'size' : self .size ,
200- 'encrypted' : self .encrypted ,
201- 'encryption_key' : utils .utf8_decode (base64 .b64encode (self .encryption_key )) if self .encrypted else None ,
202- 'compressed' : self .compressed ,
203- 'compression_alg' : self .compression_alg ,
204- 'chunks' : chunks
205- }
206-
207- def __repr__ (self ):
208- return str (self )
209-
210- def __str__ (self ):
211- d = self .serialize ()
212- d .pop ('encryption_key' )
213- d ['chunks' ] = len (d ['chunks' ])
214- return d
121+ x = copy .deepcopy (self )
122+ if self .encrypted :
123+ x .encryption_key = utils .utf8_decode (base64 .b64encode (self .encryption_key ))
124+ return x
215125
216126
217127class Block :
218128 """Block"""
219129
220- def __init__ (self , file_id , offset , data , length ):
130+ def __init__ (self , file_id , number , offset , data , length ):
221131 """
222132 Initialize a Block.
223133
224134 :param int file_id: File ID.
135+ :param int number: Block number.
225136 :param int offset: Block offset.
226137 :param bytes data: Bytes
227138 :param int length: Block length.
228139 """
229140 self ._file_id = file_id
141+ self ._number = number
230142 self ._offset = offset
231143 self ._data = data
232144 self ._length = length
@@ -235,6 +147,10 @@ def __init__(self, file_id, offset, data, length):
235147 def file_id (self ):
236148 return self ._file_id
237149
150+ @property
151+ def number (self ):
152+ return self ._number
153+
238154 @property
239155 def offset (self ):
240156 return self ._offset
0 commit comments