Exemple #1
0
 def __init__(self):
     self.api_client = ApiClient()
     self.api_headers = {
         'Accept': 'application/json',
         'Authorization': self.get_auth_value()
     }
     self.zipcode_re = re.compile(r'^tacome\s+(\d{5})\s*$')
Exemple #2
0
def test_catme_invoke_calls_api_client_fetch_text_is_none():
    api_client = ApiClient()
    api_client.fetch = MagicMock(return_value=[{"name": "foo"}])
    catme = CatMe()
    catme.api_client = api_client
    text, attachments = catme.invoke("catme", "fakeuser")
    assert text is None
Exemple #3
0
def test_action_telljoke_calls_api_client_fetch():
    joke = 'ha ha, great joke!'
    cc_bot = CCBot()
    api_client = ApiClient()
    api_client.fetch_raw = MagicMock(return_value=joke)
    cc_bot.api_client = api_client
    response = cc_bot.action_telljoke(None)
    assert response == joke
Exemple #4
0
def test_goatme_invoke_calls_api_client_fetch_returns_url_from_link_if_no_images_array(
):
    api_client = ApiClient()
    api_client.fetch = MagicMock(return_value={'data': [{'link': 'test_url'}]})
    goat_me = GoatMe()
    goat_me.imgur_key = "fake_imgur_key"
    goat_me.api_client = api_client
    text, attachments = goat_me.invoke("goatme", "fakeuser")
    assert attachments == [{'image_url': 'test_url', 'title': 'test_url'}]
Exemple #5
0
def test_catme_invoke_calls_api_client_fetch_returns_edgecats_url():
    api_client = ApiClient()
    api_client.fetch = MagicMock(return_value=[{"name": "foo"}])
    catme = CatMe()
    catme.api_client = api_client
    text, attachments = catme.invoke("catme", "fakeuser")
    assert attachments == [{
        "title": "http://edgecats.net/cats/foo",
        "image_url": "http://edgecats.net/cats/foo"
    }]
Exemple #6
0
    def __init__(self, command_name, search_term):
        """ Creates a Tenor ccbot command named command_name

        Args:
            command_name: The command name. This will be the utterance invoking the command.
            search_term: The text to search against the Tenor web service. Note that you should 
                url encode any spaces or special characters. For example 'dr.+who' not 'dr. who'
        """

        BotCommand.__init__(self, command_name, 'all')
        self.search_term = search_term
        self.api_client = ApiClient()
Exemple #7
0
def change_password():
    try:
        token = auth.get_id_token()
        passwords = ApiClient(auth.get_oauth_session(), app)
        passwords.change_password(token['sub'],
                                  request.form.get('oldPassword'),
                                  request.form.get('password'))
        flash('Password was successfully changed to a new one.', 'success')
        return redirect(url_for('index'))
    except HTTPError as error:
        log_error(
            'Could not change password for the current user because of: ',
            error)
        return render_template('change_password.html')
Exemple #8
0
class Xkcd:
    """
    xkcd [<id>|latest]
    
    Options:
        
        <id>: Shows specific comic strip by numeric id. Example: `xkcd 221`
        latest: Shows latest comic. Example: `xkcd latest`

    """
    api_client = None

    def __init__(self):
        self.api_client = ApiClient()

    def get_channel_id(self):
        return "all"

    def fetch_info(self, comic_id=None):
        url = "https://xkcd.com/info.0.json" if comic_id is None else "https://xkcd.com/" + str(
            comic_id) + "/info.0.json"
        data = self.api_client.fetch(url)
        return data

    def invoke(self, input, user):
        info = self.fetch_info()
        last_comic_id = info["num"]
        command, args = self.parse_command(input)
        comic_id = None
        if (len(args) > 0):
            command = str(args[0])
            if command.isalpha() and command == "latest":
                comic_id = last_comic_id
            else:
                comic_id = args[0]

        random_comic = comic_id if comic_id is not None else random.randint(
            0, last_comic_id)
        comic_data = self.fetch_info(random_comic)
        return SlackResponse.attachment(title=comic_data["title"],
                                        text=comic_data["alt"],
                                        image_url=comic_data["img"])

    def get_command(self):
        return "xkcd"

    def parse_command(self, command):
        parts = command.split(' ')
        size = len(parts)
        command = parts[0] if size > 0 else None
        count = 1
        args = []
        while (count < size):
            argument = parts[count].strip()
            if not argument is '':
                args.append(argument)
            count = count + 1
        return command, args
