This commit is contained in:
Karen 2011-07-04 18:33:03 +05:30
commit 9af0422068
9 changed files with 189 additions and 20 deletions

View File

@ -94,6 +94,7 @@ class File(models.Model):
file_date = models.DateField("Date", blank=True, null=True) file_date = models.DateField("Date", blank=True, null=True)
added = models.DateField("Date Added", auto_now_add=True) added = models.DateField("Date Added", auto_now_add=True)
categories = models.ManyToManyField('Category', verbose_name='Studies') categories = models.ManyToManyField('Category', verbose_name='Studies')
private = models.BooleanField(default=False)
# type = models.ForeignKey('Type', verbose_name='File Type') # type = models.ForeignKey('Type', verbose_name='File Type')
type = models.CharField(max_length=255, choices=TYPE_CHOICES) type = models.CharField(max_length=255, choices=TYPE_CHOICES)
ext = models.CharField(max_length=100, blank=True) ext = models.CharField(max_length=100, blank=True)
@ -144,7 +145,8 @@ class File(models.Model):
'title': self.title, 'title': self.title,
'description': self.description, 'description': self.description,
'type': self.type, 'type': self.type,
'studies': studies 'studies': studies,
'is_private': self.private
} }
def save_chunk(self, chunk, name='data.bin'): def save_chunk(self, chunk, name='data.bin'):
@ -215,6 +217,12 @@ class File(models.Model):
self.save() self.save()
return self return self
def can_edit(self, user):
if user.is_superuser or self.userID == user:
return True
else:
return False
class Category(models.Model): class Category(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
groups = models.ManyToManyField(Group, null=True) groups = models.ManyToManyField(Group, null=True)

View File

@ -10,6 +10,8 @@ urlpatterns = patterns('',
(r'^editFile/', views.editFile), (r'^editFile/', views.editFile),
(r'^deleteFiles/', views.deleteFiles), (r'^deleteFiles/', views.deleteFiles),
(r'^moveFiles/', views.moveFiles), (r'^moveFiles/', views.moveFiles),
(r'makePrivate/', views.makeFilePrivate),
(r'makePublic/', views.makeFilePublic),
(r'json_list', views.fileList), (r'json_list', views.fileList),
(r'browse', views.browse) (r'browse', views.browse)
) )

View File

