Beispiel #1
0
    def distance(self, event, unit, ignore, src, dst):
        unit_names = self.unit_names
        if unit and unit not in self.unit_names:
            event.addresponse(u"I don't know the unit '%(badunit)s'. I know about: %(knownunits)s", {
                'badunit': unit,
                'knownunits':
                    human_join(u"%s (%s)" % (unit, self.unit_names[unit])
                        for unit in self.unit_names),
            })
            return
        if unit:
            unit_names = [unit]

        srcp, dstp = self.get_place(src), self.get_place(dst)
        if not srcp or not dstp:
            event.addresponse(u"I don't know of anywhere called %s",
                    (u" or ".join("'%s'" % place[0]
                        for place in ((src, srcp), (dst, dstp)) if not place[1])))
            return

        dist = acos(cos(srcp['lng']) * cos(dstp['lng']) * cos(srcp['lat']) * cos(dstp['lat']) +
                    cos(srcp['lat']) * sin(srcp['lng']) * cos(dstp['lat']) * sin(dstp['lng']) +
                    sin(srcp['lat'])*sin(dstp['lat']))

        event.addresponse(u"Approximate distance, as the bot flies, between %(srcname)s and %(dstname)s is: %(distance)s", {
            'srcname': srcp['name'],
            'dstname': dstp['name'],
            'distance': human_join([
                u"%.02f %s" % (self.radius_values[unit]*dist, self.unit_names[unit])
                for unit in unit_names],
                conjunction=u'or'),
        })
Beispiel #2
0
    def __unicode__(self):
        msgs = []
        if self.definition():
            msgs = [u'it means %s' % self.definition()]

        msgs += self.variant()

        prons = []
        for reading, lang in ((self.pinyin, 'pinyin'),
                                (self.korean, 'Korean'),
                                (self.japanese_on, 'Japanese on'),
                                (self.japanese_kun, 'Japanese kun')):
            readings = reading()
            if readings:
                prons.append(u'%(readings)s (%(lang)s)' %
                                {'readings': human_join(readings, conjunction=u'or'), 'lang': lang})

        if prons:
            msgs.append(u'it is pronounced ' +
                            human_join(prons, conjunction=u'or'))

        msg =  u'; '.join(msgs)
        if msg:
            msg = msg[0].upper() + msg[1:]
        return msg
Beispiel #3
0
    def define(self, event, word, dictionary):
        connection = Connection(self.server, self.port)
        dictionary = dictionary is None and '*' or dictionary.lower()
        dictionaries = connection.getdbdescs().keys()

        if dictionary != '*' and dictionary not in dictionaries:
            event.addresponse(
                    u"I'm afraid I don't have a dictionary of that name. I know about: %s",
                    human_join(sorted(dictionaries)))
            return

        definitions = connection.define(dictionary, word.encode('utf-8'))
        if definitions:
            event.addresponse(u', '.join(d.getdefstr() for d in definitions))
        else:
            suggestions = connection.match(dictionary, 'lev', word.encode('utf-8'))
            if suggestions:
                event.addresponse(
                        u"I don't know about %(word)s. Maybe you meant %(suggestions)s?", {
                            'word': word,
                            'suggestions': human_join(
                                self.reduce_suggestions(suggestions),
                                conjunction=u'or'),
                })
            else:
                event.addresponse(u"I don't have a definition for that. Is it even a word?")
Beispiel #4
0
    def handle_spell(self, event, word, strategy):
        connection = Connection(self.server, self.port)
        word = word.encode('utf-8')
        strategies = connection.getstratdescs().keys()

        if connection.match('*', 'exact', word):
            event.addresponse(choice((
                u'That seems correct. Carry on',
                u'Looks good to me',
                u"Yup, that's a word all right",
                u'Yes, you *can* spell',
            )))
            return

        strategy = strategy is None and 'lev' or strategy.lower()
        if strategy not in strategies:
            event.addresponse(
                    u"I'm afraid I don't know about such a strategy. I know about: %s",
                    human_join(sorted(strategies)))

        suggestions = connection.match('*', strategy, word)
        if suggestions:
            event.addresponse(u'Suggestions: %s', human_join(
                    self.reduce_suggestions(suggestions), conjunction=u'or'))
        else:
            event.addresponse(u"That doesn't seem correct, but I can't find anything to suggest")
Beispiel #5
0
    def endgame(self, event):
        """Check if the game is over.

        If the game is over, announce the winners and return True. Otherwise
        return False.
        """

        if 2 * len(self.wolves) >= len(self.roles):
            # werewolves win
            event.addresponse(u'The werewolves devour the remaining '
                              u'villagers and win. OM NOM NOM.\n'
                              u'The winning werewolves were: %s',
                              human_join(self.wolves), conflate=False)
        elif not self.wolves:
            # villagers win
            event.addresponse(u'The villagers have defeated the werewolves. '
                              u'Vigilantism FTW.\n'
                              u'The surviving villagers were: %s',
                              human_join(self.roles), conflate=False)
        else:
            return False

        self.state = None
        werewolf_games.remove(self)
        return True
Beispiel #6
0
 def display_movie(self, movie):
     desc = u"%s: %s." % (movie.movieID, movie["long imdb title"])
     if len(movie.get("director", ())) > 0:
         desc += u" Dir: %s." % (human_join(x["name"] for x in movie["director"]))
     if len(movie.get("cast", ())) > 0:
         desc += u" Starring: %s." % (human_join(x["name"] for x in movie["cast"][:3]))
     if movie.has_key("rating"):
         desc += u" Rated: %.1f " % movie["rating"]
     desc += human_join(movie.get("genres", ()))
     desc += u" Plot: %s" % movie.get("plot outline", u"Unknown")
     return desc
