Exemple #1
0
def etymology(word):
    # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc
    # entries? - http://swhack.com/logs/2006-07-19#T15-05-29

    if len(word) > 25:
        raise ValueError("Word too long: %s[...]" % word[:10])
    word = {'axe': 'ax/axe'}.get(word, word)

    bytes = web.get(etyuri % web.urllib.quote(word))
    definitions = r_definition.findall(bytes)

    if not definitions:
        return None

    defn = text(definitions[0])
    m = r_sentence.match(defn)
    if not m:
        return None
    sentence = m.group(0)

    try:
        sentence = unicode(sentence, 'iso-8859-1')
        sentence = sentence.encode('utf-8')
    except:
        pass

    maxlength = 275
    if len(sentence) > maxlength:
        sentence = sentence[:maxlength]
        words = sentence[:-5].split(' ')
        words.pop()
        sentence = ' '.join(words) + ' [...]'

    sentence = '"' + sentence.replace('"', "'") + '"'
    return sentence + ' - ' + (etyuri % word)
Exemple #2
0
def dict(ircbot, input):
    if not input.group(2):
        return ircbot.reply("Nothing to define.")
    word = input.group(2)
    word = urllib.quote(word.encode('utf-8'))

    def trim(thing):
        if thing.endswith('&nbsp;'):
            thing = thing[:-6]
        return thing.strip(' :.')

    bytes = web.get(uri % word)
    results = {}
    wordkind = None
    for kind, sense in r_info.findall(bytes):
        kind, sense = trim(kind), trim(sense)
        if kind:
            wordkind = kind
        elif sense:
            results.setdefault(wordkind, []).append(sense)
    result = input.group(2).encode('utf-8') + ' - '
    for key in sorted(results.keys()):
        if results[key]:
            result += (key or '') + ' 1. ' + results[key][0]
            if len(results[key]) > 1:
                result += ', 2. ' + results[key][1]
            result += '; '
    result = result.rstrip('; ')
    if result.endswith('-') and (len(result) < 30):
        ircbot.reply('Sorry, no definition found.')
    else:
        ircbot.say(result)
Exemple #3
0
def dict(ircbot, input):
    if not input.group(2):
        return ircbot.reply("Nothing to define.")
    word = input.group(2)
    word = urllib.quote(word.encode('utf-8'))

    def trim(thing):
        if thing.endswith('&nbsp;'):
            thing = thing[:-6]
        return thing.strip(' :.')

    bytes = web.get(uri % word)
    results = {}
    wordkind = None
    for kind, sense in r_info.findall(bytes):
        kind, sense = trim(kind), trim(sense)
        if kind:
            wordkind = kind
        elif sense:
            results.setdefault(wordkind, []).append(sense)
    result = input.group(2).encode('utf-8') + ' - '
    for key in sorted(results.keys()):
        if results[key]:
            result += (key or '') + ' 1. ' + results[key][0]
            if len(results[key]) > 1:
                result += ', 2. ' + results[key][1]
            result += '; '
    result = result.rstrip('; ')
    if result.endswith('-') and (len(result) < 30):
        ircbot.reply('Sorry, no definition found.')
    else:
        ircbot.say(result)
Exemple #4
0
def py(ircbot, input):
    query = input.group(2).encode('utf-8')
    uri = 'http://tumbolia.appspot.com/py/'
    answer = web.get(uri + web.urllib.quote(query))
    if answer:
        ircbot.say(answer)
    else:
        ircbot.reply('Sorry, no result.')
Exemple #5
0
def py(ircbot, input):
    query = input.group(2).encode('utf-8')
    uri = 'http://tumbolia.appspot.com/py/'
    answer = web.get(uri + web.urllib.quote(query))
    if answer:
        ircbot.say(answer)
    else:
        ircbot.reply('Sorry, no result.')
Exemple #6
0
def search(query):
    """Search using AjaxSearch, and return its JSON."""
    uri = 'http://ajax.googleapis.com/ajax/services/search/web'
    args = '?v=1.0&safe=off&q=' + web.urllib.quote(query.encode('utf-8'))
    handler = web.urllib._urlopener
    web.urllib._urlopener = Grab()
    bytes = web.get(uri + args)
    web.urllib._urlopener = handler
    return web.json(bytes)
Exemple #7
0
def detect(text):
    uri = 'http://ajax.googleapis.com/ajax/services/language/detect'
    q = urllib.quote(text)
    bytes = web.get(uri + '?q=' + q + '&v=1.0')
    result = web.json(bytes)
    try:
         return result['responseData']['language']
    except Exception:
         return None
Exemple #8
0
def search(query):
    """Search using AjaxSearch, and return its JSON."""
    uri = 'http://ajax.googleapis.com/ajax/services/search/web'
    args = '?v=1.0&safe=off&q=' + web.urllib.quote(query.encode('utf-8'))
    handler = web.urllib._urlopener
    web.urllib._urlopener = Grab()
    bytes = web.get(uri + args)
    web.urllib._urlopener = handler
    return web.json(bytes)
Exemple #9
0
def wa(ircbot, input):
    if not input.group(2):
        return ircbot.reply("No search term.")
    query = input.group(2).encode('utf-8')
    uri = 'http://tumbolia.appspot.com/wa/'
    answer = web.get(uri + web.urllib.quote(query))
    if answer:
        ircbot.say(answer)
    else:
        ircbot.reply('Sorry, no result.')
