コード例 #1
0
def searchImage():
    """!img <... query ...>"""
    # use imgur's API to return the link to the first non-album result.
    from json import loads
    import random

    import requests

    msg = Message._create_message(flask.request.form)
    searchText = msg.textBody

    url = "https://api.imgur.com/3/gallery/search/{{sort}}/{{window}}/{{page}}"
    querystring = {"q": searchText}
    headers = {'authorization': 'Client-ID 01aa1688f43ca6c'}
    response = requests.request("GET",
                                url,
                                headers=headers,
                                params=querystring)

    a = loads(response.text)['data']
    # a = filter(lambda x: 'imgur.com/a/' not in x['link'], a)

    if len(a) > 0:
        # imageUrl = a[0]['link']
        # return random.choice(a)['link']
        try:
            return random.choice(a)['link']
        except:
            # there was an error finding a link key in the item's dict.
            return "Sorry, I couldn't find a photo of that..."
    else:
        return "Sorry, I couldn't find a photo of that..."
コード例 #2
0
def define():
    """!define <word> <... meaning ...>
    
    Create a quick alias that makes Sue say something.
    You: !define ping pong
    You: !ping
    Sue: pong"""
    msg = Message(flask.request.form)
    textBody = msg.textBody

    if len(textBody) == 0:
        return 'Please supply a word to define.'

    try:
        textBody = textBody.split(' ', 1)
        if len(textBody) == 2:
            defnName, meaning = textBody[0], textBody[1]
        else:
            return 'Please supply a meaning for the word.'
    except:
        # There was an error.
        return 'Error adding definition. No unicode pls :('

    defnName = clean(defnName)
    q = db.findDefn(defnName)
    if q:
        db.updateDefn(defnName, meaning)
        return ('%s updated.' % defnName)
    else:
        db.addDefn(defnName, meaning)
        return ('%s added.' % defnName)

    return 0
コード例 #3
0
def urbanDictionary():
    """!ud <... term ...>"""
    import sys
    import json
    import requests

    msg = Message._create_message(flask.request.form)
    term = msg.textBody

    responses = []

    if term:
        if sys.version < '3':
            from urllib import quote as urlquote
        else:
            from urllib.parse import quote as urlquote
        url = 'http://api.urbandictionary.com/v0/define?term=' + urlquote(term)
    else:
        # no term provided. Send a random one.
        url = 'http://api.urbandictionary.com/v0/random'

    r = requests.get(url)
    data = json.loads(r.content)
    if not data['list']:
        return ["Sorry, couldn't find that..."]

    clean = lambda x: x.replace('\r\n', '\n').strip()
    for entry in data['list'][:1]:
        responses.append(str(data['list'][0]['word']))
        output = 'def: ' + clean(entry['definition']) + '\n'
        output += 'ex: ' + clean(entry['example'])
        responses.append(str(output))

    return responses
コード例 #4
0
def sue_random():
    """!random <upper> <lower>"""
    msg = Message._create_message(flask.request.form)

    if not msg:
        return 'Error with message.'

    textBody = msg.textBody.lower()

    print(textBody)

    randRange = sorted(textBody.split(' '))
    if len(randRange) != 2:
        # can't have a range between 3 elements
        return sue_random.__doc__

    numberBased = set(map(lambda x: x.isdigit(), randRange))

    try:
        if numberBased == {True}:
            # 1 - 123
            randRange = [int(x) for x in randRange]
            randRange.sort()
            return str(random.randint(randRange[0], randRange[1]))
        elif numberBased == {False}:
            # a - z
            randRange = [ord(x) for x in randRange]
            randRange.sort()
            return str(chr(random.randint(randRange[0], randRange[1])))
        else:
            return str(random.random())
    except:
        return str(random.random())