Beispiel #7
0
 def display_episode(self, episode):
     desc = u"%s: %s s%02ie%02i %s(%s)." % (
             episode.movieID, episode["series title"], episode["season"],
             episode["episode"], episode["title"], episode["year"])
     if len(episode.get("director", ())) > 0:
         desc += u" Dir: %s." % (human_join(x["name"] for x in episode["director"]))
     if len(episode.get("cast", ())) > 0:
         desc += u" Starring: %s." % (human_join(x["name"] for x in episode["cast"][:3]))
     if episode.has_key("rating"):
         desc += u" Rated: %.1f " % episode["rating"]
     desc += human_join(episode.get("genres", ()))
     desc += u" Plot: %s" % episode.get("plot outline", u"Unknown")
     return desc
Beispiel #8
0
 def search(self, event, term):
     terms = re.split(r'(?u)[\s/?]', term)
     result = json_webservice(
         u'http://debtags.debian.net/dde/q/axi/cquery/%s' %
         u'/'.join(terms), {'t': 'json'})
     result = result['r']
     if not result['pkgs']:
         event.addresponse(u"Sorry, I couldn't find anything relevant. "
                           u"Try being less specific?")
         return
     event.addresponse(u"Packages: %(packages)s. "
                       u"Not there? Try these terms: %(suggested)s", {
         'packages': human_join(pkg[1] for pkg in result['pkgs']),
         'suggested': human_join(result['sugg']),
     })
Beispiel #9
0
    def playing(self, event, stream):
        if not event.get('addressed', False):
            return

        if len(self.streams) == 0:
            event.addresponse(u"Sorry, I don't know about any streams")
            return
        elif stream is None and len(self.streams) == 1:
            stream = self.streams.keys()[0]
        elif stream is not None and stream not in self.streams:
            for name in self.streams.iterkeys():
                if name.lower() == stream.lower():
                    stream = name
                    break
            else:
                stream = None
        if stream is None:
            event.addresponse(
                    u'Sorry, I only know about the following streams, '
                    u'please choose one: %s',
                    human_join(self.streams.keys()))
            return

        try:
            status = self.scrape_status(stream)
            event.addresponse(u'Currently Playing on %(stream)s: '
                u'%(song)s - %(description)s (Listeners: %(listeners)s)', {
                    'stream': stream,
                    'song': status['Current Song'],
                    'description': status['Stream Description'],
                    'listeners': status['Current Listeners'],
                })
        except HTTPError:
            event.addresponse(u'The stream must be down, back to the MP3 collection for you')
Beispiel #10
0
    def search(self, event, term, distro, arch):
        distro = distro and distro.lower() or self.distro
        arch = arch and arch.lower() or self.arch
        distro = distro + u'-' + arch
        if distro == u'all-all':
            distro = u'all'

        result = json_webservice(
            u'http://dde.debian.net/dde/q/aptfile/byfile/%s/%s' %
            (distro, quote(term)), {'t': 'json'})
        result = result['r']
        if result:
            if isinstance(result[0], list):
                bypkg = map(lambda x: (x[-1], u'/'.join(x[:-1])), result)
                numpackages = len(bypkg)
                packages = defaultdict(list)
                for p, arch in bypkg:
                    packages[p].append(arch)
                packages = map(lambda i: u'%s [%s]' % (i[0], u', '.join(i[1])),
                               packages.iteritems())
            else:
                numpackages = len(result)
                packages = result
            event.addresponse(u'Found %(num)i packages: %(names)s', {
                'num': numpackages,
                'names': human_join(packages),
            })
        else:
            event.addresponse(u'No packages found')
Beispiel #11
0
 def show(self, event, package, distro):
     if distro is None or distro.lower() == 'all':
         distro = 'all'
     else:
         if self._release_cache is None:
             self._release_cache = json_webservice(
                 u'http://dde.debian.net/dde/q/udd/packages', {
                     'list': '',
                     't': 'json',
                 })['r']
         releases = self._release_cache
         if distro not in releases:
             candidates = [x for x in releases if distro in x]
             if len(candidates) == 1:
                 distro = candidates[0]
             else:
                 event.addresponse(u"Sorry, I don't know about %(distro)s. "
                                   u"How about one of: %(releases)s?", {
                     'distro': distro,
                     'releases': human_join(
                         x.startswith('prio-') and x[5:] or x
                         for x in releases
                     ),})
                 return
     result = json_webservice(
         u'http://dde.debian.net/dde/q/udd/packages/%s/%s' %
         (distro, package), {'t': 'json'})
     result = result['r']
     if not result:
         event.addresponse(u"Sorry, I couldn't find anything of that name. "
                           u"Is it a binary package?")
         return
     event.addresponse(u'%(package)s %(version)s: %(description)s', result)
