extract validators and decorator to utils
[qcg-portal.git] / filex / utils.py
diff --git a/filex/utils.py b/filex/utils.py
new file mode 100644 (file)
index 0000000..9a96949
--- /dev/null
@@ -0,0 +1,34 @@
+from functools import wraps
+
+from django.core.validators import RegexValidator
+from django.http import JsonResponse
+from django.views.decorators.csrf import csrf_protect, csrf_exempt
+
+from filex.ftp import FTPError
+from filex.uploadhandler import FtpUploadHandler
+
+
+msg = u'Invalid value'
+host_validator = RegexValidator(r'^(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+'
+                                r'(?:[a-zA-Z]{2,6}\.?|[a-zA-Z0-9-]{2,}(?<!-)\.?))(?::\d+)?$', msg)
+path_validator = RegexValidator(r'^~?(?:/[^/\0]*)*$', msg)
+name_validator = RegexValidator(r'^[^/\0]+$', msg)
+
+
+def with_ftp_upload_handler(view_func):
+    @wraps(view_func)
+    def wrapped_view(request, *args, **kwargs):
+        request.upload_handlers = [FtpUploadHandler(request)]
+
+        try:
+            return csrf_protect(view_func)(request, *args, **kwargs)
+        except FTPError as e:
+            status = 400
+            if 'No such file or directory' in e.message:
+                status = 404
+            elif 'Permission denied' in e.message:
+                status = 403
+
+            return JsonResponse({'error': e.message}, status=status)
+
+    return csrf_exempt(wrapped_view)