Exemple #10
0
def translate(text, input, output):
    uri = 'http://ajax.googleapis.com/ajax/services/language/translate'
    q = urllib.quote(text)
    pair = input + '%7C' + output
    bytes = web.get(uri + '?q=' + q + '&v=1.0&langpair=' + pair)
    result = web.json(bytes)
    try:
         return result['responseData']['translatedText'].encode('cp1252')
    except Exception:
         return None
Exemple #11
0
def wa(ircbot, input):
    if not input.group(2):
        return ircbot.reply("No search term.")
    query = input.group(2).encode('utf-8')
    uri = 'http://tumbolia.appspot.com/wa/'
    answer = web.get(uri + web.urllib.quote(query))
    if answer:
        ircbot.say(answer)
    else:
        ircbot.reply('Sorry, no result.')
Exemple #12
0
def mappings(uri):
    result = {}
    bytes = web.get(uri)
    for item in r_item.findall(bytes):
        item = r_tag.sub('', item).strip(' \t\r\n')
        if not ' ' in item:
            continue

        command, template = item.split(' ', 1)
        if not command.isalnum():
            continue
        if not template.startswith('http://'):
            continue
        result[command] = template.replace('&amp;', '&')
    return result
Exemple #13
0
def service(ircbot, input, command, args):
    t = o.services[command]
    template = t.replace('${args}', urllib.quote(args.encode('utf-8'), ''))
    template = template.replace('${nick}', urllib.quote(input.nick, ''))
    uri = template.replace('${sender}', urllib.quote(input.sender, ''))

    info = web.head(uri)
    if isinstance(info, list):
        info = info[0]
    if not 'text/plain' in info.get('content-type', '').lower():
        return ircbot.reply("Sorry, the service didn't respond in plain text.")
    bytes = web.get(uri)
    lines = bytes.splitlines()
    if not lines:
        return ircbot.reply("Sorry, the service didn't respond any output.")
    ircbot.say(lines[0][:350])
Exemple #14
0
def local(icao, hour, minute):
    uri = ('http://www.flightstats.com/' +
             'go/Airport/airportDetails.do?airportCode=%s')
    try:
        bytes = web.get(uri % icao)
    except AttributeError:
        raise GrumbleError('A WEBSITE HAS GONE DOWN WTF STUPID WEB')
    m = re.compile(r'(?i)([+-]\d+):00 from').search(bytes)
    if m:
        offset = m.group(1)
        lhour = int(hour) + int(offset)
        lhour = lhour % 24
        return (str(lhour) + ':' + str(minute) + ', ' + str(hour) +
                  str(minute) + 'Z')
        # return (str(lhour) + ':' + str(minute) + ' (' + str(hour) +
        #            ':' + str(minute) + 'Z)')
    return str(hour) + ':' + str(minute) + 'Z'
Exemple #15
0
def local(icao, hour, minute):
    uri = ('http://www.flightstats.com/' +
           'go/Airport/airportDetails.do?airportCode=%s')
    try:
        bytes = web.get(uri % icao)
    except AttributeError:
        raise GrumbleError('A WEBSITE HAS GONE DOWN WTF STUPID WEB')
    m = re.compile(r'(?i)([+-]\d+):00 from').search(bytes)
    if m:
        offset = m.group(1)
        lhour = int(hour) + int(offset)
        lhour = lhour % 24
        return (str(lhour) + ':' + str(minute) + ', ' + str(hour) +
                str(minute) + 'Z')
        # return (str(lhour) + ':' + str(minute) + ' (' + str(hour) +
        #            ':' + str(minute) + 'Z)')
    return str(hour) + ':' + str(minute) + 'Z'
Exemple #16
0
def calc(ircbot, input):
    """Use the Frink online calculator."""
    q = input.group(2)
    if not q:
        return ircbot.say('0?')

    query = q[:]
    for a, b in subs:
        query = re.sub(a, b, query)
    query = query.rstrip(' \t')

    precision = 5
    if query[-3:] in ('GBP', 'USD', 'EUR', 'NOK'):
        precision = 2
    query = web.urllib.quote(query.encode('utf-8'))

    uri = 'http://futureboy.us/fsp/frink.fsp?fromVal='
    bytes = web.get(uri + query)
    m = r_result.search(bytes)
    if m:
        result = m.group(1)
        result = r_tag.sub('', result) # strip span.warning tags
        result = result.replace('&gt;', '>')
        result = result.replace('(undefined symbol)', '(?) ')

        if '.' in result:
            try:
                result = str(round(float(result), precision))
            except ValueError:
                pass

        if not result.strip():
            result = '?'
        elif ' in ' in q:
            result += ' ' + q.split(' in ', 1)[1]

        ircbot.say(q + ' = ' + result[:350])
    else:
        ircbot.reply("Sorry, can't calculate that.")
    ircbot.say('Note that .calc is deprecated, consider using .c')