Exemple #9
0
def test_goatme_invoke_calls_api_client_fetch_if_greater_than_30_minutes():
    #arrange
    id = uuid.uuid1()
    api_client = ApiClient()
    api_client.fetch = MagicMock(return_value={'data': [{'link': id}]})
    goat_me = GoatMe()
    goat_me.imgur_key = "fake_imgur_key"
    goat_me.api_client = api_client

    #act
    text, attachments = goat_me.invoke("goatme", "fakeuser")

    #assert
    assert attachments == [{'image_url': id, 'title': id}]

    target = datetime.datetime.now() + datetime.timedelta(
        minutes=40)  #change datetime to 12 minutes from now
    with mock_datetime(target, datetime):
        new_id = uuid.uuid1()
        api_client.fetch = MagicMock(return_value={'data': [{'link': new_id}]})
        text, attachments = goat_me.invoke("goatme", "fakeuser")
        assert attachments != [{'image_url': id, 'title': id}]
        assert attachments == [{'image_url': new_id, 'title': new_id}]
Exemple #10
0
class TenorCommand(BotCommand):
    BASE_URL = 'https://api.tenor.com/v1/search?media_filter=minimal&q='
    api_client = None

    def __init__(self, command_name, search_term):
        """ Creates a Tenor ccbot command named command_name

        Args:
            command_name: The command name. This will be the utterance invoking the command.
            search_term: The text to search against the Tenor web service. Note that you should 
                url encode any spaces or special characters. For example 'dr.+who' not 'dr. who'
        """

        BotCommand.__init__(self, command_name, 'all')
        self.search_term = search_term
        self.api_client = ApiClient()

    def get_data(self):
        return self.api_client.fetch(self.get_search_url() , {'Content-Type': 'application/json', 'Accept': 'application/json'})

    def get_search_url(self):
        return self.BASE_URL + self.search_term

    def invoke(self, command, user):
        data = self.get_data()

        if data is None or data['results'] is None or len(data['results']) < 1:
            return SlackResponse.text('No results for ' + self.search_term)

        item = random.choice(data['results'])

        return TenorCommand.create_slack_response(item)

    @staticmethod
    def create_slack_response(item):
        return SlackResponse.attachment(title='Here you go:',
                                 image_url=item['media'][0]['gif']['url'],
                                 author_link=item['url'],
                                 author_name='Via Tenor'
                                 )
Exemple #11
0
class CatMe:
    url = "https://api.github.com/repos/flores/moarcats/contents/cats?ref=master"
    api_client = None

    def __init__(self):
        self.api_client = ApiClient()

    def get_channel_id(self):
        return "all"

    @timed_memoize(minutes=30)
    def get_data(self):
        return self.api_client.fetch(self.url)

    def invoke(self, command, user):
        data = self.get_data()
        image = random.choice(data).get("name","")
        image_url = "http://edgecats.net/cats/" + image
        return SlackResponse.attachment(title=image_url,image_url= image_url)

    def get_command(self):
        return "catme"