コード例 #5
0
ファイル: images.py プロジェクト: bellyfat/Sue
def lewd():
    """!lewd <image>
    
    Queries clarif.ai to detect if an image is 'lewd'.
    Usage: !lewd <image>"""

    msg = Message(flask.request.form)
    fileName = msg.fileName

    if fileName == 'noFile':
        return 'Please supply a file.'
    elif fileName == 'fileError':
        return 'There was an error selecting the last file transfer.'
    else:
        init_clarifai()
        model = clarifai.models.get('nsfw-v1.0')

        if not model:
            return 'Model no longer exists.'

        image = ClImage(file_obj=open(fileName, 'rb'))

        responses = []

        imageData = model.predict([image])
        result = imageData['outputs'][0]['data']['concepts'][0]
        if result['name'] == u'nsfw':
            responses.append('LEEEWWWDDD!!!!!')
            responses.append('accuracy: %f' % result['value'])

            return responses
        else:
            return 'not lewd'
コード例 #6
0
def sue_help():
    help_docs = []
    msg = Message._create_message(flask.request.form)

    # iterate through our routes, getting the doc-strings we defined as
    # miniature man-pages for these commands.
    for r in app.url_map.iter_rules():
        current_doc = app.view_functions[r.endpoint].__doc__
        if current_doc and ('static' not in r.rule):
            docString = current_doc.strip()
            firstLine = docString.split('\n', 1)[0]

            # if someone wants help about a specific command, get them
            # the extra info we placed after the first line-break.
            if msg.textBody:
                if firstLine.split(' ',
                                   1)[0].replace('!',
                                                 '') == msg.textBody.lower():
                    specificDocumentation = docString.split('\n', 1)
                    if len(specificDocumentation) == 2:
                        return reduce_output(specificDocumentation[1].strip(),
                                             delimiter='\n')
                    else:
                        return 'No documentation for {0} yet. Add it to the\
                        repo! https://github.com/inculi/Sue'.format(
                            msg.textBody)
                # else:
                #     print(firstLine.split(' ',1)[0].replace('!',''))
                #     print(msg.textBody.lower())

            help_docs.append(firstLine)

    return reduce_output(sorted(help_docs), delimiter='\n')
コード例 #7
0
ファイル: images.py プロジェクト: bellyfat/Sue
def identify():
    """!identify <image>
    
    Queries clarif.ai to identify the top 10 concepts within an image.
    Usage: !identify <image>"""

    msg = Message(flask.request.form)
    fileName = msg.fileName

    if fileName == 'noFile':
        return 'Please supply a file.'
    elif fileName == 'fileError':
        return 'There was an error selecting the last file transfer.'
    else:
        init_clarifai()
        model = clarifai.models.get('general-v1.3')
        image = ClImage(file_obj=open(fileName, 'rb'))

        imageData = model.predict([image])
        try:
            imageData = imageData['outputs'][0]['data']['concepts'][:10]
            imageData = [x['name'] for x in imageData]

            return reduce_output(imageData, delimiter=', ')
        except:
            return 'Error'
コード例 #8
0
ファイル: images.py プロジェクト: jeff-hykin/Sue
def identify():
    """!identify <image>"""

    msg = Message._create_message(flask.request.form)
    fileName = msg.fileName

    if fileName == 'noFile':
        return 'Please supply a file.'
    elif fileName == 'fileError':
        return 'There was an error selecting the last file transfer.'
    else:
        from clarifai.rest import ClarifaiApp
        from clarifai.rest import Image as ClImage

        app = ClarifaiApp(api_key='ab4ea7efce5a4398bcbed8329a3d81c7')
        model = app.models.get('general-v1.3')
        image = ClImage(file_obj=open(fileName, 'rb'))

        imageData = model.predict([image])
        try:
            imageData = imageData['outputs'][0]['data']['concepts'][:10]
            imageData = [x['name'] for x in imageData]

            return reduce_output(imageData, delimiter=', ')
        except:
            return 'Error'
