summaryrefslogtreecommitdiff
path: root/lib/filebrowser/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/filebrowser/views.py')
-rw-r--r--lib/filebrowser/views.py494
1 files changed, 494 insertions, 0 deletions
diff --git a/lib/filebrowser/views.py b/lib/filebrowser/views.py
new file mode 100644
index 0000000..eece2b2
--- /dev/null
+++ b/lib/filebrowser/views.py
@@ -0,0 +1,494 @@
+# coding: utf-8
+
+# general imports
+import itertools, os, re
+from time import gmtime, strftime
+
+# django imports
+from django.shortcuts import render_to_response, HttpResponse
+from django.template import RequestContext as Context
+from django.http import HttpResponseRedirect
+from django.contrib.admin.views.decorators import staff_member_required
+from django.views.decorators.cache import never_cache
+from django.utils.translation import ugettext as _
+from django.conf import settings
+from django import forms
+from django.core.urlresolvers import reverse
+from django.core.exceptions import ImproperlyConfigured
+from django.dispatch import Signal
+from django.core.paginator import Paginator, InvalidPage, EmptyPage
+from django.utils.encoding import smart_str
+
+try:
+ # django SVN
+ from django.views.decorators.csrf import csrf_exempt
+except:
+ # django 1.1
+ from django.contrib.csrf.middleware import csrf_exempt
+
+# filebrowser imports
+from filebrowser.settings import *
+from filebrowser.functions import path_to_url, sort_by_attr, get_path, get_file, get_version_path, get_breadcrumbs, get_filterdate, get_settings_var, handle_file_upload, convert_filename
+from filebrowser.templatetags.fb_tags import query_helper
+from filebrowser.base import FileObject
+from filebrowser.decorators import flash_login_required
+
+# Precompile regular expressions
+filter_re = []
+for exp in EXCLUDE:
+ filter_re.append(re.compile(exp))
+for k,v in VERSIONS.iteritems():
+ exp = (r'_%s.(%s)') % (k, '|'.join(EXTENSION_LIST))
+ filter_re.append(re.compile(exp))
+
+
+def browse(request):
+ """
+ Browse Files/Directories.
+ """
+
+ # QUERY / PATH CHECK
+ query = request.GET.copy()
+ path = get_path(query.get('dir', ''))
+ directory = get_path('')
+ q = request.GET.get('q')
+
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ request.user.message_set.create(message=msg)
+ if directory is None:
+ # The DIRECTORY does not exist, raise an error to prevent eternal redirecting.
+ raise ImproperlyConfigured, _("Error finding Upload-Folder (MEDIA_ROOT + FILEBROWSER_DIRECTORY). Maybe it does not exist?")
+ redirect_url = reverse("fb_browse") + query_helper(query, "", "dir")
+ return HttpResponseRedirect(redirect_url)
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+
+ # INITIAL VARIABLES
+ results_var = {'results_total': 0, 'results_current': 0, 'delete_total': 0, 'images_total': 0, 'select_total': 0 }
+ counter = {}
+ for k,v in EXTENSIONS.iteritems():
+ counter[k] = 0
+
+ if q:
+ m_root = os.path.normpath(MEDIA_ROOT)
+ dirs = []
+ for root, _subdirs, filenames in os.walk(abs_path):
+ dirs_2 = []
+ items = _subdirs + filenames
+ for f in items:
+ dirs_2.append((os.path.normpath(root)[len(m_root)+1:], f))
+ # append result of every iteration to dirs
+ dirs.append(dirs_2)
+ dir_list = itertools.chain(*dirs)
+ else:
+ root = os.path.join(DIRECTORY, path)
+ dir_list = ((root, f) for f in os.listdir(abs_path))
+
+ files = []
+ for file_dir, file in dir_list:
+ # EXCLUDE FILES MATCHING VERSIONS_PREFIX OR ANY OF THE EXCLUDE PATTERNS
+ filtered = file.startswith('.')
+ for re_prefix in filter_re:
+ if re_prefix.search(file):
+ filtered = True
+ if filtered:
+ continue
+ results_var['results_total'] += 1
+
+ # CREATE FILEOBJECT
+ fileobject = FileObject(os.path.join(file_dir, file))
+
+ # FILTER / SEARCH
+ append = False
+ if fileobject.filetype == request.GET.get('filter_type', fileobject.filetype) and get_filterdate(request.GET.get('filter_date', ''), fileobject.date or 0):
+ append = True
+ if q and not re.compile(q.lower(), re.M).search(file.lower()):
+ append = False
+
+ # APPEND FILE_LIST
+ if append:
+ try:
+ # COUNTER/RESULTS
+ if fileobject.filetype == 'Image':
+ results_var['images_total'] += 1
+ if fileobject.filetype != 'Folder':
+ results_var['delete_total'] += 1
+ elif fileobject.filetype == 'Folder' and fileobject.is_empty:
+ results_var['delete_total'] += 1
+ if query.get('type') and query.get('type') in SELECT_FORMATS and fileobject.filetype in SELECT_FORMATS[query.get('type')]:
+ results_var['select_total'] += 1
+ elif not query.get('type'):
+ results_var['select_total'] += 1
+ except OSError:
+ # Ignore items that have problems
+ continue
+ else:
+ files.append(fileobject)
+ results_var['results_current'] += 1
+
+ # COUNTER/RESULTS
+ if fileobject.filetype:
+ counter[fileobject.filetype] += 1
+
+ # SORTING
+ query['o'] = request.GET.get('o', DEFAULT_SORTING_BY)
+ query['ot'] = request.GET.get('ot', DEFAULT_SORTING_ORDER)
+ files = sort_by_attr(files, request.GET.get('o', DEFAULT_SORTING_BY))
+ if not request.GET.get('ot') and DEFAULT_SORTING_ORDER == "desc" or request.GET.get('ot') == "desc":
+ files.reverse()
+
+ p = Paginator(files, LIST_PER_PAGE)
+ try:
+ page_nr = request.GET.get('p', '1')
+ except:
+ page_nr = 1
+ try:
+ page = p.page(page_nr)
+ except (EmptyPage, InvalidPage):
+ page = p.page(p.num_pages)
+
+ return render_to_response('filebrowser/index.html', {
+ 'dir': path,
+ 'p': p,
+ 'q': q,
+ 'page': page,
+ 'results_var': results_var,
+ 'counter': counter,
+ 'query': query,
+ 'title': _(u'FileBrowser'),
+ 'settings_var': get_settings_var(),
+ 'breadcrumbs': get_breadcrumbs(query, path),
+ 'breadcrumbs_title': ""
+ }, context_instance=Context(request))
+browse = staff_member_required(never_cache(browse))
+
+
+# mkdir signals
+filebrowser_pre_createdir = Signal(providing_args=["path", "dirname"])
+filebrowser_post_createdir = Signal(providing_args=["path", "dirname"])
+
+def mkdir(request):
+ """
+ Make Directory.
+ """
+
+ from filebrowser.forms import MakeDirForm
+
+ # QUERY / PATH CHECK
+ query = request.GET
+ path = get_path(query.get('dir', ''))
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(reverse("fb_browse"))
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+
+ if request.method == 'POST':
+ form = MakeDirForm(abs_path, request.POST)
+ if form.is_valid():
+ server_path = os.path.join(abs_path, form.cleaned_data['dir_name'])
+ try:
+ # PRE CREATE SIGNAL
+ filebrowser_pre_createdir.send(sender=request, path=path, dirname=form.cleaned_data['dir_name'])
+ # CREATE FOLDER
+ os.mkdir(server_path)
+ os.chmod(server_path, 0775)
+ # POST CREATE SIGNAL
+ filebrowser_post_createdir.send(sender=request, path=path, dirname=form.cleaned_data['dir_name'])
+ # MESSAGE & REDIRECT
+ msg = _('The Folder %s was successfully created.') % (form.cleaned_data['dir_name'])
+ request.user.message_set.create(message=msg)
+ # on redirect, sort by date desc to see the new directory on top of the list
+ # remove filter in order to actually _see_ the new folder
+ # remove pagination
+ redirect_url = reverse("fb_browse") + query_helper(query, "ot=desc,o=date", "ot,o,filter_type,filter_date,q,p")
+ return HttpResponseRedirect(redirect_url)
+ except OSError, (errno, strerror):
+ if errno == 13:
+ form.errors['dir_name'] = forms.util.ErrorList([_('Permission denied.')])
+ else:
+ form.errors['dir_name'] = forms.util.ErrorList([_('Error creating folder.')])
+ else:
+ form = MakeDirForm(abs_path)
+
+ return render_to_response('filebrowser/makedir.html', {
+ 'form': form,
+ 'query': query,
+ 'title': _(u'New Folder'),
+ 'settings_var': get_settings_var(),
+ 'breadcrumbs': get_breadcrumbs(query, path),
+ 'breadcrumbs_title': _(u'New Folder')
+ }, context_instance=Context(request))
+mkdir = staff_member_required(never_cache(mkdir))
+
+
+def upload(request):
+ """
+ Multipe File Upload.
+ """
+
+ from django.http import parse_cookie
+
+ # QUERY / PATH CHECK
+ query = request.GET
+ path = get_path(query.get('dir', ''))
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(reverse("fb_browse"))
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+
+ # SESSION (used for flash-uploading)
+ cookie_dict = parse_cookie(request.META.get('HTTP_COOKIE', ''))
+ engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
+ session_key = cookie_dict.get(settings.SESSION_COOKIE_NAME, None)
+
+ return render_to_response('filebrowser/upload.html', {
+ 'query': query,
+ 'title': _(u'Select files to upload'),
+ 'settings_var': get_settings_var(),
+ 'session_key': session_key,
+ 'breadcrumbs': get_breadcrumbs(query, path),
+ 'breadcrumbs_title': _(u'Upload')
+ }, context_instance=Context(request))
+upload = staff_member_required(never_cache(upload))
+
+
+@csrf_exempt
+def _check_file(request):
+ """
+ Check if file already exists on the server.
+ """
+
+ from django.utils import simplejson
+
+ folder = request.POST.get('folder')
+ fb_uploadurl_re = re.compile(r'^.*(%s)' % reverse("fb_upload"))
+ folder = fb_uploadurl_re.sub('', folder)
+
+ fileArray = {}
+ if request.method == 'POST':
+ for k,v in request.POST.items():
+ if k != "folder":
+ v = convert_filename(v)
+ if os.path.isfile(smart_str(os.path.join(MEDIA_ROOT, DIRECTORY, folder, v))):
+ fileArray[k] = v
+
+ return HttpResponse(simplejson.dumps(fileArray))
+
+
+# upload signals
+filebrowser_pre_upload = Signal(providing_args=["path", "file"])
+filebrowser_post_upload = Signal(providing_args=["path", "file"])
+
+@csrf_exempt
+@flash_login_required
+def _upload_file(request):
+ """
+ Upload file to the server.
+ """
+
+ from django.core.files.move import file_move_safe
+
+ if request.method == 'POST':
+ folder = request.POST.get('folder')
+ fb_uploadurl_re = re.compile(r'^.*(%s)' % reverse("fb_upload"))
+ folder = fb_uploadurl_re.sub('', folder)
+ abs_path = os.path.join(MEDIA_ROOT, DIRECTORY, folder)
+ if request.FILES:
+ filedata = request.FILES['Filedata']
+ filedata.name = convert_filename(filedata.name)
+ # PRE UPLOAD SIGNAL
+ filebrowser_pre_upload.send(sender=request, path=request.POST.get('folder'), file=filedata)
+ # HANDLE UPLOAD
+ uploadedfile = handle_file_upload(abs_path, filedata)
+ # MOVE UPLOADED FILE
+ # if file already exists
+ if os.path.isfile(smart_str(os.path.join(MEDIA_ROOT, DIRECTORY, folder, filedata.name))):
+ old_file = smart_str(os.path.join(abs_path, filedata.name))
+ new_file = smart_str(os.path.join(abs_path, uploadedfile))
+ file_move_safe(new_file, old_file, allow_overwrite=True)
+ # POST UPLOAD SIGNAL
+ filebrowser_post_upload.send(sender=request, path=request.POST.get('folder'), file=FileObject(smart_str(os.path.join(DIRECTORY, folder, filedata.name))))
+ return HttpResponse('True')
+#_upload_file = flash_login_required(_upload_file)
+
+
+# delete signals
+filebrowser_pre_delete = Signal(providing_args=["path", "filename"])
+filebrowser_post_delete = Signal(providing_args=["path", "filename"])
+
+def delete(request):
+ """
+ Delete existing File/Directory.
+
+ When trying to delete a Directory, the Directory has to be empty.
+ """
+
+ # QUERY / PATH CHECK
+ query = request.GET
+ path = get_path(query.get('dir', ''))
+ filename = get_file(query.get('dir', ''), query.get('filename', ''))
+ if path is None or filename is None:
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ else:
+ msg = _('The requested File does not exist.')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(reverse("fb_browse"))
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+
+ msg = ""
+ if request.GET:
+ if request.GET.get('filetype') != "Folder":
+ relative_server_path = os.path.join(DIRECTORY, path, filename)
+ try:
+ # PRE DELETE SIGNAL
+ filebrowser_pre_delete.send(sender=request, path=path, filename=filename)
+ # DELETE IMAGE VERSIONS/THUMBNAILS
+ for version in VERSIONS:
+ try:
+ os.unlink(os.path.join(MEDIA_ROOT, get_version_path(relative_server_path, version)))
+ except:
+ pass
+ # DELETE FILE
+ os.unlink(smart_str(os.path.join(abs_path, filename)))
+ # POST DELETE SIGNAL
+ filebrowser_post_delete.send(sender=request, path=path, filename=filename)
+ # MESSAGE & REDIRECT
+ msg = _('The file %s was successfully deleted.') % (filename.lower())
+ request.user.message_set.create(message=msg)
+ redirect_url = reverse("fb_browse") + query_helper(query, "", "filename,filetype")
+ return HttpResponseRedirect(redirect_url)
+ except OSError:
+ # todo: define error message
+ msg = OSError
+ else:
+ try:
+ # PRE DELETE SIGNAL
+ filebrowser_pre_delete.send(sender=request, path=path, filename=filename)
+ # DELETE FOLDER
+ os.rmdir(os.path.join(abs_path, filename))
+ # POST DELETE SIGNAL
+ filebrowser_post_delete.send(sender=request, path=path, filename=filename)
+ # MESSAGE & REDIRECT
+ msg = _('The folder %s was successfully deleted.') % (filename.lower())
+ request.user.message_set.create(message=msg)
+ redirect_url = reverse("fb_browse") + query_helper(query, "", "filename,filetype")
+ return HttpResponseRedirect(redirect_url)
+ except OSError:
+ # todo: define error message
+ msg = OSError
+
+ if msg:
+ request.user.message_set.create(message=msg)
+
+ return render_to_response('filebrowser/index.html', {
+ 'dir': dir_name,
+ 'file': request.GET.get('filename', ''),
+ 'query': query,
+ 'settings_var': get_settings_var(),
+ 'breadcrumbs': get_breadcrumbs(query, dir_name),
+ 'breadcrumbs_title': ""
+ }, context_instance=Context(request))
+delete = staff_member_required(never_cache(delete))
+
+
+# rename signals
+filebrowser_pre_rename = Signal(providing_args=["path", "filename", "new_filename"])
+filebrowser_post_rename = Signal(providing_args=["path", "filename", "new_filename"])
+
+def rename(request):
+ """
+ Rename existing File/Directory.
+
+ Includes renaming existing Image Versions/Thumbnails.
+ """
+
+ from filebrowser.forms import RenameForm
+
+ # QUERY / PATH CHECK
+ query = request.GET
+ path = get_path(query.get('dir', ''))
+ filename = get_file(query.get('dir', ''), query.get('filename', ''))
+ if path is None or filename is None:
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ else:
+ msg = _('The requested File does not exist.')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(reverse("fb_browse"))
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+ file_extension = os.path.splitext(filename)[1].lower()
+
+ if request.method == 'POST':
+ form = RenameForm(abs_path, file_extension, request.POST)
+ if form.is_valid():
+ relative_server_path = os.path.join(DIRECTORY, path, filename)
+ new_filename = form.cleaned_data['name'] + file_extension
+ new_relative_server_path = os.path.join(DIRECTORY, path, new_filename)
+ try:
+ # PRE RENAME SIGNAL
+ filebrowser_pre_rename.send(sender=request, path=path, filename=filename, new_filename=new_filename)
+ # DELETE IMAGE VERSIONS/THUMBNAILS
+ # regenerating versions/thumbs will be done automatically
+ for version in VERSIONS:
+ try:
+ os.unlink(os.path.join(MEDIA_ROOT, get_version_path(relative_server_path, version)))
+ except:
+ pass
+ # RENAME ORIGINAL
+ os.rename(os.path.join(MEDIA_ROOT, relative_server_path), os.path.join(MEDIA_ROOT, new_relative_server_path))
+ # POST RENAME SIGNAL
+ filebrowser_post_rename.send(sender=request, path=path, filename=filename, new_filename=new_filename)
+ # MESSAGE & REDIRECT
+ msg = _('Renaming was successful.')
+ request.user.message_set.create(message=msg)
+ redirect_url = reverse("fb_browse") + query_helper(query, "", "filename")
+ return HttpResponseRedirect(redirect_url)
+ except OSError, (errno, strerror):
+ form.errors['name'] = forms.util.ErrorList([_('Error.')])
+ else:
+ form = RenameForm(abs_path, file_extension)
+
+ return render_to_response('filebrowser/rename.html', {
+ 'form': form,
+ 'query': query,
+ 'file_extension': file_extension,
+ 'title': _(u'Rename "%s"') % filename,
+ 'settings_var': get_settings_var(),
+ 'breadcrumbs': get_breadcrumbs(query, path),
+ 'breadcrumbs_title': _(u'Rename')
+ }, context_instance=Context(request))
+rename = staff_member_required(never_cache(rename))
+
+
+def versions(request):
+ """
+ Show all Versions for an Image according to ADMIN_VERSIONS.
+ """
+
+ # QUERY / PATH CHECK
+ query = request.GET
+ path = get_path(query.get('dir', ''))
+ filename = get_file(query.get('dir', ''), query.get('filename', ''))
+ if path is None or filename is None:
+ if path is None:
+ msg = _('The requested Folder does not exist.')
+ else:
+ msg = _('The requested File does not exist.')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(reverse("fb_browse"))
+ abs_path = u'%s' % os.path.join(MEDIA_ROOT, DIRECTORY, path)
+
+ return render_to_response('filebrowser/versions.html', {
+ 'original': path_to_url(os.path.join(DIRECTORY, path, filename)),
+ 'query': query,
+ 'title': _(u'Versions for "%s"') % filename,
+ 'settings_var': get_settings_var(),
+ 'breadcrumbs': get_breadcrumbs(query, path),
+ 'breadcrumbs_title': _(u'Versions for "%s"') % filename
+ }, context_instance=Context(request))
+versions = staff_member_required(never_cache(versions))
+
+