diff --git a/MANIFEST.in b/MANIFEST.in
index 69b3f6a..68d76c8 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,3 @@
include README.rst AUTHORS.txt LICENSE
-recursive-include djrill/templates *.html
recursive-include djrill *.py
prune djrill/tests
diff --git a/README.rst b/README.rst
index 4ef012b..6e0dab3 100644
--- a/README.rst
+++ b/README.rst
@@ -28,7 +28,6 @@ package. It includes:
* Mandrill-specific extensions like tags, metadata, tracking, and MailChimp templates
* Optional support for Mandrill inbound email and other webhook notifications,
via Django signals
-* An optional Django admin interface
Djrill is released under the BSD license. It is tested against Django 1.3--1.8
(including Python 3 with Django 1.6+, and PyPy support with Django 1.5+).
diff --git a/djrill/__init__.py b/djrill/__init__.py
index 92b5432..3f5fb88 100644
--- a/djrill/__init__.py
+++ b/djrill/__init__.py
@@ -1,79 +1,10 @@
from django.conf import settings
-from django.contrib.admin.sites import AdminSite
-from django.utils.text import capfirst
-
-from djrill.exceptions import MandrillAPIError, NotSupportedByMandrillError, removed_in_djrill_2
+from djrill.exceptions import MandrillAPIError, NotSupportedByMandrillError
from ._version import *
+
# This backend was developed against this API endpoint.
# You can override in settings.py, if desired.
MANDRILL_API_URL = getattr(settings, "MANDRILL_API_URL",
"https://mandrillapp.com/api/1.0")
-
-
-class DjrillAdminSite(AdminSite):
- # This was originally adapted from https://github.com/jsocol/django-adminplus.
- # If new versions of Django break DjrillAdminSite, it's worth checking to see
- # whether django-adminplus has dealt with something similar.
-
- def __init__(self, *args, **kwargs):
- removed_in_djrill_2(
- "DjrillAdminSite will be removed in Djrill 2.0. "
- "You should remove references to it from your code. "
- "(All of its data is available in the Mandrill dashboard.)"
- )
- super(DjrillAdminSite, self).__init__(*args, **kwargs)
-
-
- index_template = "djrill/index.html"
- custom_views = []
- custom_urls = []
-
- def register_view(self, path, view, name, display_name=None):
- """Add a custom admin view.
-
- * `path` is the path in the admin where the view will live, e.g.
- http://example.com/admin/somepath
- * `view` is any view function you can imagine.
- * `name` is an optional pretty name for the list of custom views. If
- empty, we'll guess based on view.__name__.
- """
- self.custom_views.append((path, view, name, display_name))
-
- def register_url(self, path, view, name):
- self.custom_urls.append((path, view, name))
-
- def get_urls(self):
- """Add our custom views to the admin urlconf."""
- urls = super(DjrillAdminSite, self).get_urls()
- try:
- from django.conf.urls import include, url
- except ImportError:
- # Django 1.3
- #noinspection PyDeprecation
- from django.conf.urls.defaults import include, url
- for path, view, name, display_name in self.custom_views:
- urls += [
- url(r'^%s$' % path, self.admin_view(view), name=name)
- ]
- for path, view, name in self.custom_urls:
- urls += [
- url(r'^%s$' % path, self.admin_view(view), name=name)
- ]
-
- return urls
-
- def index(self, request, extra_context=None):
- """Make sure our list of custom views is on the index page."""
- if not extra_context:
- extra_context = {}
- custom_list = [(path, display_name if display_name else
- capfirst(view.__name__)) for path, view, name, display_name in
- self.custom_views]
- # Sort views alphabetically.
- custom_list.sort(key=lambda x: x[1])
- extra_context.update({
- 'custom_list': custom_list
- })
- return super(DjrillAdminSite, self).index(request, extra_context)
diff --git a/djrill/admin.py b/djrill/admin.py
deleted file mode 100644
index 0ad70ee..0000000
--- a/djrill/admin.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from django.contrib import admin
-
-from djrill.views import (DjrillIndexView, DjrillSendersListView,
- DjrillTagListView,
- DjrillUrlListView)
-
-# Only try to register Djrill admin views if DjrillAdminSite
-# or django-adminplus is in use
-if hasattr(admin.site,'register_view'):
- admin.site.register_view("djrill/senders/", DjrillSendersListView.as_view(),
- "djrill_senders", "senders")
- admin.site.register_view("djrill/status/", DjrillIndexView.as_view(),
- "djrill_status", "status")
- admin.site.register_view("djrill/tags/", DjrillTagListView.as_view(),
- "djrill_tags", "tags")
- admin.site.register_view("djrill/urls/", DjrillUrlListView.as_view(),
- "djrill_urls", "urls")
diff --git a/djrill/templates/djrill/_status.html b/djrill/templates/djrill/_status.html
deleted file mode 100644
index 6796adc..0000000
--- a/djrill/templates/djrill/_status.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
Tools & Info
-
Status
- {% if status %}
-
Mandrill is UP
- {% else %}
-
Mandrill is DOWN
- {% endif %}
-
diff --git a/djrill/templates/djrill/index.html b/djrill/templates/djrill/index.html
deleted file mode 100644
index 0c268a3..0000000
--- a/djrill/templates/djrill/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "admin/index.html" %}
-
-{% block sidebar %}
- {{ block.super }}
-
- {% if custom_list %}
-
- {% endif %}
-{% endblock %}
diff --git a/djrill/templates/djrill/senders_list.html b/djrill/templates/djrill/senders_list.html
deleted file mode 100644
index df86a9d..0000000
--- a/djrill/templates/djrill/senders_list.html
+++ /dev/null
@@ -1,79 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load admin_list i18n %}
-{% load url from future %}
-{% load cycle from djrill_future %}
-
-{% block extrastyle %}
- {{ block.super }}
-
- {{ media.css }}
- {% if not actions_on_top and not actions_on_bottom %}
-
- {% endif %}
-{% endblock %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ media.js }}
-{% endblock %}
-
-{% block title %} Djrill Senders | {% trans "Django site admin" %}{% endblock %}
-
-{% block bodyclass %}change-list{% endblock %}
-
-{% if not is_popup %}
- {% block breadcrumbs %}
-
- {% endblock %}
-{% endif %}
-
-{% block coltype %}flex{% endblock %}
-
-{% block content %}
-
-
-
- {% block date_hierarchy %}{% endblock %}
-
- {% block filters %}
- {% include "djrill/_status.html" %}
- {% endblock %}
-
- {% block result_list %}
- {% if objects %}
-
-
-
-
- {% for header in objects.0.keys %}
- | {{ header|capfirst }} |
- {% endfor %}
-
-
-
- {% for result in objects %}
-
- {% for item in result.values %}
- | {{ item }} |
- {% endfor %}
-
- {% endfor %}
-
-
-
- {% endif %}
- {% endblock %}
- {% block pagination %}{% endblock %}
-
-
-{% endblock %}
diff --git a/djrill/templates/djrill/status.html b/djrill/templates/djrill/status.html
deleted file mode 100644
index 33dac6f..0000000
--- a/djrill/templates/djrill/status.html
+++ /dev/null
@@ -1,67 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load admin_list i18n %}
-{% load url from future %}
-{% block extrastyle %}
- {{ block.super }}
-
- {{ media.css }}
- {% if not actions_on_top and not actions_on_bottom %}
-
- {% endif %}
-{% endblock %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ media.js }}
-{% if action_form %}{% if actions_on_top or actions_on_bottom %}
-
-{% endif %}{% endif %}
-{% endblock %}
-
-{% block title %} Djrill Status | {% trans "Django site admin" %}{% endblock %}
-
-{% block bodyclass %}change-list{% endblock %}
-
-{% if not is_popup %}
- {% block breadcrumbs %}
-
- {% endblock %}
-{% endif %}
-
-{% block coltype %}flex{% endblock %}
-
-{% block content %}
-
- {% block object-tools %}
- {% endblock %}
-
- {% block search %}{% endblock %}
- {% block date_hierarchy %}{% endblock %}
-
- {% block filters %}{% endblock %}
- {% block pagination %}{% endblock %}
-
- {% for term, value in status.items %}
- - {{ term|capfirst }}
- - {{ value }}
- {% endfor %}
-
-
-
-{% endblock %}
diff --git a/djrill/templates/djrill/tags_list.html b/djrill/templates/djrill/tags_list.html
deleted file mode 100644
index f6fb80f..0000000
--- a/djrill/templates/djrill/tags_list.html
+++ /dev/null
@@ -1,91 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load admin_list i18n %}
-{% load url from future %}
-{% load cycle from djrill_future %}
-
-{% block extrastyle %}
- {{ block.super }}
-
- {{ media.css }}
- {% if not actions_on_top and not actions_on_bottom %}
-
- {% endif %}
-{% endblock %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ media.js }}
-{% endblock %}
-
-{% block title %} Djrill Tags | {% trans "Django site admin" %}{% endblock %}
-
-{% block bodyclass %}change-list{% endblock %}
-
-{% if not is_popup %}
- {% block breadcrumbs %}
-
- {% endblock %}
-{% endif %}
-
-{% block coltype %}flex{% endblock %}
-
-{% block content %}
-
-
-
- {% block search %} {% endblock %}
-
- {% block date_hierarchy %}{% endblock %}
-
- {% block filters %}
- {% include "djrill/_status.html" %}
- {% endblock %}
-
- {% block result_list %}
- {% if objects %}
-
-
-
-
- | Tag |
- ID |
- Sent |
- Opens |
- Clicks |
- Rejects |
- Bounces |
- Complaints |
-
-
-
- {% for result in objects %}
-
- | {{ result.tag }} |
- {{ result.id }} |
- {{ result.sent }} |
- {{ result.opens }} |
- {{ result.clicks }} |
- {{ result.rejects }} |
- {{ result.bounces }} |
- {{ result.complaints }} |
-
- {% endfor %}
-
-
-
- {% endif %}
- {% endblock %}
- {% block pagination %}{% endblock %}
-
-
-{% endblock %}
diff --git a/djrill/templates/djrill/urls_list.html b/djrill/templates/djrill/urls_list.html
deleted file mode 100644
index 71c3e23..0000000
--- a/djrill/templates/djrill/urls_list.html
+++ /dev/null
@@ -1,81 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load admin_list i18n %}
-{% load url from future %}
-{% load cycle from djrill_future %}
-
-{% block extrastyle %}
- {{ block.super }}
-
- {{ media.css }}
- {% if not actions_on_top and not actions_on_bottom %}
-
- {% endif %}
-{% endblock %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ media.js }}
-{% endblock %}
-
-{% block title %} Djrill URLs | {% trans "Django site admin" %}{% endblock %}
-
-{% block bodyclass %}change-list{% endblock %}
-
-{% if not is_popup %}
- {% block breadcrumbs %}
-
- {% endblock %}
-{% endif %}
-
-{% block coltype %}flex{% endblock %}
-
-{% block content %}
-
-
-
- {% block search %}{% endblock %}
-
- {% block date_hierarchy %}{% endblock %}
-
- {% block filters %}
- {% include "djrill/_status.html" %}
- {% endblock %}
-
- {% block result_list %}
- {% if objects %}
-
-
-
-
- {% for header in objects.0.keys %}
- | {{ header|capfirst }} |
- {% endfor %}
-
-
-
- {% for result in objects %}
-
- {% for item in result.values %}
- | {{ item }} |
- {% endfor %}
-
- {% endfor %}
-
-
-
- {% endif %}
- {% endblock %}
- {% block pagination %}{% endblock %}
-
-
-{% endblock %}
diff --git a/djrill/templatetags/__init__.py b/djrill/templatetags/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/djrill/templatetags/djrill_future.py b/djrill/templatetags/djrill_future.py
deleted file mode 100644
index 0555158..0000000
--- a/djrill/templatetags/djrill_future.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Future templatetags library that is also backwards compatible with
-# older versions of Django (so long as Djrill's code is compatible
-# with the future behavior).
-
-from django import template
-
-# Django 1.8 changes autoescape behavior in cycle tag.
-# Djrill has been compatible with future behavior all along.
-try:
- from django.templatetags.future import cycle
-except ImportError:
- from django.template.defaulttags import cycle
-
-
-register = template.Library()
-register.tag(cycle)
diff --git a/djrill/tests/__init__.py b/djrill/tests/__init__.py
index 910905a..c1b7504 100644
--- a/djrill/tests/__init__.py
+++ b/djrill/tests/__init__.py
@@ -1,4 +1,3 @@
-from djrill.tests.test_admin import *
from djrill.tests.test_legacy import *
from djrill.tests.test_mandrill_send import *
from djrill.tests.test_mandrill_send_template import *
diff --git a/djrill/tests/admin_urls.py b/djrill/tests/admin_urls.py
deleted file mode 100644
index c8e5192..0000000
--- a/djrill/tests/admin_urls.py
+++ /dev/null
@@ -1,18 +0,0 @@
-try:
- from django.conf.urls import include, url
-except ImportError:
- # Django 1.3
- from django.conf.urls.defaults import include, url
-
-from django.contrib import admin
-
-from djrill import DjrillAdminSite
-
-# Set up the DjrillAdminSite as suggested in the docs
-
-admin.site = DjrillAdminSite()
-admin.autodiscover()
-
-urlpatterns = [
- url(r'^admin/', include(admin.site.urls)),
-]
diff --git a/djrill/tests/test_admin.py b/djrill/tests/test_admin.py
deleted file mode 100644
index 299cdd7..0000000
--- a/djrill/tests/test_admin.py
+++ /dev/null
@@ -1,155 +0,0 @@
-import sys
-import warnings
-
-from django.test import TestCase
-from django.contrib.auth.models import User
-from django.contrib import admin
-import six
-
-from djrill.exceptions import RemovedInDjrill2
-from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
-from djrill.tests.utils import override_settings
-
-
-def reset_admin_site():
- """Return the Django admin globals to their original state"""
- admin.site = admin.AdminSite() # restore default
- if 'djrill.admin' in sys.modules:
- del sys.modules['djrill.admin'] # force autodiscover to re-import
-
-
-@override_settings(ROOT_URLCONF='djrill.tests.admin_urls')
-class DjrillAdminTests(DjrillBackendMockAPITestCase):
- """Test the Djrill admin site"""
-
- @classmethod
- def setUpClass(cls):
- super(DjrillAdminTests, cls).setUpClass()
- # Other test cases may muck with the Django admin site globals,
- # so return it to the default state before loading test_admin_urls
- reset_admin_site()
-
- def run(self, result=None):
- with warnings.catch_warnings():
- # DjrillAdminSite deprecation is tested in test_legacy
- warnings.filterwarnings('ignore', category=RemovedInDjrill2,
- message="DjrillAdminSite will be removed in Djrill 2.0")
- # We don't care that the `cycle` template tag will be removed in Django 2.0,
- # because we're planning to drop the Djrill admin templates before then.
- warnings.filterwarnings('ignore', category=PendingDeprecationWarning,
- message="Loading the `cycle` tag from the `future` library")
- # We don't care that user messaging was deprecated in Django 1.3
- # (testing artifact of our runtests.py minimal Django settings)
- warnings.filterwarnings('ignore', category=DeprecationWarning,
- message="The user messaging API is deprecated.")
- super(DjrillAdminTests, self).run(result)
-
- def setUp(self):
- super(DjrillAdminTests, self).setUp()
- # Must be authenticated staff to access admin site...
- admin = User.objects.create_user('admin', 'admin@example.com', 'secret')
- admin.is_staff = True
- admin.save()
- self.client.login(username='admin', password='secret')
-
- def test_admin_senders(self):
- self.mock_post.return_value = self.MockResponse(raw=self.mock_api_content['users/senders.json'])
- response = self.client.get('/admin/djrill/senders/')
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "Senders")
- self.assertContains(response, "sender.example@mandrillapp.com")
-
- def test_admin_status(self):
- self.mock_post.return_value = self.MockResponse(raw=self.mock_api_content['users/info.json'])
- response = self.client.get('/admin/djrill/status/')
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "Status")
- self.assertContains(response, "myusername")
-
- def test_admin_tags(self):
- self.mock_post.return_value = self.MockResponse(raw=self.mock_api_content['tags/list.json'])
- response = self.client.get('/admin/djrill/tags/')
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "Tags")
- self.assertContains(response, "example-tag")
-
- def test_admin_urls(self):
- self.mock_post.return_value = self.MockResponse(raw=self.mock_api_content['urls/list.json'])
- response = self.client.get('/admin/djrill/urls/')
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "URLs")
- self.assertContains(response, "example.com/example-page")
-
- def test_admin_index(self):
- """Make sure Djrill section is included in the admin index page"""
- response = self.client.get('/admin/')
- self.assertEqual(response.status_code, 200)
- self.assertContains(response, "Djrill")
-
-
- mock_api_content = {
- 'users/senders.json': six.b('''
- [
- {
- "address": "sender.example@mandrillapp.com",
- "created_at": "2013-01-01 15:30:27",
- "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "clicks": 42, "unique_opens": 42, "unique_clicks": 42
- }
- ]
- '''),
-
- 'users/info.json': six.b('''
- {
- "username": "myusername",
- "created_at": "2013-01-01 15:30:27",
- "public_id": "aaabbbccc112233",
- "reputation": 42,
- "hourly_quota": 42,
- "backlog": 42,
- "stats": {
- "today": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 },
- "last_7_days": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 },
- "last_30_days": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 },
- "last_60_days": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 },
- "last_90_days": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 },
- "all_time": { "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "unique_opens": 42, "clicks": 42, "unique_clicks": 42 }
- }
- }
- '''),
-
- 'tags/list.json': six.b('''
- [
- {
- "tag": "example-tag",
- "reputation": 42,
- "sent": 42, "hard_bounces": 42, "soft_bounces": 42, "rejects": 42, "complaints": 42,
- "unsubs": 42, "opens": 42, "clicks": 42, "unique_opens": 42, "unique_clicks": 42
- }
- ]
- '''),
-
- 'urls/list.json': six.b('''
- [
- {
- "url": "http://example.com/example-page",
- "sent": 42,
- "clicks": 42,
- "unique_clicks": 42
- }
- ]
- '''),
- }
-
-
-class DjrillNoAdminTests(TestCase):
- def test_admin_autodiscover_without_djrill(self):
- """Make sure autodiscover doesn't die without DjrillAdminSite"""
- reset_admin_site()
- admin.autodiscover() # test: this shouldn't error
diff --git a/djrill/tests/test_legacy.py b/djrill/tests/test_legacy.py
index 2bcb68b..3213508 100644
--- a/djrill/tests/test_legacy.py
+++ b/djrill/tests/test_legacy.py
@@ -6,7 +6,7 @@ import warnings
from django.core import mail
from django.test import TestCase
-from djrill import MandrillAPIError, NotSupportedByMandrillError, DjrillAdminSite
+from djrill import MandrillAPIError, NotSupportedByMandrillError
from djrill.exceptions import RemovedInDjrill2
from djrill.mail import DjrillMessage
from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
@@ -19,12 +19,6 @@ class DjrillBackendDeprecationTests(DjrillBackendMockAPITestCase):
reset_warning_registry()
super(DjrillBackendDeprecationTests, self).setUp()
- def test_deprecated_admin_site(self):
- """Djrill 2.0 drops the custom DjrillAdminSite"""
- self.assertWarnsMessage(DeprecationWarning,
- "DjrillAdminSite will be removed in Djrill 2.0",
- DjrillAdminSite)
-
def test_deprecated_json_date_encoding(self):
"""Djrill 2.0+ avoids a blanket JSONDateUTCEncoder"""
# Djrill allows dates for send_at, so shouldn't warn:
diff --git a/djrill/views.py b/djrill/views.py
index 3caaec9..cb226bb 100644
--- a/djrill/views.py
+++ b/djrill/views.py
@@ -2,88 +2,15 @@ from base64 import b64encode
import hashlib
import hmac
import json
-from django import forms
from django.conf import settings
-from django.contrib import messages
from django.core.exceptions import ImproperlyConfigured
-from django.views.generic import TemplateView, View
+from django.views.generic import View
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
-import requests
-
-from djrill import MANDRILL_API_URL, signals
-from .compat import b
-
-
-class DjrillAdminMedia(object):
- def _media(self):
- js = ["js/core.js", "js/jquery.min.js", "js/jquery.init.js"]
-
- return forms.Media(js=["%s%s" % (settings.STATIC_URL, url) for url in js])
- media = property(_media)
-
-
-class DjrillApiMixin(object):
- """
- Simple Mixin to grab the api info from the settings file.
- """
- def __init__(self):
- self.api_key = getattr(settings, "MANDRILL_API_KEY", None)
- self.api_url = MANDRILL_API_URL
-
- if not self.api_key:
- raise ImproperlyConfigured(
- "You have not set your mandrill api key in the settings file.")
-
- def get_context_data(self, **kwargs):
- kwargs = super(DjrillApiMixin, self).get_context_data(**kwargs)
-
- status = False
- req = requests.post("%s/%s" % (self.api_url, "users/ping.json"),
- data={"key": self.api_key})
- if req.status_code == 200:
- status = True
-
- kwargs.update({"status": status})
- return kwargs
-
-
-class DjrillApiJsonObjectsMixin(object):
- """
- Mixin to grab json objects from the api.
- """
- api_uri = None
-
- def get_api_uri(self):
- if self.api_uri is None:
- raise NotImplementedError(
- "%(cls)s is missing an api_uri. "
- "Define %(cls)s.api_uri or override %(cls)s.get_api_uri()." % {
- "cls": self.__class__.__name__
- })
-
- def get_json_objects(self, extra_dict=None, extra_api_uri=None):
- request_dict = {"key": self.api_key}
- if extra_dict:
- request_dict.update(extra_dict)
- payload = json.dumps(request_dict)
- api_uri = extra_api_uri or self.api_uri
- req = requests.post("%s/%s" % (self.api_url, api_uri),
- data=payload)
- if req.status_code == 200:
- return req.text
- messages.error(self.request, self._api_error_handler(req))
- return json.dumps("error")
-
- def _api_error_handler(self, req):
- """
- If the API returns an error, display it to the user.
- """
- content = json.loads(req.text)
- return "Mandrill returned a %d response: %s" % (req.status_code,
- content["message"])
+from djrill import signals
+from djrill.compat import b
class DjrillWebhookSecretMixin(object):
@@ -139,66 +66,6 @@ class DjrillWebhookSignatureMixin(object):
request, *args, **kwargs)
-class DjrillIndexView(DjrillApiMixin, TemplateView):
- template_name = "djrill/status.html"
-
- def get(self, request, *args, **kwargs):
-
- payload = json.dumps({"key": self.api_key})
- req = requests.post("%s/users/info.json" % self.api_url, data=payload)
-
- return self.render_to_response({"status": json.loads(req.text)})
-
-
-class DjrillSendersListView(DjrillAdminMedia, DjrillApiMixin,
- DjrillApiJsonObjectsMixin, TemplateView):
-
- api_uri = "users/senders.json"
- template_name = "djrill/senders_list.html"
-
- def get(self, request, *args, **kwargs):
- objects = self.get_json_objects()
- context = self.get_context_data()
- context.update({
- "objects": json.loads(objects),
- "media": self.media,
- })
-
- return self.render_to_response(context)
-
-
-class DjrillTagListView(DjrillAdminMedia, DjrillApiMixin,
- DjrillApiJsonObjectsMixin, TemplateView):
-
- api_uri = "tags/list.json"
- template_name = "djrill/tags_list.html"
-
- def get(self, request, *args, **kwargs):
- objects = self.get_json_objects()
- context = self.get_context_data()
- context.update({
- "objects": json.loads(objects),
- "media": self.media,
- })
- return self.render_to_response(context)
-
-
-class DjrillUrlListView(DjrillAdminMedia, DjrillApiMixin,
- DjrillApiJsonObjectsMixin, TemplateView):
-
- api_uri = "urls/list.json"
- template_name = "djrill/urls_list.html"
-
- def get(self, request, *args, **kwargs):
- objects = self.get_json_objects()
- context = self.get_context_data()
- context.update({
- "objects": json.loads(objects),
- "media": self.media
- })
- return self.render_to_response(context)
-
-
class DjrillWebhookView(DjrillWebhookSecretMixin, DjrillWebhookSignatureMixin, View):
def head(self, request, *args, **kwargs):
return HttpResponse()
diff --git a/docs/history.rst b/docs/history.rst
index 7d72a31..745b2f7 100644
--- a/docs/history.rst
+++ b/docs/history.rst
@@ -18,19 +18,28 @@ that will change. (Warnings appear in the console when running Django
in debug mode.)
-**Djrill Admin site**
+Breaking Changes in Djrill 2.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Djrill 2.0 will remove the custom Djrill admin site. It duplicates
-information from Mandrill's dashboard, most Djrill users are unaware
-it exists, and it has caused problems tracking Django admin changes.
+Removed DjrillAdminSite
+ Earlier versions of Djrill included a custom Django admin site.
+ The equivalent functionality is available in Mandrill's dashboard.
-Drill 1.4 will report a DeprecationWarning when you try to load
-the `DjrillAdminSite`. You should remove it from your code.
+ You should remove any references to DjrillAdminSite from your
+ :file:`urls.py`. E.g.::
-Also, if you changed Django's :setting:`INSTALLED_APPS` setting to use
-`'django.contrib.admin.apps.SimpleAdminConfig'`, you may be able to
-switch that back to `'django.contrib.admin'` and let Django
-handle the admin.autodiscover() for you.
+ .. code-block:: python
+
+ # Remove these:
+ from djrill import DjrillAdminSite
+ admin.site = DjrillAdminSite()
+
+ Also, on Django 1.7 or later if you had switched your :setting:`INSTALLED_APPS`
+ (in :file:`settings.py`) to use ``'django.contrib.admin.apps.SimpleAdminConfig'``
+ you *may* want to switch back to the default ``'django.contrib.admin'``
+ and remove the call to ``admin.autodiscover()`` in your :file:`urls.py`.
+ (Do this only if you changed to SimpleAdminConfig for Djrill, and aren't
+ creating custom admin sites for any other Django apps you use.)
**Dates in merge data and other attributes**
diff --git a/docs/index.rst b/docs/index.rst
index 4d7c489..91d881a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -36,9 +36,7 @@ Thanks
------
Thanks to the MailChimp team for asking us to build this nifty little app, and to all of Djrill's
-:doc:`contributors `. Also thanks to James Socol on Github for his django-adminplus_
-library that got us off on the right foot for the custom admin views.
+:doc:`contributors `.
Oh, and, of course, Kenneth Reitz for the awesome requests_ library.
.. _requests: http://docs.python-requests.org
-.. _django-adminplus: https://github.com/jsocol/django-adminplus
diff --git a/docs/installation.rst b/docs/installation.rst
index 822a473..743f53b 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -65,47 +65,3 @@ with :ref:`Mandrill-specific sending options `.)
.. _subaccounts: http://help.mandrill.com/entries/25523278-What-are-subaccounts-
-
-
-Admin (Optional)
-----------------
-
-Djrill includes an optional Django admin interface, which allows you to:
-
-* Check the status of your Mandrill API connection
-* See stats on email senders, tags and urls
-
-If you want to enable the Djrill admin interface, edit your base :file:`urls.py`:
-
- .. code-block:: python
- :emphasize-lines: 4,6
-
- ...
- from django.contrib import admin
-
- from djrill import DjrillAdminSite
-
- admin.site = DjrillAdminSite()
- admin.autodiscover()
- ...
-
- urlpatterns = [
- ...
- url(r'^admin/', include(admin.site.urls)),
- ]
-
-If you are on **Django 1.7 or later,** you will also need to change the config used
-by the django.contrib.admin app in your :file:`settings.py`:
-
- .. code-block:: python
- :emphasize-lines: 4
-
- ...
- INSTALLED_APPS = (
- # For Django 1.7+, use SimpleAdminConfig because we'll call autodiscover...
- 'django.contrib.admin.apps.SimpleAdminConfig', # instead of 'django.contrib.admin'
- ...
- 'djrill',
- ...
- )
- ...
diff --git a/runtests.py b/runtests.py
index 9482530..9056905 100644
--- a/runtests.py
+++ b/runtests.py
@@ -3,13 +3,9 @@
# python runtests.py
import sys
-from django import VERSION as django_version
from django.conf import settings
APP = 'djrill'
-ADMIN = 'django.contrib.admin'
-if django_version >= (1, 7):
- ADMIN = 'django.contrib.admin.apps.SimpleAdminConfig'
settings.configure(
DEBUG=True,
@@ -23,7 +19,7 @@ settings.configure(
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
- ADMIN,
+ 'django.contrib.admin',
APP,
),
MIDDLEWARE_CLASSES=(
@@ -33,25 +29,10 @@ settings.configure(
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
TEMPLATES=[
- # Django 1.8 starter-project template settings
- # (needed for test_admin)
+ # Djrill doesn't have any templates, but tests need a TEMPLATES
+ # setting to avoid warnings from the Django 1.8+ test client.
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [
- # insert your TEMPLATE_DIRS here
- ],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.contrib.auth.context_processors.auth',
- 'django.template.context_processors.debug',
- 'django.template.context_processors.i18n',
- 'django.template.context_processors.media',
- 'django.template.context_processors.static',
- 'django.template.context_processors.tz',
- 'django.contrib.messages.context_processors.messages',
- ],
- },
},
],
)