Skip to content

Commit

Permalink
Adding symbolic link support.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasstudt committed Oct 28, 2009
1 parent ab0340c commit 1df9ec7
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 26 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -3,6 +3,7 @@ Revision history
1.1
- Python 2.3 fixes. [sorted(list) to list.sort()]
- Add the ability to add symbolic links. (Unix Only)
- Adjust templates and index template to handle symbolic links.

1.0.3 Thu Jun 25 14:07:33 CDT 2009:
- Changed text field to vLargeTextField class, so it will be big by
Expand Down
60 changes: 57 additions & 3 deletions file_manager/forms.py
Expand Up @@ -7,9 +7,63 @@

from file_manager import utils

class FileForm(forms.Form):
class DirectoryFileForm(forms.Form):

link = forms.ChoiceField(help_text=_('Link Destination'))

def __init__(self, file, *args, **kwargs):
self.file = file
#self.original = original
self.document_root = utils.get_document_root()
super(DirectoryFileForm, self).__init__(*args, **kwargs)

# Set the choices dynamicly.
self.fields['link'].choices = self.make_choices()

def make_choices(self):

choices = []

# Make "/" valid"
d = self.document_root
d_short = d.replace(self.document_root, "", 1)
if not d_short:
d_short = '/'

choices.append((d, d_short))

for root, dirs, files in os.walk(self.document_root):
for d in dirs:
d = os.path.join(root, d)
d_short = d.replace(self.document_root, "", 1)
choices.append((d, d_short))
for f in files:
f = os.path.join(root, f)
f_short = f.replace(self.document_root, "", 1)
choices.append((f, f_short))


#return sorted(choices)
choices.sort()
return choices

def clean_parent(self):
parent = self.cleaned_data['parent']

path = os.path.join(parent, self.file)

if self.original != path: # Let no change work correctly.
if os.access(path, os.F_OK):
raise forms.ValidationError(_('Destination already exists.'))
if path.startswith(self.original):
raise forms.ValidationError(_('Can\'t move directory into itself.'))

if not os.access(parent, os.W_OK):
raise forms.ValidationError(_('Can not write to directory.'))

return parent


file = forms.FilePathField(path=utils.get_document_root(),recursive=True)

class DirectoryForm(forms.Form):

Expand Down Expand Up @@ -90,7 +144,7 @@ class ContentForm(forms.Form):
class CreateForm(NameForm,ContentForm):
pass

class CreateLinkForm(NameForm,FileForm):
class CreateLinkForm(NameForm,DirectoryFileForm):
# FileForm only shows files, DirectoryFrom only shows directories.
pass

Expand Down
5 changes: 4 additions & 1 deletion file_manager/templates/admin/file_manager/index.html
Expand Up @@ -92,10 +92,13 @@ <h1>Directory: '/{{ directory.url }}'</h1>
<tr class="{% cycle 'row1' 'row2' %}">
<td>
{% if file.directory %}<span class="folder">D</span>{% endif %}

</td>
<td>
<a href="{% if file.directory %}{% url admin_file_manager_list file.fileurl %}{% else %}/{{ file.fileurl }}{% endif %}">{{ file.filename }}</a>

{% if file.link %}
[{% if file.broken_link %}Broken {% endif %}Link]
{% endif %}
</td>
<td>
{% if not file.directory %}
Expand Down
63 changes: 41 additions & 22 deletions file_manager/views.py
Expand Up @@ -88,24 +88,33 @@ def index(request, url=None):
directory['can_write'] = False

for file in listing:
itemstat = os.stat(os.path.join(full_path, file))

item = {}

item['filename'] = file
item['fileurl'] = os.path.join(url, file)
item['user'] = getpwuid(itemstat.st_uid)[0]
item['group'] = getgrgid(itemstat.st_gid)[0]

# size (in bytes ) for use with |filesizeformat
item['size'] = itemstat.st_size

# type (direcory/file/link)
item['directory'] = os.path.isdir(os.path.join(full_path, file))
item['link'] = os.path.islink(os.path.join(full_path, file))

# ctime, mtime
item['ctime'] = datetime.fromtimestamp(itemstat.st_ctime)
item['mtime'] = datetime.fromtimestamp(itemstat.st_mtime)
# Catch broken links.
try:
itemstat = os.stat(os.path.join(full_path, file))
item['user'] = getpwuid(itemstat.st_uid)[0]
item['group'] = getgrgid(itemstat.st_gid)[0]

# size (in bytes ) for use with |filesizeformat
item['size'] = itemstat.st_size

# ctime, mtime
item['ctime'] = datetime.fromtimestamp(itemstat.st_ctime)
item['mtime'] = datetime.fromtimestamp(itemstat.st_mtime)
except:
# Blank out because of broken link.
item['user'] = item['group'] = ''
item['size'] = item['ctime'] = item['mtime'] = None
item['broken_link'] = True


mime = mimetypes.guess_type(os.path.join(full_path, file),False)[0]

Expand Down Expand Up @@ -156,17 +165,18 @@ def mkln(request, url=None):
full_path = os.path.join(utils.get_document_root(), url)

if request.method == 'POST':
form = forms.CreateLinkForm(full_path, None, request.POST)
form = forms.CreateLinkForm(full_path, None, full_path, request.POST)

if form.is_valid():
pass
#os.symlink('source', 'destination')
#Make the directory
#os.mkdir(os.path.join(full_path, form.cleaned_data['name']))
src = os.path.join(full_path, form.cleaned_data['link'])
dest = os.path.join(full_path, form.cleaned_data['name'])
relative = os.path.relpath(src, full_path)

os.symlink(relative, dest)

return redirect('admin_file_manager_list', url=url)
else:
form = forms.CreateLinkForm(full_path, None) # An unbound form
form = forms.CreateLinkForm(full_path, None, full_path) # An unbound form

return render_to_response("admin/file_manager/mkln.html",
{'form': form, 'url': url,},
Expand Down Expand Up @@ -209,7 +219,7 @@ def delete(request, url=None):
if request.method == 'POST':

# If this is a directory, do the walk
if os.path.isdir(full_path):
if os.path.isdir(full_path) and not os.path.islink(full_path):
for root, dirs, files in os.walk(full_path, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
Expand All @@ -226,7 +236,7 @@ def delete(request, url=None):
errorlist = []

# If this is a directory, generate the list of files to be removed.
if os.path.isdir(full_path):
if os.path.isdir(full_path) and not os.path.islink(full_path):
filelist.append("/%s" % url)
for root, dirs, files, in os.walk(full_path):
for name in files:
Expand Down Expand Up @@ -269,16 +279,25 @@ def move(request, url=None):
full_path = os.path.join(utils.get_document_root(), url)
directory = url.replace(parent, "", 1).lstrip('/')

#setttings.TEMPPATH = fullpath

if request.method == 'POST':
form = forms.DirectoryForm(directory, full_path, request.POST)

if form.is_valid():
new = os.path.join(form.cleaned_data['parent'], directory)

#Rename the directory
os.rename(full_path, new)
if os.path.islink(full_path):

src = os.readlink(full_path)
if not os.path.isabs(src):
src = os.path.join(os.path.dirname(full_path), src)

relative = os.path.relpath(src, form.cleaned_data['parent'])

os.remove(full_path) # Remove original link.
os.symlink(relative, new) # Create new link.

else:
os.rename(full_path, new) #Rename the directory

return redirect('admin_file_manager_list', url=parent)
else:
Expand Down

0 comments on commit 1df9ec7

Please sign in to comment.