コード例 #9
0
ファイル: images.py プロジェクト: jeff-hykin/Sue
def lewd():
    """!lewd <image>"""
    # detect whether an image is lewd or not

    msg = Message._create_message(flask.request.form)
    fileName = msg.fileName

    if fileName == 'noFile':
        return 'Please supply a file.'
    elif fileName == 'fileError':
        return 'There was an error selecting the last file transfer.'
    else:
        from clarifai.rest import ClarifaiApp
        from clarifai.rest import Image as ClImage

        app = ClarifaiApp(api_key='ab4ea7efce5a4398bcbed8329a3d81c7')
        model = app.models.get('nsfw-v1.0')
        image = ClImage(file_obj=open(fileName, 'rb'))

        responses = []

        imageData = model.predict([image])
        result = imageData['outputs'][0]['data']['concepts'][0]
        if result['name'] == u'nsfw':
            responses.append('LEEEWWWDDD!!!!!')
            responses.append('accuracy: %f' % result['value'])

            return responses
        else:
            return 'not lewd'
コード例 #10
0
ファイル: poll.py プロジェクト: bellyfat/Sue
def poll():
    """!poll <topic>\\n<opt1>\\n<opt2> ...
    
    Create a poll for people to !vote on.
    Usage: !poll which movie?
    grand budapest
    tron
    bee movie"""

    msg = Message(flask.request.form)
    options = tokenize(msg.textBody)

    if len(options) < 2:
        return 'Please specify a topic with options delimited by newlines.'

    if '?' in options[0]:
        # Injected user data may have messed up tokenization...
        # !poll Where should we have lunch? #lunchplaces (no comma)
        # instead of: !poll Where should we have lunch?, #lunchplaces (comma)

        firstQuestionIdx = options[0].find('?')
        if options[0][-1] != '?':
            # The question ended earlier in the string. Find it.
            pollQuestion, firstOption = options[0].split('?', 1)
            options = [pollQuestion.strip() + '?',
                       firstOption.strip()] + options[1:]

    return create_poll(options, msg)
コード例 #11
0
ファイル: poll.py プロジェクト: jeff-hykin/Sue
def poll():
    """!poll <topic>\\n<opt1>\\n<opt2> ..."""

    msg = Message._create_message(flask.request.form)
    options = msg.textBody.split('\n')

    response = []

    if len(options) < 2:
        return 'Please specify a topic with options delimited by newlines.'
    
    # set this to the current poll for our group.
    poll_data = {
        "letter_options" : set(),
        "options" : options[1:],
        "question" : options[0],
        "votes" : {}
    }

    response.append(poll_data['question'])

    for i, cur_option in enumerate(poll_data["options"]):
        _option_letter = chr(ord('a') + i)
        poll_data["letter_options"].add(_option_letter)
        response.append("{0}. {1}".format(_option_letter, cur_option))
    
    # mongo doesn't like sets so I have to convert to list.
    poll_data["letter_options"] = list(poll_data["letter_options"])
    db.mUpdate('polls',
               {'group' : msg.chatId},
               {'group' : msg.chatId, 'data' : poll_data })

    return reduce_output(response, delimiter='\n')
コード例 #12
0
ファイル: webapis.py プロジェクト: rawells14/Sue
def searchImage():
    """!img <... query ...>
    
    Query imgur.com to return a url to a related image (selects randomly from results).
    Usage: !img flower"""
    # use imgur's API to return the link to the first non-album result.
    from json import loads
    import random

    import requests

    msg = Message._create_message(flask.request.form)
    searchText = msg.textBody

    url = "https://api.imgur.com/3/gallery/search/{{sort}}/{{window}}/{{page}}"
    querystring = {"q": searchText}
    headers = {'authorization': app.config['IMGUR_CLIENT_ID']}
    response = requests.request("GET",
                                url,
                                headers=headers,
                                params=querystring)

    a = loads(response.text)['data']
    # a = filter(lambda x: 'imgur.com/a/' not in x['link'], a)

    if len(a) > 0:
        try:
            return random.choice(a).get(
                'link', 'Error selecting link from response...')
        except:
            # there was an error finding a link key in the item's dict.
            return "Sorry, I couldn't find a photo of that..."
    else:
        return "Sorry, I couldn't find a photo of that..."