Exemple #17
0
def calc(ircbot, input):
    """Use the Frink online calculator."""
    q = input.group(2)
    if not q:
        return ircbot.say('0?')

    query = q[:]
    for a, b in subs:
        query = re.sub(a, b, query)
    query = query.rstrip(' \t')

    precision = 5
    if query[-3:] in ('GBP', 'USD', 'EUR', 'NOK'):
        precision = 2
    query = web.urllib.quote(query.encode('utf-8'))

    uri = 'http://futureboy.us/fsp/frink.fsp?fromVal='
    bytes = web.get(uri + query)
    m = r_result.search(bytes)
    if m:
        result = m.group(1)
        result = r_tag.sub('', result)  # strip span.warning tags
        result = result.replace('&gt;', '>')
        result = result.replace('(undefined symbol)', '(?) ')

        if '.' in result:
            try:
                result = str(round(float(result), precision))
            except ValueError:
                pass

        if not result.strip():
            result = '?'
        elif ' in ' in q:
            result += ' ' + q.split(' in ', 1)[1]

        ircbot.say(q + ' = ' + result[:350])
    else:
        ircbot.reply("Sorry, can't calculate that.")
    ircbot.say('Note that .calc is deprecated, consider using .c')
Exemple #18
0
def c(ircbot, input):
    """Google calculator."""
    if not input.group(2):
        return ircbot.reply("Nothing to calculate.")
    q = input.group(2).encode('utf-8')
    q = q.replace('\xcf\x95', 'phi')  # utf-8 U+03D5
    q = q.replace('\xcf\x80', 'pi')  # utf-8 U+03C0
    uri = 'http://www.google.com/ig/calculator?q='
    bytes = web.get(uri + web.urllib.quote(q))
    parts = bytes.split('",')
    answer = [p for p in parts if p.startswith('rhs: "')][0][6:]
    if answer:
        answer = answer.decode('unicode-escape')
        answer = ''.join(chr(ord(c)) for c in answer)
        answer = answer.decode('utf-8')
        answer = answer.replace(u'\xc2\xa0', ',')
        answer = answer.replace('<sup>', '^(')
        answer = answer.replace('</sup>', ')')
        answer = web.decode(answer)
        ircbot.say(answer)
    else:
        ircbot.say('Sorry, no result.')
Exemple #19
0
def c(ircbot, input):
    """Google calculator."""
    if not input.group(2):
        return ircbot.reply("Nothing to calculate.")
    q = input.group(2).encode('utf-8')
    q = q.replace('\xcf\x95', 'phi') # utf-8 U+03D5
    q = q.replace('\xcf\x80', 'pi') # utf-8 U+03C0
    uri = 'http://www.google.com/ig/calculator?q='
    bytes = web.get(uri + web.urllib.quote(q))
    parts = bytes.split('",')
    answer = [p for p in parts if p.startswith('rhs: "')][0][6:]
    if answer:
        answer = answer.decode('unicode-escape')
        answer = ''.join(chr(ord(c)) for c in answer)
        answer = answer.decode('utf-8')
        answer = answer.replace(u'\xc2\xa0', ',')
        answer = answer.replace('<sup>', '^(')
        answer = answer.replace('</sup>', ')')
        answer = web.decode(answer)
        ircbot.say(answer)
    else:
        ircbot.say('Sorry, no result.')
Exemple #20
0
def bing(ircbot, input):
    """Queries Bing for the specified input."""
    query = input.group(2)
    if query.startswith(':'):
        lang, query = query.split(' ', 1)
        lang = lang[1:]
    else:
        lang = 'en-GB'
    if not query:
        return ircbot.reply('.bing what?')

    query = web.urllib.quote(query.encode('utf-8'))
    base = 'http://www.bing.com/search?mkt=%s&q=' % lang
    bytes = web.get(base + query)
    m = r_bing.search(bytes)
    if m:
        uri = m.group(1)
        ircbot.reply(uri)
        if not hasattr(ircbot.bot, 'last_seen_uri'):
            ircbot.bot.last_seen_uri = {}
        ircbot.bot.last_seen_uri[input.sender] = uri
    else:
        ircbot.reply("No results found for '%s'." % query)
Exemple #21
0
def bing(ircbot, input):
    """Queries Bing for the specified input."""
    query = input.group(2)
    if query.startswith(':'):
        lang, query = query.split(' ', 1)
        lang = lang[1:]
    else:
        lang = 'en-GB'
    if not query:
        return ircbot.reply('.bing what?')

    query = web.urllib.quote(query.encode('utf-8'))
    base = 'http://www.bing.com/search?mkt=%s&q=' % lang
    bytes = web.get(base + query)
    m = r_bing.search(bytes)
    if m:
        uri = m.group(1)
        ircbot.reply(uri)
        if not hasattr(ircbot.bot, 'last_seen_uri'):
            ircbot.bot.last_seen_uri = {}
        ircbot.bot.last_seen_uri[input.sender] = uri
    else:
        ircbot.reply("No results found for '%s'." % query)