Beispiel #12
0
    def get(self, event, key):
        if 'password' in key.lower() and not auth_responses(event, u'config'):
            return

        option = self.find_option(key)
        if isinstance(option, dict):
            config = option
            key = ''
        elif option is not None:
            config = option[0].__get__(option[1], type(option[1]))
            key = option[2]
        elif key == 'plugins':
            # Construct a dictionary since this isn't a list-valued option,
            # but a list of option keys.
            config = dict((plugin, None) for plugin in list_plugins())
            key = ''
        elif key == 'sources':
            config = ibid.sources
            key = ''
        else:
            config = ibid.config

        if key:
            for part in key.split('.'):
                if not isinstance(config, dict) or part not in config:
                    event.addresponse(u'No such option')
                    return
                config = config[part]

        if isinstance(config, list):
            event.addresponse(u', '.join(config))
        elif isinstance(config, dict):
            event.addresponse(u'Keys: ' + human_join(config.keys()))
        else:
            event.addresponse(unicode(config))
Beispiel #13
0
 def query_carrying(self, event):
     items = Item.carried_items(event.session).all()
     if items:
         event.addresponse(u"I'm carrying %s",
                             human_join(map(unicode, items)))
     else:
         event.addresponse(u"I'm not carrying anything")
Beispiel #14
0
 def airport_search(self, event, search_loc, query):
     search_loc = search_loc is not None
     if not search_loc and not 3 <= len(query) <= 4:
         event.addresponse(u'Airport code must be 3 or 4 characters')
         return
     ids = self._airport_search(query, search_loc)
     if len(ids) == 0:
         event.addresponse(u"Sorry, I don't know that airport")
     elif len(ids) == 1:
         id = ids[0]
         airport = self.airports[id]
         code = u'unknown code'
         if airport[3] and airport[4]:
             code = u'codes %s and %s' % (airport[3], airport[4])
         elif airport[3]:
             code = u'code %s' % airport[3]
         elif airport[4]:
             code = u'code %s' % airport[4]
         event.addresponse(u'%(airport)s in %(city)s, %(country)s has %(code)s', {
             u'airport': airport[0],
             u'city': airport[1],
             u'country': airport[2],
             u'code': code,
         })
     else:
         event.addresponse(u'Found the following airports: %s', human_join(self.repr_airport(id) for id in ids)[:480])
Beispiel #15
0
    def resolve(self, event, record, host, nameserver):
        ipaddr = re.compile(r"\d+\.\d+\.\d+\.\d+")
        if not record:
            if ipaddr.search(host):
                host = from_address(host)
                record = "PTR"
            else:
                record = "A"

        resolver = Resolver()
        if nameserver:
            if not ipaddr.search(nameserver):
                nameserver = resolver.query(nameserver, "A")[0].address
            resolver.nameservers = [nameserver]

        try:
            answers = resolver.query(host, str(record))
        except NoAnswer:
            event.addresponse(u"I couldn't find any %(type)s records for %(host)s", {"type": record, "host": host})
            return
        except NXDOMAIN:
            event.addresponse(u"I couldn't find the domain %s", host)
            return

        responses = []
        for rdata in answers:
            responses.append(unicode(rdata))

        event.addresponse(u"Records: %s", human_join(responses))
Beispiel #16
0
 def portfor(self, event, proto):
     self._load_services()
     protocol = proto.lower()
     if protocol in self.protocols:
         event.addresponse(human_join(self.protocols[protocol]))
     else:
         event.addresponse(u"I don't know about that protocol")
Beispiel #17
0
 def list(self, event):
     feeds = event.session.query(Feed).all()
     if feeds:
         event.addresponse(u'I know about: %s', human_join(sorted([
             unicode(feed) for feed in feeds])))
     else:
         event.addresponse(u"I don't know about any feeds")
Beispiel #18
0
    def remote_tvrage(self, show):
        info_url = 'http://services.tvrage.com/tools/quickinfo.php?%s'

        info = urlopen(info_url % urlencode({'show': show.encode('utf-8')}))

        info = info.read()
        info = info.decode('utf-8')
        if info.startswith('No Show Results Were Found'):
            return
        info = info[5:].splitlines()
        show_info = [i.split('@', 1) for i in info]
        show_dict = dict(show_info)

        #check if there are actual airdates for Latest and Next Episode. None for Next
        #Episode does not neccesarily mean it is nor airing, just the date is unconfirmed.
        show_dict = defaultdict(lambda: 'None', show_info)

        for field in ('Latest Episode', 'Next Episode'):
            if field in show_dict:
                ep, name, date = show_dict[field].split('^', 2)
                count = date.count('/')
                format_from = {
                    0: '%Y',
                    1: '%b/%Y',
                    2: '%b/%d/%Y'
                }[count]
                format_to = ' '.join(('%d', '%B', '%Y')[-1 - count:])
                date = strftime(format_to, strptime(date, format_from))
                show_dict[field] = u'%s - "%s" - %s' % (ep, name, date)

        if 'Genres' in show_dict:
            show_dict['Genres'] = human_join(show_dict['Genres'].split(' | '))

        return show_dict
Beispiel #19
0
    def currency(self, event, place):
        if not self.currencies:
            self._load_currencies()

        results = defaultdict(list)
        for code, (c_places, name) in self.currencies.iteritems():
            for c_place in c_places:
                if re.search(place, c_place, re.I):
                    results[c_place].append(u'%s (%s)' % (name, code))
                    break

        if results:
            event.addresponse(
                human_join(u'%s uses %s' % (place, human_join(currencies))
                           for place, currencies in results.iteritems()))
        else:
            event.addresponse(u'No currencies found')
Beispiel #20
0
    def handler(self, event):
        plugins = []
        for processor in ibid.processors:
            if processor.name not in plugins:
                plugins.append(processor.name)

        event.addresponse(u'Plugins: %s',
                          human_join(sorted(plugins)) or u'none')