コード例 #13
0
def echo():
    """!echo <... text ...>
    
    Used to debug member-defined data structures.
    You: !echo !choose #lunchplaces
    Sue: !choose fuego, antonios, potbelly, taco bell"""
    msg = Message(flask.request.form)
    return msg.textBody
コード例 #14
0
ファイル: server.py プロジェクト: rawells14/Sue
def movie():
    # Used to get information about movies that are currently being stored/
    #   downloaded.
    # TODO: Implement.
    # return 'Needs to be implemented.'
    print('doing something')
    msg = Message._create_message(flask.request.form)
    return query_couch_potato(msg.textBody)
コード例 #15
0
def process_reply():
    """Main route for processing requests.
    
    Based on information we detect in the flask.request.form (logic provided
      in models.py), we can figure out if we are sending the response back to
      Signal, iMessage, and from there-- a group, or an individual. Cool, huh?
    """

    if not check_command(flask.request.form):
        return ''  # User isn't talking to Sue. Ignore.
    flask.request.form = prepare_message(flask.request.form)
    msg = Message(flask.request.form)

    init_sue_funcs()
    f = sue_funcs.get('/' + msg.command)
    if f:
        # Command exists. Execute it and get the response.
        sue_response = f()
    else:
        # It's not a command we made. Check to see if it is user defined.
        sue_response = sue_funcs['/callDefn']()

    # cast her response to a string. (ex: lists are reduced).
    attachment = None
    if isinstance(sue_response, list):
        sue_response = reduce_output(sue_response, delimiter='\n')
    elif isinstance(sue_response, DataResponse):
        # set the attachment to our image path
        attachment = sue_response.data

        # set the sue_response to a blank string (we won't send it anyway)
        sue_response = ''
    elif not isinstance(sue_response, str):
        try:
            sue_response = str(sue_response)
        except:
            sue_response = "Couldn't convert from {0} to str".format(
                type(sue_response))

    # TODO: Create consts for these, so we have less `magic string` usage.
    if msg.platform is 'imessage':
        # forward to applescript handler
        IMessageResponse(msg, sue_response, attachment=attachment)
        return 'success'
    elif msg.platform is 'signal':
        # return to GET request from run_signal.py
        return json.dumps({
            'messageBody': sue_response,
            'attachmentFilenames': [attachment]
        })
    elif msg.platform is 'telegram':
        return sue_response
    elif msg.platform is 'debug':
        return sue_response
    else:
        print('Unfamiliar message platform: {0}'.format(msg.platform))
        # TODO: Throw exception?
        return 'failure'
コード例 #16
0
def shuffle():
    """!shuffle <1> <2> ... <n>"""
    from functools import reduce

    msg = Message(flask.request.form)

    items = msg.textBody.split(' ')
    random.shuffle(items)
    return reduce(lambda x, y: str(x) + ' ' + str(y), items)
コード例 #17
0
def callDefn():
    msg = Message._create_message(flask.request.form)
    defnName = msg.command

    q = db.findDefn(defnName)
    if q:
        return str(q[u'meaning'])
    else:
        return 'Not found. Add it with !define'
コード例 #18
0
def sue_help():
    """Returns a sorted list of commands available for the user to use. If you
      give it a command name as an argument, it will read you the extended
      "manpage" for that command.

    Usage
    -----
    !help
    !help <command>

    Examples
    --------
    """

    help_docs = []
    msg = Message(flask.request.form)

    # Iterate through our routes, getting the doc-strings we defined as
    #   miniature man-pages for these commands.
    hiddenEndpoints = set(['/', '/help'])
    for r in app.url_map.iter_rules():
        current_doc = app.view_functions[r.endpoint].__doc__
        if current_doc:
            if 'static' in r.rule:
                continue
            if r.rule in hiddenEndpoints:
                continue

            docString = current_doc.strip()
            firstLine = docString.split('\n', 1)[0]

            # If someone wants help about a specific command, get them
            # the extra info we placed after the first line-break.
            if msg.textBody:
                if firstLine.split(' ', 1)[0].replace('!', '') != msg.command:
                    continue

                cmdDocs = docString.split('\n', 1)
                if len(cmdDocs) != 2:
                    return 'No documentation for {0} yet. Add it to the\
                    repo! https://github.com/inculi/Sue'.format(msg.command)

                response = ''
                for line in cmdDocs[1].split('\n'):
                    if not line:
                        continue
                    if line[0] == ' ':
                        response += ' ' + line.strip()
                    else:
                        response += '\n' + line.strip()

                return response

            help_docs.append(firstLine)

    return reduce_output(sorted(help_docs), delimiter='\n')