Exemple #12
0
class EarthMe:
    api_client = None

    def __init__(self):
        self.api_client = ApiClient()

    def get_info(self):
        data = self.api_client.fetch(
            "https://epic.gsfc.nasa.gov/api/images.php")
        image_data = random.choice(data)
        return image_data

    def get_channel_id(self):
        return "all"

    def get_data(self):
        image_data = self.get_info()
        return (image_data.get('image', None),
                str(image_data['centroid_coordinates']['lat']),
                str(image_data['centroid_coordinates']['lon']),
                image_data['caption'], image_data['date'])

    def invoke(self, command, user):
        image, lat, lng, caption, date = self.get_data()
        image_url = "https://epic.gsfc.nasa.gov/epic-archive/jpg/" + image + ".jpg"
        maps_url = "https://www.google.com/maps/@" + lat + "," + lng + ",6z"
        pretext = caption
        text = "Taken on " + date
        author_name = lat + " " + lng + " (location map)"
        author_link = maps_url
        return SlackResponse.attachment(pretext=pretext,
                                        text=text,
                                        image_url=image_url,
                                        author_name=author_name,
                                        author_link=author_link)

    def get_command(self):
        return "earthme"
Exemple #13
0
 def __init__(self):
     self.api_client = ApiClient()
     self.api_headers = {
         'Accept': 'application/json',
         'x-token': os.environ.get('SLACK_CODE_CAMP_BOT_CODECAMP_API_TOKEN')
     }