Beispiel #21
0
 def forecast(self, event, place):
     try:
         event.addresponse(u', '.join(self.remote_forecast(place)))
     except Weather.TooManyPlacesException, e:
         event.addresponse(u'Too many places match %(place)s: %(exception)s', {
             'place': place,
             'exception': human_join(e.args[0], separator=u';'),
         })
Beispiel #22
0
 def forecast(self, event, place):
     try:
         event.addresponse(u', '.join(self.remote_forecast(place)))
     except Weather.TooManyPlacesException, e:
         event.addresponse(u'Too many places match %(place)s: %(exception)s', {
             'place': place,
             'exception': human_join(e.args[0], separator=u';'),
         })
Beispiel #23
0
 def list(self, event):
     feeds = event.session.query(Feed).all()
     if feeds:
         event.addresponse(
             u'I know about: %s',
             human_join(sorted([unicode(feed) for feed in feeds])))
     else:
         event.addresponse(u"I don't know about any feeds")
Beispiel #24
0
    def distance(self, event, unit, ignore, src, dst):
        unit_names = self.unit_names
        if unit and unit not in self.unit_names:
            event.addresponse(
                u"I don't know the unit '%(badunit)s'. I know about: %(knownunits)s",
                {
                    'badunit':
                    unit,
                    'knownunits':
                    human_join(u"%s (%s)" % (unit, self.unit_names[unit])
                               for unit in self.unit_names),
                })
            return
        if unit:
            unit_names = [unit]

        srcp, dstp = self.get_place(src), self.get_place(dst)
        if not srcp or not dstp:
            event.addresponse(
                u"I don't know of anywhere called %s",
                (u" or ".join("'%s'" % place[0]
                              for place in ((src, srcp),
                                            (dst, dstp)) if not place[1])))
            return

        dist = acos(
            cos(srcp['lng']) * cos(dstp['lng']) * cos(srcp['lat']) *
            cos(dstp['lat']) + cos(srcp['lat']) * sin(srcp['lng']) *
            cos(dstp['lat']) * sin(dstp['lng']) +
            sin(srcp['lat']) * sin(dstp['lat']))

        event.addresponse(
            u"Approximate distance, as the bot flies, between %(srcname)s and %(dstname)s is: %(distance)s",
            {
                'srcname':
                srcp['name'],
                'dstname':
                dstp['name'],
                'distance':
                human_join([
                    u"%.02f %s" %
                    (self.radius_values[unit] * dist, self.unit_names[unit])
                    for unit in unit_names
                ],
                           conjunction=u'or'),
            })
Beispiel #25
0
 def weather(self, event, place):
     try:
         values = self.remote_weather(place)
         event.addresponse(u'In %(place)s at %(time)s: %(temp)s; Humidity: %(humidity)s; Wind: %(wind)s; Conditions: %(conditions)s; Sunrise/set: %(sunrise)s/%(sunset)s; Moonrise/set: %(moonrise)s/%(moonset)s', values)
     except Weather.TooManyPlacesException, e:
         event.addresponse(u'Too many places match %(place)s: %(exception)s', {
             'place': place,
             'exception': human_join(e.args[0], separator=u';'),
         })
Beispiel #26
0
 def _describe_category(self, event, category):
     """Respond with the help information for a category"""
     event.addresponse(u'I use the following features for %(description)s: '
                       u'%(features)s\n'
                       u'Ask me "how do I use ..." for more details.',
         {
             'description': category['description'].lower(),
             'features': human_join(sorted(category['features'])),
         }, conflate=False)
Beispiel #27
0
    def _parse_travelocity(self, etree):
        flights = []
        table = [
            t for t in etree.getiterator(u'table') if t.get(u'id') == u'tfGrid'
        ][0]
        trs = [t for t in table.getiterator(u'tr')]
        tr_index = 1
        while tr_index < len(trs):
            tds = []
            while True:
                new_tds = [t for t in trs[tr_index].getiterator(u'td')]
                tds.extend(new_tds)
                tr_index += 1
                if len(
                        filter(
                            lambda t: t.get(u'class').strip() ==
                            u'tfAirlineSeatsMR', new_tds)):
                    break
            flight = Flight()
            for td in tds:
                if td.get(u'class').strip() == u'tfAirline':
                    anchor = td.find(u'a')
                    if anchor is not None:
                        airline = anchor.text.strip()
                    else:
                        airline = td.text.split(u'\n')[0].strip()
                    flight.flight.append(
                        u'%s %s' % (airline, td.findtext(u'div').strip()))
                if td.get(u'class').strip() == u'tfDepart' and td.text:
                    flight.depart_time = td.text.split(u'\n')[0].strip()
                    flight.depart_ap = u'%s %s' % (td.findtext(
                        u'div').strip(), td.findtext(u'div/span').strip())
                if td.get(u'class').strip() == u'tfArrive' and td.text:
                    flight.arrive_time = td.text.split(u'\n')[0].strip()
                    span = td.find(u'span')
                    if span is not None and span.get(
                            u'class').strip() == u'tfNextDayDate':
                        flight.arrive_time = u'%s %s' % (flight.arrive_time,
                                                         span.text.strip()[2:])
                        span = [
                            s for s in td.find(u'div').getiterator(u'span')
                        ][1]
                        flight.arrive_ap = u'%s %s' % (
                            td.findtext(u'div').strip(), span.text.strip())
                    else:
                        flight.arrive_ap = u'%s %s' % (td.findtext(
                            u'div').strip(), td.findtext(u'div/span').strip())
                if td.get(u'class').strip() == u'tfTime' and td.text:
                    flight.duration = td.text.strip()
                    flight.stops = td.findtext(u'span/a').strip()
                if td.get(u'class').strip() in [u'tfPrice', u'tfPriceOr'
                                                ] and td.text:
                    flight.price = td.text.strip()
            flight.flight = human_join(flight.flight)
            flights.append(flight)

        return flights
