kopia lustrzana https://gitlab.com/marnanel/chapeau
124 wiersze
3.0 KiB
Python
124 wiersze
3.0 KiB
Python
from django.db import models
|
|
from collections import defaultdict
|
|
from .. import PUBLIC_IDS
|
|
import logging
|
|
|
|
logger = logging.getLogger('kepi')
|
|
|
|
FIELD_AUDIENCE = 0x01 # literally "audience"
|
|
FIELD_TO = 0x02
|
|
FIELD_CC = 0x04
|
|
|
|
BLIND = 0x70
|
|
FIELD_BTO = BLIND + FIELD_TO
|
|
FIELD_BCC = BLIND + FIELD_CC
|
|
# the spec doesn't allow for blind audience; idk why
|
|
|
|
FIELD_CHOICES = [
|
|
(FIELD_AUDIENCE, 'audience'),
|
|
(FIELD_TO, 'to'),
|
|
(FIELD_CC, 'cc'),
|
|
(FIELD_BTO, 'bto'),
|
|
(FIELD_BCC, 'bcc'),
|
|
]
|
|
|
|
AUDIENCE_FIELD_NAMES = dict([(v,f) for (f,v) in FIELD_CHOICES])
|
|
AUDIENCE_FIELD_KEYS = set([v for (f,v) in FIELD_CHOICES])
|
|
|
|
class Audience(models.Model):
|
|
|
|
parent = models.ForeignKey(
|
|
'bowler_pub.AcObject',
|
|
on_delete = models.CASCADE,
|
|
)
|
|
|
|
field = models.PositiveSmallIntegerField(
|
|
choices = FIELD_CHOICES,
|
|
)
|
|
|
|
recipient = models.CharField(
|
|
max_length=255,
|
|
)
|
|
|
|
@property
|
|
def blind(self):
|
|
return (self.field & BLIND) != 0
|
|
|
|
def __str__(self):
|
|
return '[%s %12s %s]' % (
|
|
self.parent.id,
|
|
self.get_field_display(),
|
|
self.recipient,
|
|
)
|
|
|
|
@classmethod
|
|
def add_audiences_for(cls, thing,
|
|
field, value):
|
|
|
|
"""
|
|
Add new Audiences for a given Object.
|
|
"value" is a list of strings.
|
|
|
|
This function only adds Audiences of
|
|
a single field type. This is
|
|
deliberately asymmetrical to
|
|
get_audiences_for(), which returns
|
|
all Audiences of all field types.
|
|
The difference is because of
|
|
where it's needed.
|
|
"""
|
|
|
|
if field not in AUDIENCE_FIELD_NAMES:
|
|
raise ValueError('%s is not an audience field' % (
|
|
field,
|
|
))
|
|
|
|
field = AUDIENCE_FIELD_NAMES[field]
|
|
|
|
if value is None:
|
|
value = []
|
|
elif not isinstance(value, list):
|
|
value = [str(value)]
|
|
else:
|
|
value = [str(x) for x in value]
|
|
|
|
for line in value:
|
|
a = cls(
|
|
parent = thing,
|
|
field = field,
|
|
recipient = line,
|
|
)
|
|
a.save()
|
|
|
|
@classmethod
|
|
def get_audiences_for(cls, thing,
|
|
audience_type = None,
|
|
hide_blind = False,
|
|
):
|
|
|
|
result = defaultdict(lambda: [])
|
|
|
|
for a in cls.objects.filter(
|
|
parent=thing,
|
|
):
|
|
|
|
fieldname = a.get_field_display()
|
|
|
|
if audience_type is not None:
|
|
if fieldname!=audience_type:
|
|
continue
|
|
|
|
if hide_blind and a.blind:
|
|
logger.debug('Not counting %s because blind fields are hidden',
|
|
a)
|
|
continue
|
|
|
|
result[fieldname].append(a.recipient)
|
|
|
|
if audience_type is not None:
|
|
result = result[audience_type]
|
|
else:
|
|
result = dict(result)
|
|
|
|
return result
|