예제 #1
0
파일: views.py 프로젝트: Zerack/zoll.me
def index(request):
    '''
    When the index is shown, we show the Welcome section, the Recent Uploads section,
    and the My Stats section. Welcome is static, the Recent Uploads section will show
    recently available files based on user and authenticated status, and the My Stats
    section show statistics if authenticated, and just a message saying 'login' if 
    you are not.
    
    '''
    
    # Template context dictionary.
    td = {'active_nav': 'home', 'nav_group_entries': nav_group_entries(request.user)}
    
    # Let's build the list of recently uploaded files available to the user. Any files that
    # are in groups the user is a member of, are public, or are private and owned by the user
    # count.
    public_group = Group.objects.filter(group='public').get()
    if request.user.is_authenticated():
        private_group = Group.objects.filter(group='private').get()
        user_groups = [x.group for x in Group_Member.objects.filter(user=request.user)]
        recent_files = File.objects.filter(Q(group__in=user_groups) | Q(group=public_group) | Q(Q(group=private_group) & Q(user=request.user)))
        td['user_groups'] = user_groups
    else:
        recent_files = File.objects.filter(group=public_group)
    td['recent_files'] = recent_files.order_by('-date').all()[:5]
    
    # Now we will get counts of active files if the user is authenticated.
    if request.user.is_authenticated():
        td['public_count'] =  File.objects.filter(group=public_group).filter(user=request.user).count()
        td['private_count'] = File.objects.filter(group=private_group).filter(user=request.user).count()
        td['group_count'] = File.objects.filter(group__in=user_groups).filter(user=request.user).count()
    
    return render_to_response('files/index.html', td, context_instance = RequestContext(request))
예제 #2
0
파일: views.py 프로젝트: Zerack/zoll.me
def delete(request, file_id):
    '''
    Shows two different pages on POST / GET. On GET, shows an 
    'Are you sure?' page to delete a file. On POST, deletes the
    file and redirects back to the appropriate listing page. All
    methods require that the requesting user is the owner of
    the file in question.
    
    Keyword Arguments:
    file_id -> String. Matches \d+. The id of the file in question.
    
    '''
    
    # First, make sure the file exists, and return 404 if it does not.
    try:
        db_file = File.objects.filter(id=file_id).get()
    except File.DoesNotExist:
        raise Http404
    
    # If the user does not own the file, throw forbidden. Otherwise, proceed.
    if db_file.user != request.user:
        raise PermissionDenied
    
    # Template context dictionary
    td = {'active_nav': db_file.group.group, 'nav_group_entries': nav_group_entries(request.user)}
    
    if request.method == 'POST':        
        deleted_file_name = os.path.basename(db_file.uploaded_file.name)
        
        # The file itself must be explicitly deleted prior to record deletion.
        db_file.uploaded_file.delete()
        db_file.delete()
        
        messages.add_message(request, messages.SUCCESS, 'The file "{0}" was successfully deleted.'.format(os.path.basename(deleted_file_name)))
        return redirect(reverse('files.views._list', kwargs={'group': db_file.group.group}))
        
    td['db_file'] = db_file
    return render_to_response('files/delete.html', td, context_instance = RequestContext(request))