Exemple #22
0
def wiktionary(word):
    uri = 'http://en.wiktionary.org/w/index.php?title=%s&printable=yes'
    bytes = web.get(uri % web.urllib.quote(word.encode('utf-8')))
    bytes = re.compile(r'(?ims)<ul>.*?</ul>').sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="' in line:
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Exemple #23
0
def wiktionary(word):
    uri = 'http://en.wiktionary.org/w/index.php?title=%s&printable=yes'
    bytes = web.get(uri % web.urllib.quote(word.encode('utf-8')))
    bytes = re.compile(r'(?ims)<ul>.*?</ul>').sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="' in line:
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Exemple #24
0
def wikipedia(term, language='en', last=False):
    global wikiuri
    if not '%' in term:
        if isinstance(term, unicode):
            t = term.encode('utf-8')
        else:
            t = term
        q = urllib.quote(t)
        u = wikiuri % (language, q)
        bytes = web.get(u)
    else:
        bytes = web.get(wikiuri % (language, term))
    bytes = r_tr.sub('', bytes)

    if not last:
        r = r_redirect.search(bytes[:4096])
        if r:
            term = urllib.unquote(r.group(1))
            return wikipedia(term, language=language, last=True)

    paragraphs = r_paragraph.findall(bytes)

    if not paragraphs:
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None

    # Pre-process
    paragraphs = [
        para for para in paragraphs
        if (para and 'technical limitations' not in para
            and 'window.showTocToggle' not in para and 'Deletion_policy' not in
            para and 'Template:AfD_footer' not in para
            and not (para.startswith('<p><i>') and para.endswith('</i></p>'))
            and not 'disambiguation)"' in para) and not '(images and media)' in
        para and not 'This article contains a' in para
        and not 'id="coordinates"' in para and not 'class="thumb' in para
    ]
    # and not 'style="display:none"' in para]

    for i, para in enumerate(paragraphs):
        para = para.replace('<sup>', '|')
        para = para.replace('</sup>', '|')
        paragraphs[i] = text(para).strip()

    # Post-process
    paragraphs = [
        para for para in paragraphs
        if (para and not (para.endswith(':') and len(para) < 150))
    ]

    para = text(paragraphs[0])
    m = r_sentence.match(para)

    if not m:
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None
    sentence = m.group(0)

    maxlength = 275
    if len(sentence) > maxlength:
        sentence = sentence[:maxlength]
        words = sentence[:-5].split(' ')
        words.pop()
        sentence = ' '.join(words) + ' [...]'

    if (('using the Article Wizard if you wish' in sentence)
            or ('or add a request for it' in sentence)
            or ('in existing articles' in sentence)):
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None

    sentence = '"' + sentence.replace('"', "'") + '"'
    sentence = sentence.decode('utf-8').encode('utf-8')
    wikiuri = wikiuri.decode('utf-8').encode('utf-8')
    term = term.decode('utf-8').encode('utf-8')
    return sentence + ' - ' + (wikiuri % (language, term))