Exemple #14
0
class CampMe:
    """
    CampMe [verb] [value]
    
    Options:
        now: Shows sessions going on now
        next: Shows sessions starting next time slot
        speaker [speaker name]: Shows sessions by stated speaker 
                                `campme speaker Marcel Marceau` shows sessions by Marcel Marceau.
        sessions at [HH:mm]: Shows sessions occuring at the said time slot. 
                            The time specifier should be 24 hour notation (millitary time)
                             and must match session start time.
    """
    api_client = None
    USAGE_TEXT = 'Try: `campme next` or `campme now` or `campme speaker Bob Bobbernaugh`, or `campme sessions at 14:15` .'
    MANUAL = 'Help for the Code Camp Bot\n\n* `campme next` shows sessions starting next time slot.\n* `campme now` shows sessions in progress.\n* `campme speaker Marcel Marceau` shows sessions by the specified speakr. You may use first or last name only or both.\n* `campme sessions at 16:00` will return sessions starting at 4PM today. Use 24 hour clock 13:00 is 1PM, 14:00 is 2PM etc.'
    URL = "https://www.socalcodecamp.com/v1/schedule/sessions"
    NO_MATCHES_FOUND = '¯\\_(ツ)_/¯ No sessions matching criteria'

    def __init__(self):
        self.api_client = ApiClient()
        self.api_headers = {
            'Accept': 'application/json',
            'x-token': os.environ.get('SLACK_CODE_CAMP_BOT_CODECAMP_API_TOKEN')
        }

    def get_verb(self, command):
        parts = command.split()
        return parts[1:] if len(parts) > 1 else None

    @timed_memoize(minutes=30)
    def get_data(self, url):
        return self.api_client.fetch(url, headers=self.api_headers)

    def invoke(self, command, user):

        verb = self.get_verb(command)

        if (verb is None):
            return SlackResponse.text(self.USAGE_TEXT)

        if (verb[0] == 'help' or verb[0] == '?'):
            return SlackResponse.text(self.MANUAL)

        try:
            result = self.get_data(self.URL)
        except HTTPError as he:
            return SlackResponse.text(str(he))
        except URLError as ue:
            return SlackResponse.text(str(ue.args))

        return self.create_slack_response(result, verb)

    @staticmethod
    def create_slack_response(api_response, verb):
        if (len(api_response) == 0):
            return SlackResponse.text('Server returned no data ¯\\_(ツ)_/¯')

        subset = CampMe.filter_items(api_response, verb)

        formatted = CampMe.format_text(subset, verb[0] == 'speaker')

        return SlackResponse.attachment(
            title=verb,
            text=formatted,
            author_name='Code Camp Bot',
            author_link='https://www.socalcodecamp.com/schedule.aspx')

    @staticmethod
    def filter_items(items, verb):
        if (verb[0] == 'now'):
            return [v for v in items if CampMe.is_now(v)]

        if (verb[0] == 'next'):
            return [v for v in items if CampMe.is_next(v)]

        if (verb[0] == 'speaker' and len(verb) > 1):
            regex = CampMe.build_regex(verb[1:])
            return [v for v in items if CampMe.is_by_speaker(v, regex)]

        if (verb[0] == 'sessions' and verb[1] == 'at' and len(verb) > 2):
            return [
                v for v in items
                if CampMe.is_at_time(v, verb[2], datetime.now())
            ]

        return items

    @staticmethod
    def is_now(session):
        starts = datetime.strptime(session.get('SessionStart'),
                                   "%Y-%m-%dT%H:%M:%S")
        ends = datetime.strptime(session.get('SessionEnd'),
                                 "%Y-%m-%dT%H:%M:%S")
        now = datetime.now()
        return now >= starts and now < ends

    @staticmethod
    def is_next(session):
        starts = datetime.strptime(session.get('SessionStart'),
                                   "%Y-%m-%dT%H:%M:%S")
        now = datetime.now()
        return starts > now and starts < now + timedelta(hours=1, minutes=15)

    @staticmethod
    def build_regex(name_parts):
        pattern = '(\\b'
        pattern += '\\b|\\b'.join(name_parts)
        pattern += '\\b)'
        return re.compile(pattern, re.IGNORECASE)

    @staticmethod
    def is_by_speaker(session, regex):
        return (regex.search(session['SpeakerFirstName']) != None
                or regex.search(session['SpeakerLastName']) != None)

    @staticmethod
    def is_at_time(session, stated_time, clock):
        session_dt = datetime.strptime(session.get('SessionStart'),
                                       "%Y-%m-%dT%H:%M:%S")
        stated_dt = datetime.strptime(stated_time, "%H:%M")
        return (session_dt.hour == stated_dt.hour
                and session_dt.minute == stated_dt.minute
                and session_dt.day == clock.day)

    @staticmethod
    def nice(time_string):
        parsed = datetime.strptime(time_string, "%Y-%m-%dT%H:%M:%S")
        return parsed.strftime('%a %H:%M')

    @staticmethod
    def format_text(items, is_by_speaker=False):
        result = ''

        if items is None or len(items) == 0:
            return CampMe.NO_MATCHES_FOUND

        # u'Room' (98644544):u'SLH 102'
        # u'SessionEnd' (98644880):u'2018-11-11T11:15:00'
        # u'SessionId' (98644352):u'a83dca4a-06f8-48b6-a398-e857c74d6a30'
        # u'SessionName' (96970048):u'How to Ace Technical Interviews'
        # u'SessionStart' (98644304):u'2018-11-11T10:15:00'
        # u'SpeakerFirstName' (98639808):u'Abhi'
        # u'SpeakerLastName' (98639664):u'Jain'
        isfirst = True

        for item in items:
            if (isfirst and not is_by_speaker):
                result += ('%s - %s\n================\n' %
                           (CampMe.nice(item.get('SessionStart')),
                            CampMe.nice(item.get('SessionEnd'))))
                isfirst = False

            result = result + (
                '*  %s %s: %s  @ %s %s\n' %
                (item.get('SpeakerFirstName'), item.get('SpeakerLastName'),
                 item.get('SessionName'), item.get('Room'),
                 CampMe.nice(item.get('SessionStart'))
                 if is_by_speaker else ''))

        return result

    def get_command(self):
        return "campme"

    def get_channel_id(self):
        return "all"
