Add visibility management
This commit is contained in:
parent
38be8017a0
commit
72c3a97ffa
|
@ -21,6 +21,7 @@
|
|||
from django.forms import ModelForm
|
||||
from django import forms
|
||||
from denote.models import *
|
||||
from datetime import datetime
|
||||
|
||||
class NoteForm(ModelForm):
|
||||
text = forms.CharField(widget=forms.Textarea(attrs={'rows':'20', 'cols':'150'}))
|
||||
|
@ -28,10 +29,13 @@ class NoteForm(ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Note
|
||||
exclude = ('author', 'transformed_text', 'long_summary', 'short_summary', 'created_date', 'modified_date', 'category', 'visibility')
|
||||
exclude = ('author', 'transformed_text', 'long_summary', 'short_summary', 'created_date', 'modified_date', 'category')
|
||||
|
||||
|
||||
class UserForm(ModelForm):
|
||||
|
||||
password = forms.CharField(required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(UserForm, self).__init__(*args, **kwargs)
|
||||
self.fields['first_name'].label = 'Name'
|
||||
|
@ -39,4 +43,4 @@ class UserForm(ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'username', 'password')
|
||||
fields = ('first_name', 'username', 'password', 'home_notes_visibility')
|
||||
|
|
|
@ -33,6 +33,7 @@ from search import Search
|
|||
|
||||
class User(AbstractUser):
|
||||
hidden_categories = models.TextField(blank=True)
|
||||
home_notes_visibility = models.IntegerField(default=0, choices=[(0, 'private'), (1, 'registered'), (2, 'public')])
|
||||
|
||||
def getPreference(self, name):
|
||||
if name == 'hidden_categories':
|
||||
|
@ -58,6 +59,16 @@ class Category(models.Model):
|
|||
name = models.CharField(max_length=50, unique=True, blank=False)
|
||||
|
||||
class Note(models.Model):
|
||||
|
||||
PRIVATE = 0
|
||||
REGISTERED = 1
|
||||
PUBLIC = 2
|
||||
|
||||
VISIBILITY = ((PRIVATE, 'Private'),
|
||||
(REGISTERED, 'Registered'),
|
||||
(PUBLIC, 'Public')
|
||||
)
|
||||
|
||||
author = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
|
||||
title = models.CharField(max_length=100, blank=False)
|
||||
long_summary = models.CharField(max_length=255)
|
||||
|
@ -66,7 +77,7 @@ class Note(models.Model):
|
|||
transformed_text = models.TextField()
|
||||
created_date = models.DateTimeField()
|
||||
modified_date = models.DateTimeField()
|
||||
visibility = models.IntegerField(default=0)
|
||||
visibility = models.IntegerField(default=PRIVATE, choices=VISIBILITY)
|
||||
category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
|
||||
|
||||
def _wrap(self, text, limit, max_limit):
|
||||
|
@ -124,7 +135,10 @@ class Note(models.Model):
|
|||
@receiver(post_save, sender=Note)
|
||||
def post_save_note_signal(sender, **kwargs):
|
||||
s = Search()
|
||||
s.edit_note(kwargs['instance'].id)
|
||||
if kwargs['created']:
|
||||
s.index_note(kwargs['instance'].id)
|
||||
else:
|
||||
s.edit_note(kwargs['instance'].id)
|
||||
|
||||
@receiver(pre_delete, sender=Note)
|
||||
def pre_delete_note_signal(sender, **kwargs):
|
||||
|
|
|
@ -111,7 +111,7 @@ div#categories div.name img
|
|||
margin : 1em;
|
||||
}
|
||||
|
||||
#main_panel .note .title a
|
||||
.note .title a
|
||||
{
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
|
|
|
@ -96,6 +96,7 @@ function category_setup()
|
|||
category = categories.childNodes[i];
|
||||
if (category.nodeType != Node.ELEMENT_NODE) continue;
|
||||
categoryId = category.getAttribute("category_id");
|
||||
if (categoryId == null) continue;
|
||||
hide = false;
|
||||
for(a=0; a<hidden_categories.length;a++)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<head>
|
||||
<title>Dénote{% if user.get_full_name|length != 0 %} - {{ user.get_full_name }}{% endif %}</title>
|
||||
<link rel="icon" type="image/png" href="{{ STATIC_URL }}images/favicon.png" />
|
||||
<script type="text/javascript">
|
||||
var hidden_categories = null;
|
||||
function get_csrf_token() { return '{{ csrf_token }}';}
|
||||
</script>
|
||||
{% block head %} {% endblock %}
|
||||
<link href="{{ STATIC_URL }}css/denote.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="{{ STATIC_URL }}css/pygments.css" rel="stylesheet" type="text/css"/>
|
||||
|
@ -9,8 +13,9 @@
|
|||
</head>
|
||||
<body onload="startup();">
|
||||
<!-- Header -->
|
||||
<div class="settings"><a href="/user/edit">Settings</a> <a href="/disconnect">Disconnect</a><br/>
|
||||
<form action="/search">{% csrf_token %}<input name="text"/><input type="button" value="Search"/></form></div>
|
||||
<div class="settings">{% if authenticated %}<a href="/user/edit">Settings</a> <a href="/disconnect">Disconnect</a><br/>
|
||||
{% endif %}
|
||||
<form action="/search" method="post">{% csrf_token %}<input name="text"/><input type="submit" value="Search"/></form></div>
|
||||
<!-- Left panel -->
|
||||
<div id="left_panel">
|
||||
<a id="home_icon" href="/" alt="Home"><img src="{{ STATIC_URL }}images/home.png"/></a><br/><br/>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<script type="text/javascript">
|
||||
var hidden_categories = "{{ user.hidden_categories }}";
|
||||
hidden_categories = "{{ user.hidden_categories }}";
|
||||
hidden_categories = hidden_categories.split(",");
|
||||
function get_csrf_token() { return '{{ csrf_token }}';}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block left %}
|
||||
|
|
20
denote/templates/public_note.html
Normal file
20
denote/templates/public_note.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block left %}
|
||||
{% for note in public_notes %}
|
||||
<div id="categories">
|
||||
<div class="note">
|
||||
<a href="/note/{{ note.author.id}}/{{ note.id }}"><div class="title">{{ note.title }}</div></a>
|
||||
<div class="date">{{ note.created_date }}</div>
|
||||
<div class="summary">{{ note.short_summary }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="note">
|
||||
<div id="title" class="title">{{ note.title }}</div>
|
||||
<div id="transformed_content">{{ note.transformed_text|safe }}</div>
|
||||
</div>
|
||||
{% endblock %}
|
26
denote/templates/public_notes.html
Normal file
26
denote/templates/public_notes.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block left %}
|
||||
{% for note in public_notes %}
|
||||
<div id="categories">
|
||||
<div class="note">
|
||||
<a href="/note/{{ note.author.id}}/{{ note.id }}"><div class="title">{{ note.title }}</div></a>
|
||||
<div class="date">{{ note.created_date }}</div>
|
||||
<div class="summary">{{ note.short_summary }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% for note in notes %}
|
||||
<div class="note">
|
||||
<div class="title"><a href="/note/{{ note.author.id }}/{{ note.id }}">{{ note.title }}</a></div>
|
||||
<div class="date">{{ note.modified_date }}</div>
|
||||
<div class="summary">{{ note.long_summary }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if notes|length == 0 %}
|
||||
<b>Any note</b>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -12,4 +12,7 @@
|
|||
<div class="summary">{{ note.long_summary }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if notes|length == 0 %}
|
||||
<b>Any note</b>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
{% block content %}
|
||||
<div class="note">
|
||||
{% if note != None %}
|
||||
{% if note and note_form != None %}
|
||||
<div id="title" class="title" ondblclick="edit_note();">{{ note.title }}</div>
|
||||
{% if note.category != None %}
|
||||
{% else %}
|
||||
<div id="title" class="title">{{ note.title }}</div>
|
||||
{% endif %}
|
||||
{% if note and note.category != None %}
|
||||
<div class="category">{{ note.category.name }}</div>
|
||||
{% endif %}
|
||||
<div id="transformed_content">{{ note.transformed_text|safe }}</div>
|
||||
{% if note and note_form != None %}
|
||||
<div class="edit_button"><input id="edit_button" type="button" value="Edit" onclick="edit_note();"/> <form id="form_delete" action="/note/{{ note.id }}" method="post">{% csrf_token %}<input type="submit" name="delete" value="Delete" onclick="return confirm('Do you really want to delete this note ?')"/></form></div>
|
||||
<div id="div_edit">
|
||||
<form id="form_edit" action="/note/{{ note.id }}" method="post">{% csrf_token %}
|
||||
|
@ -21,54 +25,7 @@
|
|||
<input type="submit" name="edit" value="Edit" />
|
||||
<input type="button" value="Cancel" onclick="cancel_edit_note();"/>
|
||||
</form>
|
||||
<b>Markdown syntax</b><br /><br />
|
||||
<table>
|
||||
<tr>
|
||||
<td class="markdown_help">
|
||||
<pre style="display:inline">_italic_</pre> <span style="font-style:italic">italic</span><br/>
|
||||
<pre style="display:inline">**bold**</pre> <span style="font-weight:bold">bold</span><br/>
|
||||
<pre style="display:inline">~~line through~~</pre> <span style="text-decoration:line-through">line through</span><br/>
|
||||
<pre style="display:inline">~underline~</pre> <span style="text-decoration:underline">underline</span><br/>
|
||||
<pre style="display:inline">>Citation</pre><br/>
|
||||
<pre>
|
||||
* Unordered list
|
||||
* Second element
|
||||
</pre>
|
||||
<ul>
|
||||
<li>Unordered list
|
||||
<li>Second element
|
||||
</ul>
|
||||
<pre>
|
||||
1. Ordered list
|
||||
1. Second element
|
||||
</pre>
|
||||
<ol>
|
||||
<li>Ordered list
|
||||
<li>Second element
|
||||
</ol>
|
||||
<pre style="display:inline">![Picture](https://bits.wikimedia.org/images/wikimedia-button.png)</pre><img src="https://bits.wikimedia.org/images/wikimedia-button.png" alt="Picture"/><br/>
|
||||
<pre style="display:inline">#[Inline Picture](https://bits.wikimedia.org/images/wikimedia-button.png)</pre><img src="https://bits.wikimedia.org/images/wikimedia-button.png" alt="Picture"/><br/>
|
||||
<pre style="display:inline">[Link](http://www.wikipedia.org)</pre> <a href="http://www.wikipedia.org">Link</a><br/><br/>
|
||||
<pre>
|
||||
Code : 4 whitespaces ahead
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre># Title # or
|
||||
Title
|
||||
=====</pre>
|
||||
<h1>Title</h1>
|
||||
<pre>## Sub title ## or
|
||||
Sub title
|
||||
---------</pre>
|
||||
<h2>Sub title</h2>
|
||||
<pre>### Sub sub title ###</pre>
|
||||
<h3>Sub sub title</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
{% else %}
|
||||
<div class="form_add">
|
||||
<form action="/note/add" method="post">{% csrf_token %}
|
||||
{{ note_form.as_p }}
|
||||
|
@ -81,7 +38,7 @@
|
|||
<input type="submit" name="add" value="Add" />
|
||||
<input type="submit" name="cancel" value="Cancel" />
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<b>Markdown syntax</b><br /><br />
|
||||
<table>
|
||||
<tr>
|
||||
|
@ -131,6 +88,6 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -28,6 +28,7 @@ urlpatterns = patterns('',
|
|||
url(r'^user/edit$','denote.views.edit_user', name='edit_user'),
|
||||
url(r'^note/add$', 'denote.views.add_note', name='add_note'),
|
||||
url(r'^note/(\d+)$', 'denote.views.note', name='note'),
|
||||
url(r'^note/(\d+)/(\d+)$', 'denote.views.public_note', name='public_note'),
|
||||
url(r'^category/edit/(\d)$','denote.views.edit_category', name='edit_category'),
|
||||
url(r'^preferences$', 'denote.views.preferences', name='preferences'),
|
||||
url(r'^search$', 'denote.views.search', name='search'),
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from django.http import HttpResponseRedirect, HttpResponse, Http404
|
||||
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseForbidden
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.shortcuts import render
|
||||
|
@ -115,6 +115,11 @@ def edit_user(request):
|
|||
return render(request, 'edit_user.html', c)
|
||||
|
||||
def _prepare_note_context(user):
|
||||
if not user.is_authenticated():
|
||||
return {
|
||||
'authenticated' : False,
|
||||
}
|
||||
|
||||
categories = Category.objects.filter(author=user.id).order_by('name')
|
||||
notes_by_category = []
|
||||
need_refresh = False
|
||||
|
@ -134,6 +139,7 @@ def _prepare_note_context(user):
|
|||
|
||||
context = {
|
||||
'user': user,
|
||||
'authenticated' : True,
|
||||
'notes_by_category': notes_by_category,
|
||||
'categories': categories,
|
||||
'notes_without_category': notes_without_category,
|
||||
|
@ -167,7 +173,8 @@ def add_note(request):
|
|||
if 'cancel' in request.POST:
|
||||
return HttpResponseRedirect('/')
|
||||
else:
|
||||
form = NoteForm()
|
||||
note = Note(visibility=user.home_notes_visibility)
|
||||
form = NoteForm(instance=note)
|
||||
|
||||
context = _prepare_note_context(user)
|
||||
context['note_form'] = form
|
||||
|
@ -201,6 +208,36 @@ def note(request, note_id):
|
|||
|
||||
return render(request, 'user_note.html', context)
|
||||
|
||||
def public_note(request, user_id, note_id):
|
||||
user = request.user
|
||||
|
||||
try:
|
||||
note = Note.objects.get(pk=note_id, author=user_id)
|
||||
except:
|
||||
raise Http404
|
||||
|
||||
if note is None:
|
||||
raise Http404
|
||||
|
||||
if not user or not user.is_authenticated():
|
||||
if note.visibility != Note.PUBLIC:
|
||||
return HttpResponseForbidden()
|
||||
else:
|
||||
if note.visibility == Note.PRIVATE and\
|
||||
user_id != user.id:
|
||||
return HttpResponseForbidden()
|
||||
|
||||
if user.is_authenticated():
|
||||
public_notes = Note.objects.filter(author=user_id, visibility__gte=Note.REGISTERED).order_by('-modified_date')
|
||||
else:
|
||||
public_notes = Note.objects.filter(author=user_id, visibility__gte=Note.PUBLIC).order_by('-modified_date')
|
||||
|
||||
context = _prepare_note_context(user)
|
||||
context['note'] = note
|
||||
context['public_notes'] = public_notes
|
||||
|
||||
return render(request, 'public_note.html', context)
|
||||
|
||||
@login_required
|
||||
def edit_category(request, category_id):
|
||||
user = request.user
|
||||
|
@ -237,7 +274,6 @@ def preferences(request):
|
|||
else:
|
||||
raise Http404
|
||||
|
||||
@login_required
|
||||
def search(request):
|
||||
context = _prepare_note_context(request.user)
|
||||
|
||||
|
@ -251,11 +287,17 @@ def search(request):
|
|||
s = Search()
|
||||
note_list = s.search(text)
|
||||
|
||||
notes = Note.objects.filter(pk__in=note_list, author=request.user)
|
||||
context['notes'] = notes
|
||||
context['note_form'] = NoteForm()
|
||||
if request.user.is_authenticated():
|
||||
notes = Note.objects.filter(pk__in=note_list, author=request.user)
|
||||
|
||||
return render(request, 'user_index.html', context)
|
||||
context['notes'] = notes
|
||||
context['note_form'] = NoteForm()
|
||||
|
||||
return render(request, 'user_index.html', context)
|
||||
else:
|
||||
notes = Note.objects.filter(pk__in=note_list, visibility__gte=Note.PUBLIC)
|
||||
context['notes'] = notes
|
||||
return render(request, 'public_notes.html', context)
|
||||
|
||||
@login_required
|
||||
def generate_search_index(request):
|
||||
|
|
Loading…
Reference in New Issue
Block a user