コード例 #19
0
def callDefn():
    # the route used to call !define'd objects.

    msg = Message(flask.request.form)
    defnName = msg.command

    q = db.findDefn(defnName)
    if q:
        return str(q[u'meaning'])
    else:
        return 'Not found. Add it with !define'
コード例 #20
0
ファイル: rand.py プロジェクト: rawells14/Sue
def shuffle():
    """!shuffle <1> <2> ... <n>
    
    Shuffles and then returns your input."""
    from functools import reduce

    msg = Message._create_message(flask.request.form)
    
    items = tokenize(msg.textBody)
    random.shuffle(items)
    return reduce(lambda x,y: str(x)+' '+str(y), items)
コード例 #21
0
def name():
    """!name <newname>"""
    msg = Message._create_message(flask.request.form)
    sender = msg.sender
    textBody = msg.textBody
    # make changes to our names collection.
    if len(textBody) == 0:
        return 'Please specify a name.'
    else:
        db.updateName(sender, textBody)
        return '{0} shall now be known as {1}'.format(sender, textBody)
コード例 #22
0
def whoami():
    """!whoami"""
    msg = Message._create_message(flask.request.form)
    sender = msg.sender
    # load names from pickle file
    nameFound = db.findName(sender)

    if nameFound:
        print('You are {0}.'.format(nameFound))
        return 'You are {0}.'.format(nameFound)
    else:
        return 'I do not know you. Set your name with !name'
コード例 #23
0
ファイル: poll.py プロジェクト: jeff-hykin/Sue
def lunchPlaces():
    """!lunchPlaces <place1>, <place2>, ..."""

    msg = Message._create_message(flask.request.form)
    
    # split by commas and trim whitespace
    lunchPlaces = [each.strip() for each in msg.textBody.split(',')]

    # add lunchPlaces to the mongo polls collection 
    db.mUpdate('polls',
               {'group' : msg.chatId},
               {'group' : msg.chatId, 'lunchPlaces' : lunchPlaces })
コード例 #24
0
def wiki():
    """!wiki <... topic ...>"""
    import wikipedia as wikip

    msg = Message._create_message(flask.request.form)
    searchTerm = msg.textBody

    try:
        data = wikip.summary(searchTerm, sentences=1)
        if len(data) < 50:
            data = wikip.summary(searchTerm, sentences=2)
        return str(data)
    except:
        return "Hmm, couldn't find that..."
コード例 #25
0
def name():
    """!name <newname>
    
    Create a new name for Sue to call you by. This currently isn't used for anything.
    You: !name Robert
    Sue: +1234567890 shall now be known as Robert"""
    msg = Message(flask.request.form)
    sender = msg.sender
    textBody = msg.textBody
    # make changes to our names collection.
    if len(textBody) == 0:
        return 'Please specify a name.'
    else:
        db.updateName(sender, textBody)
        return '{0} shall now be known as {1}'.format(sender, textBody)
コード例 #26
0
ファイル: rand.py プロジェクト: rawells14/Sue
def choose():
    """!choose <1> <2> ... <n>
    
    Returns a random object in your space-delimited argument.
    Usage: !choose up down left right"""

    msg = Message._create_message(flask.request.form)
    options = tokenize(msg.textBody)

    meguminOption = ('megumin' in map(lambda x: x.lower(), options))
    if meguminOption and msg.sender == '+12107485865':
        return 'megumin'
    elif meguminOption and msg.sender == '+12108342408':
        return 'Roses are Red, Violets are Blue. Megumin best girl and glorious waifu.'
    else:
        return random.choice(options)
