Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b5e01ca31b | ||
|
b983d6d3f1 | ||
|
d3327f13a2 | ||
|
d6b2cad5b8 | ||
|
b4e7d60760 | ||
|
72c3a97ffa | ||
|
38be8017a0 | ||
|
abcde9da12 | ||
|
9a41eb2f49 | ||
|
ff010746a3 | ||
|
712ae02a32 | ||
|
e7b8640481 | ||
|
a5771bf958 | ||
|
21d361c7ac | ||
|
f48b0516df |
6
ChangeLog
Normal file
6
ChangeLog
Normal file
|
@ -0,0 +1,6 @@
|
|||
v0.2 (30/06/2016)
|
||||
|
||||
**User**
|
||||
Add autofocus to login page
|
||||
Add search
|
||||
Add templates
|
|
@ -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,20 @@ 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 TemplateForm(ModelForm):
|
||||
text = forms.CharField(widget=forms.Textarea(attrs={'rows':'20', 'cols':'150'}), required=False)
|
||||
title = forms.CharField(widget=forms.Textarea(attrs={'rows':'1', 'cols':'100'}), required=False)
|
||||
|
||||
class Meta:
|
||||
model = Template
|
||||
exclude = ('author', '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 +50,4 @@ class UserForm(ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'username', 'password')
|
||||
fields = ('first_name', 'username', 'password', 'home_notes_visibility')
|
||||
|
|
|
@ -24,11 +24,17 @@ import re
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.http import HttpResponse
|
||||
from django.db.models.signals import pre_init, post_init, pre_delete, post_delete
|
||||
from django.db.models.signals import pre_save, post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
import markdown2
|
||||
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')])
|
||||
default_template = models.ForeignKey('Template', null=True, on_delete=models.SET_NULL)
|
||||
|
||||
def getPreference(self, name):
|
||||
if name == 'hidden_categories':
|
||||
|
@ -54,6 +60,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)
|
||||
|
@ -62,7 +78,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):
|
||||
|
@ -113,8 +129,32 @@ class Note(models.Model):
|
|||
self.modified_date = datetime.now()
|
||||
self.transformed_text = markdown2.markdown(self.text, extras=['fenced-code-blocks'])
|
||||
self._summarize()
|
||||
s = Search()
|
||||
|
||||
super(Note, self).save()
|
||||
|
||||
class Template(models.Model):
|
||||
name = models.CharField(max_length=30, blank=False, unique=True)
|
||||
|
||||
author = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
|
||||
title = models.CharField(max_length=100, blank=True)
|
||||
text = models.TextField(blank=True)
|
||||
visibility = models.IntegerField(default=Note.PRIVATE, choices=Note.VISIBILITY)
|
||||
category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
|
||||
|
||||
@receiver(post_save, sender=Note)
|
||||
def post_save_note_signal(sender, **kwargs):
|
||||
s = Search()
|
||||
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):
|
||||
s = Search()
|
||||
s.delete_note(kwargs['instance'].id)
|
||||
|
||||
def manage_category(user, cat_name):
|
||||
category = None
|
||||
if cat_name:
|
||||
|
|
196
denote/search.py
Executable file
196
denote/search.py
Executable file
|
@ -0,0 +1,196 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright 2016 Grégory Soutadé
|
||||
|
||||
This file is part of Dénote.
|
||||
|
||||
Dynastie is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Dynastie is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Dynastie. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import re
|
||||
import unicodedata
|
||||
import os
|
||||
import operator
|
||||
import pickle
|
||||
from django.db import models
|
||||
|
||||
import models
|
||||
#from models import Note
|
||||
|
||||
class Search:
|
||||
MINIMUM_LETTERS = 3
|
||||
|
||||
def __init__(self):
|
||||
self.report = ''
|
||||
|
||||
self.tagreg = re.compile('<[^>]+>')
|
||||
self.htmlreg = re.compile('&[^;]+;')
|
||||
self.numreg = re.compile('[0-9]+')
|
||||
self.pat = re.compile(r'\s+')
|
||||
|
||||
self.replace_by_space = (u'(', u')', u'#', u'\'', u'{', u'}', u'[', u']',
|
||||
u'-', u'|', u'\t', u'\\', u'_', u'^' '=', u'+', u'$',
|
||||
u'£', u'%', u'µ', u'*', u',', u'?', u';', u'.', u'/',
|
||||
u':', u'!', u'§', u'€', u'²')
|
||||
|
||||
# Imported from generator.py
|
||||
def _addReport(self, string, color=''):
|
||||
if color != '':
|
||||
self.report = self.report + '<span style="color:' + color + '">'
|
||||
self.report = self.report + '<b>' + self.__class__.__name__ + '</b> : '
|
||||
self.report = self.report + string
|
||||
if color != '':
|
||||
self.report = self.report + '</span>'
|
||||
self.report = self.report + '<br/>\n'
|
||||
|
||||
def _addWarning(self, string):
|
||||
self.addReport(string, 'yellow')
|
||||
|
||||
def _addError(self, string):
|
||||
self.addReport(string, 'red')
|
||||
|
||||
|
||||
def _saveDatabase(self, hashtable):
|
||||
d = pickle.dumps(hashtable)
|
||||
|
||||
f = open(os.environ['DENOTE_ROOT'] + '/_search.db', 'w')
|
||||
f.write(d)
|
||||
f.close()
|
||||
|
||||
def _loadDatabase(self):
|
||||
filename = os.environ['DENOTE_ROOT'] + '/_search.db'
|
||||
|
||||
if not os.path.exists(filename):
|
||||
print 'No search index !'
|
||||
return {}
|
||||
|
||||
f = open(filename, 'rb')
|
||||
hashtable = pickle.load(f)
|
||||
f.close()
|
||||
|
||||
return hashtable
|
||||
|
||||
def _strip_accents(self, s):
|
||||
return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
|
||||
|
||||
def _remove_tag(self, content):
|
||||
content = self.htmlreg.sub('', content)
|
||||
content = self.numreg.sub('', content)
|
||||
|
||||
content = content.replace('\n', '')
|
||||
content = content.replace('\r', '')
|
||||
content = content.replace('"', '')
|
||||
|
||||
for c in self.replace_by_space:
|
||||
content = content.replace(c, ' ')
|
||||
|
||||
content = self.tagreg.sub('', content)
|
||||
|
||||
content = self.pat.sub(' ', content)
|
||||
|
||||
return content
|
||||
|
||||
def _prepare_string(self, content):
|
||||
content = self._remove_tag(content)
|
||||
content = self._strip_accents(content)
|
||||
|
||||
return content
|
||||
|
||||
def _indexContent(self, hashtable, index, content, word_weight):
|
||||
content = self._prepare_string(content)
|
||||
|
||||
wordlist = content.split(' ')
|
||||
|
||||
for word in wordlist:
|
||||
if len(word) < self.MINIMUM_LETTERS:
|
||||
continue
|
||||
word = word.lower()
|
||||
if not word in hashtable:
|
||||
hashtable[word] = []
|
||||
if not index in hashtable[word]:
|
||||
hashtable[word].insert(0, [index, word_weight])
|
||||
else:
|
||||
weight = hashtable[word][1]
|
||||
hashtable[word][1] = weight + word_weight
|
||||
|
||||
def _index(self, hashtable, index):
|
||||
note = models.Note.objects.get(pk=index)
|
||||
|
||||
self._indexContent(hashtable, index, note.text, 1)
|
||||
self._indexContent(hashtable, index, note.title, 5)
|
||||
|
||||
def _index_note(self, note, saveDatabase=True):
|
||||
hashtable = self._loadDatabase()
|
||||
|
||||
self._index(hashtable, int(note))
|
||||
|
||||
if saveDatabase:
|
||||
self._saveDatabase(hashtable)
|
||||
|
||||
def _remove_note(self, note, saveDatabase=True):
|
||||
hashtable = self._loadDatabase()
|
||||
|
||||
if hashtable is None: return
|
||||
|
||||
for k, v in hashtable.items():
|
||||
# For tuples in values
|
||||
for t in v:
|
||||
if note == v[0]:
|
||||
v.remove(t)
|
||||
|
||||
if saveDatabase:
|
||||
self._saveDatabase(hashtable)
|
||||
|
||||
def generate_index(self, notes):
|
||||
hashtable = self._loadDatabase()
|
||||
|
||||
for note in notes:
|
||||
self._indexContent(hashtable, note.id, note.text, 1)
|
||||
self._indexContent(hashtable, note.id, note.title, 5)
|
||||
|
||||
self._saveDatabase(hashtable)
|
||||
|
||||
def index_note(self, note):
|
||||
return self._index_note(note, True)
|
||||
|
||||
def delete_note(self, note):
|
||||
return self._remove_note(note, True)
|
||||
|
||||
def edit_note(self, note, saveDatabase=True):
|
||||
self._remove_note(note, False)
|
||||
self._index_note(note, True)
|
||||
|
||||
def search(self, string):
|
||||
hashtable = self._loadDatabase()
|
||||
|
||||
string = self._prepare_string(string)
|
||||
|
||||
wordlist = string.split(' ')
|
||||
|
||||
res = {}
|
||||
for word in wordlist:
|
||||
if len(word) < Search.MINIMUM_LETTERS:
|
||||
continue
|
||||
word = word.lower()
|
||||
reg = re.compile('.*' + word + '.*')
|
||||
for key in hashtable.keys():
|
||||
if reg.match(key):
|
||||
for note in hashtable[key]:
|
||||
res[note[0]] = res.get(note[0],0) + note[1]
|
||||
|
||||
sorted_res = sorted(res.iteritems(), key=operator.itemgetter(1))
|
||||
sorted_res.reverse()
|
||||
|
||||
res = [sorted_res[i][0] for i in range(len(sorted_res))]
|
||||
|
||||
return res
|
|
@ -111,7 +111,7 @@ div#categories div.name img
|
|||
margin : 1em;
|
||||
}
|
||||
|
||||
#main_panel .note .title a
|
||||
.note .title a
|
||||
{
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
|
|
|
@ -26,7 +26,7 @@ function getPreference(cname) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function set_visible(id, visible, display="block")
|
||||
function set_visible(id, visible, display)
|
||||
{
|
||||
widget = document.getElementById(id);
|
||||
if (visible)
|
||||
|
@ -64,21 +64,21 @@ function updateHiddenCategories(cat_id, add)
|
|||
setPreference('hidden_categories', hidden_categories.join(","));
|
||||
}
|
||||
|
||||
function hide_category(cat_id, update_cookie=true)
|
||||
function hide_category(cat_id, update_cookie)
|
||||
{
|
||||
set_visible("content_" + cat_id, false);
|
||||
set_visible("minus_" + cat_id, false);
|
||||
set_visible("content_" + cat_id, false, "");
|
||||
set_visible("minus_" + cat_id, false, "");
|
||||
set_visible("plus_" + cat_id, true, "inline-block");
|
||||
|
||||
if (update_cookie)
|
||||
updateHiddenCategories(cat_id, true);
|
||||
}
|
||||
|
||||
function show_category(cat_id, update_cookie=true)
|
||||
function show_category(cat_id, update_cookie)
|
||||
{
|
||||
set_visible("content_" + cat_id, true);
|
||||
set_visible("content_" + cat_id, true, "block");
|
||||
set_visible("minus_" + cat_id, true, "inline-block");
|
||||
set_visible("plus_" + cat_id, false);
|
||||
set_visible("plus_" + cat_id, false, "");
|
||||
|
||||
if (update_cookie)
|
||||
updateHiddenCategories(cat_id, false);
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -115,12 +116,14 @@ function category_setup()
|
|||
function startup()
|
||||
{
|
||||
category_setup();
|
||||
if (location.search.search('edit_note') != -1)
|
||||
edit_note();
|
||||
}
|
||||
|
||||
function edit_category(cat_id, name)
|
||||
{
|
||||
set_visible("category_" + cat_id, false);
|
||||
set_visible("edit_category_" + cat_id, true);
|
||||
set_visible("category_" + cat_id, false, "");
|
||||
set_visible("edit_category_" + cat_id, true, "block");
|
||||
|
||||
input = document.getElementById("cat_name_" + cat_id);
|
||||
input.value = name;
|
||||
|
@ -129,8 +132,8 @@ function edit_category(cat_id, name)
|
|||
|
||||
function end_edit_category(cat_id)
|
||||
{
|
||||
set_visible("category_" + cat_id, true);
|
||||
set_visible("edit_category_" + cat_id, false);
|
||||
set_visible("category_" + cat_id, true, "block");
|
||||
set_visible("edit_category_" + cat_id, false, "");
|
||||
}
|
||||
|
||||
function submit_category_name(cat_id, orig)
|
||||
|
@ -157,19 +160,24 @@ function handleKeyPress(e, cat_id, orig){
|
|||
function edit_note()
|
||||
{
|
||||
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||
set_visible("title", false);
|
||||
set_visible("transformed_content", false);
|
||||
set_visible("edit_button", false);
|
||||
set_visible("form_delete", false);
|
||||
set_visible("div_edit", true);
|
||||
set_visible("title", false, "");
|
||||
set_visible("transformed_content", false, "");
|
||||
set_visible("edit_button", false, "");
|
||||
set_visible("form_delete", false, "");
|
||||
set_visible("div_edit", true, "block");
|
||||
}
|
||||
|
||||
function cancel_edit_note()
|
||||
{
|
||||
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||
set_visible("title", true);
|
||||
set_visible("transformed_content", true);
|
||||
set_visible("title", true, "block");
|
||||
set_visible("transformed_content", true, "block");
|
||||
set_visible("edit_button", true, "inline");
|
||||
set_visible("form_delete", true, "inline");
|
||||
set_visible("div_edit", false);
|
||||
set_visible("div_edit", false, "");
|
||||
}
|
||||
|
||||
function DoEdit(url) {
|
||||
window.location.href = '/note/' + url + '?edit_note=1';
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2,16 +2,46 @@
|
|||
<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"/>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/denote.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="startup();">
|
||||
<!-- Header -->
|
||||
<div class="settings"><a href="/user/edit">Settings</a> <a href="/disconnect">Disconnect</a></div>
|
||||
<div class="settings"><a href="/public_notes">Public notes</a> {% if authenticated %}<a href="/templates">Templates</a> <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/>
|
||||
{% if authenticated %}
|
||||
<form id="form_note_add" action="/note/add" method="POST">
|
||||
{% csrf_token %}
|
||||
<a href="#" onclick="document.getElementById('form_note_add').submit();">Add a note</a>
|
||||
{% if templates_by_name|length != 0 %}
|
||||
<br/>
|
||||
<select name="template">
|
||||
<option value="-1">None</option>
|
||||
{% for template in templates_by_name %}
|
||||
{% if template.id == user.default_template.id %}
|
||||
<option value="{{ template.id }}" selected="1">{{ template.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ template.id }}">{{ template.name }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br/>
|
||||
{% else %}
|
||||
<input type="hidden" name="template" value="-1"/>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endif %}
|
||||
{% block left %} {% endblock %}
|
||||
</div>
|
||||
<div id="main_panel">
|
||||
<div id="content">
|
||||
|
@ -19,6 +49,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<br/><br/><br/>
|
||||
<center><a href="http://indefero.soutade.fr/p/denote">Dénote</a> 0.1</center>
|
||||
<center><a href="http://indefero.soutade.fr/p/denote">Dénote</a> 0.2</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,29 +1,16 @@
|
|||
<html>
|
||||
<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" />
|
||||
{% 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"/>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/denote.js"> </script>
|
||||
{% 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>
|
||||
</head>
|
||||
<body onload="startup();">
|
||||
<!-- Header -->
|
||||
<div class="settings"><a href="/user/edit">Settings</a> <a href="/disconnect">Disconnect</a></div>
|
||||
<!-- Left panel -->
|
||||
<div id="left_panel">
|
||||
<a id="home_icon" href="/" alt="Home"><img src="{{ STATIC_URL }}images/home.png"/></a><br/><br/>
|
||||
<a href="/note/add">Add a note</a>
|
||||
{% endblock %}
|
||||
{% block left %}
|
||||
<div id="categories">
|
||||
{% for meta_note in notes_by_category %}
|
||||
<div class="category" category_id="{{ meta_note.category_id }}">
|
||||
<div id="category_{{ meta_note.category_id }}" class="name" ondblclick="edit_category({{ meta_note.category_id }}, '{{ meta_note.category }}')">
|
||||
<img id="minus_{{ meta_note.category_id }}" src="{{ STATIC_URL }}images/denote_minus.png" onclick="hide_category({{ meta_note.category_id }});"/><img id="plus_{{ meta_note.category_id }}" src="{{ STATIC_URL }}images/denote_plus.png" onclick="show_category({{ meta_note.category_id }});"/>{{ meta_note.category }} ({{ meta_note.notes|length }})
|
||||
<img id="minus_{{ meta_note.category_id }}" src="{{ STATIC_URL }}images/denote_minus.png" onclick="hide_category({{ meta_note.category_id }},true);"/><img id="plus_{{ meta_note.category_id }}" src="{{ STATIC_URL }}images/denote_plus.png" onclick="show_category({{ meta_note.category_id }},true);"/>{{ meta_note.category }} ({{ meta_note.notes|length }})
|
||||
</div>
|
||||
<div class="edit_category" id="edit_category_{{ meta_note.category_id }}">
|
||||
<form id="form_edit_category_{{ meta_note.category_id }}" action="/category/edit/{{ meta_note.category_id }}" method="post" onsubmit="return submit_category_name({{ meta_note.category_id }}, '{{ meta_note.category }}');">
|
||||
|
@ -34,7 +21,7 @@
|
|||
<div id="content_{{ meta_note.category_id }}" class="content" >
|
||||
{% for note in meta_note.notes %}
|
||||
<div class="note">
|
||||
<a href="/note/{{ note.id}}"><div class="title">{{ note.title }}</div></a>
|
||||
<a href="/note/{{ note.id}}" oncontextmenu="return DoEdit('{{ note.id}}');"><div class="title">{{ note.title }}</div></a>
|
||||
<div class="date">{{ note.created_date }}</div>
|
||||
<div class="summary">{{ note.short_summary }}</div>
|
||||
</div>
|
||||
|
@ -45,31 +32,17 @@
|
|||
{% if notes_without_category|length != 0 %}
|
||||
<div class="category" category_id="-1">
|
||||
<div id="category_-1" class="name">
|
||||
<img id="minus_-1" src="{{ STATIC_URL }}images/denote_minus.png" onclick="hide_category(-1);"/><img id="plus_-1" src="{{ STATIC_URL }}images/denote_plus.png" onclick="show_category(-1);"/>Other ({{ notes_without_category|length }})</div>
|
||||
<img id="minus_-1" src="{{ STATIC_URL }}images/denote_minus.png" onclick="hide_category(-1,true);"/><img id="plus_-1" src="{{ STATIC_URL }}images/denote_plus.png" onclick="show_category(-1,true);"/>Other ({{ notes_without_category|length }})</div>
|
||||
<div id="content_-1" class="content">
|
||||
{% for note in notes_without_category %}
|
||||
<div class="note">
|
||||
<a href="/note/{{ note.id}}"><div class="title">{{ note.title }}</div></a>
|
||||
<a href="/note/{{ note.id}}" oncontextmenu="return DoEdit('{{ note.id}}');"><div class="title">{{ note.title }}</div></a>
|
||||
<div class="date">{{ note.created_date }}</div>
|
||||
<div class="summary">{{ note.short_summary }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if notes_by_category|length == 0 %}
|
||||
<b>Any note</b>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main panel -->
|
||||
<div id="main_panel">
|
||||
<div id="content">
|
||||
{% block content %} {% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<br/><br/><br/>
|
||||
<center><a href="http://indefero.soutade.fr/p/denote">Dénote</a> 0.1</center>
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
|
|
|
@ -8,6 +8,20 @@
|
|||
<form action="/user/edit" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<p>
|
||||
<label for="id_default_template">Default template:</label>
|
||||
<select id="id_default_template" name="default_template">
|
||||
<option value="-1">None</option>
|
||||
{% for template in templates_by_name %}
|
||||
{% if template.id == user.default_template.id %}
|
||||
<option value="{{ template.id }}" selected="1">{{ template.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ template.id }}">{{ template.name }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<input type="submit" name="edit" value="Edit" /><input type="submit" name="cancel" value="Cancel" /><input type="submit" name="delete" value="Delete" onclick="return confirm('Do you really want to delete your account ?')"/>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
{% csrf_token %}
|
||||
{% if login_failed %} <p id="login_failed">Login or password is invalid</p> {% endif %}
|
||||
<table>
|
||||
<tr><td>Login</td><td><input type="text" name="login"/></td></tr>
|
||||
<tr><td>Login</td><td><input type="text" name="login" autofocus/></td></tr>
|
||||
<tr><td>Password</td><td><input id="password" type="password" name="password"/></td></tr>
|
||||
<tr><td/><td><input type="submit" value="Connect"/></td></tr>
|
||||
<tr><td/><td><a href="/user/add">Create an account</a></td></tr>
|
||||
<tr><td/><td><a href="/user/add">Create an account</a><br/>({{ nb_people_registered }} people(s) registered)</td></tr>
|
||||
<tr><td></td><td></td></tr>
|
||||
<tr><td></td><td><a href="/public_notes">Public notes</a></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
|
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 %}
|
|
@ -4,12 +4,15 @@
|
|||
{% for note in notes %}
|
||||
<div class="note">
|
||||
{% if note.category != None %}
|
||||
<div class="title"><a href="/note/{{ note.id }}">{{ note.title }} [{{ note.category.name }}]</a></div>
|
||||
<div class="title"><a href="/note/{{ note.id}}" oncontextmenu="return DoEdit('{{ note.id}}');">{{ note.title }} [{{ note.category.name }}]</a></div>
|
||||
{% else %}
|
||||
<div class="title"><a href="/note/{{ note.id }}">{{ note.title }}</a></div>
|
||||
<div class="title"><a href="/note/{{ note.id}}" oncontextmenu="return DoEdit('{{ note.id}}');">{{ note.title }}</a></div>
|
||||
{% endif %}
|
||||
<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 %}
|
||||
|
|
|
@ -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,58 +25,11 @@
|
|||
<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 }}
|
||||
Category <input name="category" list=all_categories>
|
||||
Category <input name="category" list=all_categories {% if category != None %} value="{{ category }}" {% endif %}>
|
||||
<datalist id="all_categories">
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.name }}"></option>
|
||||
|
@ -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 %}
|
||||
|
|
77
denote/templates/user_template.html
Normal file
77
denote/templates/user_template.html
Normal file
|
@ -0,0 +1,77 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="template">
|
||||
{% if template != None %}
|
||||
<form action="/template/{{ template.id }}" method="post">{% csrf_token %}
|
||||
{% else %}
|
||||
<form action="/template/add" method="post">{% csrf_token %}
|
||||
{% endif %}
|
||||
{{ template_form.as_p }}
|
||||
Category <input name="category" list="all_categories" {% if template.category != None %} value="{{ template.category.name }}" {% endif %}>
|
||||
<datalist id="all_categories">
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.name }}"></option>
|
||||
{% endfor %}
|
||||
</datalist><br/>
|
||||
{% if template != None %}
|
||||
<input type="submit" name="edit" value="Edit" />
|
||||
<input type="submit" name="delete" value="Delete" onclick="return confirm('Do you really want to delete this template ?')"/>
|
||||
{% else %}
|
||||
<input type="submit" name="add" value="Add"/>
|
||||
{% endif %}
|
||||
<input type="submit" name="cancel" value="Cancel"/>
|
||||
</form>
|
||||
<br/>
|
||||
<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 OR
|
||||
```language
|
||||
Code
|
||||
```
|
||||
</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>
|
||||
</div>
|
||||
{% endblock %}
|
14
denote/templates/user_template_index.html
Normal file
14
denote/templates/user_template_index.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% for template in templates %}
|
||||
<div class="template">
|
||||
<div class="title"><a href="/template/{{ template.id}}" oncontextmenu="return DoEdit('{{ template.id }}');">{{ template.name }}</a></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if templates|length == 0 %}
|
||||
<b>Any template</b>
|
||||
{% endif %}
|
||||
<div class="settings"><a href="/template/add">Add a Template</a><br/></div>
|
||||
|
||||
{% endblock %}
|
|
@ -24,10 +24,18 @@ urlpatterns = patterns('',
|
|||
url(r'^index[/]?$', 'denote.views.index', name='index'),
|
||||
url(r'^[/]?$', 'denote.views.index', name='index'),
|
||||
url(r'^disconnect?$', 'denote.views.disconnect', name='disconnect'),
|
||||
url(r'^user/add$','denote.views.new_user', name='add_user'),
|
||||
url(r'^user/add$','denote.views.new_user', name='new_user'),
|
||||
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'^public_notes$', 'denote.views.public_notes', name='public_notes'),
|
||||
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'),
|
||||
url(r'^generate_search_index$', 'denote.views.generate_search_index', name='generate_search_index'),
|
||||
|
||||
url(r'^template/add$','denote.views.add_template', name='add_template'),
|
||||
url(r'^template/(\d+)$','denote.views.template', name='template'),
|
||||
url(r'^templates$','denote.views.templates', name='templates'),
|
||||
)
|
||||
|
|
245
denote/views.py
245
denote/views.py
|
@ -18,15 +18,17 @@
|
|||
along with Dénote. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
from denote.models import *
|
||||
from denote.forms import *
|
||||
from denote.search import *
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated():
|
||||
|
@ -46,7 +48,10 @@ def index(request):
|
|||
else:
|
||||
return user_home(request, request.user)
|
||||
|
||||
c = {'login_failed' : login_failed}
|
||||
c = {
|
||||
'login_failed' : login_failed,
|
||||
'nb_people_registered' : User.objects.all().count()
|
||||
}
|
||||
|
||||
return render(request, 'login.html', c)
|
||||
|
||||
|
@ -79,7 +84,7 @@ def new_user(request):
|
|||
form = UserForm()
|
||||
|
||||
c = {'login' : login_val, 'password' : password, 'form': form}
|
||||
|
||||
|
||||
return render(request, 'add_user.html', c)
|
||||
|
||||
@login_required
|
||||
|
@ -89,13 +94,22 @@ def edit_user(request):
|
|||
|
||||
if request.method == 'POST':
|
||||
if 'edit' in request.POST:
|
||||
template_id = request.POST['default_template']
|
||||
if template_id == '-1':
|
||||
template = None
|
||||
else:
|
||||
try:
|
||||
template= Template.objects.get(author=user.id, id=template_id)
|
||||
except:
|
||||
template = None
|
||||
user.default_template = template
|
||||
form = UserForm(request.POST, instance=user, initial={'password':''})
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
if request.POST['password'] != '':
|
||||
user.set_password(request.POST['password'])
|
||||
user.save()
|
||||
edited = True
|
||||
edited = True
|
||||
else:
|
||||
if 'delete' in request.POST:
|
||||
logout(request)
|
||||
|
@ -105,11 +119,45 @@ def edit_user(request):
|
|||
login = 'login' in request.POST and request.POST['login'] or ''
|
||||
form = UserForm(instance=user, initial={'password':'', 'login':login})
|
||||
|
||||
c = {'user_to_edit' : user, 'form' : form, 'edited' : edited}
|
||||
templates = Template.objects.filter(author=user.id).order_by('name')
|
||||
templates_by_name = []
|
||||
for template in templates:
|
||||
t = {}
|
||||
t['name'] = template.name
|
||||
t['id'] = template.id
|
||||
templates_by_name.append(t)
|
||||
|
||||
c = {'authenticated' : True, 'user_to_edit' : user, 'form' : form, 'edited' : edited}
|
||||
c['templates_by_name'] = templates_by_name
|
||||
|
||||
return render(request, 'edit_user.html', c)
|
||||
|
||||
def _prepare_template_context(user):
|
||||
categories = Category.objects.filter(author=user.id).order_by('name')
|
||||
|
||||
templates = Template.objects.filter(author=user.id).order_by('name')
|
||||
templates_by_name = []
|
||||
for template in templates:
|
||||
t = {}
|
||||
t['name'] = template.name
|
||||
t['id'] = template.id
|
||||
templates_by_name.append(t)
|
||||
|
||||
context = {
|
||||
'user': user,
|
||||
'authenticated' : True,
|
||||
'categories': categories,
|
||||
'templates_by_name': templates_by_name,
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
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
|
||||
|
@ -127,11 +175,21 @@ def _prepare_note_context(user):
|
|||
categories = Category.objects.filter(author=user.id).order_by('name')
|
||||
notes_without_category = Note.objects.filter(author=user,category=None).order_by('-modified_date')
|
||||
|
||||
templates = Template.objects.filter(author=user.id).order_by('name')
|
||||
templates_by_name = []
|
||||
for template in templates:
|
||||
t = {}
|
||||
t['name'] = template.name
|
||||
t['id'] = template.id
|
||||
templates_by_name.append(t)
|
||||
|
||||
context = {
|
||||
'user': user,
|
||||
'authenticated' : True,
|
||||
'notes_by_category': notes_by_category,
|
||||
'categories': categories,
|
||||
'notes_without_category': notes_without_category,
|
||||
'templates_by_name': templates_by_name,
|
||||
}
|
||||
|
||||
return context
|
||||
|
@ -150,23 +208,32 @@ def user_home(request, user):
|
|||
def add_note(request):
|
||||
user = request.user
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'add' in request.POST:
|
||||
note = Note(author=user, created_date=datetime.now())
|
||||
note.category = manage_category(user, request.POST['category'])
|
||||
form = NoteForm(request.POST, instance=note)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('/note/%d' % (note.id))
|
||||
else:
|
||||
if 'cancel' in request.POST:
|
||||
return HttpResponseRedirect('/')
|
||||
if 'add' in request.POST:
|
||||
note = Note(author=user, created_date=datetime.now())
|
||||
note.category = manage_category(user, request.POST['category'])
|
||||
form = NoteForm(request.POST, instance=note)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('/note/%d' % (note.id))
|
||||
elif 'cancel' in request.POST:
|
||||
return HttpResponseRedirect('/')
|
||||
else:
|
||||
form = NoteForm()
|
||||
note = None
|
||||
template_id = request.POST['template']
|
||||
if template_id != '-1':
|
||||
note = Template.objects.get(id=template_id, author=user.id)
|
||||
if not note:
|
||||
note = Note(visibility=user.home_notes_visibility)
|
||||
|
||||
form = NoteForm(instance=note)
|
||||
|
||||
context = _prepare_note_context(user)
|
||||
context['note_form'] = form
|
||||
context['note'] = None
|
||||
|
||||
if note.category:
|
||||
context['category'] = note.category.name
|
||||
|
||||
return render(request, 'user_note.html', context)
|
||||
|
||||
@login_required
|
||||
|
@ -196,6 +263,50 @@ 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)
|
||||
|
||||
def public_notes(request):
|
||||
user = request.user
|
||||
|
||||
if user.is_authenticated():
|
||||
public_notes = Note.objects.filter(visibility__gte=Note.REGISTERED).order_by('-modified_date')
|
||||
else:
|
||||
public_notes = Note.objects.filter(visibility__gte=Note.PUBLIC).order_by('-modified_date')
|
||||
|
||||
context = _prepare_note_context(user)
|
||||
context['notes'] = public_notes[:50]
|
||||
context['public_notes'] = public_notes[:50]
|
||||
|
||||
return render(request, 'public_notes.html', context)
|
||||
|
||||
@login_required
|
||||
def edit_category(request, category_id):
|
||||
user = request.user
|
||||
|
@ -221,12 +332,9 @@ def edit_category(request, category_id):
|
|||
|
||||
@login_required
|
||||
def preferences(request):
|
||||
print request.method
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
print request.POST.items()
|
||||
|
||||
if 'get' in request.POST and 'name' in request.POST:
|
||||
return request.user.getPreference(request.POST['name'])
|
||||
elif 'set' in request.POST and 'name' in request.POST and \
|
||||
|
@ -235,3 +343,100 @@ def preferences(request):
|
|||
else:
|
||||
raise Http404
|
||||
|
||||
def search(request):
|
||||
context = _prepare_note_context(request.user)
|
||||
|
||||
ref = request.META['HTTP_REFERER']
|
||||
|
||||
if 'text' in request.POST:
|
||||
text = request.POST['text']
|
||||
else:
|
||||
return HttpResponseRedirect(ref)
|
||||
|
||||
s = Search()
|
||||
note_list = s.search(text)
|
||||
|
||||
if request.user.is_authenticated():
|
||||
notes = Note.objects.filter(pk__in=note_list, author=request.user)
|
||||
|
||||
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):
|
||||
|
||||
if os.path.exists('_search.db'):
|
||||
os.path.remove('_search.db')
|
||||
|
||||
s = Search()
|
||||
s.generate_index(Note.objects.all())
|
||||
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
@login_required
|
||||
def add_template(request):
|
||||
user = request.user
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'add' in request.POST:
|
||||
template = Template(author=user)
|
||||
template.category = manage_category(user, request.POST['category'])
|
||||
form = TemplateForm(request.POST, instance=template)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('/templates')
|
||||
else:
|
||||
if 'cancel' in request.POST:
|
||||
return HttpResponseRedirect('/templates')
|
||||
else:
|
||||
template = Template(visibility=user.home_notes_visibility)
|
||||
form = TemplateForm(instance=template)
|
||||
|
||||
context = _prepare_template_context(user)
|
||||
context['template_form'] = form
|
||||