예제 #1
0
class InboundMessageV3(Model):
    bucket = 'inboundmessage'

    VERSION = 3
    MIGRATOR = InboundMessageMigrator

    # key is message_id
    msg = VumiMessage(TransportUserMessage)
    batches = ManyToMany(BatchVNone)

    # Extra fields for compound indexes
    batches_with_timestamps = ListOf(Unicode(), index=True)
    batches_with_addresses = ListOf(Unicode(), index=True)

    def save(self):
        # We override this method to set our index fields before saving.
        batches_with_timestamps = []
        batches_with_addresses = []
        timestamp = self.msg['timestamp']
        for batch_id in self.batches.keys():
            batches_with_timestamps.append(u"%s$%s" % (batch_id, timestamp))
            batches_with_addresses.append(
                u"%s$%s$%s" % (batch_id, timestamp, self.msg['from_addr']))
        self.batches_with_timestamps = batches_with_timestamps
        self.batches_with_addresses = batches_with_addresses
        return super(InboundMessageV3, self).save()
예제 #2
0
class OutboundMessage(Model):
    VERSION = 5
    MIGRATOR = OutboundMessageMigrator

    # key is message_id
    msg = VumiMessage(TransportUserMessage)
    batches = ManyToMany(Batch)

    # Extra fields for compound indexes
    batches_with_addresses = ListOf(Unicode(), index=True)
    batches_with_addresses_reverse = ListOf(Unicode(), index=True)

    def save(self):
        # We override this method to set our index fields before saving.
        self.batches_with_addresses = []
        self.batches_with_addresses_reverse = []
        timestamp = self.msg['timestamp']
        if not isinstance(timestamp, basestring):
            timestamp = format_vumi_date(timestamp)
        reverse_ts = to_reverse_timestamp(timestamp)
        for batch_id in self.batches.keys():
            self.batches_with_addresses.append(
                u"%s$%s$%s" % (batch_id, timestamp, self.msg['to_addr']))
            self.batches_with_addresses_reverse.append(
                u"%s$%s$%s" % (batch_id, reverse_ts, self.msg['to_addr']))
        return super(OutboundMessage, self).save()
예제 #3
0
 def test_validate(self):
     """
     By default, a ListOf field is a list of Unicode fields.
     """
     listof = ListOf()
     listof.validate([u'foo', u'bar'])
     self.assertRaises(ValidationError, listof.validate,
                       u'this is not a list')
     self.assertRaises(ValidationError, listof.validate, ['a', 2])
     self.assertRaises(ValidationError, listof.validate, [1, 2])
예제 #4
0
 def test_validate(self):
     """
     By default, a ListOf field is a list of Unicode fields.
     """
     listof = ListOf()
     listof.validate([u'foo', u'bar'])
     self.assertRaises(ValidationError, listof.validate,
                       u'this is not a list')
     self.assertRaises(ValidationError, listof.validate, ['a', 2])
     self.assertRaises(ValidationError, listof.validate, [1, 2])
예제 #5
0
 class ComputedValueModel(Model):
     """
     Toy model for ComputedValue tests.
     """
     a = Integer()
     b = Unicode()
     c = ListOf(Unicode())
     a_with_b = ComputedValue(lambda m: u"%s::%s" % (m.a, m.b),
                              Unicode(index=True))
     b_with_a = ComputedValue(lambda m: u"%s::%s" % (m.b, m.a), Unicode())
     a_with_c = ComputedValue(lambda m: [u"%s::%s" % (m.a, c) for c in m.c],
                              ListOf(Unicode(), index=True))
예제 #6
0
class Event(Model):
    VERSION = 2
    MIGRATOR = EventMigrator

    # key is event_id
    event = VumiMessage(TransportEvent)
    message = ForeignKey(OutboundMessage)
    batches = ManyToMany(Batch)

    # Extra fields for compound indexes
    message_with_status = Unicode(index=True, null=True)
    batches_with_statuses_reverse = ListOf(Unicode(), index=True)

    def save(self):
        # We override this method to set our index fields before saving.
        timestamp = self.event['timestamp']
        if not isinstance(timestamp, basestring):
            timestamp = format_vumi_date(timestamp)
        status = self.event['event_type']
        if status == "delivery_report":
            status = "%s.%s" % (status, self.event['delivery_status'])
        self.message_with_status = u"%s$%s$%s" % (self.message.key, timestamp,
                                                  status)
        self.batches_with_statuses_reverse = []
        reverse_ts = to_reverse_timestamp(timestamp)
        for batch_id in self.batches.keys():
            self.batches_with_statuses_reverse.append(
                u"%s$%s$%s" % (batch_id, reverse_ts, status))
        return super(Event, self).save()