コード例 #27
0
ファイル: images.py プロジェクト: bellyfat/Sue
def image():
    """!i <param> <image>
    
    Available parameters are: smile, smile2, hot, old, young, hollywood, glasses, hitman, mustache, pan, heisenberg, female, female2, male
    """
    global VALID_IMAGE_PARAMS

    msg = Message(flask.request.form)
    _param = msg.textBody.lower()

    paramAliases = {
        'mustache': 'mustache_free',
        'glasses': 'fun_glasses',
        'smile2': 'smile_2',
        'female2': 'female_2'
    }

    if _param not in VALID_IMAGE_PARAMS:
        _param = paramAliases.get(_param)
        if not _param:
            return 'Not a valid parameter. See !help i'

    if msg.fileName == 'noFile':
        return 'Please supply a file.'
    elif msg.fileName == 'fileError':
        return 'There was an error selecting the last file transfer.'

    import faces
    import uuid

    try:
        img = faces.FaceAppImage(file=open(msg.fileName, 'rb'))
        outimg = img.apply_filter(_param, cropped=False)
    except faces.ImageHasNoFaces:
        return 'No faces on this image.'
    except faces.BadInfo as ex:
        return str(ex)

    # Create the directory for us to store these files if it doesn't exist.
    if not os.path.exists('resources/iout/'):
        os.mkdir('resources/iout')

    outPath = os.path.abspath('resources/iout/{}.jpg'.format(uuid.uuid4()))
    with open(outPath, 'wb') as f:
        f.write(outimg)

    return DataResponse(outPath)
コード例 #28
0
def choose():
    """!choose <1> <2> ... <n>"""
    msg = Message._create_message(flask.request.form)

    print(msg.__dict__)

    textBody = msg.textBody
    sender = msg.buddyId

    options = textBody.split(' ')
    meguminOption = 'megumin' in map(lambda x: x.lower(), options)
    if meguminOption and sender == '12107485865':
        return 'megumin'
    elif meguminOption and sender == '12108342408':
        return 'http://megumin.club Roses are Red, Violets are Blue. Megumin best girl and glorious waifu.'
    else:
        return random.choice(options)
コード例 #29
0
ファイル: main.py プロジェクト: jeff-hykin/Sue
def process_reply():
    if app.config['DEBUG']:
        print(flask.request.form)

    command = check_command(flask.request.form)
    if not command:
        return ''

    # get a list of our available functions
    sue_funcs = {}
    for r in app.url_map.iter_rules():
        sue_funcs[r.rule] = app.view_functions[r.endpoint]

    f = sue_funcs.get('/' + command)
    if f:
        # get the response back from Sue.
        sue_response = f()

        # cast her response to a string. (ex: lists are reduced).
        if isinstance(sue_response, list):
            sue_response = reduce_output(sue_response, delimiter='\n')
        elif not isinstance(sue_response, str):
            try:
                sue_response = str(sue_response)
            except:
                sue_response = "Couldn't convert from {0} to str".format(
                    type(sue_response))

        # message metadata will be used to direct response output.
        msg = Message._create_message(flask.request.form)

        if msg.platform is 'imessage':
            # forward to applescript handler
            Response(msg, sue_response)
            return 'success'
        elif msg.platform is 'signal':
            # return to GET request from run_signal.py
            return sue_response
        else:
            print('Unfamiliar message platform: {0}'.format(msg.platform))
            return 'failure'
    else:
        # see if it is user defined
        sue_response = sue_funcs['/callDefn']()
        Response(flask.request.form, sue_response)
        return 'success'
コード例 #30
0
def whoami():
    """!whoami
    
    Fetches the name you set for yourself using !name
    You: !whoami
    Sue: You are Robert."""

    msg = Message(flask.request.form)
    sender = msg.sender
    # load names from pickle file
    nameFound = db.findName(sender)

    if nameFound:
        print('You are {0}.'.format(nameFound))
        return 'You are {0}.'.format(nameFound)
    else:
        return 'I do not know you. Set your name with !name'