forms.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. from future import standard_library
  18. standard_library.install_aliases()
  19. from builtins import zip
  20. from builtins import range
  21. import logging
  22. import sys
  23. import urllib.request, urllib.error
  24. from django import forms
  25. from django.forms import FileField, CharField, BooleanField, Textarea
  26. from django.forms.formsets import formset_factory, BaseFormSet
  27. from django.utils.translation import ugettext_lazy as _
  28. from aws.s3 import S3A_ROOT, normpath as s3_normpath
  29. from azure.abfs.__init__ import ABFS_ROOT, normpath as abfs_normpath
  30. from desktop.lib import i18n
  31. from hadoop.fs import normpath
  32. from useradmin.models import User, Group
  33. from filebrowser.lib import rwx
  34. if sys.version_info[0] > 2:
  35. from urllib.parse import unquote as urllib_unquote
  36. else:
  37. from urllib import unquote as urllib_unquote
  38. logger = logging.getLogger(__name__)
  39. class FormSet(BaseFormSet):
  40. def __init__(self, data=None, prefix=None, *args, **kwargs):
  41. self.prefix = prefix or self.get_default_prefix()
  42. if data:
  43. self.data = {}
  44. # Add management field info
  45. # This is hard coded given that none of these keys or info is exportable
  46. # This could be a problem point if the management form changes in later releases
  47. self.data['%s-TOTAL_FORMS' % self.prefix] = len(data)
  48. self.data['%s-INITIAL_FORMS' % self.prefix] = len(data)
  49. self.data['%s-MAX_NUM_FORMS' % self.prefix] = 0
  50. # Add correct data
  51. for i in range(0, len(data)):
  52. prefix = self.add_prefix(i)
  53. for field in data[i]:
  54. self.data['%s-%s' % (prefix, field)] = data[i][field]
  55. BaseFormSet.__init__(self, self.data, self.prefix, *args, **kwargs)
  56. class PathField(CharField):
  57. def __init__(self, label, help_text=None, **kwargs):
  58. kwargs.setdefault('required', True)
  59. kwargs.setdefault('min_length', 1)
  60. forms.CharField.__init__(self, label=label, help_text=help_text, **kwargs)
  61. def clean(self, value):
  62. cleaned_path = CharField.clean(self, value)
  63. if value.lower().startswith(S3A_ROOT):
  64. cleaned_path = s3_normpath(cleaned_path)
  65. elif value.lower().startswith(ABFS_ROOT):
  66. cleaned_path = abfs_normpath(cleaned_path)
  67. else:
  68. cleaned_path = normpath(cleaned_path)
  69. return cleaned_path
  70. class EditorForm(forms.Form):
  71. path = PathField(label=_("File to edit"))
  72. contents = CharField(widget=Textarea, label=_("Contents"), required=False)
  73. encoding = CharField(label=_('Encoding'), required=False)
  74. def clean_path(self):
  75. return urllib_unquote(self.cleaned_data.get('path', ''))
  76. def clean_contents(self):
  77. return self.cleaned_data.get('contents', '').replace('\r\n', '\n')
  78. def clean_encoding(self):
  79. encoding = self.cleaned_data.get('encoding', '').strip()
  80. if not encoding:
  81. return i18n.get_site_encoding()
  82. return encoding
  83. class RenameForm(forms.Form):
  84. op = "rename"
  85. src_path = CharField(label=_("File to rename"), help_text=_("The file to rename."))
  86. dest_path = CharField(label=_("New name"), help_text=_("Rename the file to:"))
  87. class BaseRenameFormSet(FormSet):
  88. op = "rename"
  89. RenameFormSet = formset_factory(RenameForm, formset=BaseRenameFormSet, extra=0)
  90. class CopyForm(forms.Form):
  91. op = "copy"
  92. src_path = CharField(label=_("File to copy"), help_text=_("The file to copy."))
  93. dest_path = CharField(label=_("Destination location"), help_text=_("Copy the file to:"))
  94. class BaseCopyFormSet(FormSet):
  95. op = "copy"
  96. CopyFormSet = formset_factory(CopyForm, formset=BaseCopyFormSet, extra=0)
  97. class SetReplicationFactorForm(forms.Form):
  98. op = "setreplication"
  99. src_path = CharField(label=_("File to set replication factor"), help_text=_("The file to set replication factor."))
  100. replication_factor = CharField(label=_("Value of replication factor"), help_text=_("The value of replication factor."))
  101. class UploadFileForm(forms.Form):
  102. op = "upload"
  103. # The "hdfs" prefix in "hdfs_file" triggers the HDFSfileUploadHandler
  104. hdfs_file = FileField(label=_("File to Upload"))
  105. dest = PathField(label=_("Destination Path"), help_text=_("Filename or directory to upload to."))
  106. extract_archive = BooleanField(required=False)
  107. class UploadArchiveForm(forms.Form):
  108. op = "upload"
  109. archive = FileField(label=_("Archive to Upload"))
  110. dest = PathField(label=_("Destination Path"), help_text=_("Archive to upload to."))
  111. class RemoveForm(forms.Form):
  112. op = "remove"
  113. path = PathField(label=_("File to remove"))
  114. class RmDirForm(forms.Form):
  115. op = "rmdir"
  116. path = PathField(label=_("Directory to remove"))
  117. class RmTreeForm(forms.Form):
  118. op = "rmtree"
  119. path = PathField(label=_("Directory to remove (recursively)"))
  120. class BaseRmTreeFormset(FormSet):
  121. op = "rmtree"
  122. RmTreeFormSet = formset_factory(RmTreeForm, formset=BaseRmTreeFormset, extra=0)
  123. class RestoreForm(forms.Form):
  124. op = "rmtree"
  125. path = PathField(label=_("Path to restore"))
  126. class BaseRestoreFormset(FormSet):
  127. op = "restore"
  128. RestoreFormSet = formset_factory(RestoreForm, formset=BaseRestoreFormset, extra=0)
  129. class TrashPurgeForm(forms.Form):
  130. op = "purge_trash"
  131. class MkDirForm(forms.Form):
  132. op = "mkdir"
  133. path = PathField(label=_("Path in which to create the directory"))
  134. name = PathField(label=_("Directory Name"))
  135. class TouchForm(forms.Form):
  136. op = "touch"
  137. path = PathField(label=_("Path in which to create the file"))
  138. name = PathField(label=_("File Name"))
  139. class ChownForm(forms.Form):
  140. op = "chown"
  141. path = PathField(label=_("Path to change user/group ownership"))
  142. # These could be "ChoiceFields", listing only users and groups
  143. # that the current user has permissions for.
  144. user = CharField(label=_("User"), min_length=1)
  145. user_other = CharField(label=_("OtherUser"), min_length=1, required=False)
  146. group = CharField(label=_("Group"), min_length=1)
  147. group_other = CharField(label=_("OtherGroup"), min_length=1, required=False)
  148. recursive = BooleanField(label=_("Recursive"), required=False)
  149. def __init__(self, *args, **kwargs):
  150. super(ChownForm, self).__init__(*args, **kwargs)
  151. self.all_groups = [group.name for group in Group.objects.all()]
  152. self.all_users = [user.username for user in User.objects.all()]
  153. class BaseChownFormSet(FormSet):
  154. op = "chown"
  155. ChownFormSet = formset_factory(ChownForm, formset=BaseChownFormSet, extra=0)
  156. class ChmodForm(forms.Form):
  157. op = "chmod"
  158. path = PathField(label=_("Path to change permissions"))
  159. # By default, BooleanField only validates when
  160. # it's checked.
  161. user_read = BooleanField(required=False)
  162. user_write = BooleanField(required=False)
  163. user_execute = BooleanField(required=False)
  164. group_read = BooleanField(required=False)
  165. group_write = BooleanField(required=False)
  166. group_execute = BooleanField(required=False)
  167. other_read = BooleanField(required=False)
  168. other_write = BooleanField(required=False)
  169. other_execute = BooleanField(required=False)
  170. sticky = BooleanField(required=False)
  171. recursive = BooleanField(required=False)
  172. names = ("user_read", "user_write", "user_execute",
  173. "group_read", "group_write", "group_execute",
  174. "other_read", "other_write", "other_execute",
  175. "sticky")
  176. def __init__(self, initial, *args, **kwargs):
  177. logging.info(dir(self))
  178. logging.info(dir(type(self)))
  179. # Convert from string representation.
  180. mode = initial.get("mode")
  181. if mode is not None:
  182. mode = int(mode, 8)
  183. bools = rwx.expand_mode(mode)
  184. for name, b in zip(self.names, bools):
  185. initial[name] = b
  186. logging.debug(initial)
  187. kwargs['initial'] = initial
  188. forms.Form.__init__(self, *args, **kwargs)
  189. def full_clean(self):
  190. forms.Form.full_clean(self)
  191. if hasattr(self, "cleaned_data"):
  192. self.cleaned_data["mode"] = rwx.compress_mode([self.cleaned_data[name] for name in self.names])
  193. class BaseChmodFormSet(FormSet):
  194. op = "chmod"
  195. ChmodFormSet = formset_factory(ChmodForm, formset=BaseChmodFormSet, extra=0)