@ -17,6 +17,10 @@ try:
import json import json
except: except:
import simplejson as json import simplejson as json
from utils.decorators import user_passes_test_json
from django.db.models import Q
from django.template import RequestContext
''' '''
class folder_names(object): class folder_names(object):
@ -24,6 +28,36 @@ class folder_names(object):
return iter(map(lambda x: (x,x), os.listdir(UPLOAD_ROOT))) return iter(map(lambda x: (x,x), os.listdir(UPLOAD_ROOT)))
''' '''
def canEditFile(request):
id = request.POST.get("id", 0)
fil = File.objects.get(pk=id)
u = request.user
response = {}
if fil.can_edit(u):
response['status'] = 'pass'
else:
response['status'] = 'fail'
response['error'] = "you do not have permission to edit this file."
return response
def canEditFiles(request):
ids = request.POST.get("ids", "[]")
files = json.loads(ids)
u = request.user
response = {}
for f in files:
fil = File.objects.get(pk=f)
if not fil.can_edit(u):
response['status'] = 'fail'
if response['status'] == 'fail':
response['error'] = 'sorry, you do not have necessary permissions to edit these files'
else:
response['status'] = 'pass'
return response
def getFolderList(): def getFolderList():
os.chdir(FTP_ROOT) os.chdir(FTP_ROOT)
dirs = filter(isdir, os.listdir(FTP_ROOT)) dirs = filter(isdir, os.listdir(FTP_ROOT))
@ -211,7 +245,7 @@ def add(request):
@csrf_exempt @csrf_exempt
@login_required @user_passes_test_json(canEditFile)
def editFile(request): def editFile(request):
errors = [] errors = []
try: try:
@ -226,35 +260,61 @@ def editFile(request):
fil.__setattr__(k, val) fil.__setattr__(k, val)
fil.save() fil.save()
response = { response = {
'errors': errors 'status': 'pass'
} }
return render_to_json_response(response) return render_to_json_response(response)
@csrf_exempt @csrf_exempt
@login_required @user_passes_test_json(canEditFile)
def deleteFiles(request): def deleteFiles(request):
errors = []
files = json.loads(request.POST.get("ids", "[]")) files = json.loads(request.POST.get("ids", "[]"))
for f in files: for f in files:
fil = File.objects.get(pk=f) fil = File.objects.get(pk=f)
fil.delete() fil.delete()
response = { response = {
'errors': errors 'status': 'pass'
} }
return render_to_json_response(response) return render_to_json_response(response)
@csrf_exempt
@user_passes_test_json(canEditFile)
def makeFilePrivate(request):
# errors = []
id = request.POST.get("id", "0")
fil = File.objects.get(pk=id)
fil.private = True
fil.save()
response = {
'status': 'pass'
}
return render_to_json_response(response)
@csrf_exempt @csrf_exempt
@login_required @user_passes_test_json(canEditFile)
def moveFiles(request): def makeFilePublic(request):
errors = [] errors = []
id = request.POST.get("id", "0")
fil = File.objects.get(pk=id)
fil.private = False
fil.save()
response = {
'status': 'pass'
}
return render_to_json_response(response)
@csrf_exempt
@user_passes_test_json(canEditFiles)
def moveFiles(request):
response = {}
files = json.loads(request.POST.get("ids", "[]")) files = json.loads(request.POST.get("ids", "[]"))
study_id = int(request.POST.get("study", "0")) study_id = int(request.POST.get("study", "0"))
study = Category.objects.get(pk=study_id) study = Category.objects.get(pk=study_id)
for f in files: for f in files:
fil = File.objects.get(pk=f) fil = File.objects.get(pk=f)
fil.move_to(study) fil.move_to(study)
response['status'] = 'pass'
return render_to_json_response(errors) return render_to_json_response(errors)
@ -264,7 +324,12 @@ def fileList(request):
typ = request.POST.get("fileType", '') typ = request.POST.get("fileType", '')
search = request.POST.get("search", '') search = request.POST.get("search", '')
page = request.POST.get("page_no", 1) page = request.POST.get("page_no", 1)
qset = File.objects.all() # private = request.POST.get("private", "0")
user = request.user
if user.is_superuser:
qset = File.objects.all()
else:
qset = File.objects.filter(Q(private=False) | (Q(private=True) & Q(userID=user.id)))
if category != '': if category != '':
qset = File.filter_category(category, qset) qset = File.filter_category(category, qset)
if typ != '': if typ != '':
@ -282,6 +347,7 @@ def fileList(request):
files = results.object_list files = results.object_list
d = {} d = {}
d['status'] = 'pass'
d['noOfResults'] = qset.count() d['noOfResults'] = qset.count()
d['noOfPages'] = paginator.num_pages d['noOfPages'] = paginator.num_pages
d['currentPage'] = current_page d['currentPage'] = current_page
@ -289,12 +355,17 @@ def fileList(request):
# d['hasNext'] = paginator.has_next() # d['hasNext'] = paginator.has_next()
d['files'] = [] d['files'] = []
for f in files: for f in files:
d['files'].append(f.get_dict()) fileData = f.get_dict()
fileData['can_edit'] = f.can_edit(user)
d['files'].append(fileData)
return render_to_json_response(d) return render_to_json_response(d)
def browse(request): def browse(request):
form = FileFilterForm() form = FileFilterForm()
return render_to_response("files/browser.html", { context = RequestContext(request, {
'filterForm': form 'filterForm': form
}) })
return render_to_response("files/browser.html", context)

View File