Exemple #25
0
def f_weather(self, origin, match, args):
    """.weather <ICAO> - Show the weather at airport with the code <ICAO>."""
    if origin.sender == '#talis':
        if args[0].startswith('.weather '):
            return

    icao_code = match.group(2)
    if not icao_code:
        return self.msg(origin.sender, 'Try .weather London, for example?')

    icao_code = code(self, icao_code)

    if not icao_code:
        self.msg(origin.sender, 'No ICAO code found, sorry')
        return

    uri = 'http://weather.noaa.gov/pub/data/observations/metar/stations/%s.TXT'
    try:
        bytes = web.get(uri % icao_code)
    except AttributeError:
        raise GrumbleError('OH CRAP NOAA HAS GONE DOWN THE WEB IS BROKEN')
    if 'Not Found' in bytes:
        self.msg(origin.sender, icao_code+': no such ICAO code, or no NOAA data')
        return

    metar = bytes.splitlines().pop()
    metar = metar.split(' ')

    if len(metar[0]) == 4:
        metar = metar[1:]

    if metar[0].endswith('Z'):
        time = metar[0]
        metar = metar[1:]
    else:
        time = None

    if metar[0] == 'AUTO':
        metar = metar[1:]
    if metar[0] == 'VCU':
        self.msg(origin.sender, icao_code + ': no data provided')
        return

    if metar[0].endswith('KT'):
        wind = metar[0]
        metar = metar[1:]
    else:
        wind = None

    if ('V' in metar[0]) and (metar[0] != 'CAVOK'):
        metar = metar[1:]

    if ((len(metar[0]) == 4) or
         metar[0].endswith('SM')):
        visibility = metar[0]
        metar = metar[1:]
    else:
        visibility = None

    while metar[0].startswith('R') and (metar[0].endswith('L') or 'L/' in metar[0]):
        metar = metar[1:]

    if len(metar[0]) == 6 and (metar[0].endswith('N') or
                                        metar[0].endswith('E') or
                                        metar[0].endswith('S') or
                                        metar[0].endswith('W')):
        metar = metar[1:] # 7000SE?

    cond = []
    while (((len(metar[0]) < 5) or
             metar[0].startswith('+') or
             metar[0].startswith('-')) and (not (metar[0].startswith('VV') or
             metar[0].startswith('SKC') or metar[0].startswith('CLR') or
             metar[0].startswith('FEW') or metar[0].startswith('SCT') or
             metar[0].startswith('BKN') or metar[0].startswith('OVC')))):
        cond.append(metar[0])
        metar = metar[1:]

    while '/P' in metar[0]:
        metar = metar[1:]

    if not metar:
        self.msg(origin.sender, icao_code + ': no data provided')
        return

    cover = []
    while (metar[0].startswith('VV') or metar[0].startswith('SKC') or
             metar[0].startswith('CLR') or metar[0].startswith('FEW') or
             metar[0].startswith('SCT') or metar[0].startswith('BKN') or
             metar[0].startswith('OVC')):
        cover.append(metar[0])
        metar = metar[1:]
        if not metar:
            self.msg(origin.sender, icao_code + ': no data provided')
            return

    if metar[0] == 'CAVOK':
        cover.append('CLR')
        metar = metar[1:]

    if metar[0] == 'PRFG':
        cover.append('CLR') # @@?
        metar = metar[1:]

    if metar[0] == 'NSC':
        cover.append('CLR')
        metar = metar[1:]

    if ('/' in metar[0]) or (len(metar[0]) == 5 and metar[0][2] == '.'):
        temp = metar[0]
        metar = metar[1:]
    else:
        temp = None

    if metar[0].startswith('QFE'):
        metar = metar[1:]

    if metar[0].startswith('Q') or metar[0].startswith('A'):
        pressure = metar[0]
        metar = metar[1:]
    else:
        pressure = None

    if time:
        hour = time[2:4]
        minute = time[4:6]
        time = local(icao_code, hour, minute)
    else:
        time = '(time unknown)'

    if wind:
        speed = int(wind[3:5])
        if speed < 1:
            description = 'Calm'
        elif speed < 4:
            description = 'Light air'
        elif speed < 7:
            description = 'Light breeze'
        elif speed < 11:
            description = 'Gentle breeze'
        elif speed < 16:
            description = 'Moderate breeze'
        elif speed < 22:
            description = 'Fresh breeze'
        elif speed < 28:
            description = 'Strong breeze'
        elif speed < 34:
            description = 'Near gale'
        elif speed < 41:
            description = 'Gale'
        elif speed < 48:
            description = 'Strong gale'
        elif speed < 56:
            description = 'Storm'
        elif speed < 64:
            description = 'Violent storm'
        else:
            description = 'Hurricane'

        degrees = wind[0:3]
        if degrees == 'VRB':
            degrees = u'\u21BB'.encode('utf-8')
        elif (degrees <= 22.5) or (degrees > 337.5):
            degrees = u'\u2191'.encode('utf-8')
        elif (degrees > 22.5) and (degrees <= 67.5):
            degrees = u'\u2197'.encode('utf-8')
        elif (degrees > 67.5) and (degrees <= 112.5):
            degrees = u'\u2192'.encode('utf-8')
        elif (degrees > 112.5) and (degrees <= 157.5):
            degrees = u'\u2198'.encode('utf-8')
        elif (degrees > 157.5) and (degrees <= 202.5):
            degrees = u'\u2193'.encode('utf-8')
        elif (degrees > 202.5) and (degrees <= 247.5):
            degrees = u'\u2199'.encode('utf-8')
        elif (degrees > 247.5) and (degrees <= 292.5):
            degrees = u'\u2190'.encode('utf-8')
        elif (degrees > 292.5) and (degrees <= 337.5):
            degrees = u'\u2196'.encode('utf-8')

        if not icao_code.startswith('EN') and not icao_code.startswith('ED'):
            wind = '%s %skt (%s)' % (description, speed, degrees)
        elif icao_code.startswith('ED'):
            kmh = int(round(speed * 1.852, 0))
            wind = '%s %skm/h (%skt) (%s)' % (description, kmh, speed, degrees)
        elif icao_code.startswith('EN'):
            ms = int(round(speed * 0.514444444, 0))
            wind = '%s %sm/s (%skt) (%s)' % (description, ms, speed, degrees)
    else:
        wind = '(wind unknown)'

    if visibility:
        visibility = visibility + 'm'
    else:
        visibility = '(visibility unknown)'

    if cover:
        level = None
        for c in cover:
            if c.startswith('OVC') or c.startswith('VV'):
                if (level is None) or (level < 8):
                    level = 8
            elif c.startswith('BKN'):
                if (level is None) or (level < 5):
                    level = 5
            elif c.startswith('SCT'):
                if (level is None) or (level < 3):
                    level = 3
            elif c.startswith('FEW'):
                if (level is None) or (level < 1):
                    level = 1
            elif c.startswith('SKC') or c.startswith('CLR'):
                if level is None:
                    level = 0

        if level == 8:
            cover = u'Overcast \u2601'.encode('utf-8')
        elif level == 5:
            cover = 'Cloudy'
        elif level == 3:
            cover = 'Scattered'
        elif (level == 1) or (level == 0):
            cover = u'Clear \u263C'.encode('utf-8')
        else:
            cover = 'Cover Unknown'
    else:
        cover = 'Cover Unknown'

    if temp:
        if '/' in temp:
            temp = temp.split('/')[0]
        else:
            temp = temp.split('.')[0]
        if temp.startswith('M'):
            temp = '-' + temp[1:]
        try:
            temp = int(temp)
        except ValueError:
            temp = '?'
    else:
        temp = '?'

    if pressure:
        if pressure.startswith('Q'):
            pressure = pressure.lstrip('Q')
            if pressure != 'NIL':
                pressure = str(int(pressure)) + 'mb'
            else:
                pressure = '?mb'
        elif pressure.startswith('A'):
            pressure = pressure.lstrip('A')
            if pressure != 'NIL':
                inches = pressure[:2] + '.' + pressure[2:]
                mb = int(float(inches) * 33.7685)
                pressure = '%sin (%smb)' % (inches, mb)
            else:
                pressure = '?mb'

            if isinstance(temp, int):
                f = round((temp * 1.8) + 32, 2)
                temp = u'%s\u2109 (%s\u2103)'.encode('utf-8') % (f, temp)
    else:
        pressure = '?mb'
    if isinstance(temp, int):
        temp = u'%s\u2103'.encode('utf-8') % temp

    if cond:
        conds = cond
        cond = ''

        intensities = {
            '-': 'Light',
            '+': 'Heavy'
        }

        descriptors = {
            'MI': 'Shallow',
            'PR': 'Partial',
            'BC': 'Patches',
            'DR': 'Drifting',
            'BL': 'Blowing',
            'SH': 'Showers of',
            'TS': 'Thundery',
            'FZ': 'Freezing',
            'VC': 'In the vicinity:'
        }

        phenomena = {
            'DZ': 'Drizzle',
            'RA': 'Rain',
            'SN': 'Snow',
            'SG': 'Snow Grains',
            'IC': 'Ice Crystals',
            'PL': 'Ice Pellets',
            'GR': 'Hail',
            'GS': 'Small Hail',
            'UP': 'Unknown Precipitation',
            'BR': 'Mist',
            'FG': 'Fog',
            'FU': 'Smoke',
            'VA': 'Volcanic Ash',
            'DU': 'Dust',
            'SA': 'Sand',
            'HZ': 'Haze',
            'PY': 'Spray',
            'PO': 'Whirls',
            'SQ': 'Squalls',
            'FC': 'Tornado',
            'SS': 'Sandstorm',
            'DS': 'Duststorm',
            # ? Cf. http://swhack.com/logs/2007-10-05#T07-58-56
            'TS': 'Thunderstorm',
            'SH': 'Showers'
        }

        for c in conds:
            if c.endswith('//'):
                if cond:
                    cond += ', '
                cond += 'Some Precipitation'
            elif len(c) == 5:
                intensity = intensities[c[0]]
                descriptor = descriptors[c[1:3]]
                phenomenon = phenomena.get(c[3:], c[3:])
                if cond:
                    cond += ', '
                cond += intensity + ' ' + descriptor + ' ' + phenomenon
            elif len(c) == 4:
                descriptor = descriptors.get(c[:2], c[:2])
                phenomenon = phenomena.get(c[2:], c[2:])
                if cond:
                    cond += ', '
                cond += descriptor + ' ' + phenomenon
            elif len(c) == 3:
                intensity = intensities.get(c[0], c[0])
                phenomenon = phenomena.get(c[1:], c[1:])
                if cond:
                    cond += ', '
                cond += intensity + ' ' + phenomenon
            elif len(c) == 2:
                phenomenon = phenomena.get(c, c)
                if cond:
                    cond += ', '
                cond += phenomenon

    if not cond:
        format = u'%s, %s, %s, %s - %s %s'
        args = (cover, temp, pressure, wind, str(icao_code), time)
    else:
        format = u'%s, %s, %s, %s, %s - %s, %s'
        args = (cover, temp, pressure, cond, wind, str(icao_code), time)

    self.msg(origin.sender, format.encode('utf-8') % args)
