diff --git a/src/comms/admin.py b/src/comms/admin.py index 0d0a200f1c..420d037360 100644 --- a/src/comms/admin.py +++ b/src/comms/admin.py @@ -4,7 +4,7 @@ # from django.contrib import admin -from src.comms.models import ChannelDB, Msg, PlayerChannelConnection, ExternalChannelConnection +from src.comms.models import ChannelDB class MsgAdmin(admin.ModelAdmin): @@ -20,30 +20,8 @@ class MsgAdmin(admin.ModelAdmin): #admin.site.register(Msg, MsgAdmin) -class PlayerChannelConnectionInline(admin.TabularInline): - model = PlayerChannelConnection - fieldsets = ( - (None, { - 'fields':(('db_player', 'db_channel')), - 'classes':('collapse',)}),) - extra = 1 - - -class ExternalChannelConnectionInline(admin.StackedInline): - model = ExternalChannelConnection - fieldsets = ( - (None, { - 'fields': (('db_is_enabled','db_external_key', 'db_channel'), - 'db_external_send_code', 'db_external_config'), - 'classes': ('collapse',) - }),) - extra = 1 - - class ChannelAdmin(admin.ModelAdmin): - inlines = (PlayerChannelConnectionInline, ExternalChannelConnectionInline) - - list_display = ('id', 'db_key', 'db_lock_storage') + list_display = ('id', 'db_key', 'db_lock_storage', "db_subscriptions") list_display_links = ("id", 'db_key') ordering = ["db_key"] search_fields = ['id', 'db_key', 'db_aliases'] @@ -51,7 +29,7 @@ class ChannelAdmin(admin.ModelAdmin): save_on_top = True list_select_related = True fieldsets = ( - (None, {'fields': (('db_key',), 'db_lock_storage',)}), + (None, {'fields': (('db_key',), 'db_lock_storage')}), ) -admin.site.register(ChannelDB, ChannelAdmin) \ No newline at end of file +admin.site.register(ChannelDB, ChannelAdmin) diff --git a/src/comms/managers.py b/src/comms/managers.py index 3581a612c0..3b57607163 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -11,7 +11,6 @@ _PlayerDB = None _ObjectDB = None _ChannelDB = None _SESSIONS = None -_ExternalConnection = None # error class @@ -46,15 +45,13 @@ def dbref(dbref, reqhash=True): def identify_object(inp): "identify if an object is a player or an object; return its database model" # load global stores - global _PlayerDB, _ObjectDB, _ChannelDB, _ExternalConnection + global _PlayerDB, _ObjectDB, _ChannelDB if not _PlayerDB: from src.players.models import PlayerDB as _PlayerDB if not _ObjectDB: from src.objects.models import ObjectDB as _ObjectDB if not _ChannelDB: from src.comms.models import ChannelDB as _ChannelDB - if not _ExternalConnection: - from src.comms.models import ExternalChannelConnection as _ExternalConnection if not inp: return inp, None # try to identify the type @@ -73,8 +70,6 @@ def identify_object(inp): return dbref(obj), "dbref" elif typ == basestring: return obj, "string" - elif typ == _ExternalConnection: - return obj, "external" return obj, None # Something else @@ -114,14 +109,6 @@ def to_object(inp, objtype='player'): return _ChannelDB.objects.get(id=obj) print objtype, inp, obj, typ, type(inp) raise CommError() - elif objtype == 'external': - if typ == 'string': - return _ExternalConnection.objects.get(db_key=inp) - if typ == 'dbref': - return _ExternalConnection.objects.get(id=obj) - print objtype, inp, obj, typ, type(inp) - raise CommError() - # # Msg manager @@ -342,8 +329,6 @@ class ChannelManager(models.Manager): # # PlayerChannelConnection = ContentType.objects.get(app_label="comms", # model="playerchannelconnection").model_class() -# ExternalChannelConnection = ContentType.objects.get(app_label="comms", -# model="externalchannelconnection").model_class() # players = [] # if online: # session_list = _SESSIONS.get_sessions() @@ -456,64 +441,3 @@ class PlayerChannelConnectionManager(models.Manager): conn.delete() -class ExternalChannelConnectionManager(models.Manager): - """ - This ExternalChannelConnectionManager implements methods for searching - and manipulating HelpEntries directly from the database. - - These methods will all return database objects - (or QuerySets) directly. - - An ExternalChannelConnetion describes the connection between an in-game - channel and some external source, such as an IRC or IMC channel. - - Evennia-specific: - get_all_external_connections - has_connection - get_all_connections - create_connection - break_connection - - """ - - def get_all_external_connections(self, external): - "Get all connections that the given as external." - external = to_object(external, objtype='external') - return self.filter(db_external_key=external) - - def has_connection(self, external, channel): - "Checks so a connection exists external<->channel" - external = to_object(external, objtype='external') - channel = to_object(channel, objtype="channel") - if external and channel: - return self.filter(db_external_key=external).filter(db_channel=channel).count() > 0 - return False - - def get_all_connections(self, channel): - """ - Get all connections for a channel - """ - channel = to_object(channel, objtype='channel') - return self.filter(db_channel=channel) - - def create_connection(self, external, channel, config=""): - """ - Connect a external to a channel. external and channel - can be actual objects or keystrings. - """ - channel = to_object(channel, objtype='channel') - if not channel: - raise CommError("NOTFOUND") - new_connection = self.model(db_external_key=external, db_channel=channel, db_external_config=config) - new_connection.save() - return new_connection - - def break_connection(self, external, channel): - "Remove link between external and channel" - external = to_object(external) - channel = to_object(channel, objtype='channel') - if not external or not channel: - raise CommError("NOTFOUND") - conns = self.filter(db_external_key=external).filter(db_channel=channel) - for conn in conns: - conn.delete() diff --git a/src/comms/migrations/0021_auto__del_externalchannelconnection.py b/src/comms/migrations/0021_auto__del_externalchannelconnection.py new file mode 100644 index 0000000000..40d6e0ccac --- /dev/null +++ b/src/comms/migrations/0021_auto__del_externalchannelconnection.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'ExternalChannelConnection' + db.delete_table(u'comms_externalchannelconnection') + + + def backwards(self, orm): + # Adding model 'ExternalChannelConnection' + db.create_table(u'comms_externalchannelconnection', ( + ('db_external_config', self.gf('django.db.models.fields.TextField')(blank=True)), + ('db_external_key', self.gf('django.db.models.fields.CharField')(max_length=128)), + ('db_channel', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['comms.ChannelDB'])), + ('db_is_enabled', self.gf('django.db.models.fields.BooleanField')(default=True)), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('db_external_send_code', self.gf('django.db.models.fields.TextField')(blank=True)), + )) + db.send_create_signal(u'comms', ['ExternalChannelConnection']) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'comms.channeldb': { + 'Meta': {'object_name': 'ChannelDB'}, + 'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_subscriptions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'subscription_set'", 'null': 'True', 'db_index': 'True', 'to': u"orm['players.PlayerDB']"}), + 'db_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'comms.msg': { + 'Meta': {'object_name': 'Msg'}, + 'db_date_sent': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'db_header': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'db_hide_from_channels': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_channels_set'", 'null': 'True', 'to': u"orm['comms.ChannelDB']"}), + 'db_hide_from_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_objects_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_hide_from_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'hide_from_players_set'", 'null': 'True', 'to': u"orm['players.PlayerDB']"}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_message': ('django.db.models.fields.TextField', [], {}), + 'db_receivers_channels': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'channel_set'", 'null': 'True', 'to': u"orm['comms.ChannelDB']"}), + 'db_receivers_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_object_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_receivers_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'receiver_player_set'", 'null': 'True', 'to': u"orm['players.PlayerDB']"}), + 'db_sender_external': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}), + 'db_sender_objects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_object_set'", 'null': 'True', 'db_index': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_sender_players': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'sender_player_set'", 'null': 'True', 'db_index': 'True', 'to': u"orm['players.PlayerDB']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'objects.objectdb': { + 'Meta': {'object_name': 'ObjectDB'}, + 'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}), + 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': u"orm['objects.ObjectDB']"}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}), + 'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'db_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'players.playerdb': { + 'Meta': {'object_name': 'PlayerDB'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'db_attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Attribute']", 'null': 'True', 'symmetrical': 'False'}), + 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_is_bot': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['typeclasses.Tag']", 'null': 'True', 'symmetrical': 'False'}), + 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'typeclasses.attribute': { + 'Meta': {'object_name': 'Attribute'}, + 'db_attrtype': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'db_category': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'db_model': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'db_strvalue': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'typeclasses.tag': { + 'Meta': {'unique_together': "(('db_key', 'db_category'),)", 'object_name': 'Tag', 'index_together': "(('db_key', 'db_category'),)"}, + 'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), + 'db_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}), + 'db_model': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'db_index': 'True'}), + 'db_tagtype': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'db_index': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['comms'] \ No newline at end of file diff --git a/src/comms/models.py b/src/comms/models.py index 5b469a5500..0b9be1964c 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -27,11 +27,10 @@ from src.utils.idmapper.models import SharedMemoryModel from src.comms import managers from src.comms.managers import identify_object from src.locks.lockhandler import LockHandler -from src.utils import logger -from src.utils.utils import to_str, crop, make_iter +from src.utils.utils import crop, make_iter + +__all__ = ("Msg", "TempMsg", "ChannelDB") -__all__ = ("Msg", "TempMsg", "ChannelDB", - "ExternalChannelConnection") _GA = object.__getattribute__ _SA = object.__setattr__ @@ -136,9 +135,6 @@ class Msg(SharedMemoryModel): self.db_sender_players.add(obj) elif typ == 'object': self.db_sender_objects.add(obj) - elif typ == 'external': - self.db_sender_external = "1" - self.extra_senders.append(obj) elif isinstance(typ, basestring): self.db_sender_external = obj elif not obj: @@ -165,9 +161,6 @@ class Msg(SharedMemoryModel): self.db_sender_players.remove(obj) elif typ == 'object': self.db_sender_objects.remove(obj) - elif typ == 'external': - self.extra_senders = [receiver for receiver in - self.extra_senders if receiver != obj] elif isinstance(obj, basestring): self.db_sender_external = obj else: @@ -442,155 +435,3 @@ class ChannelDB(TypedObject): super(ChannelDB, self).delete() from src.comms.channelhandler import CHANNELHANDLER CHANNELHANDLER.update() - - -class ExternalChannelConnection(SharedMemoryModel): - """ - This defines an external protocol connecting to - a channel, while storing some critical info about - that connection. - """ - # evennia channel connecting to - db_channel = models.ForeignKey(ChannelDB, verbose_name='channel', - help_text='which channel this connection is tied to.') - # external connection identifier - db_external_key = models.CharField('external key', max_length=128, - help_text='external connection identifier, used by calling protocol.') - # eval-code to use when the channel tries to send a message - # to the external protocol. - db_external_send_code = models.TextField('executable code', blank=True, - help_text='this is a custom snippet of Python code to connect the external protocol to the in-game channel.') - # custom config for the connection - db_external_config = models.TextField('external config', blank=True, - help_text='configuration options on form understood by connection.') - # activate the connection - db_is_enabled = models.BooleanField('is enabled', default=True, help_text='turn on/off the connection.') - - objects = managers.ExternalChannelConnectionManager() - - class Meta: - verbose_name = "External Channel Connection" - - def __str__(self): - return "%s <-> external %s" % (self.channel.key, self.db_external_key) - - # channel property (wraps db_channel) - #@property - def channel_get(self): - "Getter. Allows for value = self.channel" - return self.db_channel - #@channel.setter - - def channel_set(self, value): - "Setter. Allows for self.channel = value" - self.db_channel = value - self.save() - - #@channel.deleter - def channel_del(self): - "Deleter. Allows for del self.channel. Deletes connection." - self.delete() - channel = property(channel_get, channel_set, channel_del) - - # external_key property (wraps db_external_key) - #@property - def external_key_get(self): - "Getter. Allows for value = self.external_key" - return self.db_external_key - - #@external_key.setter - def external_key_set(self, value): - "Setter. Allows for self.external_key = value" - self.db_external_key = value - self.save() - - #@external_key.deleter - def external_key_del(self): - "Deleter. Allows for del self.external_key. Deletes connection." - self.delete() - external_key = property(external_key_get, external_key_set, external_key_del) - - # external_send_code property (wraps db_external_send_code) - #@property - def external_send_code_get(self): - "Getter. Allows for value = self.external_send_code" - return self.db_external_send_code - - #@external_send_code.setter - def external_send_code_set(self, value): - "Setter. Allows for self.external_send_code = value" - self.db_external_send_code = value - self.save() - - #@external_send_code.deleter - def external_send_code_del(self): - "Deleter. Allows for del self.external_send_code. Deletes connection." - self.db_external_send_code = "" - self.save() - external_send_code = property(external_send_code_get, external_send_code_set, external_send_code_del) - - # external_config property (wraps db_external_config) - #@property - def external_config_get(self): - "Getter. Allows for value = self.external_config" - return self.db_external_config - - #@external_config.setter - def external_config_set(self, value): - "Setter. Allows for self.external_config = value" - self.db_external_config = value - self.save() - - #@external_config.deleter - def external_config_del(self): - "Deleter. Allows for del self.external_config. Deletes connection." - self.db_external_config = "" - self.save() - external_config = property(external_config_get, external_config_set, external_config_del) - - # is_enabled property (wraps db_is_enabled) - #@property - def is_enabled_get(self): - "Getter. Allows for value = self.is_enabled" - return self.db_is_enabled - - #@is_enabled.setter - def is_enabled_set(self, value): - "Setter. Allows for self.is_enabled = value" - self.db_is_enabled = value - self.save() - - #@is_enabled.deleter - def is_enabled_del(self): - "Deleter. Allows for del self.is_enabled. Deletes connection." - self.delete() - is_enabled = property(is_enabled_get, is_enabled_set, is_enabled_del) - - # - # methods - # - - def to_channel(self, message, *args, **kwargs): - "Send external -> channel" - #if 'from_obj' in kwargs and kwargs.pop('from_obj'): - # from_obj = self.external_key - self.channel.msg(message, senders=[self], *args, **kwargs) - - def to_external(self, message, senders=None, from_channel=None): - "Send channel -> external" - - # make sure we are not echoing back our own message to ourselves - # (this would result in a nasty infinite loop) - #print senders - if self in make_iter(senders): #.external_key: - return - - try: - # we execute the code snippet that should make it possible for the - # connection to contact the protocol correctly (as set by the - # protocol). - # Note that the code block has access to the variables here, such - # as message, from_obj and from_channel. - exec(to_str(self.external_send_code)) - except Exception: - logger.log_trace("Channel %s could not send to External %s" % (self.channel, self.external_key))