work on package prep
git-svn-id: https://vault.zeeksgeeks.com/svn/django_aws_ses/trunk@5 ed966f06-d3d6-432b-bc91-693151a5c6b4
This commit is contained in:
parent
6329154ffa
commit
54b5c97ce9
|
@ -11,7 +11,7 @@ from .models import (
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
|
||||||
logger = settings.logger
|
#logger = settings.logger
|
||||||
|
|
||||||
class AwsSesSettingsAdmin(admin.ModelAdmin):
|
class AwsSesSettingsAdmin(admin.ModelAdmin):
|
||||||
model = AwsSesSettings
|
model = AwsSesSettings
|
||||||
|
@ -44,7 +44,7 @@ admin.site.register(SESStat, SESStatAdmin)
|
||||||
|
|
||||||
class AdminEmailListFilter(admin.SimpleListFilter):
|
class AdminEmailListFilter(admin.SimpleListFilter):
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
logger.info('self.value(): %s' % self.value())
|
#logger.info('self.value(): %s' % self.value())
|
||||||
return queryset.filter(email__contains=self.value())
|
return queryset.filter(email__contains=self.value())
|
||||||
|
|
||||||
class BounceRecordAdmin(admin.ModelAdmin):
|
class BounceRecordAdmin(admin.ModelAdmin):
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.dispatch import Signal
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
import sys
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
from . import signals
|
from . import signals
|
||||||
|
@ -91,6 +92,23 @@ class SESBackend(BaseEmailBackend):
|
||||||
"""Sends one or more EmailMessage objects and returns the number of
|
"""Sends one or more EmailMessage objects and returns the number of
|
||||||
email messages sent.
|
email messages sent.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
calling_func = ''
|
||||||
|
try:
|
||||||
|
fcount = 0
|
||||||
|
while sys._getframe(fcount).f_code.co_name in ['send_messages', 'send', 'mail_admins', 'send_mail', 'emit', 'handle']:
|
||||||
|
fcount +=1
|
||||||
|
|
||||||
|
calling_func = sys._getframe(fcount).f_code.co_name
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.info("fcount:%s, called from exception = %s" , (fcount, e))
|
||||||
|
|
||||||
|
logger.info("called from %s" , (calling_func))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("send_messages")
|
logger.info("send_messages")
|
||||||
if not email_messages:
|
if not email_messages:
|
||||||
return
|
return
|
||||||
|
@ -188,6 +206,15 @@ class SESBackend(BaseEmailBackend):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info("Try to send raw email")
|
logger.info("Try to send raw email")
|
||||||
|
#logger.info('message.message().as_string() = %s' % message.message().as_string())
|
||||||
|
logger.info("source = %s" % source)
|
||||||
|
logger.info("message.from_email = %s" % self.dkim_key)
|
||||||
|
logger.info("message.recipients() = %s" % message.recipients())
|
||||||
|
|
||||||
|
logger.info("dkim_key = %s" % self.dkim_key)
|
||||||
|
logger.info("dkim_domain = %s" % self.dkim_domain)
|
||||||
|
logger.info("dkim_selector = %s" % self.dkim_selector)
|
||||||
|
logger.info("dkim_headers = %s" % str(self.dkim_headers))
|
||||||
response = self.connection.send_raw_email(
|
response = self.connection.send_raw_email(
|
||||||
Source=source or message.from_email,
|
Source=source or message.from_email,
|
||||||
Destinations=message.recipients(),
|
Destinations=message.recipients(),
|
||||||
|
|
|
@ -60,7 +60,7 @@ def update_awsses_user(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
AwsSesUserAddon.objects.create(user=instance)
|
AwsSesUserAddon.objects.create(user=instance)
|
||||||
try:
|
try:
|
||||||
instance.AwsSesUserAddon.save()
|
instance.aws_ses.save()
|
||||||
except AwsSesUserAddon.DoesNotExist:
|
except AwsSesUserAddon.DoesNotExist:
|
||||||
AwsSesUserAddon.objects.create(user=instance)
|
AwsSesUserAddon.objects.create(user=instance)
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ class BounceRecord(models.Model):
|
||||||
reporting_mta = models.CharField(max_length=255, blank=True, null=True,)
|
reporting_mta = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
status = models.CharField(max_length=255, blank=True, null=True,)
|
status = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
action = models.CharField(max_length=255, blank=True, null=True,)
|
action = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
feedback_id = models.CharField(max_length=255, blank=True, null=True,)
|
feedback_id = models.TextField(max_length=255, blank=True, null=True,)
|
||||||
diagnostic_code = models.CharField(max_length=255, blank=True, null=True,)
|
diagnostic_code = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
cleared = models.BooleanField(default=False)
|
cleared = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class ComplaintRecord(models.Model):
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
timestamp = models.DateTimeField(auto_now_add=True)
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
sub_type = models.CharField(max_length=255, blank=True, null=True,)
|
sub_type = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
feedback_id = models.CharField(max_length=255, blank=True, null=True,)
|
feedback_id = models.TextField(max_length=255, blank=True, null=True,)
|
||||||
feedback_type = models.CharField(max_length=255, blank=True, null=True,)
|
feedback_type = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -116,8 +116,8 @@ class SendRecord(models.Model):
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
timestamp = models.DateTimeField(auto_now_add=True)
|
||||||
source = models.EmailField()
|
source = models.EmailField()
|
||||||
destination = models.EmailField()
|
destination = models.EmailField()
|
||||||
subject = models.CharField(max_length=255, blank=True, null=True,)
|
subject = models.TextField(max_length=255, blank=True, null=True,)
|
||||||
message_id = models.CharField(max_length=255, blank=True, null=True,)
|
message_id = models.TextField(max_length=255, blank=True, null=True,)
|
||||||
aws_process_time = models.IntegerField()
|
aws_process_time = models.IntegerField()
|
||||||
smtp_response = models.CharField(max_length=255, blank=True, null=True,)
|
smtp_response = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
status = models.CharField(max_length=255, blank=True, null=True,)
|
status = models.CharField(max_length=255, blank=True, null=True,)
|
||||||
|
|
|
@ -5,78 +5,79 @@ import logging
|
||||||
from .models import (
|
from .models import (
|
||||||
AwsSesSettings
|
AwsSesSettings
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
aws_ses_Settings, c = AwsSesSettings.objects.get_or_create(site_id=settings.SITE_ID)
|
||||||
|
except Exception as e:
|
||||||
|
print("AwsSesSettings does not exist: error: %s" % e)
|
||||||
|
else:
|
||||||
|
__all__ = ('ACCESS_KEY', 'SECRET_KEY', 'AWS_SES_REGION_NAME',
|
||||||
|
'AWS_SES_REGION_ENDPOINT', 'AWS_SES_AUTO_THROTTLE',
|
||||||
|
'AWS_SES_RETURN_PATH', 'DKIM_DOMAIN', 'DKIM_PRIVATE_KEY',
|
||||||
|
'DKIM_SELECTOR', 'DKIM_HEADERS', 'TIME_ZONE', 'BASE_DIR',
|
||||||
|
'BOUNCE_LIMIT','SES_BACKEND_DEBUG','SES_BACKEND_DEBUG_LOGFILE_PATH',
|
||||||
|
'SES_BACKEND_DEBUG_LOGFILE_FORMATTER')
|
||||||
|
|
||||||
aws_ses_Settings, c = AwsSesSettings.objects.get_or_create(site_id=settings.SITE_ID)
|
BASE_DIR = getattr(settings, 'BASE_DIR', None)
|
||||||
|
|
||||||
__all__ = ('ACCESS_KEY', 'SECRET_KEY', 'AWS_SES_REGION_NAME',
|
if not BASE_DIR:
|
||||||
'AWS_SES_REGION_ENDPOINT', 'AWS_SES_AUTO_THROTTLE',
|
raise RuntimeError('No BASE_DIR defined in project settings, django_aws_ses requires BASE_DIR to be defined and pointed at your root directory. i.e. BASE_DIR = os.path.dirname(os.path.abspath(__file__))')
|
||||||
'AWS_SES_RETURN_PATH', 'DKIM_DOMAIN', 'DKIM_PRIVATE_KEY',
|
|
||||||
'DKIM_SELECTOR', 'DKIM_HEADERS', 'TIME_ZONE', 'BASE_DIR',
|
|
||||||
'BOUNCE_LIMIT','SES_BACKEND_DEBUG','SES_BACKEND_DEBUG_LOGFILE_PATH',
|
|
||||||
'SES_BACKEND_DEBUG_LOGFILE_FORMATTER')
|
|
||||||
|
|
||||||
BASE_DIR = getattr(settings, 'BASE_DIR', None)
|
DEFAULT_FROM_EMAIL = getattr(settings, 'DEFAULT_FROM_EMAIL', 'no_reply@%s' % aws_ses_Settings.site.domain)
|
||||||
|
|
||||||
if not BASE_DIR:
|
HOME_URL = getattr(settings, 'HOME_URL', '')
|
||||||
raise RuntimeError('No BASE_DIR defined in project settings, django_aws_ses requires BASE_DIR to be defined and pointed at your root directory. i.e. BASE_DIR = os.path.dirname(os.path.abspath(__file__))')
|
|
||||||
|
|
||||||
DEFAULT_FROM_EMAIL = getattr(settings, 'DEFAULT_FROM_EMAIL', 'no_reply@%s' % aws_ses_Settings.site.domain)
|
UNSUBSCRIBE_TEMPLET = getattr(settings, 'UNSUBSCRIBE_TEMPLET', 'django_aws_ses/unsebscribe.html')
|
||||||
|
BASE_TEMPLET = getattr(settings, 'UNSUBSCRIBE_TEMPLET', 'django_aws_ses/base.html')
|
||||||
|
|
||||||
HOME_URL = getattr(settings, 'HOME_URL', '')
|
ACCESS_KEY = aws_ses_Settings.access_key or getattr(settings, 'AWS_SES_ACCESS_KEY_ID',getattr(settings, 'AWS_ACCESS_KEY_ID', None))
|
||||||
|
|
||||||
UNSUBSCRIBE_TEMPLET = getattr(settings, 'UNSUBSCRIBE_TEMPLET', 'django_aws_ses/unsebscribe.html')
|
SECRET_KEY = aws_ses_Settings.secret_key or getattr(settings, 'AWS_SES_SECRET_ACCESS_KEY',getattr(settings, 'AWS_SECRET_ACCESS_KEY', None))
|
||||||
BASE_TEMPLET = getattr(settings, 'UNSUBSCRIBE_TEMPLET', 'django_aws_ses/base.html')
|
|
||||||
|
|
||||||
ACCESS_KEY = aws_ses_Settings.access_key or getattr(settings, 'AWS_SES_ACCESS_KEY_ID',getattr(settings, 'AWS_ACCESS_KEY_ID', None))
|
AWS_SES_REGION_NAME = aws_ses_Settings.region_name or getattr(settings, 'AWS_SES_REGION_NAME',getattr(settings, 'AWS_DEFAULT_REGION', 'us-east-1'))
|
||||||
|
|
||||||
SECRET_KEY = aws_ses_Settings.secret_key or getattr(settings, 'AWS_SES_SECRET_ACCESS_KEY',getattr(settings, 'AWS_SECRET_ACCESS_KEY', None))
|
AWS_SES_REGION_ENDPOINT = aws_ses_Settings.region_endpoint or getattr(settings, 'AWS_SES_REGION_ENDPOINT','email.us-east-1.amazonaws.com')
|
||||||
|
|
||||||
AWS_SES_REGION_NAME = aws_ses_Settings.region_name or getattr(settings, 'AWS_SES_REGION_NAME',getattr(settings, 'AWS_DEFAULT_REGION', 'us-east-1'))
|
AWS_SES_REGION_ENDPOINT_URL = getattr(settings, 'AWS_SES_REGION_ENDPOINT_URL','https://' + AWS_SES_REGION_ENDPOINT)
|
||||||
|
|
||||||
AWS_SES_REGION_ENDPOINT = aws_ses_Settings.region_endpoint or getattr(settings, 'AWS_SES_REGION_ENDPOINT','email.us-east-1.amazonaws.com')
|
AWS_SES_AUTO_THROTTLE = getattr(settings, 'AWS_SES_AUTO_THROTTLE', 0.5)
|
||||||
|
AWS_SES_RETURN_PATH = getattr(settings, 'AWS_SES_RETURN_PATH', None)
|
||||||
|
AWS_SES_CONFIGURATION_SET = getattr(settings, 'AWS_SES_CONFIGURATION_SET', None)
|
||||||
|
|
||||||
AWS_SES_REGION_ENDPOINT_URL = getattr(settings, 'AWS_SES_REGION_ENDPOINT_URL','https://' + AWS_SES_REGION_ENDPOINT)
|
DKIM_DOMAIN = getattr(settings, "DKIM_DOMAIN", None)
|
||||||
|
DKIM_PRIVATE_KEY = getattr(settings, 'DKIM_PRIVATE_KEY', None)
|
||||||
|
DKIM_SELECTOR = getattr(settings, 'DKIM_SELECTOR', 'ses')
|
||||||
|
DKIM_HEADERS = getattr(settings, 'DKIM_HEADERS', ('From', 'To', 'Cc', 'Subject'))
|
||||||
|
|
||||||
AWS_SES_AUTO_THROTTLE = getattr(settings, 'AWS_SES_AUTO_THROTTLE', 0.5)
|
TIME_ZONE = settings.TIME_ZONE
|
||||||
AWS_SES_RETURN_PATH = getattr(settings, 'AWS_SES_RETURN_PATH', None)
|
|
||||||
AWS_SES_CONFIGURATION_SET = getattr(settings, 'AWS_SES_CONFIGURATION_SET', None)
|
|
||||||
|
|
||||||
DKIM_DOMAIN = getattr(settings, "DKIM_DOMAIN", None)
|
VERIFY_BOUNCE_SIGNATURES = getattr(settings, 'AWS_SES_VERIFY_BOUNCE_SIGNATURES', True)
|
||||||
DKIM_PRIVATE_KEY = getattr(settings, 'DKIM_PRIVATE_KEY', None)
|
|
||||||
DKIM_SELECTOR = getattr(settings, 'DKIM_SELECTOR', 'ses')
|
|
||||||
DKIM_HEADERS = getattr(settings, 'DKIM_HEADERS',
|
|
||||||
('From', 'To', 'Cc', 'Subject'))
|
|
||||||
|
|
||||||
TIME_ZONE = settings.TIME_ZONE
|
# Domains that are trusted when retrieving the certificate
|
||||||
|
# used to sign bounce messages.
|
||||||
|
BOUNCE_CERT_DOMAINS = getattr(settings, 'AWS_SNS_BOUNCE_CERT_TRUSTED_DOMAINS', (
|
||||||
|
'amazonaws.com',
|
||||||
|
'amazon.com',
|
||||||
|
))
|
||||||
|
|
||||||
VERIFY_BOUNCE_SIGNATURES = getattr(settings, 'AWS_SES_VERIFY_BOUNCE_SIGNATURES', True)
|
SES_BOUNCE_LIMIT = getattr(settings,'BOUNCE_LIMT', 1)
|
||||||
|
|
||||||
# Domains that are trusted when retrieving the certificate
|
SES_BACKEND_DEBUG = getattr(settings,'SES_BACKEND_DEBUG', False)
|
||||||
# used to sign bounce messages.
|
|
||||||
BOUNCE_CERT_DOMAINS = getattr(settings, 'AWS_SNS_BOUNCE_CERT_TRUSTED_DOMAINS', (
|
|
||||||
'amazonaws.com',
|
|
||||||
'amazon.com',
|
|
||||||
))
|
|
||||||
|
|
||||||
SES_BOUNCE_LIMIT = getattr(settings,'BOUNCE_LIMT', 1)
|
SES_BACKEND_DEBUG_LOGFILE_PATH = getattr(settings,'SES_BACKEND_DEBUG_LOGFILE_PATH', '%s/aws_ses.log' % BASE_DIR)
|
||||||
|
|
||||||
SES_BACKEND_DEBUG = getattr(settings,'SES_BACKEND_DEBUG', False)
|
SES_BACKEND_DEBUG_LOGFILE_FORMATTER = getattr(settings,'SES_BACKEND_DEBUG_LOGFILE_FORMATTER', '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
SES_BACKEND_DEBUG_LOGFILE_PATH = getattr(settings,'SES_BACKEND_DEBUG_LOGFILE_PATH', '%s/aws_ses.log' % BASE_DIR)
|
logger = logging.getLogger('django_aws_ses')
|
||||||
|
# logger.setLevel(logging.WARNING)
|
||||||
SES_BACKEND_DEBUG_LOGFILE_FORMATTER = getattr(settings,'SES_BACKEND_DEBUG_LOGFILE_FORMATTER', '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
if SES_BACKEND_DEBUG:
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
logger = logging.getLogger('django_aws_ses')
|
# create a file handler
|
||||||
# logger.setLevel(logging.WARNING)
|
if SES_BACKEND_DEBUG_LOGFILE_PATH:
|
||||||
if SES_BACKEND_DEBUG:
|
handler = logging.FileHandler(SES_BACKEND_DEBUG_LOGFILE_PATH)
|
||||||
logger.setLevel(logging.INFO)
|
handler.setLevel(logging.INFO)
|
||||||
# create a file handler
|
# create a logging format
|
||||||
if SES_BACKEND_DEBUG_LOGFILE_PATH:
|
formatter = logging.Formatter(SES_BACKEND_DEBUG_LOGFILE_FORMATTER)
|
||||||
handler = logging.FileHandler(SES_BACKEND_DEBUG_LOGFILE_PATH)
|
handler.setFormatter(formatter)
|
||||||
handler.setLevel(logging.INFO)
|
# add the handlers to the logger
|
||||||
# create a logging format
|
logger.addHandler(handler)
|
||||||
formatter = logging.Formatter(SES_BACKEND_DEBUG_LOGFILE_FORMATTER)
|
#logger.info('something we are logging')
|
||||||
handler.setFormatter(formatter)
|
|
||||||
# add the handlers to the logger
|
|
||||||
logger.addHandler(handler)
|
|
||||||
#logger.info('something we are logging')
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.urls import path
|
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
|
|
|
@ -17,7 +17,6 @@ User = get_user_model()
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
from . import signals
|
from . import signals
|
||||||
from . import utils
|
|
||||||
from .models import (
|
from .models import (
|
||||||
BounceRecord,
|
BounceRecord,
|
||||||
ComplaintRecord
|
ComplaintRecord
|
||||||
|
|
|
@ -365,8 +365,8 @@ def handle_bounce(request):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info("error well trying to get_or_create record: %s" % e)
|
logger.info("error well trying to get_or_create record: %s" % e)
|
||||||
logger.info(
|
logger.info(
|
||||||
u'Received delivery notification: messageId: %s, feedbackType: %s',
|
u'Received delivery notification: messageId: %s',
|
||||||
message_id, feedback_type,
|
message_id,
|
||||||
extra={
|
extra={
|
||||||
'notification': notification,
|
'notification': notification,
|
||||||
},
|
},
|
||||||
|
@ -375,7 +375,7 @@ def handle_bounce(request):
|
||||||
signals.delivery_received.send(
|
signals.delivery_received.send(
|
||||||
sender=handle_bounce,
|
sender=handle_bounce,
|
||||||
mail_obj=mail_obj,
|
mail_obj=mail_obj,
|
||||||
delivery_obj=delivery_obj,
|
delivery_obj=send_obj,
|
||||||
raw_message=raw_json,
|
raw_message=raw_json,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
import ast
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from fnmatch import fnmatchcase
|
||||||
|
|
||||||
|
from distutils.util import convert_path
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
|
||||||
|
def read(*path):
|
||||||
|
return open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||||
|
*path)).read()
|
||||||
|
|
||||||
|
# Provided as an attribute, so you can append to these instead
|
||||||
|
# of replicating them:
|
||||||
|
standard_exclude = ["*.py", "*.pyc", "*~", ".*", "*.bak"]
|
||||||
|
standard_exclude_directories = [
|
||||||
|
".*", "CVS", "_darcs", "./build",
|
||||||
|
"./dist", "EGG-INFO", "*.egg-info"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Copied from paste/util/finddata.py
|
||||||
|
def find_package_data(where=".", package="", exclude=standard_exclude,
|
||||||
|
exclude_directories=standard_exclude_directories,
|
||||||
|
only_in_packages=True, show_ignored=False):
|
||||||
|
"""
|
||||||
|
Return a dictionary suitable for use in ``package_data``
|
||||||
|
in a distutils ``setup.py`` file.
|
||||||
|
The dictionary looks like::
|
||||||
|
{"package": [files]}
|
||||||
|
Where ``files`` is a list of all the files in that package that
|
||||||
|
don't match anything in ``exclude``.
|
||||||
|
If ``only_in_packages`` is true, then top-level directories that
|
||||||
|
are not packages won't be included (but directories under packages
|
||||||
|
will).
|
||||||
|
Directories matching any pattern in ``exclude_directories`` will
|
||||||
|
be ignored; by default directories with leading ``.``, ``CVS``,
|
||||||
|
and ``_darcs`` will be ignored.
|
||||||
|
If ``show_ignored`` is true, then all the files that aren't
|
||||||
|
included in package data are shown on stderr (for debugging
|
||||||
|
purposes).
|
||||||
|
Note patterns use wildcards, or can be exact paths (including
|
||||||
|
leading ``./``), and all searching is case-insensitive.
|
||||||
|
"""
|
||||||
|
|
||||||
|
out = {}
|
||||||
|
stack = [(convert_path(where), "", package, only_in_packages)]
|
||||||
|
while stack:
|
||||||
|
where, prefix, package, only_in_packages = stack.pop(0)
|
||||||
|
for name in os.listdir(where):
|
||||||
|
fn = os.path.join(where, name)
|
||||||
|
if os.path.isdir(fn):
|
||||||
|
bad_name = False
|
||||||
|
for pattern in exclude_directories:
|
||||||
|
if (fnmatchcase(name, pattern) or
|
||||||
|
fn.lower() == pattern.lower()):
|
||||||
|
bad_name = True
|
||||||
|
if show_ignored:
|
||||||
|
sys.stderr.write("Directory %s ignored by pattern %s" % (fn, pattern))
|
||||||
|
break
|
||||||
|
if bad_name:
|
||||||
|
continue
|
||||||
|
if os.path.isfile(os.path.join(fn, "__init__.py")) \
|
||||||
|
and not prefix:
|
||||||
|
if not package:
|
||||||
|
new_package = name
|
||||||
|
else:
|
||||||
|
new_package = package + "." + name
|
||||||
|
stack.append((fn, "", new_package, False))
|
||||||
|
else:
|
||||||
|
stack.append((fn, prefix + name + "/", package,
|
||||||
|
only_in_packages))
|
||||||
|
elif package or not only_in_packages:
|
||||||
|
# is a file
|
||||||
|
bad_name = False
|
||||||
|
for pattern in exclude:
|
||||||
|
if (fnmatchcase(name, pattern) or
|
||||||
|
fn.lower() == pattern.lower()):
|
||||||
|
bad_name = True
|
||||||
|
if show_ignored:
|
||||||
|
sys.stderr.write("File %s ignored by pattern %s" % (fn, pattern))
|
||||||
|
break
|
||||||
|
if bad_name:
|
||||||
|
continue
|
||||||
|
out.setdefault(package, []).append(prefix + name)
|
||||||
|
return out
|
||||||
|
|
||||||
|
excluded_directories = standard_exclude_directories + ["example", "tests"]
|
||||||
|
package_data = find_package_data(exclude_directories=excluded_directories)
|
||||||
|
|
||||||
|
DESCRIPTION = "A Django email backend for Amazon's Simple Email Service"
|
||||||
|
|
||||||
|
LONG_DESCRIPTION = None
|
||||||
|
try:
|
||||||
|
LONG_DESCRIPTION = open('README.rst').read()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Parse version
|
||||||
|
_version_re = re.compile(r"VERSION\s+=\s+(.*)")
|
||||||
|
with open("django_aws_ses/__init__.py", "rb") as f:
|
||||||
|
version = ".".join(
|
||||||
|
map(str, ast.literal_eval(_version_re.search(f.read().decode("utf-8")).group(1)))
|
||||||
|
)
|
||||||
|
|
||||||
|
CLASSIFIERS = [
|
||||||
|
'Development Status :: 4 - Beta',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'License :: OSI Approved :: MIT License',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||||
|
'Framework :: Django',
|
||||||
|
'Framework :: Django :: 1.11',
|
||||||
|
'Framework :: Django :: 2.0',
|
||||||
|
'Framework :: Django :: 2.1',
|
||||||
|
'Framework :: Django :: 2.2',
|
||||||
|
'Programming Language :: Python :: 2',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Programming Language :: Python :: 3.5',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
|
]
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='django_aws_ses',
|
||||||
|
version=version,
|
||||||
|
packages=find_packages(exclude=['example', 'tests']),
|
||||||
|
package_data=package_data,
|
||||||
|
python_requires='>=2.7',
|
||||||
|
author='ZeeksGeeks',
|
||||||
|
author_email='development@zeeksgeeks.com',
|
||||||
|
url='https://github.com/django-ses/django-ses',
|
||||||
|
license='MIT',
|
||||||
|
description=DESCRIPTION,
|
||||||
|
long_description=LONG_DESCRIPTION,
|
||||||
|
platforms=['any'],
|
||||||
|
classifiers=CLASSIFIERS,
|
||||||
|
install_requires=["boto3>=1.0.0", "pytz>=2016.10", "future>=0.16.0", "django>1.10"],
|
||||||
|
include_package_data=True,
|
||||||
|
extras_require={
|
||||||
|
'bounce': ['requests<3', 'M2Crypto'],
|
||||||
|
},
|
||||||
|
)
|
Loading…
Reference in New Issue