Beispiel #28
0
 def placesearch(self, event, place):
     js = self.get_place_data(place, 10)
     if js['totalResultsCount'] == 0:
         event.addresponse(u"I don't know of anywhere even remotely like '%s'", place)
     else:
         event.addresponse(u"I can find: %s",
                 (human_join([u"%s, %s, %s" % (p['name'], p['adminName1'], p['countryName'])
                     for p in js['geonames'][:10]],
                     separator=u';')))
    def twitchList(self, event):
        twitch_names = []

        for broadcaster in self.twitchlist.iterate():
            twitch_names.append(broadcaster.name)

        message = u'The following people are being watched: %s' % \
                  (human_join(twitch_names))
        event.addresponse(message, address=False, processed=True)
Beispiel #30
0
    def currency(self, event, place):
        if not self.currencies:
            self._load_currencies()

        results = defaultdict(list)
        for code, (c_places, name) in self.currencies.iteritems():
            for c_place in c_places:
                if re.search(place, c_place, re.I):
                    results[c_place].append(u'%s (%s)' % (name, code))
                    break

        if results:
            event.addresponse(human_join(
                u'%s uses %s' % (place, human_join(currencies))
                for place, currencies in results.iteritems()
            ))
        else:
            event.addresponse(u'No currencies found')
Beispiel #31
0
 def variant(self):
     msgs = []
     for name in ('simplified', 'traditional'):
         variants = self.data['k' + name.title() + 'Variant'].split()[1::2]
         if variants:
             msgs.append(u'the %(name)s form is %(var)s' %
                         {'name': name,
                          'var': human_join(variants, conjunction='or')})
     return msgs
Beispiel #32
0
 def display_character(self, character):
     desc = u"%s: %s." % (character.characterID, character["long imdb name"])
     filmography = character.get("filmography", ())
     if len(filmography):
         more = (u"", u" etc")[len(filmography) > 5]
         desc += u" Appeared in %s%s." % (human_join(x["long imdb title"] for x in filmography[:5]), more)
     if character.has_key("introduction"):
         desc += u" Bio: %s" % character["introduction"]
     return desc
Beispiel #33
0
 def placesearch(self, event, place):
     js = self.get_place_data(place, 10)
     if js['totalResultsCount'] == 0:
         event.addresponse(u"I don't know of anywhere even remotely like '%s'", place)
     else:
         event.addresponse(u"I can find: %s",
                 (human_join([u"%s, %s, %s" % (p['name'], p['adminName1'], p['countryName'])
                     for p in js['geonames'][:10]],
                     separator=u';')))
Beispiel #34
0
 def intro(self, event):
     categories, features = self._get_features()
     categories = filter(lambda c: c['weight'] is not None,
                         categories.itervalues())
     categories = sorted(categories, key=lambda c: c['weight'])
     event.addresponse(
         u'I can help you with: %s.\n'
         u'Ask me "help me with ..." for more details.',
         human_join(c['description'].lower() for c in categories),
         conflate=False)
Beispiel #35
0
 def variant(self):
     msgs = []
     for name in ('simplified', 'traditional'):
         variants = self.data['k' + name.title() + 'Variant'].split()[1::2]
         if variants:
             msgs.append(u'the %(name)s form is %(var)s' % {
                 'name': name,
                 'var': human_join(variants, conjunction='or')
             })
     return msgs
Beispiel #36
0
 def _describe_category(self, event, category):
     """Respond with the help information for a category"""
     event.addresponse(
         u'I use the following features for %(description)s: '
         u'%(features)s\n'
         u'Ask me "how do I use ..." for more details.', {
             'description': category['description'].lower(),
             'features': human_join(sorted(category['features'])),
         },
         conflate=False)
Beispiel #37
0
 def display_company(self, company):
     desc = "%s: %s" % (company.companyID, company["long imdb name"])
     for key, title in (
             (u"production companies", u"Produced"),
             (u"distributors", u"Distributed"),
             (u"miscellaneous companies", u"Was involved in")):
         if len(company.get(key, ())) > 0:
             more = (u"", u" etc.")[len(company[key]) > 3]
             desc += u" %s %s%s" % (title, human_join(x["long imdb title"] for x in company[key][:3]), more)
     return desc
Beispiel #38
0
 def display_character(self, character):
     desc = u"%s: %s." % (character.characterID,
                          character["long imdb name"])
     filmography = character.get("filmography", ())
     if len(filmography):
         more = (u"", u" etc")[len(filmography) > 5]
         desc += u" Appeared in %s%s." % (human_join(
             x["long imdb title"] for x in filmography[:5]), more)
     if character.has_key("introduction"):
         desc += u" Bio: %s" % character["introduction"]
     return desc
