# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from shellbot import Context
from .base import List
__all__ = [
'List',
'ListFactory',
]
[docs]class ListFactory(object):
"""
Manages named lists
Example::
factory = ListFactory(context=my_context)
factory.configure()
...
my_list = factory.get_list('The Famous Four')
"""
def __init__(self, context=None):
self.context = context if context else Context()
self.lists = {}
[docs] def build_list(self, attributes):
"""
Builds one list
Example in YAML::
- name: The Famous Four
as_command: true
items:
- alice@acme.com
- bob@project.org
- celine@secret.mil
- dude@bangkok.travel
The ``as_command`` parameter is a boolean that indicates if the list
can be used as a shell command. When ``as_command`` is set to true,
the named list appears in the list of shell commands. Members of the
list are added to a channel when the name of the list is submitted to
the shell.
"""
assert isinstance(attributes, dict)
items = attributes.get('items', [])
list = List(items=items)
list.name = attributes.get('name')
list.as_command = attributes.get('as_command', False)
return list
[docs] def get_list(self, name):
"""
Gets a named list
:param name: Name of the target list
:type name: str
:return: an iterator
An empty list is returned when the name is unknown.
Example use case, where an alert is sent to members of a team::
for person in factory.get_list('SupportTeam'):
number = get_phone_number(person)
send_sms(important_message, number)
"""
if name:
name = name.lower() # align across chat devices
return self.lists.get(name, [])
[docs] def list_commands(self):
"""
Lists items that can be invoked as shell commands
:return: an iterator of list names
"""
for name in self.lists.keys():
list = self.lists[name]
if list.as_command:
yield list.name
[docs] def apply_to_list(self, name, apply):
"""
Handles each item of a named list
:param name: designates the list to use
:type name: str
:param apply: the function that is applied to each item
:type apply: callable
This function calls the provided function for each item of a named
list.
For example, you could write an alerting system like this::
def alert(person):
number = get_phone_number(person)
send_sms(important_message, number)
factory.apply_to_list('SupportTeam', alert)
Lambda functions are welcome as well. For example, this can be useful
for the straightforward addition of participants to a given bot::
factory.apply_to_list(name='SupportTeam',
apply=lambda x: my_bot.add_participant(x))
"""
for item in self.get_list(name):
apply(item)