Exemple #15
0
class TacoMe:
    url = "https://api.yelp.com/v3/businesses/search?term=taco&sort_by=distance&categories=foodtrucks&location="
    api_client = None

    def __init__(self):
        self.api_client = ApiClient()
        self.api_headers = {
            'Accept': 'application/json',
            'Authorization': self.get_auth_value()
        }
        self.zipcode_re = re.compile(r'^tacome\s+(\d{5})\s*$')

    def get_channel_id(self):
        return "all"

    def get_auth_value(self):
        token = os.environ.get('SLACK_CODE_CAMP_BOT_YELP_TOKEN')
        return 'Bearer ' + token if token else None

    def get_zipcode(self, command):
        matched = self.zipcode_re.match(command)
        return matched.group(1) if matched else None

    def get_data(self, url):
        return self.api_client.fetch(url, headers=self.api_headers)

    def invoke(self, command, user):

        zip = self.get_zipcode(command)

        if (zip is None):
            return SlackResponse.text(
                r'Try: `tacome _ZIP_CODE_`. Example: `tacome 90405`')

        url = self.url + zip

        try:
            result = self.get_data(url)
        except HTTPError as he:
            return SlackResponse.text(str(he))
        except URLError as ue:
            return SlackResponse.text(str(ue.args))

        return self.create_slack_response(result)

    def create_slack_response(self, api_response):
        if (api_response['total'] == 0):
            return SlackResponse.text('No taco ¯\\_(ツ)_/¯')

        found = random.choice(api_response['businesses'])

        description = 'Rated %s by %s people, is %s meters away' % (
            found['rating'], found['review_count'], int(found['distance']))

        return SlackResponse.attachment(title=found['name'],
                                        image_url=found['image_url'],
                                        text=description,
                                        author_name='Taco details...',
                                        author_link=found['url'])

    def get_command(self):
        return "tacome"
Exemple #16
0
def change_password():
    passwords = ApiClient(auth.get_oauth_session(), app)
    password_pattern = passwords.get_user_password_pattern(
        auth.get_id_token()['sub'])
    return render_template('change_password.html',
                           passwordPattern=password_pattern)
Exemple #17
0
class CCBot:
    deny_response = [
        'No, {name}. I won''t {action}. I REFUSE',
        'Oh boy, here we go again. Why don''t you like me {name}? {action}? really .. REALLY?',
        'Doesn''t this get old, {name}? Would you rather I give you a computer error? Fine.... {action} is not supported. Go Away',
        'What did I ever do to you {name}? Do I deserve this torment? I''m just a friendly bot and you ask me unspeakable things like {action}',
        'JUST ... STOP, {name}. URGH..{action}, really?'
    ]
    bully_id = os.environ.get('BULLY_USER_ID')
    bully_name = None
    api_client = None

    def __init__(self):
        self.api_client = ApiClient()
        
    def get_channel_id(self):
        return "all"

    def invoke(self, input, user):
        self.bully_name = bot.get_user_name_by_id(self.bully_id)
        text = None
        command,action,args= self.parse_command(input)
        method_name = "action_" + action
        if method_name in dir(self):
            method_to_call = getattr(self, method_name)
            result = method_to_call(args)
            text = result
        else:
            if user == self.bully_id:
                result = random.choice(self.deny_response).format(name=self.bully_name, action=action)
                text = result

        return SlackResponse.text(text)

    def get_command(self):
        return "ccbot"

    def parse_command(self,command):
        parts = command.split(' ')
        size = len(parts)
        command = parts[0] if size > 0 else None
        action = parts[1] if size > 1 else None
        count = 2
        args = []
        while(count<size):
            argument = parts[count].strip()
            if not argument is '':
                args.append(argument)
            count = count + 1
        return command,action,args

#CCBot actions in the format "ccbot <action> <args>"
#All actions receive an args array with any data passed in
    def action_get_time(self,args):
        return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    def action_schedule(self,args=[]):
        return "https://www.socalcodecamp.com/schedule.aspx"

    def action_telljoke(self,args):
        headers = {'Accept' : 'text/plain'}
        data = self.api_client.fetch_raw("https://icanhazdadjoke.com/",headers)
        return data

    def action_debug_bully_id(self,args=[]):
        return self.bully_id

    def action_debug_bully_name(self,args=[]):
        return self.bully_name
Exemple #18
0
 def __init__(self):
     self.api_client = ApiClient()