From 794676f241a284a2df95b57224aa7f9165f058e0 Mon Sep 17 00:00:00 2001 From: Aslak Knutsen Date: Fri, 1 Mar 2013 18:46:45 +0100 Subject: Update REST API to new KittyStore backend * Move to use APIView as Resource base * Add List Resource to show all lists * Custom serialize Thread, Email and List objects --- hyperkitty/api.py | 105 +++++++++++++++++++++++++++++------------- hyperkitty/templates/api.html | 19 ++++++-- hyperkitty/urls.py | 6 ++- 3 files changed, 93 insertions(+), 37 deletions(-) (limited to 'hyperkitty') diff --git a/hyperkitty/api.py b/hyperkitty/api.py index f7c7431..1160c3d 100644 --- a/hyperkitty/api.py +++ b/hyperkitty/api.py @@ -20,68 +20,111 @@ import json import re -from rest_framework.views import View +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import serializers +from rest_framework.exceptions import ParseError from django.conf.urls import url from django.conf import settings -from django.http import HttpResponseNotModified, HttpResponse from hyperkitty.lib import get_store +from kittystore.storm.model import Email, Thread -class EmailResource(View): +class ListSerializer(serializers.Serializer): + name = serializers.CharField() + display_name = serializers.CharField() + description = serializers.CharField() + +class EmailSerializer(serializers.Serializer): + list_name = serializers.EmailField() + message_id = serializers.CharField() + thread_id = serializers.CharField() + sender_name = serializers.CharField() + sender_email = serializers.EmailField() + subject = serializers.CharField() + in_reply_to = serializers.CharField() + date = serializers.DateTimeField() + +class EmailLinkSerializer(serializers.Serializer): + list_name = serializers.EmailField() + message_id = serializers.CharField() + sender_name = serializers.CharField() + sender_email = serializers.EmailField() + date = serializers.DateTimeField() + +class ThreadSerializer(serializers.Serializer): + thread_id = serializers.CharField() + list_name = serializers.EmailField() + date_active = serializers.DateTimeField() + subject = serializers.CharField() + starting_email = EmailLinkSerializer() + email_ids = serializers.CharField() + participants = serializers.CharField() + + +class ListResource(APIView): + """ Resource used to retrieve lists from the archives using the + REST API. + """ + + def get(self, request): + store = get_store(request) + lists = store.get_lists() + if not lists: + return Response(status=404) + else: + return Response(ListSerializer(lists, many=True).data) + +class EmailResource(APIView): """ Resource used to retrieve emails from the archives using the REST API. """ def get(self, request, mlist_fqdn, messageid): - list_name = mlist_fqdn.split('@')[0] store = get_store(request) - email = store.get_message_by_hash_from_list(list_name, messageid) + email = store.get_message_by_id_from_list(mlist_fqdn, messageid) if not email: - return HttpResponse(status=404) + return Response(status=404) else: - return email + return Response(EmailSerializer(email).data) -class ThreadResource(View): +class ThreadResource(APIView): """ Resource used to retrieve threads from the archives using the REST API. """ def get(self, request, mlist_fqdn, threadid): - list_name = mlist_fqdn.split('@')[0] store = get_store(request) - thread = store.get_thread(list_name, threadid) + thread = store.get_thread(mlist_fqdn, threadid) if not thread: - return HttpResponse(status=404) + return Response(status=404) else: - return thread + return Response(ThreadSerializer(thread).data) -class SearchResource(View): +class SearchResource(APIView): """ Resource used to search the archives using the REST API. """ def get(self, request, mlist_fqdn, field, keyword): - list_name = mlist_fqdn.split('@')[0] - - if field not in ['Subject', 'Content', 'SubjectContent', 'From']: - return HttpResponse(status=404) + fields = ['Subject', 'Content', 'SubjectContent', 'From'] + if field not in fields: + raise ParseError(detail="Unknown field: " + field + ". Supported fields are " + ", ".join(fields)) - regex = '.*%s.*' % keyword - if field == 'SubjectContent': - query_string = {'$or' : [ - {'Subject': re.compile(regex, re.IGNORECASE)}, - {'Content': re.compile(regex, re.IGNORECASE)} - ]} - else: - query_string = {field.capitalize(): - re.compile(regex, re.IGNORECASE)} - - #print query_string, field, keyword store = get_store(request) - threads = store.search_archives(list_name, query_string) + threads = None + if field == 'Subject': + threads = store.search_list_for_subject(mlist_fqdn, keyword) + elif field == 'Content': + threads = store.search_list_for_content(mlist_fqdn, keyword) + elif field == 'SubjectContent': + threads = store.search_list_for_content_subject(mlist_fqdn, keyword) + elif field == 'From': + threads = store.search_list_for_sender(mlist_fqdn, keyword) + if not threads: - return HttpResponse(status=404) + return Response(status=404) else: - return threads + return Response(EmailSerializer(threads, many=True).data) diff --git a/hyperkitty/templates/api.html b/hyperkitty/templates/api.html index 4c4af27..422d6a2 100644 --- a/hyperkitty/templates/api.html +++ b/hyperkitty/templates/api.html @@ -26,14 +26,25 @@ +
+

Lists /api/list/

+

+Using the address /api/list/ you will be able to +retrieve the information known about all the mailing-lists. +

+

For example: + {% url 'api_list' %} + +

+

Emails /api/email/<list name>/<Message-ID>

Using the address /api/email/<list name>/<Message-ID> you will be able to retrieve the information known about a specific email on the specified mailing-list.

-

For example: - {% url 'api_email' mlist_fqdn='devel@fp.o' hashid='13129854572893334' %} +

For example: + {% url 'api_email' mlist_fqdn='devel@fp.o' messageid='13129854572893334' %}

@@ -43,7 +54,7 @@ retrieve the information known about a specific email on the specified mailing-l Using the address /api/thread/<list name>/<Message-ID> you will be able to retrieve the all the email for a specific thread on the specified mailing-list.

-

For example: +

For example: {% url 'api_thread' mlist_fqdn='devel@fp.o' threadid='13129854572893334' %}

@@ -61,7 +72,7 @@ search for all emails of the specified mailing-list containing the provided keyw
  • Content
  • SubjectContent
  • -

    For example: +

    For example: {% url 'api_search' mlist_fqdn='devel@fp.o' field='From' keyword='pingoured' %}

    diff --git a/hyperkitty/urls.py b/hyperkitty/urls.py index 887c54f..1a2e945 100644 --- a/hyperkitty/urls.py +++ b/hyperkitty/urls.py @@ -23,7 +23,7 @@ from django.conf.urls import patterns, include, url from django.conf import settings from django.views.generic.base import TemplateView -from api import EmailResource, ThreadResource, SearchResource +from api import ListResource, EmailResource, ThreadResource, SearchResource from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.auth.views import login as login_view @@ -93,7 +93,9 @@ urlpatterns = patterns('hyperkitty.views', # REST API url(r'^api/$', TemplateView.as_view(template_name="api.html")), - url(r'^api/email\/(?P[^/@]+@[^/@]+)\/(?P.*)/', + url(r'^api/list\/', + ListResource.as_view(), name="api_list"), + url(r'^api/email\/(?P[^/@]+@[^/@]+)\/(?P.*)/', EmailResource.as_view(), name="api_email"), url(r'^api/thread\/(?P[^/@]+@[^/@]+)\/(?P.*)/', ThreadResource.as_view(), name="api_thread"), -- cgit