Beispiel #39
0
    def ipcalc_deggregate(self, event, frm, to):
        code, output, error = self.call_ipcalc([frm, "-", to])

        if code == 0:
            if output.startswith(u"INVALID ADDRESS"):
                event.addresponse(u"That's an invalid address. " u"Try something like 192.168.1.0")
            else:
                event.addresponse(u"Deaggregates to: %s", human_join(output.splitlines()[1:]))
        else:
            error = unicode_output(error.strip())
            event.addresponse(error.replace(u"\n", u" "))
Beispiel #40
0
 def intro(self, event):
     categories, features = self._get_features()
     categories = categories.itervalues()
     if not ibid.auth.authorise(event, 'admin'):
         categories = filter(lambda c: c['weight'] is not None,
                             categories)
     categories = sorted(categories, key=lambda c: c['weight'])
     event.addresponse(u'I can help you with: %s.\n'
                       u'Ask me "help me with ..." for more details.',
         human_join(c['description'].lower() for c in categories),
         conflate=False)
Beispiel #41
0
    def country_to_tld(self, event, location):
        if not self.country_codes:
            self.country_codes = get_country_codes()

        output = []
        for tld, country in self.country_codes.iteritems():
            if location.lower() in country.lower():
                output.append(u"%(tld)s is the ccTLD for %(country)s" % {"tld": tld, "country": country})
        if output:
            event.addresponse(human_join(output))
        else:
            event.addresponse(u"ISO doesn't know about any TLD for %s", location)
Beispiel #42
0
 def display_company(self, company):
     desc = "%s: %s" % (company.companyID, company["long imdb name"])
     for key, title in ((u"production companies",
                         u"Produced"), (u"distributors", u"Distributed"),
                        (u"miscellaneous companies", u"Was involved in")):
         if len(company.get(key, ())) > 0:
             more = (u"", u" etc.")[len(company[key]) > 3]
             desc += u" %s %s%s" % (title,
                                    human_join(
                                        x["long imdb title"]
                                        for x in company[key][:3]), more)
     return desc
Beispiel #43
0
    def port(self, event, transport, number):
        self._load_services()
        results = []
        if transport:
            results.extend(self.ports.get('%s/%s' % (number, transport.lower()), []))
        else:
            for transport in ('tcp', 'udp', 'sctp'):
                results.extend('%s (%s)' % (protocol, transport.upper()) for protocol in self.ports.get('%s/%s' % (number, transport.lower()), []))

        if results:
            event.addresponse(human_join(results))
        else:
            event.addresponse(u"I don't know about any protocols using that port")
Beispiel #44
0
    def list_permissions(self, event):
        permissions = []
        for processor in ibid.processors:
            if hasattr(processor, 'permission') and getattr(
                    processor, 'permission') not in permissions:
                permissions.append(getattr(processor, 'permission'))
            if hasattr(processor, 'permissions'):
                for permission in getattr(processor, 'permissions'):
                    if permission not in permissions:
                        permissions.append(permission)

        event.addresponse(u'Permissions: %s',
                          human_join(sorted(permissions)) or u'none')
Beispiel #45
0
    def ipcalc_deggregate(self, event, frm, to):
        code, output, error = self.call_ipcalc([frm, '-', to])

        if code == 0:
            if output.startswith(u'INVALID ADDRESS'):
                event.addresponse(u"That's an invalid address. "
                                  u"Try something like 192.168.1.0")
            else:
                event.addresponse(u'Deaggregates to: %s',
                                  human_join(output.splitlines()[1:]))
        else:
            error = unicode_output(error.strip())
            event.addresponse(error.replace(u'\n', u' '))
Beispiel #46
0
    def weather(self, event, place):
        # The regex also matches "weather forecast..." which forecast should
        # process. So ignore it when this happens
        if place.lower().startswith('forecast'):
            return

        try:
            values = self.remote_weather(place)
            event.addresponse(u'In %(place)s at %(time)s: %(temp)s; Humidity: %(humidity)s; Wind: %(wind)s; Conditions: %(conditions)s; Sunrise/set: %(sunrise)s/%(sunset)s; Moonrise/set: %(moonrise)s/%(moonset)s', values)
        except Weather.TooManyPlacesException, e:
            event.addresponse(u'Too many places match %(place)s: %(exception)s', {
                'place': place,
                'exception': human_join(e.args[0], separator=u';'),
            })
Beispiel #47
0
    def weather(self, event, place):
        # The regex also matches "weather forecast..." which forecast should
        # process. So ignore it when this happens
        if place.lower().startswith('forecast'):
            return

        try:
            values = self.remote_weather(place)
            event.addresponse(u'In %(place)s at %(time)s: %(temp)s; Humidity: %(humidity)s; Wind: %(wind)s; Conditions: %(conditions)s; Sunrise/set: %(sunrise)s/%(sunset)s; Moonrise/set: %(moonrise)s/%(moonset)s', values)
        except Weather.TooManyPlacesException, e:
            event.addresponse(u'Too many places match %(place)s: %(exception)s', {
                'place': place,
                'exception': human_join(e.args[0], separator=u';'),
            })
