Dénote

Dénote Git Source Tree

Root/denote/models.py

1# -*- coding: utf-8 -*-
2"""
3 Copyright 2015 Grégory Soutadé
4
5 This file is part of Dénote.
6
7 Dénote is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Dénote is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Dénote. If not, see <http://www.gnu.org/licenses/>.
19"""
20
21from datetime import datetime
22import re
23
24from django.db import models
25from django.contrib.auth.models import AbstractUser
26from django.http import HttpResponse
27from django.db.models.signals import pre_init, post_init, pre_delete, post_delete
28from django.db.models.signals import pre_save, post_save
29from django.dispatch import receiver
30
31import markdown2
32import search
33
34class User(AbstractUser):
35 hidden_categories = models.TextField(blank=True)
36
37 def getPreference(self, name):
38 if name == 'hidden_categories':
39 return HttpResponse('{"hidden_categories" : [' + self.hidden_categories + ']}', 'application/json')
40 else:
41 raise Http404
42
43 def setPreference(self, name, value):
44 if name == 'hidden_categories':
45 categories = []
46 for c in value.split(','):
47 if c == '-1' or \
48 (c and Category.objects.filter(id=c).exists()):
49 categories.append(c)
50 self.hidden_categories = ','.join(categories)
51 self.save()
52 return HttpResponse('')
53 else:
54 raise Http404
55
56class Category(models.Model):
57 author = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
58 name = models.CharField(max_length=50, unique=True, blank=False)
59
60class Note(models.Model):
61 author = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
62 title = models.CharField(max_length=100, blank=False)
63 long_summary = models.CharField(max_length=255)
64 short_summary = models.CharField(max_length=255)
65 text = models.TextField(blank=False)
66 transformed_text = models.TextField()
67 created_date = models.DateTimeField()
68 modified_date = models.DateTimeField()
69 visibility = models.IntegerField(default=0)
70 category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
71
72 def _wrap(self, text, limit, max_limit):
73 if len(text) < limit: return text
74
75 lower_limit = upper_limit = limit
76
77 while text[lower_limit-1] != ' ' and\
78 lower_limit > 1:
79 lower_limit -= 1
80
81 while text[upper_limit-1] != ' ' and\
82 upper_limit < len(text):
83 upper_limit += 1
84
85 lower = limit - lower_limit
86 upper = upper_limit - limit
87
88 if lower > max_limit and upper > max_limit:
89 cur_limit = limit + max_limit
90 else:
91 if lower < upper:
92 cur_limit = limit - lower
93 else:
94 cur_limit = limit + upper
95
96 if cur_limit and text[cur_limit-1] == ' ':
97 cur_limit -= 1
98
99 return text[:cur_limit] + '...'
100
101 def _summarize(self):
102 # Remove markup
103 self.long_summary = re.sub(r'<[^>]+>', '', self.transformed_text)
104 self.long_summary = re.sub(r'&[^;]+;', '', self.long_summary)
105 # Remove return
106 self.long_summary = re.sub(r'\n', ' ', self.long_summary)
107 self.long_summary = re.sub(r'\r', ' ', self.long_summary)
108 # Remove duplicated spaces
109 self.long_summary = re.sub(r' [ ]+', ' ', self.long_summary)
110 self.long_summary = self.long_summary.strip()
111 self.short_summary = self.long_summary[:]
112
113 self.long_summary = self._wrap(self.long_summary, 100, 5)
114 self.short_summary = self._wrap(self.short_summary, 30, 5)
115
116 def save(self):
117 self.modified_date = datetime.now()
118 self.transformed_text = markdown2.markdown(self.text, extras=['fenced-code-blocks'])
119 self._summarize()
120 s = Search()
121
122 super(Note, self).save()
123
124@receiver(post_save, sender=Note)
125def post_save_note_signal(sender, **kwargs):
126 s = Search()
127 s.edit_note(kwargs['instance'].id)
128
129@receiver(pre_delete, sender=Note)
130def pre_delete_note_signal(sender, **kwargs):
131 s = Search()
132 s.remove_note(kwargs['instance'].id)
133
134def manage_category(user, cat_name):
135 category = None
136 if cat_name:
137 category = Category.objects.filter(name=cat_name)
138 # Create a new one
139 if not category:
140 if len(cat_name) > 50: cat_name = cat_name[:50]
141 category = Category(author=user, name=cat_name)
142 category.save()
143 else:
144 category = category[0]
145 return category

Archive Download this file

Branches

Tags