##// END OF EJS Templates
Subscribe to a multiple of users for notifications
neko259 -
r1429:5967a527 default
parent child Browse files
Show More
@@ -143,6 +143,14 b' class SettingsManager:'
143 def thread_is_fav(self, opening_post):
143 def thread_is_fav(self, opening_post):
144 return str(opening_post.id) in self.get_fav_threads()
144 return str(opening_post.id) in self.get_fav_threads()
145
145
146 def get_notification_usernames(self):
147 name_list = self.get_setting(SETTING_USERNAME)
148 if name_list is not None and len(name_list) > 0:
149 return name_list.lower().split(',')
150 else:
151 return list()
152
153
146 class SessionSettingsManager(SettingsManager):
154 class SessionSettingsManager(SettingsManager):
147 """
155 """
148 Session-based settings manager. All settings are saved to the user's
156 Session-based settings manager. All settings are saved to the user's
@@ -1,10 +1,10 b''
1 from boards.abstracts.settingsmanager import get_settings_manager, \
1 from boards.abstracts.settingsmanager import get_settings_manager, \
2 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID, SETTING_IMAGE_VIEWER
2 SETTING_LAST_NOTIFICATION_ID, SETTING_IMAGE_VIEWER
3 from boards.models.user import Notification
3 from boards.models.user import Notification
4
4
5 __author__ = 'neko259'
5 __author__ = 'neko259'
6
6
7 from boards import settings, utils
7 from boards import settings
8 from boards.models import Post, Tag
8 from boards.models import Post, Tag
9
9
10 CONTEXT_SITE_NAME = 'site_name'
10 CONTEXT_SITE_NAME = 'site_name'
@@ -15,7 +15,7 b" CONTEXT_PPD = 'posts_per_day'"
15 CONTEXT_TAGS = 'tags'
15 CONTEXT_TAGS = 'tags'
16 CONTEXT_USER = 'user'
16 CONTEXT_USER = 'user'
17 CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_notifications_count'
17 CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_notifications_count'
18 CONTEXT_USERNAME = 'username'
18 CONTEXT_USERNAMES = 'usernames'
19 CONTEXT_TAGS_STR = 'tags_str'
19 CONTEXT_TAGS_STR = 'tags_str'
20 CONTEXT_IMAGE_VIEWER = 'image_viewer'
20 CONTEXT_IMAGE_VIEWER = 'image_viewer'
21 CONTEXT_HAS_FAV_THREADS = 'has_fav_threads'
21 CONTEXT_HAS_FAV_THREADS = 'has_fav_threads'
@@ -24,16 +24,16 b" CONTEXT_POW_DIFFICULTY = 'pow_difficulty"
24
24
25 def get_notifications(context, request):
25 def get_notifications(context, request):
26 settings_manager = get_settings_manager(request)
26 settings_manager = get_settings_manager(request)
27 username = settings_manager.get_setting(SETTING_USERNAME)
27 usernames = settings_manager.get_notification_usernames()
28 new_notifications_count = 0
28 new_notifications_count = 0
29 if username is not None and len(username) > 0:
29 if usernames is not None:
30 last_notification_id = settings_manager.get_setting(
30 last_notification_id = settings_manager.get_setting(
31 SETTING_LAST_NOTIFICATION_ID)
31 SETTING_LAST_NOTIFICATION_ID)
32
32
33 new_notifications_count = Notification.objects.get_notification_posts(
33 new_notifications_count = Notification.objects.get_notification_posts(
34 username=username, last=last_notification_id).count()
34 usernames=usernames, last=last_notification_id).count()
35 context[CONTEXT_NEW_NOTIFICATIONS_COUNT] = new_notifications_count
35 context[CONTEXT_NEW_NOTIFICATIONS_COUNT] = new_notifications_count
36 context[CONTEXT_USERNAME] = username
36 context[CONTEXT_USERNAMES] = usernames
37
37
38
38
39 def user_and_ui_processor(request):
39 def user_and_ui_processor(request):
@@ -26,6 +26,7 b' POW_HASH_LENGTH = 16'
26 POW_LIFE_MINUTES = 1
26 POW_LIFE_MINUTES = 1
27
27
28 REGEX_TAGS = re.compile(r'^[\w\s\d]+$', re.UNICODE)
28 REGEX_TAGS = re.compile(r'^[\w\s\d]+$', re.UNICODE)
29 REGEX_USERNAMES = re.compile(r'^[\w\s\d,]+$', re.UNICODE)
29
30
30 VETERAN_POSTING_DELAY = 5
31 VETERAN_POSTING_DELAY = 5
31
32
@@ -429,7 +430,7 b' class SettingsForm(NeboardForm):'
429 def clean_username(self):
430 def clean_username(self):
430 username = self.cleaned_data['username']
431 username = self.cleaned_data['username']
431
432
432 if username and not REGEX_TAGS.match(username):
433 if username and not REGEX_USERNAMES.match(username):
433 raise forms.ValidationError(_('Inappropriate characters.'))
434 raise forms.ValidationError(_('Inappropriate characters.'))
434
435
435 return username
436 return username
@@ -23,10 +23,10 b' class Ban(models.Model):'
23
23
24
24
25 class NotificationManager(models.Manager):
25 class NotificationManager(models.Manager):
26 def get_notification_posts(self, username: str, last: int = None):
26 def get_notification_posts(self, usernames: list, last: int = None):
27 i_username = username.lower()
27 lower_names = [username.lower() for username in usernames]
28
28 posts = boards.models.post.Post.objects.filter(
29 posts = boards.models.post.Post.objects.filter(notification__name=i_username)
29 notification__name__in=lower_names).distinct()
30 if last is not None:
30 if last is not None:
31 posts = posts.filter(id__gt=last)
31 posts = posts.filter(id__gt=last)
32 posts = posts.order_by('-id')
32 posts = posts.order_by('-id')
@@ -43,8 +43,8 b''
43 <a href="#" id="fav-panel-btn">{% trans 'favorites' %} <span id="new-fav-post-count"></span></a>
43 <a href="#" id="fav-panel-btn">{% trans 'favorites' %} <span id="new-fav-post-count"></span></a>
44 {% endif %}
44 {% endif %}
45
45
46 {% if username %}
46 {% if usernames %}
47 <a class="right-link link" href="{% url 'notifications' username %}" title="{% trans 'Notifications' %}">
47 <a class="right-link link" href="{% url 'notifications' %}" title="{% trans 'Notifications' %}">
48 {% trans 'Notifications' %}
48 {% trans 'Notifications' %}
49 {% ifnotequal new_notifications_count 0 %}
49 {% ifnotequal new_notifications_count 0 %}
50 (<b>{{ new_notifications_count }}</b>)
50 (<b>{{ new_notifications_count }}</b>)
@@ -5,11 +5,15 b''
5
5
6 {% block head %}
6 {% block head %}
7 <meta name="robots" content="noindex">
7 <meta name="robots" content="noindex">
8 <title>{{ site_name }} - {% trans 'Notifications' %} - {{ notification_username }}</title>
8 <title>{{ site_name }} - {% trans 'Notifications' %} - {{ notification_usernames|join:', ' }}</title>
9 {% endblock %}
9 {% endblock %}
10
10
11 {% block content %}
11 {% block content %}
12 <div class="tag_info"><a href="{% url 'notifications' notification_username %}" class="user-cast">@{{ notification_username }}</a></div>
12 <div class="tag_info">
13 {% for username in notification_usernames %}
14 <a href="{% url 'notifications' username %}" class="user-cast">@{{ username }}</a>
15 {% endfor %}
16 </div>
13
17
14 {% if page %}
18 {% if page %}
15 {% if page.has_previous %}
19 {% if page.has_previous %}
@@ -40,8 +40,6 b' class ViewTest(TestCase):'
40 except NoReverseMatch:
40 except NoReverseMatch:
41 # This view just needs additional arguments
41 # This view just needs additional arguments
42 pass
42 pass
43 except Exception as e:
44 self.fail('Got exception %s at %s view' % (e, view_name))
45 except AttributeError:
43 except AttributeError:
46 # This is normal, some views do not have names
44 # This is normal, some views do not have names
47 pass
45 pass
@@ -78,7 +78,8 b" urlpatterns = patterns('',"
78 url(r'^search/$', BoardSearchView.as_view(), name='search'),
78 url(r'^search/$', BoardSearchView.as_view(), name='search'),
79
79
80 # Notifications
80 # Notifications
81 url(r'^notifications/(?P<username>\w+)$', NotificationView.as_view(), name='notifications'),
81 url(r'^notifications/(?P<username>\w+)/$', NotificationView.as_view(), name='notifications'),
82 url(r'^notifications/$', NotificationView.as_view(), name='notifications'),
82
83
83 # Post preview
84 # Post preview
84 url(r'^preview/$', PostPreviewView.as_view(), name='preview')
85 url(r'^preview/$', PostPreviewView.as_view(), name='preview')
@@ -10,37 +10,40 b" DEFAULT_PAGE = '1'"
10
10
11 TEMPLATE = 'boards/notifications.html'
11 TEMPLATE = 'boards/notifications.html'
12 PARAM_PAGE = 'page'
12 PARAM_PAGE = 'page'
13 PARAM_USERNAME = 'notification_username'
13 PARAM_USERNAMES = 'notification_usernames'
14 REQUEST_PAGE = 'page'
14 REQUEST_PAGE = 'page'
15 RESULTS_PER_PAGE = 10
15 RESULTS_PER_PAGE = 10
16
16
17
17
18 class NotificationView(BaseBoardView):
18 class NotificationView(BaseBoardView):
19
19
20 def get(self, request, username):
20 def get(self, request, username=None):
21 params = self.get_context_data()
21 params = self.get_context_data()
22
22
23 settings_manager = get_settings_manager(request)
23 settings_manager = get_settings_manager(request)
24
24
25 # If we open our notifications, reset the "new" count
25 # If we open our notifications, reset the "new" count
26 my_username = settings_manager.get_setting(SETTING_USERNAME)
26 if username is None:
27
27 notification_usernames = settings_manager.get_notification_usernames()
28 notification_username = username.lower()
28 else:
29 notification_usernames = [username]
29
30
30 posts = Notification.objects.get_notification_posts(
31 posts = Notification.objects.get_notification_posts(
31 username=notification_username)
32 usernames=notification_usernames)
32 if notification_username == my_username:
33
34 if username is None:
33 last = posts.first()
35 last = posts.first()
34 if last is not None:
36 if last is not None:
35 last_id = last.id
37 last_id = last.id
36 settings_manager.set_setting(SETTING_LAST_NOTIFICATION_ID,
38 settings_manager.set_setting(SETTING_LAST_NOTIFICATION_ID,
37 last_id)
39 last_id)
38
40
41
39 paginator = get_paginator(posts, RESULTS_PER_PAGE)
42 paginator = get_paginator(posts, RESULTS_PER_PAGE)
40
43
41 page = int(request.GET.get(REQUEST_PAGE, DEFAULT_PAGE))
44 page = int(request.GET.get(REQUEST_PAGE, DEFAULT_PAGE))
42
45
43 params[PARAM_PAGE] = paginator.page(page)
46 params[PARAM_PAGE] = paginator.page(page)
44 params[PARAM_USERNAME] = notification_username
47 params[PARAM_USERNAMES] = notification_usernames
45
48
46 return render(request, TEMPLATE, params)
49 return render(request, TEMPLATE, params)
General Comments 0
You need to be logged in to leave comments. Login now