Exemple #26
0
def f_weather(self, origin, match, args):
    """.weather <ICAO> - Show the weather at airport with the code <ICAO>."""
    if origin.sender == '#talis':
        if args[0].startswith('.weather '):
            return

    icao_code = match.group(2)
    if not icao_code:
        return self.msg(origin.sender, 'Try .weather London, for example?')

    icao_code = code(self, icao_code)

    if not icao_code:
        self.msg(origin.sender, 'No ICAO code found, sorry')
        return

    uri = 'http://weather.noaa.gov/pub/data/observations/metar/stations/%s.TXT'
    try:
        bytes = web.get(uri % icao_code)
    except AttributeError:
        raise GrumbleError('OH CRAP NOAA HAS GONE DOWN THE WEB IS BROKEN')
    if 'Not Found' in bytes:
        self.msg(origin.sender,
                 icao_code + ': no such ICAO code, or no NOAA data')
        return

    metar = bytes.splitlines().pop()
    metar = metar.split(' ')

    if len(metar[0]) == 4:
        metar = metar[1:]

    if metar[0].endswith('Z'):
        time = metar[0]
        metar = metar[1:]
    else:
        time = None

    if metar[0] == 'AUTO':
        metar = metar[1:]
    if metar[0] == 'VCU':
        self.msg(origin.sender, icao_code + ': no data provided')
        return

    if metar[0].endswith('KT'):
        wind = metar[0]
        metar = metar[1:]
    else:
        wind = None

    if ('V' in metar[0]) and (metar[0] != 'CAVOK'):
        metar = metar[1:]

    if ((len(metar[0]) == 4) or metar[0].endswith('SM')):
        visibility = metar[0]
        metar = metar[1:]
    else:
        visibility = None

    while metar[0].startswith('R') and (metar[0].endswith('L')
                                        or 'L/' in metar[0]):
        metar = metar[1:]

    if len(metar[0]) == 6 and (metar[0].endswith('N') or metar[0].endswith('E')
                               or metar[0].endswith('S')
                               or metar[0].endswith('W')):
        metar = metar[1:]  # 7000SE?

    cond = []
    while (((len(metar[0]) < 5) or metar[0].startswith('+')
            or metar[0].startswith('-')) and
           (not (metar[0].startswith('VV') or metar[0].startswith('SKC')
                 or metar[0].startswith('CLR') or metar[0].startswith('FEW')
                 or metar[0].startswith('SCT') or metar[0].startswith('BKN')
                 or metar[0].startswith('OVC')))):
        cond.append(metar[0])
        metar = metar[1:]

    while '/P' in metar[0]:
        metar = metar[1:]

    if not metar:
        self.msg(origin.sender, icao_code + ': no data provided')
        return

    cover = []
    while (metar[0].startswith('VV') or metar[0].startswith('SKC')
           or metar[0].startswith('CLR') or metar[0].startswith('FEW')
           or metar[0].startswith('SCT') or metar[0].startswith('BKN')
           or metar[0].startswith('OVC')):
        cover.append(metar[0])
        metar = metar[1:]
        if not metar:
            self.msg(origin.sender, icao_code + ': no data provided')
            return

    if metar[0] == 'CAVOK':
        cover.append('CLR')
        metar = metar[1:]

    if metar[0] == 'PRFG':
        cover.append('CLR')  # @@?
        metar = metar[1:]

    if metar[0] == 'NSC':
        cover.append('CLR')
        metar = metar[1:]

    if ('/' in metar[0]) or (len(metar[0]) == 5 and metar[0][2] == '.'):
        temp = metar[0]
        metar = metar[1:]
    else:
        temp = None

    if metar[0].startswith('QFE'):
        metar = metar[1:]

    if metar[0].startswith('Q') or metar[0].startswith('A'):
        pressure = metar[0]
        metar = metar[1:]
    else:
        pressure = None

    if time:
        hour = time[2:4]
        minute = time[4:6]
        time = local(icao_code, hour, minute)
    else:
        time = '(time unknown)'

    if wind:
        speed = int(wind[3:5])
        if speed < 1:
            description = 'Calm'
        elif speed < 4:
            description = 'Light air'
        elif speed < 7:
            description = 'Light breeze'
        elif speed < 11:
            description = 'Gentle breeze'
        elif speed < 16:
            description = 'Moderate breeze'
        elif speed < 22:
            description = 'Fresh breeze'
        elif speed < 28:
            description = 'Strong breeze'
        elif speed < 34:
            description = 'Near gale'
        elif speed < 41:
            description = 'Gale'
        elif speed < 48:
            description = 'Strong gale'
        elif speed < 56:
            description = 'Storm'
        elif speed < 64:
            description = 'Violent storm'
        else:
            description = 'Hurricane'

        degrees = wind[0:3]
        if degrees == 'VRB':
            degrees = u'\u21BB'.encode('utf-8')
        elif (degrees <= 22.5) or (degrees > 337.5):
            degrees = u'\u2191'.encode('utf-8')
        elif (degrees > 22.5) and (degrees <= 67.5):
            degrees = u'\u2197'.encode('utf-8')
        elif (degrees > 67.5) and (degrees <= 112.5):
            degrees = u'\u2192'.encode('utf-8')
        elif (degrees > 112.5) and (degrees <= 157.5):
            degrees = u'\u2198'.encode('utf-8')
        elif (degrees > 157.5) and (degrees <= 202.5):
            degrees = u'\u2193'.encode('utf-8')
        elif (degrees > 202.5) and (degrees <= 247.5):
            degrees = u'\u2199'.encode('utf-8')
        elif (degrees > 247.5) and (degrees <= 292.5):
            degrees = u'\u2190'.encode('utf-8')
        elif (degrees > 292.5) and (degrees <= 337.5):
            degrees = u'\u2196'.encode('utf-8')

        if not icao_code.startswith('EN') and not icao_code.startswith('ED'):
            wind = '%s %skt (%s)' % (description, speed, degrees)
        elif icao_code.startswith('ED'):
            kmh = int(round(speed * 1.852, 0))
            wind = '%s %skm/h (%skt) (%s)' % (description, kmh, speed, degrees)
        elif icao_code.startswith('EN'):
            ms = int(round(speed * 0.514444444, 0))
            wind = '%s %sm/s (%skt) (%s)' % (description, ms, speed, degrees)
    else:
        wind = '(wind unknown)'

    if visibility:
        visibility = visibility + 'm'
    else:
        visibility = '(visibility unknown)'

    if cover:
        level = None
        for c in cover:
            if c.startswith('OVC') or c.startswith('VV'):
                if (level is None) or (level < 8):
                    level = 8
            elif c.startswith('BKN'):
                if (level is None) or (level < 5):
                    level = 5
            elif c.startswith('SCT'):
                if (level is None) or (level < 3):
                    level = 3
            elif c.startswith('FEW'):
                if (level is None) or (level < 1):
                    level = 1
            elif c.startswith('SKC') or c.startswith('CLR'):
                if level is None:
                    level = 0

        if level == 8:
            cover = u'Overcast \u2601'.encode('utf-8')
        elif level == 5:
            cover = 'Cloudy'
        elif level == 3:
            cover = 'Scattered'
        elif (level == 1) or (level == 0):
            cover = u'Clear \u263C'.encode('utf-8')
        else:
            cover = 'Cover Unknown'
    else:
        cover = 'Cover Unknown'

    if temp:
        if '/' in temp:
            temp = temp.split('/')[0]
        else:
            temp = temp.split('.')[0]
        if temp.startswith('M'):
            temp = '-' + temp[1:]
        try:
            temp = int(temp)
        except ValueError:
            temp = '?'
    else:
        temp = '?'

    if pressure:
        if pressure.startswith('Q'):
            pressure = pressure.lstrip('Q')
            if pressure != 'NIL':
                pressure = str(int(pressure)) + 'mb'
            else:
                pressure = '?mb'
        elif pressure.startswith('A'):
            pressure = pressure.lstrip('A')
            if pressure != 'NIL':
                inches = pressure[:2] + '.' + pressure[2:]
                mb = int(float(inches) * 33.7685)
                pressure = '%sin (%smb)' % (inches, mb)
            else:
                pressure = '?mb'

            if isinstance(temp, int):
                f = round((temp * 1.8) + 32, 2)
                temp = u'%s\u2109 (%s\u2103)'.encode('utf-8') % (f, temp)
    else:
        pressure = '?mb'
    if isinstance(temp, int):
        temp = u'%s\u2103'.encode('utf-8') % temp

    if cond:
        conds = cond
        cond = ''

        intensities = {'-': 'Light', '+': 'Heavy'}

        descriptors = {
            'MI': 'Shallow',
            'PR': 'Partial',
            'BC': 'Patches',
            'DR': 'Drifting',
            'BL': 'Blowing',
            'SH': 'Showers of',
            'TS': 'Thundery',
            'FZ': 'Freezing',
            'VC': 'In the vicinity:'
        }

        phenomena = {
            'DZ': 'Drizzle',
            'RA': 'Rain',
            'SN': 'Snow',
            'SG': 'Snow Grains',
            'IC': 'Ice Crystals',
            'PL': 'Ice Pellets',
            'GR': 'Hail',
            'GS': 'Small Hail',
            'UP': 'Unknown Precipitation',
            'BR': 'Mist',
            'FG': 'Fog',
            'FU': 'Smoke',
            'VA': 'Volcanic Ash',
            'DU': 'Dust',
            'SA': 'Sand',
            'HZ': 'Haze',
            'PY': 'Spray',
            'PO': 'Whirls',
            'SQ': 'Squalls',
            'FC': 'Tornado',
            'SS': 'Sandstorm',
            'DS': 'Duststorm',
            # ? Cf. http://swhack.com/logs/2007-10-05#T07-58-56
            'TS': 'Thunderstorm',
            'SH': 'Showers'
        }

        for c in conds:
            if c.endswith('//'):
                if cond:
                    cond += ', '
                cond += 'Some Precipitation'
            elif len(c) == 5:
                intensity = intensities[c[0]]
                descriptor = descriptors[c[1:3]]
                phenomenon = phenomena.get(c[3:], c[3:])
                if cond:
                    cond += ', '
                cond += intensity + ' ' + descriptor + ' ' + phenomenon
            elif len(c) == 4:
                descriptor = descriptors.get(c[:2], c[:2])
                phenomenon = phenomena.get(c[2:], c[2:])
                if cond:
                    cond += ', '
                cond += descriptor + ' ' + phenomenon
            elif len(c) == 3:
                intensity = intensities.get(c[0], c[0])
                phenomenon = phenomena.get(c[1:], c[1:])
                if cond:
                    cond += ', '
                cond += intensity + ' ' + phenomenon
            elif len(c) == 2:
                phenomenon = phenomena.get(c, c)
                if cond:
                    cond += ', '
                cond += phenomenon

    if not cond:
        format = u'%s, %s, %s, %s - %s %s'
        args = (cover, temp, pressure, wind, str(icao_code), time)
    else:
        format = u'%s, %s, %s, %s, %s - %s, %s'
        args = (cover, temp, pressure, cond, wind, str(icao_code), time)

    self.msg(origin.sender, format.encode('utf-8') % args)