예제 #3
0
파일: views.py 프로젝트: Zerack/zoll.me
def _list(request, group):
    '''
    Defines the view for the list of all available files under a given group. This includes
    hierarchical display of data in folder structures, etc. If the group is public,
    we require no permissions. Otherwise, we require either that the user is a member of
    the given group, or that the user is authenticated (to view private files).
    
    Keyword Arguments:
    group -> String. The group being displayed. Can be 'public', 'private', or an actual group.
    
    '''
    
    # Template context dictionary
    td = {'active_nav': group, 'nav_group_entries': nav_group_entries(request.user)}
    
    if group == 'public':
        # The public group requires no permissions, and returns just public files.
        files = File.objects.filter(group=Group.objects.filter(group='public').get()).all()
    else:
        # All other groups require an authenticated user, so redirect to login if we aren't 
        # currently authenticated.
        if not request.user.is_authenticated():
            return redirect('{0}?{1}'.format(reverse('zoll_me-login'),urlencode({'next':request.get_full_path()})))
        if group == 'private':
            # The private group returns files in "private" that are owned by the current user.
            files = File.objects.filter(group=Group.objects.filter(group='private').get()).filter(user=request.user).all()
        else:
            # Otherwise, return all files in the requested group, as long as the current user
            # is a member of that group. If the user is not a member of the group, show the forbidden page.
            try:
                db_group = Group.objects.filter(group=group).get()
                db_group_member = Group_Member.objects.filter(user=request.user).filter(group=db_group).get()
            except (Group.DoesNotExist, Group_Member.DoesNotExist):
                raise PermissionDenied          
            files = File.objects.filter(group=db_group).all()
            
    # Now we iterate over all files and construct the list of files for the template. First we
    # generate a list of the path objects we need to display, and then loop through and fill
    # them with the files.
    list_paths = []    
    for f in files:
        dp = os.path.normpath(f.display_path)
        if dp == os.path.normpath('.'):
            if dp not in list_paths:
                list_paths.append('.')
            continue
        while dp not in list_paths:
            list_paths.append(dp)
            dp = os.path.normpath(os.path.split(dp)[0])
    list_paths.sort()
    
    display_list = []
    for lp in list_paths:
        if lp != os.path.normpath('.'):
            lp_len = len(lp.split(sep))
            display_list.append(((lp_len - 1) * OFFSET_PX, LIST_ENTRY_DIR, lp.split(sep)[-1]))
        else:
            lp_len = 0
        for f in filter(lambda x: os.path.normpath(x.display_path) == lp, files):
            display_list.append((lp_len * OFFSET_PX, LIST_ENTRY_FILE, f))
            
    print display_list
    td['list'] = display_list
    
    # Add a little bit of decorative styling to the template.
    td['header'] = group.capitalize() if group in ['public','private'] else group
    if group == 'public':
        td['info'] = LIST_INFO_PUBLIC
    elif group == 'private':
        td['info'] = LIST_INFO_PRIVATE
    else:
        td['info'] = LIST_INFO_GROUP
        
    return render_to_response('files/list.html', td, context_instance = RequestContext(request))    
예제 #4
0
파일: views.py 프로젝트: Zerack/zoll.me
def add(request, group):
    '''
    This method accepts GET and POST. On GET, displays the page to add a file to the appropriate
    group. On POST, validates the upload and adds the file to the group and path. In case of errors
    on POST, returns the GET page with an error message. On a successful POST, returns to the matching
    _list view.
    
    Keyword Arguments:
    group -> String. The group affected. Can be 'public', 'private', or a group string.
    
    '''
    
    # First we make sure the user has the appropriate permissions. Anyone can add public
    # or private files, but only members of groups can add files to that group. This permissions
    # check applies to both the GET and POST methods.
    try:
        db_group = Group.objects.filter(group=group).get()
    except Group.DoesNotExist:
        raise Http404
    
    if group not in ['public','private']:
        try:
            db_user_group = Group_Member.objects.filter(user=request.user).filter(group=db_group).get()
        except Group_Member.DoesNotExist:
            raise PermissionDenied
    
    # Template context dictionary
    td = {'active_nav': group, 'nav_group_entries': nav_group_entries(request.user)}
    
    if request.method == 'POST':        
        # If the request is a POST, validate the form input. In this case, it's just that the
        # file exists and that file_path is a valid filepath.
        if 'file_path' not in request.POST or 'new_file' not in request.FILES:
            return error_400(request)
        
        file_path = os.path.normpath(request.POST['file_path'].strip())
        uploaded_file = request.FILES['new_file']
        
        # Process file path. We need to do some cleaning to make sure we can get a clear
        # path from it. We don't have to worry about _security_, because the file isn't
        # written to disk using this path, just displayed.
        if file_path == os.path.normpath(''):
            cleaned_path = ''
        else:
            file_path = file_path.split(sep)
            cleaned_path = []
            for entry in file_path:
                if re.match(r'[/\\?*:|"<>.\']', entry):
                    return error_400(request)
                cleaned_entry = entry.strip()
                if cleaned_entry == '':
                    return error_400(request)               
                cleaned_path.append(cleaned_entry)
            cleaned_path = sep.join(cleaned_path)
        
        # All is well, so add the file object to the database, which will also write it do disk via
        # Django's FileField model field.
        db_file = File(uploaded_file=uploaded_file, display_path=cleaned_path, date=datetime.datetime.now(),
                       group=db_group, user=request.user)
        db_file.save()
        
        messages.add_message(request, messages.SUCCESS, 'The file "{0}" was successfully uploaded.'.format(os.path.basename(db_file.uploaded_file.name)))
        return redirect(reverse('files.views._list', kwargs={'group': group}))    
    
    # If this is a get request, we can just go ahead and return the add template.
    return render_to_response('files/add.html', td, context_instance = RequestContext(request))