Beispiel #48
0
class Nmap(Processor):
    usage = u"""port scan <hostname>
    net scan <network>/<prefix>"""

    feature = ('nmap', )
    permission = 'nmap'
    min_prefix = IntOption('min_prefix',
                           'Minimum network prefix that may be scanned', 24)

    def setup(self):
        if not file_in_path('nmap'):
            raise Exception("Cannot locate nmap executable")

    @match(r'^(?:port\s+scan|nmap)\s+([0-9a-z.-]+)$')
    @authorise()
    def host_scan(self, event, host):
        try:
            ip = gethostbyname(host)
        except gaierror, e:
            event.addresponse(unicode(e.args[1]))
            return

        if ip.startswith('127.'):
            event.addresponse(
                u"I'm not allowed to inspect my host's internal interface.")
            return

        output, error, code = get_process_output(
            ['nmap', '--open', '-n', host])

        ports = []
        gotports = False
        for line in output.splitlines():
            if gotports:
                if not line.split():
                    break
                port, state, service = line.split()
                ports.append('%s (%s)' % (port, service))
            else:
                if line.startswith('Note: Host seems down.'):
                    event.addresponse(u'That host seems to be down')
                    return
                if line.startswith('PORT'):
                    gotports = True

        if ports:
            event.addresponse(human_join(ports))
        else:
            event.addresponse(u'No open ports detected')
Beispiel #49
0
    def cs_players(self, event):
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        server.sendto('\xFF\xFF\xFF\xFFdetails', (self.cs_host, self.cs_port))
        server.settimeout(5)
        data = server.recv(16384)

        assert data.startswith('\xFF\xFF\xFF\xFFm')
        data = data[5:]

        address, hostname, map, mod, modname, details = data.split('\x00', 5)

        details = details[:5]  # We don't care about the rest
        clientcount, clientmax, protocol, type, os = struct.unpack(
            '<3Bcc', details)

        if clientcount == 0:
            event.addresponse(u'Nobody. Everyone must have lives...')
            return

        server.sendto('\xFF\xFF\xFF\xFFplayers', (self.cs_host, self.cs_port))
        data = server.recv(16384)

        assert data.startswith('\xFF\xFF\xFF\xFF')
        data = data[6:]

        players = []
        while data:
            player = {}
            data = data[1:]
            player['nickname'], data = data.split('\x00', 1)
            player['fragtotal'] = struct.unpack('<i', data[:4])[0]
            data = data[8:]
            players.append(player)

        players.sort(key=lambda x: x['fragtotal'], reverse=True)
        event.addresponse(
            u'There are %(clients)i/%(clientmax)s players playing %(map)s: %(players)s',
            {
                'clients':
                clientcount,
                'clientmax':
                clientmax,
                'map':
                map,
                'players':
                human_join(u'%s (%i)' % (p['nickname'], p['fragtotal'])
                           for p in players),
            })
Beispiel #50
0
    def query_giver(self, event, determiner, object):
        if determiner is None:
            determiner = ''

        who = event.sender['nick']
        if determiner.lower() == 'our':
            if who[-1] in 'sS':
                determiner = who + "'"
            else:
                determiner = who + "'s"
            yours = True
        elif determiner.lower() == 'my':
            determiner = who + "'s"
            yours = True
        else:
            yours = False

        kind, items = self.find_items(event.session, determiner, object)

        if items:
            explanation = u''
            if kind == 'unowned':
                explanation = plural(len(items),
                                     u". I didn't realise it was ",
                                     u". I didn't realise they were ")
                if yours:
                    explanation += u"yours"
                else:
                    explanation += determiner
                explanation += u"."
                yours = False

            event.addresponse(u'I got ' +
                human_join(u'%(item)s from %(giver)s' %
                                {'item':
                                    [item, u'your ' + item.description][yours],
                                'giver': identity_name(event, item.giver)}
                            for item in items)
                        + explanation)
            return
        else:
            if yours:
                object = u'your ' + object
            elif determiner:
                object = determiner + u' ' + object
            event.addresponse(choice((
                u"There's nothing like that in my bucket.",
                u"I don't have %s" % object)))
Beispiel #51
0
    def currency(self, event, place):
        if not self.currencies:
            self._load_currencies()

        search = re.compile(place, re.I)
        results = []
        for code, (places, name) in self.currencies.iteritems():
            for place in places:
                if search.search(place):
                    results.append(u'%s uses %s (%s)' % (place, name, code))
                    break

        if results:
            event.addresponse(human_join(results))
        else:
            event.addresponse(u'No currencies found')
Beispiel #52
0
    def country_to_tld(self, event, location):
        if not self.country_codes:
            self.country_codes = get_country_codes()

        output = []
        for tld, country in self.country_codes.iteritems():
            if location.lower() in country.lower():
                output.append(u'%(tld)s is the ccTLD for %(country)s' % {
                    'tld': tld,
                    'country': country,
                })
        if output:
            event.addresponse(human_join(output))
        else:
            event.addresponse(u"ISO doesn't know about any TLD for %s",
                              location)
Beispiel #53
0
    def net_scan(self, event, network, prefix):
        if int(prefix) < self.min_prefix:
            event.addresponse(u"Sorry, I can't scan networks with a prefix less than %s", self.min_prefix)
            return

        output, error, code = get_process_output(['nmap', '-sP', '-n', '%s/%s' % (network, prefix)])

        hosts = []
        for line in output.splitlines():
            if line.startswith('Host '):
                hosts.append(line.split()[1])

        if hosts:
            event.addresponse(human_join(hosts))
        else:
            event.addresponse(u'No hosts responded to pings')
