def test_setup_conversations(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_conversations(user, account_info['conversations']) user_api = vumi_api_for_user(user) [conv1, conv2] = sorted(user_api.active_conversations(), key=lambda c: c.key) self.assertEqual(conv1.key, 'conv1') self.assertEqual(conv1.conversation_type, 'survey') self.assertEqual(conv1.name, 'foo') self.assertEqual(conv1.config, {'foo': 'bar'}) self.assertEqual(list(conv1.extra_endpoints), []) self.assertTrue( 'Conversation conv1 created' in self.command.stdout.getvalue()) self.assertEqual(conv2.key, 'conv2') self.assertEqual(conv2.conversation_type, 'wikipedia') self.assertEqual(conv2.name, 'Wikipedia') self.assertEqual(conv2.config, {}) self.assertEqual(list(conv2.extra_endpoints), ['sms_content']) self.assertTrue( 'Conversation conv2 created' in self.command.stdout.getvalue())
def setup_routers(self, user, routers): user_api = vumi_api_for_user(user) for router_info in routers: router_info = router_info.copy() # So we can modify it. self.router_info.append({ 'account': user.email, 'key': router_info['key'], 'start': router_info.pop('start', True), }) router_key = router_info.pop('key') if user_api.get_router(router_key): self.stderr.write( 'Router %s already exists. Skipping.\n' % ( router_key,)) continue router_type = router_info.pop('router_type') view_def = get_router_view_definition(router_type) config = router_info.pop('config', {}) extra_inbound_endpoints = view_def.get_inbound_endpoints(config) extra_outbound_endpoints = view_def.get_outbound_endpoints(config) batch_id = user_api.api.mdb.batch_start() # We bypass the usual mechanisms so we can set the key ourselves. router = user_api.router_store.routers( router_key, user_account=user_api.user_account_key, router_type=router_type, name=router_info.pop('name'), config=config, extra_inbound_endpoints=extra_inbound_endpoints, extra_outbound_endpoints=extra_outbound_endpoints, batch=batch_id, **router_info) router.save() self.stdout.write('Router %s created\n' % (router.key,))
def process_request(self, request): user = getattr(request, 'user', None) if user is not None and user.is_authenticated(): user_api = vumi_api_for_user(request.user) request.user_api = user_api SessionManager.set_user_account_key( request.session, user_api.user_account_key)
def setup_conversations(self, user, conversations): user_api = vumi_api_for_user(user) for conv_info in conversations: conv_info = conv_info.copy() # So we can modify it. self.conversation_info.append({ 'account': user.email, 'key': conv_info['key'], 'start': conv_info.pop('start', True), # Don't pass to conv. }) conversation_key = conv_info.pop('key') if user_api.get_wrapped_conversation(conversation_key): self.stderr.write( 'Conversation %s already exists. Skipping.\n' % ( conversation_key,)) continue conversation_type = conv_info.pop('conversation_type') view_def = get_conversation_view_definition(conversation_type) config = conv_info.pop('config', {}) batch_id = user_api.api.mdb.batch_start() # We bypass the usual mechanisms so we can set the key ourselves. conv = user_api.conversation_store.conversations( conversation_key, user_account=user_api.user_account_key, conversation_type=conversation_type, name=conv_info.pop('name'), config=config, batch=batch_id, extra_endpoints=view_def.get_endpoints(config), **conv_info) conv.save() self.stdout.write('Conversation %s created\n' % (conv.key,))
def test_setup_conversations(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_conversations(user, account_info['conversations']) user_api = vumi_api_for_user(user) [conv1, conv2] = sorted( user_api.active_conversations(), key=lambda c: c.key) self.assertEqual(conv1.key, 'conv1') self.assertEqual(conv1.conversation_type, 'survey') self.assertEqual(conv1.name, 'foo') self.assertEqual(conv1.config, {'foo': 'bar'}) self.assertEqual(list(conv1.extra_endpoints), []) self.assertTrue( 'Conversation conv1 created' in self.command.stdout.getvalue()) self.assertEqual(conv2.key, 'conv2') self.assertEqual(conv2.conversation_type, 'wikipedia') self.assertEqual(conv2.name, 'Wikipedia') self.assertEqual(conv2.config, {}) self.assertEqual(list(conv2.extra_endpoints), ['sms_content']) self.assertTrue( 'Conversation conv2 created' in self.command.stdout.getvalue())
def handle_validated(self, *args, **options): email_address = options['email-address'] user = get_user_by_email(email_address) user_api = vumi_api_for_user(user) self.show_opt_outs(user_api, email_address)
def handle(self, *args, **options): options = options.copy() for opt in self.LOCAL_OPTIONS: if options.get(opt.dest) is None: value = raw_input("%s: " % (opt.help, )) if value: options[opt.dest] = value else: raise CommandError('Please provide %s:' % (opt.dest, )) command_options = [c for c in self.CONFLICTING_OPTIONS if options[c]] if len(command_options) != 1: raise CommandError('Please provide exactly one of: %s' % (['--%s' % c for c in self.CONFLICTING_OPTIONS], )) user = get_user_by_email(options['email-address']) user_api = vumi_api_for_user(user) if options['show']: return self.handle_show(user_api, options) elif options['clear']: return self.handle_clear(user_api, options) elif options['add']: return self.handle_add(user_api, options) elif options['remove']: return self.handle_remove(user_api, options) raise NotImplementedError('Unknown command.')
def handle(self, *args, **options): options = options.copy() for opt in self.LOCAL_OPTIONS: if options.get(opt.dest) is None: value = raw_input("%s: " % (opt.help,)) if value: options[opt.dest] = value else: raise CommandError('Please provide %s:' % (opt.dest,)) command_options = [c for c in self.CONFLICTING_OPTIONS if options[c]] if len(command_options) != 1: raise CommandError('Please provide exactly one of: %s' % ( ['--%s' % c for c in self.CONFLICTING_OPTIONS],)) user = get_user_by_email(options['email-address']) user_api = vumi_api_for_user(user) if options['show']: return self.handle_show(user_api, options) elif options['clear']: return self.handle_clear(user_api, options) elif options['add']: return self.handle_add(user_api, options) elif options['remove']: return self.handle_remove(user_api, options) raise NotImplementedError('Unknown command.')
def test_setup_routing(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_routing(user, account_info) routing_table = vumi_api_for_user(user).get_routing_table() self.assertEqual(routing_table, RoutingTable({ u'TRANSPORT_TAG:pool1:default0': { u'default': [u'CONVERSATION:survey:conv1', u'default'], }, u'CONVERSATION:survey:conv1': { u'default': [u'TRANSPORT_TAG:pool1:default0', u'default'], }, u'TRANSPORT_TAG:pool1:default1': { u'default': [u'ROUTER:keyword:router1:INBOUND', u'default'], }, u'ROUTER:keyword:router1:INBOUND': { u'default': [u'TRANSPORT_TAG:pool1:default1', u'default'], }, u'ROUTER:keyword:router1:OUTBOUND': { u'default': [u'CONVERSATION:wikipedia:conv2', u'default'], }, u'CONVERSATION:wikipedia:conv2': { u'default': [u'ROUTER:keyword:router1:OUTBOUND', u'default'], }, }))
def process_request(self, request): user = getattr(request, 'user', None) if user is not None and user.is_authenticated(): user_api = vumi_api_for_user(request.user) request.user_api = user_api SessionManager.set_user_account_key(request.session, user_api.user_account_key)
def test_setup_routing(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_routing(user, account_info) routing_table = vumi_api_for_user(user).get_routing_table() self.assertEqual( routing_table, RoutingTable({ u'TRANSPORT_TAG:pool1:default0': { u'default': [u'CONVERSATION:survey:conv1', u'default'], }, u'CONVERSATION:survey:conv1': { u'default': [u'TRANSPORT_TAG:pool1:default0', u'default'], }, u'TRANSPORT_TAG:pool1:default1': { u'default': [u'ROUTER:keyword:router1:INBOUND', u'default'], }, u'ROUTER:keyword:router1:INBOUND': { u'default': [u'TRANSPORT_TAG:pool1:default1', u'default'], }, u'ROUTER:keyword:router1:OUTBOUND': { u'default': [u'CONVERSATION:wikipedia:conv2', u'default'], }, u'CONVERSATION:wikipedia:conv2': { u'default': [u'ROUTER:keyword:router1:OUTBOUND', u'default'], }, }))
def create_user_profile(sender, instance, created, **kwargs): if created: username = instance.get_username() account = get_account_store().new_user(unicode(username)) UserProfile.objects.create(user=instance, user_account=account.key) user_api = vumi_api_for_user(instance) # Enable search for the contact & group stores user_api.contact_store.contacts.enable_search() user_api.contact_store.groups.enable_search()
def test_setup_channels(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_channels(user, account_info['channels']) user_api = vumi_api_for_user(user) self.assertEqual(set([u'pool1:default0', u'pool1:default1']), set(ch.key for ch in user_api.active_channels()))
def enable_application(self, user, account, application_module): user_api = vumi_api_for_user(user) api = user_api.api app_permission = api.account_store.application_permissions( uuid.uuid4().hex, application=application_module) app_permission.save() account.applications.add(app_permission) account.save()
def mk_user_api(self, email_address=None, options=None): if email_address is None and options is None: raise ValueError("email_address or options is required") if email_address is None: if 'email_address' not in options: raise CommandError("--email-address must be specified") email_address = options.get('email_address') user = get_user_by_email(email_address) user_api = vumi_api_for_user(user) return user, user_api
def test_setup_channels(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_channels(user, account_info['channels']) user_api = vumi_api_for_user(user) self.assertEqual( set([u'pool1:default0', u'pool1:default1']), set(ch.key for ch in user_api.active_channels()))
def handle(self, *args, **options): options = options.copy() self.ask_for_options(options, ['email-address', 'contacts-csv']) user = get_user_by_email(options['email-address']) user_api = vumi_api_for_user(user) groups = [g.key for g in user_api.list_groups()] for group in options['groups']: if group not in groups: raise CommandError('Group not found: %s' % (group,)) return self.import_contacts(user_api, options)
def create_permission(self, user, account, tagpool, max_keys): user_api = vumi_api_for_user(user) api = user_api.api if tagpool not in api.tpm.list_pools(): raise CommandError("Tagpool '%s' does not exist" % (tagpool,)) permission = api.account_store.tag_permissions(uuid.uuid4().hex, tagpool=tagpool, max_keys=max_keys) permission.save() account.tagpools.add(permission) account.save()
def test_setup_contact_groups(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_contact_groups(user, account_info['contact_groups']) user_api = vumi_api_for_user(user) [group] = user_api.list_groups() self.assertEqual(group.key, 'group1') self.assertEqual(group.name, 'group1') self.assertTrue( 'Group group1 created' in self.command.stdout.getvalue())
def make_django_user(self, email='*****@*****.**', password='******', first_name="Test", last_name="User", superuser=False): if superuser: user = get_user_model().objects.create_superuser( email=email, password=password) else: user = get_user_model().objects.create_user( email=email, password=password) user.first_name = first_name user.last_name = last_name user.save() user_api = base_utils.vumi_api_for_user(user) return self.get_user_helper(user_api.user_account_key)
def handle_reconcile_cache(self, worker_name, command, account_key, conversation_key): user = get_user_by_account_key(account_key) user_api = vumi_api_for_user(user) conversation = user_api.get_wrapped_conversation(conversation_key) if conversation is None: raise CommandError('Conversation does not exist') return VumiApiCommand.command(worker_name, command, user_account_key=account_key, conversation_key=conversation_key)
def send_user_account_summary(user): user_api = vumi_api_for_user(user) contact_store = user_api.contact_store conv_store = user_api.conversation_store contact_keys = contact_store.list_contacts() uniques = get_uniques(contact_store, contact_keys=contact_keys, plucker=attrgetter('msisdn')) conversation_keys = conv_store.list_conversations() all_conversations = [] bunches = conv_store.conversations.load_all_bunches(conversation_keys) for bunch in bunches: all_conversations.extend([user_api.wrap_conversation(conv) for conv in bunch]) all_conversations.sort(key=(lambda conv: conv.created_at), reverse=True) active_conversations = {} known_types = configured_conversation_types() for conv in all_conversations: conv_list = active_conversations.setdefault( known_types.get(conv.conversation_type, 'Unknown'), []) if conv.get_status() == CONVERSATION_RUNNING: conv_list.append(conv) message_count = get_messages_count(all_conversations) message_count_friendly = dict((known_types.get(conv_type), value) for conv_type, value in message_count.items()) total_messages_sent = sum(conv_type['sent'] for conv_type in message_count.values()) total_messages_received = sum(conv_type['received'] for conv_type in message_count.values()) total_message_count = total_messages_received + total_messages_sent send_mail('Vumi Go Account Summary', render_to_string( 'account/account_summary_mail.txt', { 'all_conversations': all_conversations, 'user': user, 'unique_identifier': 'contact number', 'total_uniques': len(uniques), 'total_contacts': len(contact_keys), 'total_messages_received': total_messages_received, 'total_messages_sent': total_messages_sent, 'total_message_count': total_message_count, 'message_count': message_count, 'message_count_friendly': message_count_friendly, 'active_conversations': active_conversations, }), settings.DEFAULT_FROM_EMAIL, [user.email], fail_silently=False)
def setup_contact_groups(self, user, contact_groups): user_api = vumi_api_for_user(user) for group_info in contact_groups: self.contact_group_info.append({ 'account': user.email, 'key': group_info['key'], 'contacts_csv': group_info['contacts_csv'], }) name = group_info['name'].decode('utf-8') account_key = user_api.user_account_key group = user_api.contact_store.groups( group_info['key'], name=name, user_account=account_key) group.save() self.stdout.write('Group %s created\n' % (group.key,))
def test_setup_account(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) new_user = self.command.setup_account(account_info['account']) user = authenticate(username='******', password='******') self.assertEqual(user, new_user) self.assertTrue(user.is_active) user_api = vumi_api_for_user(user) self.assertEqual(set(user_api.tagpools().pools()), set(['pool1', 'pool2'])) self.assertEqual(set(user_api.applications().keys()), set(['go.apps.bulk_message', 'go.apps.surveys']))
def test_setup_account(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) new_user = self.command.setup_account(account_info['account']) user = authenticate(username='******', password='******') self.assertEqual(user, new_user) self.assertTrue(user.is_active) user_api = vumi_api_for_user(user) self.assertEqual( set(user_api.tagpools().pools()), set(['pool1', 'pool2'])) self.assertEqual( set(user_api.applications().keys()), set(['go.apps.bulk_message', 'go.apps.surveys']))
def print_account(self, index, user, options): output = u"%s. %s\n" % (index, user_details_as_string(user)) self.stdout.write(output.encode(self.encoding)) user_api = vumi_api_for_user(user) if options.get('show-pools'): self.stdout.write(" Pools:\n") user_account = user_api.get_user_account() for tp_bunch in user_account.tagpools.load_all_bunches(): for tp in tp_bunch: self.stdout.write( " %r (max-keys: %s)" % (tp.tagpool, tp.max_keys)) if options.get('show-tags'): self.stdout.write(" Tags:\n") for channel in user_api.active_channels(): self.stdout.write( " (%r, %r)\n" % (channel.tagpool, channel.tag))
def print_account(self, index, user, options): output = u"%s. %s\n" % (index, user_details_as_string(user)) self.stdout.write(output.encode(self.encoding)) user_api = vumi_api_for_user(user) if options.get('show-pools'): self.stdout.write(" Pools:\n") user_account = user_api.get_user_account() for tp_bunch in user_account.tagpools.load_all_bunches(): for tp in tp_bunch: self.stdout.write(" %r (max-keys: %s)" % (tp.tagpool, tp.max_keys)) if options.get('show-tags'): self.stdout.write(" Tags:\n") for channel in user_api.active_channels(): self.stdout.write(" (%r, %r)\n" % (channel.tagpool, channel.tag))
def test_setup_account_objects(self): self.command.setup_tagpools(self.tagpool_file.name) self.command.setup_account_objects(self.account_1_file.name) user = authenticate(username='******', password='******') user_api = vumi_api_for_user(user) def assert_keys(keys, objects): self.assertEqual(set(keys), set(obj.key for obj in objects)) self.assertEqual(set([u'pool1:default0', u'pool1:default1']), set(ch.key for ch in user_api.active_channels())) assert_keys(['router1'], user_api.active_routers()) assert_keys(['conv1', 'conv2'], user_api.active_conversations()) assert_keys(['group1'], user_api.list_groups()) self.assertNotEqual(user_api.get_routing_table(), {})
def test_setup_account_objects(self): self.command.setup_tagpools(self.tagpool_file.name) self.command.setup_account_objects(self.account_1_file.name) user = authenticate(username='******', password='******') user_api = vumi_api_for_user(user) def assert_keys(keys, objects): self.assertEqual(set(keys), set(obj.key for obj in objects)) self.assertEqual( set([u'pool1:default0', u'pool1:default1']), set(ch.key for ch in user_api.active_channels())) assert_keys(['router1'], user_api.active_routers()) assert_keys(['conv1', 'conv2'], user_api.active_conversations()) assert_keys(['group1'], user_api.list_groups()) self.assertNotEqual(user_api.get_routing_table(), {})
def handle(self, *args, **options): options = options.copy() operation = self.get_operation(options, ("list", "create", "create-smart", "delete")) self.ask_for_options(options, ["email-address"]) user = get_user_by_email(options["email-address"]) user_api = vumi_api_for_user(user) if operation == "list": return self.handle_list(user_api, options) elif operation == "create": self.ask_for_options(options, ["group"]) return self.handle_create(user_api, options) elif operation == "create-smart": self.ask_for_options(options, ["group", "query"]) return self.handle_create_smart(user_api, options) elif operation == "delete": self.ask_for_options(options, ["group"]) return self.handle_delete(user_api, options)
def handle(self, *args, **options): options = options.copy() operation = self.get_operation( options, ('list', 'create', 'create-smart', 'delete')) self.ask_for_options(options, ['email-address']) user = get_user_by_email(options['email-address']) user_api = vumi_api_for_user(user) if operation == 'list': return self.handle_list(user_api, options) elif operation == 'create': self.ask_for_options(options, ['group']) return self.handle_create(user_api, options) elif operation == 'create-smart': self.ask_for_options(options, ['group', 'query']) return self.handle_create_smart(user_api, options) elif operation == 'delete': self.ask_for_options(options, ['group']) return self.handle_delete(user_api, options)
def test_setup_routers(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_routers(user, account_info['routers']) user_api = vumi_api_for_user(user) [router1] = user_api.active_routers() self.assertEqual(router1.key, 'router1') self.assertEqual(router1.router_type, 'keyword') self.assertEqual(router1.name, 'foo') self.assertEqual(router1.config, { 'keyword_endpoint_mapping': {'foo': 'keyword_foo'}, }) self.assertEqual(list(router1.extra_inbound_endpoints), []) self.assertEqual( list(router1.extra_outbound_endpoints), ['keyword_foo']) self.assertTrue( 'Router router1 created' in self.command.stdout.getvalue())
def handle_user(self, user, migrator): user_api = vumi_api_for_user(user) all_keys = user_api.conversation_store.list_conversations() conversations = [] for conv_key in all_keys: try: conv = migrator.get_conversation(user_api, conv_key) except ModelMigrationError as e: self.stderr.write("Error migrating conversation %s: %s" % ( conv_key, e.message)) continue if migrator.applies_to(user_api, conv): conversations.append(conv) self.outln( u'%s %s <%s> [%s]\n Migrating %d of %d conversations ...' % ( user.first_name, user.last_name, user.email, user_api.user_account_key, len(conversations), len(all_keys))) for conv in conversations: self.outln(u' Migrating conversation: %s [%s] ...' % (conv.key, conv.name), ending='') migrator.run(user_api, conv) self.outln(u' done.')
def test_setup_routers(self): self.command.setup_tagpools(self.tagpool_file.name) account_info = self.read_yaml(self.account_1_file) user = self.command.setup_account(account_info['account']) self.command.setup_routers(user, account_info['routers']) user_api = vumi_api_for_user(user) [router1] = user_api.active_routers() self.assertEqual(router1.key, 'router1') self.assertEqual(router1.router_type, 'keyword') self.assertEqual(router1.name, 'foo') self.assertEqual(router1.config, { 'keyword_endpoint_mapping': { 'foo': 'keyword_foo' }, }) self.assertEqual(list(router1.extra_inbound_endpoints), []) self.assertEqual(list(router1.extra_outbound_endpoints), ['keyword_foo']) self.assertTrue( 'Router router1 created' in self.command.stdout.getvalue())
def handle_user(self, user, migrator): user_api = vumi_api_for_user(user) all_keys = user_api.conversation_store.list_conversations() conversations = [] for conv_key in all_keys: try: conv = migrator.get_conversation(user_api, conv_key) except ModelMigrationError as e: self.stderr.write("Error migrating conversation %s: %s" % (conv_key, e.message)) continue if migrator.applies_to(user_api, conv): conversations.append(conv) self.outln( u'%s %s <%s> [%s]\n Migrating %d of %d conversations ...' % (user.first_name, user.last_name, user.email, user_api.user_account_key, len(conversations), len(all_keys))) for conv in conversations: self.outln(u' Migrating conversation: %s [%s] ...' % (conv.key, conv.name), ending='') migrator.run(user_api, conv) self.outln(u' done.')
def setup_routing(self, user, account_objects): connectors = {} for conv in account_objects['conversations']: connectors[conv['key']] = GoConnector.for_conversation( conv['conversation_type'], conv['key']) for tag in account_objects['channels']: connectors[tag] = GoConnector.for_transport_tag(*(tag.split(':'))) for router in account_objects['routers']: connectors[router['key'] + ':INBOUND'] = GoConnector.for_router( router['router_type'], router['key'], GoConnector.INBOUND) connectors[router['key'] + ':OUTBOUND'] = GoConnector.for_router( router['router_type'], router['key'], GoConnector.OUTBOUND) rt = RoutingTable() for src, src_ep, dst, dst_ep in account_objects['routing_entries']: rt.add_entry( str(connectors[src]), src_ep, str(connectors[dst]), dst_ep) user_account = vumi_api_for_user(user).get_user_account() user_account.routing_table = rt user_account.save() self.stdout.write('Routing table for %s built\n' % (user.email,))
def handle(self, *args, **options): user = get_user_by_email(options['email_address']) user_api = vumi_api_for_user(user) conversation = user_api.get_wrapped_conversation( options['conversation_key']) if conversation is None: raise CommandError('Conversation does not exist') elif (conversation.conversation_type not in self.allowed_conversation_types): raise CommandError('Conversation is not allowed for an HTTP API') if options.get('create_token'): self.create_token(conversation) elif options.get('remove_token'): self.remove_token(conversation, options['remove_token']) elif options.get('set_message_url'): self.set_message_url(conversation, options['set_message_url']) elif options.get('remove_message_url'): self.remove_message_url(conversation) elif options.get('set_event_url'): self.set_event_url(conversation, options['set_event_url']) elif options.get('remove_event_url'): self.remove_event_url(conversation)
def get_user_api(self, email): return vumi_api_for_user(get_user_by_email(email))
def test_vumi_api_for_user(self): user_api = utils.vumi_api_for_user(self.user) self.assertTrue(isinstance(user_api, VumiUserApi)) self.assertEqual(user_api.user_account_key, self.user.get_profile().user_account)
def get_api(self, user): return vumi_api_for_user(user)
def setup_channels(self, user, channels): user_api = vumi_api_for_user(user) for channel in channels: tag = tuple(channel.split(':')) user_api.acquire_specific_tag(tag) self.stdout.write('Tag %s acquired\n' % (tag,))
def mk_all_user_apis(self): apis = [(user, vumi_api_for_user(user)) for user in get_users()] apis.sort(key=lambda u: u[0].email) return apis