<s> from __future__ import absolute_import <EOL> from collections import namedtuple <EOL> import json <EOL> import logging <EOL> import inspect <EOL> import datetime <EOL> import os <EOL> import sys <EOL> import time <EOL> from slackclient import SlackClient <EOL> from . scheduler import Task <EOL> from . import __version__ <EOL> import six <EOL> import yaml <EOL> log = logging . getLogger ( __name__ ) <EOL> Listener = namedtuple ( '<STR_LIT>' , ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> class Gendo ( object ) : <EOL> def __init__ ( self , slack_token = None , settings = None ) : <EOL> self . settings = settings or { } <EOL> self . listeners = [ ] <EOL> self . scheduled_tasks = [ ] <EOL> self . client = SlackClient ( <EOL> slack_token or self . settings . get ( '<STR_LIT>' , { } ) . get ( '<STR_LIT>' ) ) <EOL> self . sleep = self . settings . get ( '<STR_LIT>' , { } ) . get ( '<STR_LIT>' ) or <NUM_LIT:0.5> <EOL> @ classmethod <EOL> def config_from_yaml ( cls , path_to_yaml ) : <EOL> with open ( path_to_yaml , '<STR_LIT:r>' ) as ymlfile : <EOL> settings = yaml . load ( ymlfile ) <EOL> log . info ( "<STR_LIT>" , path_to_yaml ) <EOL> return cls ( settings = settings ) <EOL> def _verify_rule ( self , supplied_rule ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( supplied_rule , six . string_types ) : <EOL> return lambda user , message : supplied_rule in message . lower ( ) <EOL> if not six . callable ( supplied_rule ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> expected = ( '<STR_LIT:user>' , '<STR_LIT:message>' ) <EOL> signature = tuple ( inspect . getargspec ( supplied_rule ) . args ) <EOL> try : <EOL> assert len ( signature ) in ( <NUM_LIT:2> , <NUM_LIT:3> ) <EOL> assert expected == signature or expected == signature [ - <NUM_LIT:2> : ] <EOL> except AssertionError : <EOL> msg = '<STR_LIT>' <EOL> raise ValueError ( msg ) <EOL> return supplied_rule <EOL> def listen_for ( self , rule , ** options ) : <EOL> """<STR_LIT>""" <EOL> rule = self . _verify_rule ( rule ) <EOL> def decorator ( f ) : <EOL> self . add_listener ( rule , f , ** options ) <EOL> return f <EOL> return decorator <EOL> def cron ( self , schedule , ** options ) : <EOL> def decorator ( f ) : <EOL> self . add_cron ( schedule , f , ** options ) <EOL> return f <EOL> return decorator <EOL> def run ( self ) : <EOL> running = True <EOL> if self . client . rtm_connect ( ) : <EOL> while running : <EOL> time . sleep ( self . sleep ) <EOL> now = datetime . datetime . now ( ) <EOL> try : <EOL> data = self . client . rtm_read ( ) <EOL> if data and data [ <NUM_LIT:0> ] . get ( '<STR_LIT:type>' ) == '<STR_LIT:message>' : <EOL> log . debug ( data ) <EOL> user = data [ <NUM_LIT:0> ] . get ( '<STR_LIT:user>' ) <EOL> message = data [ <NUM_LIT:0> ] . get ( '<STR_LIT:text>' ) <EOL> channel = data [ <NUM_LIT:0> ] . get ( '<STR_LIT>' ) <EOL> self . respond ( user , message , channel ) <EOL> for idx , task in enumerate ( self . scheduled_tasks ) : <EOL> if now > task . next_run : <EOL> t = self . scheduled_tasks . pop ( idx ) <EOL> t . run ( ) <EOL> self . add_cron ( t . schedule , t . fn , ** t . options ) <EOL> except ( KeyboardInterrupt , SystemExit ) : <EOL> log . info ( "<STR_LIT>" ) <EOL> running = False <EOL> try : <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> except SystemExit : <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> def respond ( self , user , message , channel ) : <EOL> if not message : <EOL> return <EOL> elif message == '<STR_LIT>' : <EOL> self . speak ( "<STR_LIT>" . format ( __version__ ) , channel ) <EOL> return <EOL> for rule , view_func , options in self . listeners : <EOL> if rule ( user , message ) : <EOL> response = view_func ( user , message , ** options ) <EOL> if response : <EOL> if '<STR_LIT>' in response : <EOL> response = response . replace ( '<STR_LIT>' , <EOL> self . get_user_name ( user ) ) <EOL> self . speak ( response , channel ) <EOL> def add_listener ( self , rule , view_func , ** options ) : <EOL> """<STR_LIT>""" <EOL> if not six . callable ( rule ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if not six . callable ( view_func ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> self . listeners . append ( Listener ( rule , view_func , options ) ) <EOL> def add_cron ( self , schedule , f , ** options ) : <EOL> self . scheduled_tasks . append ( Task ( schedule , f , ** options ) ) <EOL> def speak ( self , message , channel ) : <EOL> self . client . api_call ( "<STR_LIT>" , as_user = "<STR_LIT>" , <EOL> channel = channel , text = message ) <EOL> def get_user_info ( self , user_id ) : <EOL> user = self . client . api_call ( '<STR_LIT>' , user = user_id ) . decode ( '<STR_LIT:utf-8>' ) <EOL> return json . loads ( user ) <EOL> def get_user_name ( self , user_id ) : <EOL> user = self . get_user_info ( user_id ) <EOL> return user . get ( '<STR_LIT:user>' , { } ) . get ( '<STR_LIT:name>' ) </s>