@ -120,6 +120,9 @@ color:#555353;}
.previewObject a:active .previewObject a:active
{color:#000;} {color:#000;}
.itemForm
{width:400px;}
.itemForm p .itemForm p
{padding-top:12px;} {padding-top:12px;}
@ -139,6 +142,7 @@ float:left;}
.itemDescription .itemDescription
{float:right; {float:right;
height:50px; height:50px;
width: 200px;
border:2px groove #efecec;} border:2px groove #efecec;}
.submitItem .submitItem

View File

@ -67,7 +67,7 @@ ul {
#intro { #intro {
position: absolute; position: absolute;
width: 350px; width: 370px;
right: 20px; right: 20px;
top: 12px; top: 12px;
font-size: 11px; font-size: 11px;

View File

@ -5,6 +5,11 @@ $(function() {
$('#id_category').children().eq(0).text("All"); $('#id_category').children().eq(0).text("All");
$('#moveSelectedSelect').html(selectHTML); $('#moveSelectedSelect').html(selectHTML);
$('#submitFilter').click(function(e) {
e.preventDefault();
$('#firstPage').click();
});
$('#filterForm').submit(function(e) { $('#filterForm').submit(function(e) {
e.preventDefault(); e.preventDefault();
var formData = $(this).serializeArray(); var formData = $(this).serializeArray();
@ -67,6 +72,9 @@ $(function() {
var url = "/files/deleteFiles/"; var url = "/files/deleteFiles/";
var params = {'ids': JSON.stringify(ids)}; var params = {'ids': JSON.stringify(ids)};
$.post(url, params, function(response) { $.post(url, params, function(response) {
if (response.status == 'fail') {
alert(response.error);
}
$this.removeAttr("disabled"); $this.removeAttr("disabled");
$('#filterForm').submit(); $('#filterForm').submit();
}); });
@ -88,6 +96,9 @@ $(function() {
} }
$.post(url, params, function(response) { $.post(url, params, function(response) {
if (response.status == 'fail') {
alert(response.error);
}
$this.removeAttr("disabled"); $this.removeAttr("disabled");
$('#filterForm').submit(); $('#filterForm').submit();
}, "json"); }, "json");
@ -157,13 +168,38 @@ function getItemForm(f) {
var $titleLabel = $('<span />').addClass("itemFormLabel").addClass("titleLabel").text("Title").appendTo($labelsP); var $titleLabel = $('<span />').addClass("itemFormLabel").addClass("titleLabel").text("Title").appendTo($labelsP);
var $descriptionLabel = $('<span />').addClass("itemFormLabel").addClass("descriptionLabel").text("Description").appendTo($labelsP); var $descriptionLabel = $('<span />').addClass("itemFormLabel").addClass("descriptionLabel").text("Description").appendTo($labelsP);
var $inputsP = $('<p />').appendTo($form); var $inputsP = $('<p />').appendTo($form);
var $titleInput = $('<input />').addClass("itemTitle").val(f.title).appendTo($inputsP); var $titleInput = $('<input />').addClass("itemTitle").val(f.title).appendTo($inputsP);
if (f.can_edit) {
var $privateLabel = $('<span />').addClass("pvtLabel").text("Private ").appendTo($inputsP);
var $pvtCheckbox = $('<input />').attr("type", "checkbox").attr("checked", f.is_private).appendTo($inputsP);
$pvtCheckbox.change(function() {
var checked = $(this).is(":checked");
if (checked) {
var url = "/files/makePrivate/";
} else {
var url = "/files/makePublic/";
}
var parent = $(this).parents(".itemForm");
var id = parent.find(".itemId").val();
var params = {'id': id}
$.post(url, params, function(response) {
if (response.status == 'fail') {
alert(response.error);
}
}, "json");
});
}
var $descriptionInput = $('<textarea />').addClass("itemDescription").val(f.description).appendTo($inputsP); var $descriptionInput = $('<textarea />').addClass("itemDescription").val(f.description).appendTo($inputsP);
var $hiddenInput = $('<input />').addClass("itemId").attr("type", "hidden").val(f.id).appendTo($inputsP); var $hiddenInput = $('<input />').addClass("itemId").attr("type", "hidden").val(f.id).appendTo($inputsP);
var $submitP = $('<p />').addClass("submitInput").appendTo($form); var $submitP = $('<p />').addClass("submitInput").appendTo($form);
var $submit = $('<input />').addClass("submitItem").attr("type", "submit").val("Submit").appendTo($submitP); var $submit = $('<input />').addClass("submitItem").attr("type", "submit").val("Submit").appendTo($submitP);
var $submitStatus = $('<span />').addClass("submitStatus").appendTo($submitP); var $submitStatus = $('<span />').addClass("submitStatus").appendTo($submitP);
$submit.click(function(e) { $submit.click(function(e) {
if (typeof($(this).attr("disabled")) != 'undefined') {
return false;
}
var url = "/files/editFile/"; var url = "/files/editFile/";
var parent = $(this).parents('.itemForm'); var parent = $(this).parents('.itemForm');
$('.submitStatus').text("Submitting..."); $('.submitStatus').text("Submitting...");
@ -178,6 +214,9 @@ function getItemForm(f) {
$('.submitItem').removeAttr("disabled"); $('.submitItem').removeAttr("disabled");
}, "json"); }, "json");
}); });
if (!f.can_edit) {
$submit.attr("disabled", "disabled");
}
return $form; return $form;
} }

View File

@ -112,12 +112,12 @@ function fileUploadedCallback(jq, data) {
var $error = $('<div />').addClass("fileError").text(data.errors[0]).appendTo(jq); var $error = $('<div />').addClass("fileError").text(data.errors[0]).appendTo(jq);
} else { } else {
var $formContainer = $('<div />').addClass("fileForm"); var $formContainer = $('<div />').addClass("fileForm");
var $title = $('<div />').addClass("formHelp").text("Add Description").appendTo($formContainer); // var $title = $('<div />').addClass("formHelp").text("Add Description").appendTo($formContainer);
// console.log(data); // console.log(data);
var $titleInput = $('<input />').attr("type", "text").addClass("fileTitle").val(d.title); var $titleInput = $('<input />').attr("type", "text").addClass("fileTitle").val(d.title);
// console.log($titleInput); // console.log($titleInput);
$titleInput.appendTo($formContainer); $titleInput.appendTo($formContainer);
var $descInput = $('<textarea />').addClass("fileDesc").appendTo($formContainer); var $descInput = $('<textarea />').attr("placeholder", "Add Description").addClass("fileDesc").appendTo($formContainer);
var $submitBtn = $('<button />').text("Submit").click(function() { var $submitBtn = $('<button />').text("Submit").click(function() {
var $this = $(this); var $this = $(this);
$this.attr("disabled", "disabled"); $this.attr("disabled", "disabled");

View File

@ -34,16 +34,21 @@
<div id="nextBtn">&gt;&gt;</div> <div id="nextBtn">&gt;&gt;</div>
<div id="lastPage">Last</div> <div id="lastPage">Last</div>
</div> </div>
{% if user.is_authenticated %}
<div id="withSelected"> <div id="withSelected">
Selected Items: <button id="deleteSelectedBtn">Delete</button> Selected Items: <button id="deleteSelectedBtn">Delete</button>
<button id="makePrivate">Make Private</button>
<p id="em">OR</p> <p>Move to: <p id="em">OR</p> <p>Move to:
<select id="moveSelectedSelect"> <select id="moveSelectedSelect">
</select> <button id="moveSelectedBtn">Move</button></p> </select>
</div> <button id="moveSelectedBtn">Move</button></p>
</div> </div>
</div> {% endif %}
</div>
</div>
<div id="previewPane"> <div id="previewPane">
</div> </div>

View File

@ -0,0 +1,40 @@
import urlparse
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from ox.django.shortcuts import render_to_json_response
from django.utils.decorators import available_attrs
def user_passes_test_json(test_func):
"""
Decorator for views that checks that the user passes the given test,
redirecting to the log-in page if necessary. The test should be a callable
that takes the user object and returns True if the user passes.
"""
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
result = test_func(request)
if result['status'] == 'pass':
return view_func(request, *args, **kwargs)
else:
return render_to_json_response(result)
'''
path = request.build_absolute_uri()
# If the login url is the same scheme and net location then just
# use the path as the "next" url.
login_scheme, login_netloc = urlparse.urlparse(login_url or
settings.LOGIN_URL)[:2]
current_scheme, current_netloc = urlparse.urlparse(path)[:2]
if ((not login_scheme or login_scheme == current_scheme) and
(not login_netloc or login_netloc == current_netloc)):
path = request.get_full_path()
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(path, login_url, redirect_field_name)
'''
return _wrapped_view
return decorator