diff options
author | Adolfo Fitoria <adolfo.fitoria@gmail.com> | 2012-10-02 09:58:07 -0600 |
---|---|---|
committer | Adolfo Fitoria <adolfo.fitoria@gmail.com> | 2012-10-02 10:40:25 -0600 |
commit | 2a398269923b779b63ca8432b6d98dc2ae6c6a50 (patch) | |
tree | 3b946679a96442d2b0d3081a40624db124a7c1a9 /group_messaging/views.py | |
parent | f1eda1494b753b052c82811419aff8380520ec85 (diff) | |
parent | 8559f348eab0f59aa32d037a43d4a730112bab3c (diff) | |
download | askbot-2a398269923b779b63ca8432b6d98dc2ae6c6a50.tar.gz askbot-2a398269923b779b63ca8432b6d98dc2ae6c6a50.tar.bz2 askbot-2a398269923b779b63ca8432b6d98dc2ae6c6a50.zip |
Merge branch 'master' into haystack
Conflicts:
askbot/models/__init__.py
askbot/models/question.py
askbot/setup_templates/settings.py
askbot/setup_templates/settings.py.mustache
askbot/tests/__init__.py
askbot/tests/badge_tests.py
askbot/tests/db_api_tests.py
askbot/views/commands.py
askbot/views/readers.py
askbot/views/users.py
askbot/views/writers.py
Diffstat (limited to 'group_messaging/views.py')
-rw-r--r-- | group_messaging/views.py | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/group_messaging/views.py b/group_messaging/views.py new file mode 100644 index 00000000..289961ff --- /dev/null +++ b/group_messaging/views.py @@ -0,0 +1,214 @@ +"""semi-views for the `group_messaging` application +These are not really views - rather context generator +functions, to be used separately, when needed. + +For example, some other application can call these +in order to render messages within the page. + +Notice that :mod:`urls` module decorates all these functions +and turns them into complete views +""" +import copy +import datetime +from coffin.template.loader import get_template +from django.contrib.auth.models import User +from django.forms import IntegerField +from django.http import HttpResponse +from django.http import HttpResponseNotAllowed +from django.http import HttpResponseForbidden +from django.utils import simplejson +from group_messaging.models import Message +from group_messaging.models import SenderList +from group_messaging.models import LastVisitTime +from group_messaging.models import get_personal_group_by_user_id +from group_messaging.models import get_personal_groups_for_users + +class InboxView(object): + """custom class-based view + to be used for pjax use and for generation + of content in the traditional way, where + the only the :method:`get_context` would be used. + """ + template_name = None #used only for the "GET" method + http_method_names = ('GET', 'POST') + + def render_to_response(self, context, template_name=None): + """like a django's shortcut, except will use + template_name from self, if `template_name` is not given. + Also, response is packaged as json with an html fragment + for the pjax consumption + """ + if template_name is None: + template_name = self.template_name + template = get_template(template_name) + html = template.render(context) + json = simplejson.dumps({'html': html, 'success': True}) + return HttpResponse(json, mimetype='application/json') + + + def get(self, request, *args, **kwargs): + """view function for the "GET" method""" + context = self.get_context(request, *args, **kwargs) + return self.render_to_response(context) + + def post(self, request, *args, **kwargs): + """view function for the "POST" method""" + pass + + def dispatch(self, request, *args, **kwargs): + """checks that the current request method is allowed + and calls the corresponding view function""" + if request.method not in self.http_method_names: + return HttpResponseNotAllowed() + view_func = getattr(self, request.method.lower()) + return view_func(request, *args, **kwargs) + + def get_context(self, request, *args, **kwargs): + """Returns the context dictionary for the "get" + method only""" + return {} + + def as_view(self): + """returns the view function - for the urls.py""" + def view_function(request, *args, **kwargs): + """the actual view function""" + if request.user.is_authenticated() and request.is_ajax(): + view_method = getattr(self, request.method.lower()) + return view_method(request, *args, **kwargs) + else: + return HttpResponseForbidden() + + return view_function + + +class NewThread(InboxView): + """view for creation of new thread""" + http_method_list = ('POST',) + + def post(self, request): + """creates a new thread on behalf of the user + response is blank, because on the client side we just + need to go back to the thread listing view whose + content should be cached in the client' + """ + usernames = request.POST['to_usernames'] + usernames = map(lambda v: v.strip(), usernames.split(',')) + users = User.objects.filter(username__in=usernames) + + missing = copy.copy(usernames) + for user in users: + if user.username in missing: + missing.remove(user.username) + + result = dict() + if missing: + result['success'] = False + result['missing_users'] = missing + else: + recipients = get_personal_groups_for_users(users) + message = Message.objects.create_thread( + sender=request.user, + recipients=recipients, + text=request.POST['text'] + ) + result['success'] = True + result['message_id'] = message.id + return HttpResponse(simplejson.dumps(result), mimetype='application/json') + + +class PostReply(InboxView): + """view to create a new response""" + http_method_list = ('POST',) + + def post(self, request): + parent_id = IntegerField().clean(request.POST['parent_id']) + parent = Message.objects.get(id=parent_id) + message = Message.objects.create_response( + sender=request.user, + text=request.POST['text'], + parent=parent + ) + last_visit = LastVisitTime.objects.get( + message=message.root, + user=request.user + ) + last_visit.at = datetime.datetime.now() + last_visit.save() + return self.render_to_response( + {'post': message, 'user': request.user}, + template_name='group_messaging/stored_message.html' + ) + +class ThreadsList(InboxView): + """shows list of threads for a given user""" + template_name = 'group_messaging/threads_list.html' + http_method_list = ('GET',) + + def get_context(self, request): + """returns thread list data""" + #get threads and the last visit time + threads = Message.objects.get_threads_for_user(request.user) + + sender_id = IntegerField().clean(request.GET.get('sender_id', '-1')) + if sender_id != -1: + threads = threads.filter(sender__id=sender_id) + + #for each thread we need to know if there is something + #unread for the user - to mark "new" threads as bold + threads_data = dict() + for thread in threads: + thread_data = dict() + #determine status + thread_data['status'] = 'new' + #determine the senders info + senders_names = thread.senders_info.split(',') + if request.user.username in senders_names: + senders_names.remove(request.user.username) + thread_data['senders_info'] = ', '.join(senders_names) + thread_data['thread'] = thread + threads_data[thread.id] = thread_data + + last_visit_times = LastVisitTime.objects.filter( + user=request.user, + message__in=threads + ) + for last_visit in last_visit_times: + thread_data = threads_data[last_visit.message_id] + if thread_data['thread'].last_active_at <= last_visit.at: + thread_data['status'] = 'seen' + + #after we have all the data - update the last visit time + last_visit_times.update(at=datetime.datetime.now()) + return {'threads': threads, 'threads_data': threads_data} + + +class SendersList(InboxView): + """shows list of senders for a user""" + template_name = 'group_messaging/senders_list.html' + http_method_names = ('GET',) + + def get_context(self, request): + """get data about senders for the user""" + senders = SenderList.objects.get_senders_for_user(request.user) + senders = senders.values('id', 'username') + return {'senders': senders} + + +class ThreadDetails(InboxView): + """shows entire thread in the unfolded form""" + template_name = 'group_messaging/thread_details.html' + http_method_names = ('GET',) + + def get_context(self, request, thread_id=None): + """shows individual thread""" + #todo: assert that current thread is the root + root = Message.objects.get(id=thread_id) + responses = Message.objects.filter(root__id=thread_id) + last_visit, created = LastVisitTime.objects.get_or_create( + message=root, + user=request.user + ) + if created is False: + last_visit.at = datetime.datetime.now() + last_visit.save() + return {'root_message': root, 'responses': responses, 'request': request} |