예제 #7
0
 def test_validate_listof(self):
     """
     If an explicit subtype is provided, its validation is used.
     """
     comp = ComputedValue(lambda m: NotImplemented, ListOf())
     comp.validate([u'foo', u'bar'])
     self.assertRaises(ValidationError, comp.validate,
                       u'this is not a list')
     self.assertRaises(ValidationError, comp.validate, ['a', 2])
     self.assertRaises(ValidationError, comp.validate, [1, 2])
예제 #8
0
    def test_validate_with_subtype(self):
        """
        If an explicit subtype is provided, its validation is used.
        """
        listof_unicode = ListOf(Unicode())
        listof_unicode.validate([u"a", u"b"])
        self.assertRaises(ValidationError, listof_unicode.validate, [1, 2])

        listof_int = ListOf(Integer())
        listof_int.validate([1, 2])
        self.assertRaises(ValidationError, listof_int.validate, [u"a", u"b"])

        listof_smallint = ListOf(Integer(max=10))
        listof_smallint.validate([1, 2])
        self.assertRaises(
            ValidationError, listof_smallint.validate, [1, 100])
예제 #9
0
class OutboundMessage(Model):
    VERSION = 3
    MIGRATOR = OutboundMessageMigrator

    # key is message_id
    msg = VumiMessage(TransportUserMessage)
    batches = ManyToMany(Batch)

    # Extra fields for compound indexes
    batches_with_timestamps = ListOf(Unicode(), index=True)
    batches_with_addresses = ListOf(Unicode(), index=True)

    def save(self):
        # We override this method to set our index fields before saving.
        batches_with_timestamps = []
        batches_with_addresses = []
        timestamp = format_vumi_date(self.msg['timestamp'])
        for batch_id in self.batches.keys():
            batches_with_timestamps.append(u"%s$%s" % (batch_id, timestamp))
            batches_with_addresses.append(
                u"%s$%s$%s" % (batch_id, timestamp, self.msg['to_addr']))
        self.batches_with_timestamps = batches_with_timestamps
        self.batches_with_addresses = batches_with_addresses
        return super(OutboundMessage, self).save()
예제 #10
0
class Router(Model):
    """A router for sending messages to interesting places."""

    VERSION = 1
    MIGRATOR = None

    user_account = ForeignKey(UserAccount)
    name = Unicode(max_length=255)
    description = Unicode(default=u'')
    router_type = Unicode(index=True)
    config = Json(default=dict)
    extra_inbound_endpoints = ListOf(Unicode())
    extra_outbound_endpoints = ListOf(Unicode())

    created_at = Timestamp(default=datetime.utcnow, index=True)
    archived_at = Timestamp(null=True, index=True)

    archive_status = Unicode(default=ROUTER_ACTIVE, index=True)
    status = Unicode(default=ROUTER_STOPPED, index=True)

    batch = ForeignKey(Batch)

    def active(self):
        return self.archive_status == ROUTER_ACTIVE

    def archived(self):
        return self.archive_status == ROUTER_ARCHIVED

    def starting(self):
        return self.status == ROUTER_STARTING

    def running(self):
        return self.status == ROUTER_RUNNING

    def stopping(self):
        return self.status == ROUTER_STOPPING

    def stopped(self):
        return self.status == ROUTER_STOPPED

    # The following are to keep the implementation of this stuff in the model
    # rather than potentially multiple external places.
    def set_status_starting(self):
        self.status = ROUTER_STARTING

    def set_status_started(self):
        self.status = ROUTER_RUNNING

    def set_status_stopping(self):
        self.status = ROUTER_STOPPING

    def set_status_stopped(self):
        self.status = ROUTER_STOPPED

    def set_status_finished(self):
        self.archive_status = ROUTER_ARCHIVED

    def __unicode__(self):
        return self.name

    def get_inbound_connector(self):
        return GoConnector.for_router(self.router_type, self.key,
                                      GoConnector.INBOUND)

    def get_outbound_connector(self):
        return GoConnector.for_router(self.router_type, self.key,
                                      GoConnector.OUTBOUND)
예제 #11
0
class Batch(Model):
    # key is batch_id
    tags = ListOf(Tag())
    metadata = Dynamic(Unicode())
예제 #12
0
class BatchVNone(Model):
    bucket = 'batch'

    # key is batch_id
    tags = ListOf(Tag())
    metadata = Dynamic(Unicode())