Beispiel #54
0
    def get(self, event, key):
        if 'password' in key.lower() and not auth_responses(event, u'config'):
            return

        config = ibid.config
        for part in key.split('.'):
            if not isinstance(config, dict) or part not in config:
                event.addresponse(u'No such option')
                return
            config = config[part]
        if isinstance(config, list):
            event.addresponse(u', '.join(config))
        elif isinstance(config, dict):
            event.addresponse(u'Keys: ' + human_join(config.keys()))
        else:
            event.addresponse(unicode(config))
Beispiel #55
0
    def _find_timezone(self, string):
        for name, zonename in self.custom_zones.items():
            if string.lower() == name.lower():
                return gettz(zonename)

        zone = gettz(string)
        if zone:
            return zone

        zone = gettz(string.upper())
        if zone:
            return zone

        if string.lower() in self.lowerzones:
            return gettz(self.lowerzones[string.lower()])

        ccode = None
        for code, name in self.countries.items():
            if name.lower() == string.lower():
                ccode = code
        if not ccode:
            if string.replace('.', '').upper() in self.timezones:
                ccode = string.replace('.', '').upper()

        if ccode:
            if len(self.timezones[ccode]) == 1:
                return gettz(self.timezones[ccode][0])
            else:
                raise TimezoneException(u'%s has multiple timezones: %s' % (self.countries[ccode], human_join(self.timezones[ccode])))

        possibles = []
        for zones in self.timezones.values():
            for name in zones:
                if string.replace(' ', '_').lower() in [part.lower() for part in name.split('/')]:
                    possibles.append(name)

        if len(possibles) == 1:
            return gettz(possibles[0])
        elif len(possibles) > 1:
            raise TimezoneException(u'Multiple timezones found: %s' % (human_join(possibles)))

        zone = self._geonames_lookup(string)
        if zone:
            return zone

        raise TimezoneException(u"I don't know about the %s timezone" % (string,))
Beispiel #56
0
    def list(self, event, username):
        if not username:
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            account = event.session.query(Account).get(event.account)
        else:
            if not auth_responses(event, u'accounts'):
                return
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        permissions = sorted(u'%s%s' % (permission_values[perm.value], perm.name) for perm in account.permissions)
        event.addresponse(u'Permissions: %s', human_join(permissions) or u'none')
Beispiel #57
0
 def _usage_search(self, event, terms, features):
     terms = frozenset(self.stemmer.stemWord(term) for term in terms)
     results = set()
     for name, feat in features.iteritems():
         if terms.issubset(feat['usage_keywords']):
             results.add(name)
     results = sorted(results)
     if len(results) == 1:
         self._describe_feature(event, features[results[0]])
     elif len(results) > 1:
         event.addresponse(
             u"Please be more specific. I don't know if you mean %s",
             human_join((features[result]['name'] for result in results),
                        conjunction=u'or'))
     else:
         event.addresponse(
             u"I'm afraid I don't know what you are asking about. "
             u'Ask "what can you do" to browse my features.')
Beispiel #58
0
    def describe(self, event, username):
        if username.lower() == 'my':
            if not event.account:
                identity = event.session.query(Identity).get(event.identity)
                event.addresponse(u"%(name)s on %(source)s", {
                    'name': identity.identity,
                    'source': identity.source,
                })
                return
            account = event.session.query(Account).get(event.account)

        else:
            account = event.session.query(Account).filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        event.addresponse(u'%(accountname)s is %(identities)s', {
            'accountname': account.username,
            'identities': human_join(u'%s on %s' % (identity.identity, identity.source) for identity in account.identities),
        })
Beispiel #59
0
 def display_person(self, person):
     desc = u"%s: %s. %s." % (
         person.personID, person["name"],
         human_join(role.title() for role in (
             u"actor", u"animation department", u"art department",
             u"art director", u"assistant director", u"camera department",
             u"casting department", u"casting director", u"cinematographer",
             u"composer", u"costume department", u"costume designer",
             u"director", u"editorial department", u"editor",
             u"make up department", u"music department", u"producer",
             u"production designer", u"set decorator", u"sound department",
             u"speccial effects department", u"stunts",
             u"transport department", u"visual effects department",
             u"writer", u"miscellaneous crew") if person.has_key(role)))
     if person.has_key("mini biography"):
         desc += u" " + u" ".join(person["mini biography"])
     else:
         if person.has_key("birth name") or person.has_key("birth date"):
             desc += u" Born %s." % u", ".join(person[attr] for attr in (
                 "birth name", "birth date") if person.has_key(attr))
     return desc
Beispiel #60
0
    def describe_category(self, event, terms):
        categories, features = self._get_features()
        termset = frozenset(
            self.stemmer.stemWord(term) for term in terms.lower().split())

        if len(termset) == 1:
            term = list(termset)[0]
            exact = [c for c in categories.itervalues() if c['name'] == term]
            if exact:
                self._describe_category(event, exact[0])
                return

        results = []
        for name, cat in categories.iteritems():
            if termset.issubset(cat['description_keywords']):
                results.append(name)

        if len(results) == 0:
            for name, cat in categories.iteritems():
                if terms.lower() in cat['description'].lower():
                    results.append(name)

        results.sort()
        if len(results) == 1:
            self._describe_category(event, categories[results[0]])
            return
        elif len(results) > 1:
            event.addresponse(
                u"Please be more specific, I don't know if you mean %s.",
                human_join(
                    ('%s (%s)' % (categories[r]['description'].lower(), r)
                     for r in results),
                    conjunction=u'or'))
            return

        event.addresponse(
            u"I'm afraid I don't know what you are asking about. "
            u'Ask "what can you do" to browse my features.')