1717from pydantic import ValidationError
1818from rest_framework import serializers
1919
20- from filebrowser .schemas import RenameSchema
20+ from filebrowser .schemas import (
21+ CheckExistsSchema ,
22+ CompressFilesSchema ,
23+ CopyOperationSchema ,
24+ CreateDirectorySchema ,
25+ CreateFileSchema ,
26+ DeleteOperationSchema ,
27+ ExtractArchiveSchema ,
28+ GetFileContentsSchema ,
29+ GetStatsSchema ,
30+ GetTrashPathSchema ,
31+ ListDirectorySchema ,
32+ MoveOperationSchema ,
33+ RenameSchema ,
34+ SaveFileSchema ,
35+ SetOwnershipSchema ,
36+ SetPermissionsSchema ,
37+ SetReplicationSchema ,
38+ TrashRestoreSchema ,
39+ )
2140
2241
2342class UploadFileSerializer (serializers .Serializer ):
@@ -44,3 +63,306 @@ def validate(self, data):
4463 raise serializers .ValidationError (e .errors ())
4564
4665 return data
66+
67+
68+ class GetFileContentsSerializer (serializers .Serializer ):
69+ """
70+ Validates the parameters for the file contents API.
71+ """
72+
73+ path = serializers .CharField (required = True , allow_blank = False )
74+ # Range specifiers (mutually exclusive)
75+ offset = serializers .IntegerField (required = False , min_value = 0 )
76+ length = serializers .IntegerField (required = False , min_value = 1 )
77+ begin = serializers .IntegerField (required = False , min_value = 1 )
78+ end = serializers .IntegerField (required = False , min_value = 1 )
79+ # Options
80+ encoding = serializers .CharField (required = False )
81+ compression = serializers .CharField (required = False )
82+ read_until_newline = serializers .BooleanField (default = False )
83+
84+ def validate (self , data ):
85+ try :
86+ GetFileContentsSchema .model_validate (data )
87+ except ValidationError as e :
88+ raise serializers .ValidationError (e .errors ())
89+ return data
90+
91+
92+ class DownloadFileSerializer (serializers .Serializer ):
93+ """
94+ Validates the parameters for the file download API.
95+ """
96+
97+ path = serializers .CharField (required = True , allow_blank = False , help_text = "Path to the file to download" )
98+ disposition = serializers .ChoiceField (
99+ choices = ["attachment" , "inline" ],
100+ default = "attachment" ,
101+ help_text = "Content-Disposition type: 'attachment' forces download, 'inline' attempts browser display" ,
102+ )
103+
104+ def validate_path (self , value ):
105+ if not value or value .strip () != value :
106+ raise serializers .ValidationError ("Path cannot be empty or contain only whitespace" )
107+
108+ if ".." in value or value .startswith ("~" ):
109+ raise serializers .ValidationError ("Invalid path: path traversal patterns are not allowed" )
110+
111+ return value
112+
113+
114+ class CreateFileSerializer (serializers .Serializer ):
115+ """
116+ Validates the parameters for the file creation API.
117+ """
118+
119+ path = serializers .CharField (required = True , allow_blank = False , help_text = "Path where the file should be created" )
120+ overwrite = serializers .BooleanField (default = False , help_text = "Whether to overwrite if file exists" )
121+ encoding = serializers .CharField (default = "utf-8" , help_text = "Character encoding for the file" )
122+ initial_content = serializers .CharField (required = False , help_text = "Initial content to write to the file" )
123+
124+ def validate (self , data ):
125+ try :
126+ CreateFileSchema .model_validate (data )
127+ except ValidationError as e :
128+ raise serializers .ValidationError (e .errors ())
129+ return data
130+
131+
132+ class SaveFileSerializer (serializers .Serializer ):
133+ """
134+ Validates the parameters for the file save/edit API.
135+ """
136+
137+ path = serializers .CharField (required = True , allow_blank = False , help_text = "Path to the file to save" )
138+ contents = serializers .CharField (required = True , help_text = "File contents to save" )
139+ encoding = serializers .CharField (default = "utf-8" , help_text = "Character encoding for the file" )
140+ create_parent_dirs = serializers .BooleanField (default = False , help_text = "Create parent directories if they don't exist" )
141+
142+ def validate (self , data ):
143+ try :
144+ SaveFileSchema .model_validate (data )
145+ except ValidationError as e :
146+ raise serializers .ValidationError (e .errors ())
147+ return data
148+
149+
150+ class ListDirectorySerializer (serializers .Serializer ):
151+ """
152+ Validates the parameters for the directory listing API.
153+ """
154+
155+ path = serializers .CharField (default = "/" , help_text = "Directory path to list" )
156+ pagenum = serializers .IntegerField (default = 1 , min_value = 1 , max_value = 10000 , help_text = "Page number (1-10000)" )
157+ pagesize = serializers .IntegerField (default = 30 , min_value = 1 , max_value = 1000 , help_text = "Items per page (1-1000)" )
158+ sortby = serializers .ChoiceField (
159+ choices = ["name" , "size" , "type" , "mtime" , "atime" , "user" , "group" ],
160+ default = "name" ,
161+ help_text = "Sort by field" ,
162+ )
163+ descending = serializers .BooleanField (default = False , help_text = "Sort in descending order" )
164+ filter = serializers .CharField (required = False , max_length = 255 , help_text = "Filter results by filename substring" )
165+
166+ def validate (self , data ):
167+ try :
168+ ListDirectorySchema .model_validate (data )
169+ except ValidationError as e :
170+ raise serializers .ValidationError (e .errors ())
171+ return data
172+
173+
174+ class CreateDirectorySerializer (serializers .Serializer ):
175+ """
176+ Validates the parameters for the directory creation API.
177+ """
178+
179+ path = serializers .CharField (required = True , allow_blank = False , help_text = "Full path of the directory to create" )
180+
181+ def validate (self , data ):
182+ try :
183+ CreateDirectorySchema .model_validate (data )
184+ except ValidationError as e :
185+ raise serializers .ValidationError (e .errors ())
186+ return data
187+
188+
189+ class GetStatsSerializer (serializers .Serializer ):
190+ """
191+ Validates the parameters for the path statistics API.
192+ """
193+
194+ path = serializers .CharField (required = True , allow_blank = False )
195+ include_content_summary = serializers .BooleanField (default = False )
196+
197+ def validate (self , data ):
198+ try :
199+ GetStatsSchema .model_validate (data )
200+ except ValidationError as e :
201+ raise serializers .ValidationError (e .errors ())
202+ return data
203+
204+
205+ class CheckExistsSerializer (serializers .Serializer ):
206+ """Serializer for checking if paths exist."""
207+
208+ paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
209+
210+ def validate (self , data ):
211+ try :
212+ CheckExistsSchema .model_validate (data )
213+ except ValidationError as e :
214+ raise serializers .ValidationError (e .errors ())
215+ return data
216+
217+
218+ class CopyOperationSerializer (serializers .Serializer ):
219+ """Serializer for copy operation."""
220+
221+ source_paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
222+ destination_path = serializers .CharField (required = True , allow_blank = False )
223+
224+ def validate (self , data ):
225+ try :
226+ CopyOperationSchema .model_validate (data )
227+ except ValidationError as e :
228+ raise serializers .ValidationError (e .errors ())
229+ return data
230+
231+
232+ class MoveOperationSerializer (serializers .Serializer ):
233+ """Serializer for move operation."""
234+
235+ source_paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
236+ destination_path = serializers .CharField (required = True , allow_blank = False )
237+
238+ def validate (self , data ):
239+ try :
240+ MoveOperationSchema .model_validate (data )
241+ except ValidationError as e :
242+ raise serializers .ValidationError (e .errors ())
243+ return data
244+
245+
246+ class DeleteOperationSerializer (serializers .Serializer ):
247+ """Serializer for delete operation."""
248+
249+ paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
250+ skip_trash = serializers .BooleanField (default = False )
251+
252+ def validate (self , data ):
253+ try :
254+ DeleteOperationSchema .model_validate (data )
255+ except ValidationError as e :
256+ raise serializers .ValidationError (e .errors ())
257+ return data
258+
259+
260+ class TrashRestoreSerializer (serializers .Serializer ):
261+ """Serializer for restoring from trash."""
262+
263+ paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
264+
265+ def validate (self , data ):
266+ try :
267+ TrashRestoreSchema .model_validate (data )
268+ except ValidationError as e :
269+ raise serializers .ValidationError (e .errors ())
270+ return data
271+
272+
273+ class SetPermissionsSerializer (serializers .Serializer ):
274+ """Serializer for setting file/directory permissions."""
275+
276+ paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
277+ mode = serializers .CharField (required = False )
278+ recursive = serializers .BooleanField (default = False )
279+ # Individual permission fields
280+ user_read = serializers .BooleanField (required = False )
281+ user_write = serializers .BooleanField (required = False )
282+ user_execute = serializers .BooleanField (required = False )
283+ group_read = serializers .BooleanField (required = False )
284+ group_write = serializers .BooleanField (required = False )
285+ group_execute = serializers .BooleanField (required = False )
286+ other_read = serializers .BooleanField (required = False )
287+ other_write = serializers .BooleanField (required = False )
288+ other_execute = serializers .BooleanField (required = False )
289+ sticky = serializers .BooleanField (required = False )
290+
291+ def validate (self , data ):
292+ try :
293+ SetPermissionsSchema .model_validate (data )
294+ except ValidationError as e :
295+ raise serializers .ValidationError (e .errors ())
296+ return data
297+
298+
299+ class SetOwnershipSerializer (serializers .Serializer ):
300+ """Serializer for setting file/directory ownership."""
301+
302+ paths = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
303+ user = serializers .CharField (required = False )
304+ group = serializers .CharField (required = False )
305+ recursive = serializers .BooleanField (default = False )
306+
307+ def validate (self , data ):
308+ try :
309+ SetOwnershipSchema .model_validate (data )
310+ except ValidationError as e :
311+ raise serializers .ValidationError (e .errors ())
312+ return data
313+
314+
315+ class SetReplicationSerializer (serializers .Serializer ):
316+ """Serializer for setting replication factor."""
317+
318+ path = serializers .CharField (required = True , allow_blank = False )
319+ replication_factor = serializers .IntegerField (required = True , min_value = 1 )
320+
321+ def validate (self , data ):
322+ try :
323+ SetReplicationSchema .model_validate (data )
324+ except ValidationError as e :
325+ raise serializers .ValidationError (e .errors ())
326+ return data
327+
328+
329+ class CompressFilesSerializer (serializers .Serializer ):
330+ """Serializer for compressing files."""
331+
332+ file_names = serializers .ListField (child = serializers .CharField (), required = True , min_length = 1 )
333+ upload_path = serializers .CharField (required = True , allow_blank = False )
334+ archive_name = serializers .CharField (required = True , allow_blank = False )
335+
336+ def validate (self , data ):
337+ try :
338+ CompressFilesSchema .model_validate (data )
339+ except ValidationError as e :
340+ raise serializers .ValidationError (e .errors ())
341+ return data
342+
343+
344+ class ExtractArchiveSerializer (serializers .Serializer ):
345+ """Serializer for extracting archives."""
346+
347+ upload_path = serializers .CharField (required = True , allow_blank = False )
348+ archive_name = serializers .CharField (required = True , allow_blank = False )
349+
350+ def validate (self , data ):
351+ try :
352+ ExtractArchiveSchema .model_validate (data )
353+ except ValidationError as e :
354+ raise serializers .ValidationError (e .errors ())
355+ return data
356+
357+
358+ class GetTrashPathSerializer (serializers .Serializer ):
359+ """Serializer for getting trash path."""
360+
361+ path = serializers .CharField (required = True , allow_blank = False )
362+
363+ def validate (self , data ):
364+ try :
365+ GetTrashPathSchema .model_validate (data )
366+ except ValidationError as e :
367+ raise serializers .ValidationError (e .errors ())
368+ return data
0 commit comments