예제 #13
0
 def test_validate(self):
     listof = ListOf()
     listof.validate([u'foo', u'bar'])
     self.assertRaises(ValidationError, listof.validate,
                       u'this is not a list')
     self.assertRaises(ValidationError, listof.validate, ['a', 2])
예제 #14
0
class ListOfModel(Model):
    items = ListOf(Integer())
예제 #15
0
 def test_validate(self):
     listof = ListOf()
     listof.validate([u'foo', u'bar'])
     self.assertRaises(ValidationError, listof.validate,
                       u'this is not a list')
     self.assertRaises(ValidationError, listof.validate, ['a', 2])
예제 #16
0
class Conversation(Model):
    """A conversation with an audience"""

    VERSION = 3
    MIGRATOR = ConversationMigrator

    user_account = ForeignKey(UserAccount)
    name = Unicode(max_length=255)
    description = Unicode(default=u'')
    conversation_type = Unicode(index=True)
    config = Json(default=dict)
    extra_endpoints = ListOf(Unicode())

    created_at = Timestamp(default=datetime.utcnow, index=True)
    archived_at = Timestamp(null=True, index=True)

    archive_status = Unicode(default=CONVERSATION_ACTIVE, index=True)
    status = Unicode(default=CONVERSATION_STOPPED, index=True)

    groups = ManyToMany(ContactGroup)
    batch = ForeignKey(Batch)

    delivery_class = Unicode(null=True)

    def active(self):
        return self.archive_status == CONVERSATION_ACTIVE

    def archived(self):
        return self.archive_status == CONVERSATION_ARCHIVED

    def ended(self):
        # TODO: Get rid of this once the old UI finally goes away.
        return self.archived()

    def starting(self):
        return self.status == CONVERSATION_STARTING

    def running(self):
        return self.status == CONVERSATION_RUNNING

    def stopping(self):
        return self.status == CONVERSATION_STOPPING

    def stopped(self):
        return self.status == CONVERSATION_STOPPED

    def is_draft(self):
        # TODO: Get rid of this once the old UI finally goes away.
        return self.active() and self.status == CONVERSATION_STOPPED

    def get_status(self):
        """Get the status of this conversation.

        Possible values are:

          * CONVERSATION_STARTING
          * CONVERSATION_RUNNING
          * CONVERSATION_STOPPING
          * CONVERSATION_STOPPED

        :rtype: str

        """
        return self.status

    # The following are to keep the implementation of this stuff in the model
    # rather than potentially multiple external places.
    def set_status_starting(self):
        self.status = CONVERSATION_STARTING

    def set_status_started(self):
        self.status = CONVERSATION_RUNNING

    def set_status_stopping(self):
        self.status = CONVERSATION_STOPPING

    def set_status_stopped(self):
        self.status = CONVERSATION_STOPPED

    def set_status_finished(self):
        self.archive_status = CONVERSATION_ARCHIVED

    def add_group(self, group):
        if isinstance(group, ContactGroup):
            self.groups.add(group)
        else:
            self.groups.add_key(group)

    def __unicode__(self):
        return self.name

    def get_contacts_addresses(self, contacts):
        """
        Get the contacts assigned to this group with an address attribute
        that is appropriate for this conversation's delivery_class
        """
        addrs = [contact.addr_for(self.delivery_class) for contact in contacts]
        return [addr for addr in addrs if addr]

    def get_connector(self):
        return GoConnector.for_conversation(self.conversation_type, self.key)
예제 #17
0
 class IndexedListOfModel(Model):
     """
     Toy model for ListOf index tests.
     """
     items = ListOf(Integer(), index=True)
예제 #18
0
 class ListOfModel(Model):
     """
     Toy model for ListOf tests.
     """
     items = ListOf(Integer())
     texts = ListOf(Unicode())
예제 #19
0
    def test_validate_with_subtype(self):
        """
        If an explicit subtype is provided, its validation is used.
        """
        listof_unicode = ListOf(Unicode())
        listof_unicode.validate([u"a", u"b"])
        self.assertRaises(ValidationError, listof_unicode.validate, [1, 2])

        listof_int = ListOf(Integer())
        listof_int.validate([1, 2])
        self.assertRaises(ValidationError, listof_int.validate, [u"a", u"b"])

        listof_smallint = ListOf(Integer(max=10))
        listof_smallint.validate([1, 2])
        self.assertRaises(ValidationError, listof_smallint.validate, [1, 100])