Exemple #27
0
def wikipedia(term, language='en', last=False):
    global wikiuri
    if not '%' in term:
        if isinstance(term, unicode):
            t = term.encode('utf-8')
        else:
            t = term
        q = urllib.quote(t)
        u = wikiuri % (language, q)
        bytes = web.get(u)
    else:
        bytes = web.get(wikiuri % (language, term))
    bytes = r_tr.sub('', bytes)

    if not last:
        r = r_redirect.search(bytes[:4096])
        if r:
            term = urllib.unquote(r.group(1))
            return wikipedia(term, language=language, last=True)

    paragraphs = r_paragraph.findall(bytes)

    if not paragraphs:
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None

    # Pre-process
    paragraphs = [para for para in paragraphs
                      if (para and 'technical limitations' not in para
                                  and 'window.showTocToggle' not in para
                                  and 'Deletion_policy' not in para
                                  and 'Template:AfD_footer' not in para
                                  and not (para.startswith('<p><i>') and
                                              para.endswith('</i></p>'))
                                  and not 'disambiguation)"' in para)
                                  and not '(images and media)' in para
                                  and not 'This article contains a' in para
                                  and not 'id="coordinates"' in para
                                  and not 'class="thumb' in para]
                                  # and not 'style="display:none"' in para]

    for i, para in enumerate(paragraphs):
        para = para.replace('<sup>', '|')
        para = para.replace('</sup>', '|')
        paragraphs[i] = text(para).strip()

    # Post-process
    paragraphs = [para for para in paragraphs if
                      (para and not (para.endswith(':') and len(para) < 150))]

    para = text(paragraphs[0])
    m = r_sentence.match(para)

    if not m:
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None
    sentence = m.group(0)

    maxlength = 275
    if len(sentence) > maxlength:
        sentence = sentence[:maxlength]
        words = sentence[:-5].split(' ')
        words.pop()
        sentence = ' '.join(words) + ' [...]'

    if (('using the Article Wizard if you wish' in sentence)
     or ('or add a request for it' in sentence)
     or ('in existing articles' in sentence)):
        if not last:
            term = search(term)
            return wikipedia(term, language=language, last=True)
        return None

    sentence = '"' + sentence.replace('"', "'") + '"'
    sentence = sentence.decode('utf-8').encode('utf-8')
    wikiuri = wikiuri.decode('utf-8').encode('utf-8')
    term = term.decode('utf-8').encode('utf-8')
    return sentence + ' - ' + (wikiuri % (language, term))