示例#1
0
    def _opencage_geocode(self, location):
        location = location.lower()
        apikey = self.registryValue('apikeys.opencage')
        if not apikey:
            raise callbacks.Error("No OpenCage API key.")

        url = "https://api.opencagedata.com/geocode/v1/json?q={0}&key={1}&abbrv=1&limit=1".format(
            utils.web.urlquote(location), apikey)
        self.log.debug('NuWeather: using url %s (geocoding)', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')

        data = json.loads(f)
        if data['status']['message'] != "OK":
            raise callbacks.Error("{0} from OpenCage for location {1}".format(
                data['status']['message'], location))

        data = data['results'][0]
        lat = data['geometry']['lat']
        lon = data['geometry']['lng']
        display_name = data['formatted']
        place_id = data['annotations']['geohash']

        self.log.debug(
            'NuWeather: saving %s,%s (place_id %s, %s) for location %s from OpenCage',
            lat, lon, place_id, display_name, location)
        result = (lat, lon, display_name, place_id, "OpenCage")
        return result
示例#2
0
    def _googlemaps_geocode(self, location):
        location = location.lower()
        apikey = self.registryValue('apikeys.googlemaps')
        if not apikey:
            raise callbacks.Error("No Google Maps API key.")

        url = "https://maps.googleapis.com/maps/api/geocode/json?address={0}&key={1}".format(
            utils.web.urlquote(location), apikey)
        self.log.debug('NuWeather: using url %s (geocoding)', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')

        data = json.loads(f)
        if data['status'] != "OK":
            raise callbacks.Error(
                "{0} from Google Maps for location {1}".format(
                    data['status'], location))

        data = data['results'][0]
        lat = data['geometry']['location']['lat']
        lon = data['geometry']['location']['lng']
        display_name = data['formatted_address']
        place_id = data['place_id']

        self.log.debug(
            'NuWeather: saving %s,%s (place_id %s, %s) for location %s from Google Maps',
            lat, lon, place_id, display_name, location)
        result = (lat, lon, display_name, place_id, "Google\xa0Maps")
        return result
示例#3
0
    def _weatherstack_geocode(self, location):
        location = location.lower()
        apikey = self.registryValue('apikeys.weatherstack')
        if not apikey:
            raise callbacks.Error("No weatherstack API key.")

        url = "http://api.weatherstack.com/current?access_key={0}&query={1}".format(
            apikey, utils.web.urlquote(location))
        self.log.debug('NuWeather: using url %s (geocoding)', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')

        data = json.loads(f)
        if data.get('error'):
            raise callbacks.Error(
                "{0} From weatherstack for location {1}".format(
                    data['error']['info'], location))

        lat = data['location']['lat']
        lon = data['location']['lon']
        display_name = data['request']['query']
        place_id = "{0},{1}".format(lat, lon)

        self.log.debug(
            'NuWeather: saving %s,%s (place_id %s,%s) for location %s from weatherstack',
            lat, lon, place_id, display_name, location)
        result = (lat, lon, display_name, place_id, "weatherstack")
        return result
示例#4
0
 def assert_feed_does_not_exist(self, name, url=None):
     if self.isCommandMethod(name):
         s = format(_('I already have a command in this plugin named %s.'),
                    name)
         raise callbacks.Error(s)
     if url:
         feed = self.feeds.get(url)
         if feed and feed.name != feed.url:
             s = format(_('I already have a feed with that URL named %s.'),
                        feed.name)
             raise callbacks.Error(s)
示例#5
0
    def makeFeedCommand(self, name, url):
        docstring = format(
            """[<number of headlines>]

        Reports the titles for %s at the RSS feed %u.  If
        <number of headlines> is given, returns only that many headlines.
        RSS feeds are only looked up every supybot.plugins.RSS.waitPeriod
        seconds, which defaults to 1800 (30 minutes) since that's what most
        websites prefer.
        """, name, url)
        if url not in self.locks:
            self.locks[url] = threading.RLock()
        if self.isCommandMethod(name):
            s = format('I already have a command in this plugin named %s.',
                       name)
            raise callbacks.Error(s)

        def f(self, irc, msg, args):
            args.insert(0, url)
            self.rss(irc, msg, args)

        f = utils.python.changeFunctionName(f, name, docstring)
        f = types.MethodType(f, self)
        self.feedNames[name] = (url, f)
        self._registerFeed(name, url)
示例#6
0
    def _getDb(self, channel, debug=False):
        if channel in self.dbs:
            return self.dbs[channel]

        try:
            import sqlalchemy as sql
            self.sql = sql
        except ImportError:
            raise callbacks.Error('You need to have SQLAlchemy installed to use this ' \
                    'plugin.  Download it at <http://www.sqlalchemy.org/>')

        filename = plugins.makeChannelFilename(self.filename, channel)
        engine = sql.create_engine(self.engine + filename, echo=debug)
        metadata = sql.MetaData()
        firsts = sql.Table('firsts', metadata,
                           sql.Column('id', sql.Integer, primary_key=True),
                           sql.Column('first', sql.Text, unique=True),
                           sql.Column('count', sql.Integer, default=1),
                          )
        lasts = sql.Table('lasts', metadata,
                          sql.Column('id', sql.Integer, primary_key=True),
                          sql.Column('last', sql.Text, unique=True),
                          sql.Column('count', sql.Integer, default=1),
                         )
        pairs = sql.Table('pairs', metadata,
                          sql.Column('id', sql.Integer, primary_key=True),
                          sql.Column('first', sql.Text, default=sql.null),
                          sql.Column('second', sql.Text, default=sql.null),
                          sql.Column('follow', sql.Text, default=sql.null),
                          sql.Column('count', sql.Integer, default=1),
                          sql.UniqueConstraint('first', 'second', 'follow'),
                         )
        metadata.create_all(engine)
        self.dbs[channel] = (engine, firsts, lasts, pairs)
        return self.dbs[channel]
示例#7
0
    def _format(self, data, forecast=False):
        """
        Formats and returns current conditions.
        """
        # Work around IRC length limits for config opts...
        data['c'] = data['current']
        data['f'] = data.get('forecast')

        flat_data = flatten_subdicts(data)
        if flat_data.get('url'):
            flat_data['url'] = utils.str.url(flat_data['url'])

        forecast_available = bool(data.get('forecast'))
        if forecast:  # --forecast option was given
            if forecast_available:
                fmt = self.registryValue(
                    'outputFormat.forecast',
                    dynamic.msg.args[0]) or DEFAULT_FORECAST_FORMAT
            else:
                raise callbacks.Error(
                    _("Extended forecast info is not available from this backend."
                      ))
        else:
            if forecast_available:
                fmt = self.registryValue('outputFormat',
                                         dynamic.msg.args[0]) or DEFAULT_FORMAT
            else:
                fmt = self.registryValue(
                    'outputFormat.currentOnly',
                    dynamic.msg.args[0]) or DEFAULT_FORMAT_CURRENTONLY
        template = string.Template(fmt)

        return template.safe_substitute(flat_data)
示例#8
0
    def _geocode(self, location, geobackend=None):
        geocode_backend = geobackend or self.registryValue(
            'geocodeBackend', dynamic.msg.args[0])
        if geocode_backend not in GEOCODE_BACKENDS:
            raise callbacks.Error(
                _("Unknown geocode backend %r. Valid ones are: %s") %
                (geocode_backend, ', '.join(GEOCODE_BACKENDS)))

        result_pair = str(
            (location, geocode_backend))  # escape for json purposes
        if result_pair in self.geocode_db:
            self.log.debug('NuWeather: using cached latlon %s for location %r',
                           self.geocode_db[result_pair], location)
            return self.geocode_db[result_pair]
        elif location in self.geocode_db:
            # Old DBs from < 2019-03-14 only had one field storing location, and always
            # used OSM/Nominatim. Remove these old entries and regenerate them.
            self.log.debug('NuWeather: deleting outdated cached location %r',
                           location)
            del self.geocode_db[location]

        backend_func = getattr(self, '_%s_geocode' % geocode_backend)
        result = backend_func(location)
        self.geocode_db[result_pair] = result  # Cache result persistently
        return result
示例#9
0
    def _nominatim_geocode(self, location):
        location = location.lower()

        url = 'https://nominatim.openstreetmap.org/search/%s?format=jsonv2' % utils.web.urlquote(location)
        self.log.debug('NuWeather: using url %s (geocoding)', url)
        # Custom User agent & caching are required for Nominatim per https://operations.osmfoundation.org/policies/nominatim/
        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
        data = json.loads(f)
        if not data:
            raise callbacks.Error("Unknown location %s from OSM/Nominatim" % location)

        data = data[0]
        # Limit location verbosity to 3 divisions (e.g. City, Province/State, Country)
        display_name = data['display_name']
        display_name_parts = display_name.split(', ')
        if len(display_name_parts) > 3:
            if display_name_parts[-2].isdigit():  # Try to remove ZIP code-like divisions
                display_name_parts.pop(-2)
            display_name = ', '.join([display_name_parts[0]] + display_name_parts[-2:])

        lat = data['lat']
        lon = data['lon']
        osm_id = data.get('osm_id')
        self.log.debug('NuWeather: saving %s,%s (osm_id %s, %s) for location %s from OSM/Nominatim', lat, lon, osm_id, display_name, location)

        result = (lat, lon, display_name, osm_id, "OSM/Nominatim")
        return result
示例#10
0
 def _getIrc(self, network):
     irc = world.getIrc(network)
     if irc:
         return irc
     else:
         raise callbacks.Error('I\'m not currently connected to %s.' %
                               network)
示例#11
0
def get_file_opener(extension):
    if extension == 'lz4':
        try:
            return lz4.frame.open
        except AttributeError:
            raise callbacks.Error(
                _('Cannot open lz4 file, python3-lz4 0.23.1 or higher '
                  'is required.'))
示例#12
0
    def _darksky_fetcher(self, location, geobackend=None):
        """Grabs weather data from Dark Sky."""
        apikey = self.registryValue('apikeys.darksky')
        if not apikey:
            raise callbacks.Error(_("Please configure the Dark Sky API key in plugins.nuweather.apikeys.darksky."))

        # Convert location to lat,lon first
        latlon = self._geocode(location, geobackend=geobackend)
        if not latlon:
            raise callbacks.Error("Unknown location %s." % location)

        lat, lon, display_name, geocodeid, geocode_backend = latlon

        # Request US units - this is reflected (mi, mph) and processed in our output format as needed
        url = 'https://api.darksky.net/forecast/%s/%s,%s?units=us&exclude=minutely' % (apikey, lat, lon)
        self.log.debug('NuWeather: using url %s', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
        data = json.loads(f, strict=False)

        currentdata = data['currently']

        # N.B. Dark Sky docs tell to not expect any values to exist except the timestamp attached to the response
        return {
            'location': display_name,
            'poweredby': 'Dark\xa0Sky+' + geocode_backend,
            'url': 'https://darksky.net/forecast/%s,%s' % (lat, lon),
            'current': {
                'condition': currentdata.get('summary', 'N/A'),
                'temperature': self._format_temp(f=currentdata.get('temperature')),
                'feels_like': self._format_temp(f=currentdata.get('apparentTemperature')),
                'humidity': self._format_percentage(currentdata.get('humidity')),
                'precip': self._format_precip(mm=currentdata.get('precipIntensity')),
                'wind': self._format_distance(mi=currentdata.get('windSpeed', 0), speed=True),
                'wind_dir': self._wind_direction(currentdata.get('windBearing')),
                'uv': self._format_uv(currentdata.get('uvIndex')),
                'visibility': self._format_distance(mi=currentdata['visibility']),
            },
            'forecast': [{'dayname': self._get_dayname(forecastdata['time'], idx, tz=data['timezone']),
                          'max': self._format_temp(f=forecastdata['temperatureHigh']),
                          'min': self._format_temp(f=forecastdata['temperatureLow']),
                          'summary': forecastdata['summary'].rstrip('.')} for idx, forecastdata in enumerate(data['daily']['data'])]
        }
示例#13
0
        def setUp(self):
            super().setUp()

            self.myVerbose = verbosity.MESSAGES

            apikey = os.environ.get('AQICN_APIKEY')
            if not apikey:
                e = ("The aqicn API key has not been set. Please set the AQICN_APIKEY environment variable "
                     "and try again.")
                raise callbacks.Error(e)

            conf.supybot.plugins.AQI.apikey.setValue(apikey)
示例#14
0
 def _getSkype(self):
     if self._skype is None:
         username = self.registryValue("auth.username")
         password = self.registryValue("auth.password")
         if not username or not password:
             raise callbacks.Error(
                 _("Missing Skype username and/or password. "
                   "Configure them in supybot.plugins.SkypeRelay.auth.username "
                   "supybot.plugins.SkypeRelay.auth.password."))
         self._skype = Skype()
         self._skype.conn.liveLogin(username, password)
     return self._skype
示例#15
0
def getChannel(irc, msg, args):
    """Returns the channel the msg came over or the channel given in args.

    If the channel was given in args, args is modified (the channel is
    removed).
    """
    if args and msg.channel:
        if conf.supybot.reply.requireChannelCommandsToBeSentInChannel():
            if args[0] != msg.channel:
                s = 'Channel commands must be sent in the channel to which ' \
                    'they apply; if this is not the behavior you desire, ' \
                    'ask the bot\'s administrator to change the registry ' \
                    'variable ' \
                    'supybot.reply.requireChannelCommandsToBeSentInChannel ' \
                    'to False.'
                raise callbacks.Error(s)
        return args.pop(0)
    elif msg.channel:
        return msg.channel
    else:
        raise callbacks.Error('Command must be sent in a channel or ' \
                               'include a channel in its arguments.')
示例#16
0
def get_file_opener(extension):
    """Returns a callable suitable for opening a file with the provided
    extension."""
    if extension == 'lz4':
        try:
            return lz4.frame.open
        except AttributeError:
            raise callbacks.Error(
                _('Cannot open lz4 file, python3-lz4 0.23.1 or higher '
                  'is required.'))
    elif extension == 'diff_Index':
        return None
    else:
        raise ValueError(
            'Cannot open .%s files, unknown extension' % extension)
示例#17
0
    def _weatherstack_fetcher(self, location, geobackend=None):
        """Grabs weather data from weatherstack (formerly Apixu)."""
        apikey = self.registryValue('apikeys.weatherstack')
        if not apikey:
            raise callbacks.Error(
                _("Please configure the weatherstack API key in plugins.nuweather.apikeys.weatherstack . "
                  "Apixu users please see https://github.com/apilayer/weatherstack#readme"
                  ))
        # HTTPS is not supported on free accounts. Don't ask me why
        url = 'http://api.weatherstack.com/current?' + utils.web.urlencode(
            {
                'access_key': apikey,
                'query': location,
                'units': 'f',
            })
        self.log.debug('NuWeather: using url %s', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
        data = json.loads(f)

        currentdata = data['current']

        return {
            'location': data['request']['query'],
            'poweredby': 'weatherstack',
            'url': '',
            'current': {
                'condition':
                currentdata['weather_descriptions'][0],
                'temperature':
                self._format_temp(f=currentdata['temperature']),
                'feels_like':
                self._format_temp(f=currentdata['feelslike']),
                'humidity':
                self._format_percentage(currentdata['humidity']),
                'precip':
                self._format_precip(inches=currentdata['precip']),
                'wind':
                self._format_distance(mi=currentdata['wind_speed'],
                                      speed=True),
                'wind_dir':
                currentdata['wind_dir'],
                'uv':
                self._format_uv(currentdata['uv_index']),
                'visibility':
                self._format_distance(mi=currentdata.get('visibility')),
            }
        }
示例#18
0
    def _wuac(self, q, return_names=False):
        """Internal helper to find locations via Wunderground's GeoLookup API.
        Previous versions of this plugin used the Autocompete API instead."""

        if q.startswith('zmw:'):
            # If we're given a ZMW code, just return it as is.
            return [q]

        apikey = self.registryValue('apiKey')
        if not apikey:
            raise callbacks.Error(
                "No Wunderground API key was defined; set "
                "the 'plugins.Weather.apiKey' config variable.")

        url = 'http://api.wunderground.com/api/%s/geolookup/q/%s.json' % (
            apikey, utils.web.urlquote(q))
        self.log.debug("Weather: GeoLookup URL %s", url)
        page = utils.web.getUrl(url, timeout=5)
        data = json.loads(page.decode('utf-8'))

        if data.get('location'):
            # This form is used when there's only one result.
            zmw = 'zmw:{zip}.{magic}.{wmo}'.format(**data['location'])
            if return_names:
                name = self._format_geolookup_name(data['location'])
                return [(name, zmw)]
            else:
                return [zmw]
        else:
            if data['response'].get('error'):
                errdata = data['response']['error']
                raise WeatherAPIError(
                    'Error in _wuac step: [%s] %s' %
                    (errdata.get('type', 'N/A'),
                     errdata.get('description', 'No message specified')))
            # This form of result is returned there are multiple places matching a query
            results = data['response'].get('results')
            if not results:
                return []

            if return_names:
                results = [(self._format_geolookup_name(result),
                            'zmw:' + result['zmw']) for result in results]
            else:
                results = [('zmw:' + result['zmw']) for result in results]
            return results
示例#19
0
    def _apixu_fetcher(self, location, geobackend=None):
        """Grabs weather data from Apixu."""
        apikey = self.registryValue('apikeys.apixu')
        if not apikey:
            raise callbacks.Error(_("Please configure the apixu API key in plugins.nuweather.apikeys.apixu."))
        url = 'https://api.apixu.com/v1/forecast.json?' + utils.web.urlencode({
            'key': apikey,
            'q': location,
            'days': 5
        })
        self.log.debug('NuWeather: using url %s', url)

        f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
        data = json.loads(f)

        locationdata = data['location']
        if locationdata['region']:
            location = "%s, %s, %s" % (locationdata['name'], locationdata['region'], locationdata['country'])
        else:
            location = "%s, %s" % (locationdata['name'], locationdata['country'])

        currentdata = data['current']

        return {
            'location': location,
            'poweredby': 'Apixu',
            'url': '',
            'current': {
                'condition': currentdata['condition']['text'],
                'temperature': self._format_temp(currentdata['temp_f'], currentdata['temp_c']),
                'feels_like': self._format_temp(currentdata['feelslike_f'], currentdata['feelslike_c']),
                'humidity': self._format_percentage(currentdata['humidity']),
                'precip': self._format_precip(currentdata['precip_mm'], currentdata['precip_in']),
                'wind': self._format_distance(currentdata['wind_mph'], currentdata['wind_kph'], speed=True),
                'wind_dir': currentdata['wind_dir'],
                'uv': self._format_uv(currentdata['uv']),
                'visibility': self._format_distance(currentdata.get('vis_miles'), currentdata.get('vis_km')),
            },
            'forecast': [{'dayname': self._get_dayname(forecastdata['date_epoch'], idx, tz=locationdata['tz_id']),
                          'max': self._format_temp(forecastdata['day']['maxtemp_f'], forecastdata['day']['maxtemp_c']),
                          'min': self._format_temp(forecastdata['day']['mintemp_f'], forecastdata['day']['mintemp_c']),
                          'summary': forecastdata['day']['condition']['text']} for idx, forecastdata in enumerate(data['forecast']['forecastday'])]
        }
示例#20
0
    def search(self, query, channel, options={}):
        """Perform a search using Google's AJAX API.
        search("search phrase", options={})

        Valid options are:
            smallsearch - True/False (Default: False)
            filter - {active,moderate,off} (Default: "moderate")
            language - Restrict search to documents in the given language
                       (Default: "lang_en")
        """
        ref = self.registryValue('referer')
        if not ref:
            ref = 'http://%s/%s' % (dynamic.irc.server,
                                    dynamic.irc.nick)
        headers = dict(utils.web.defaultHeaders)
        headers['Referer'] = ref
        opts = {'q': query, 'v': '1.0'}
        for (k, v) in options.items():
            if k == 'smallsearch':
                if v:
                    opts['rsz'] = 'small'
                else:
                    opts['rsz'] = 'large'
            elif k == 'filter':
                opts['safe'] = v
            elif k == 'language':
                opts['lr'] = v
        defLang = self.registryValue('defaultLanguage', channel)
        if 'lr' not in opts and defLang:
            opts['lr'] = defLang
        if 'safe' not in opts:
            opts['safe'] = self.registryValue('searchFilter', dynamic.channel)
        if 'rsz' not in opts:
            opts['rsz'] = 'large'

        text = utils.web.getUrl('%s?%s' % (self._gsearchUrl,
                                           utils.web.urlencode(opts)),
                                headers=headers).decode('utf8')
        data = json.loads(text)
        if data['responseStatus'] != 200:
            self.log.info("Google: unhandled error message: ", text)
            raise callbacks.Error(data['responseDetails'])
        return data
示例#21
0
    def getFeed(self, url):
        def error(s):
            return {'items': [{'title': s}]}

        try:
            # This is the most obvious place to acquire the lock, because a
            # malicious user could conceivably flood the bot with rss commands
            # and DoS the website in question.
            self.acquireLock(url)
            if self.willGetNewFeed(url):
                results = {}
                try:
                    self.log.debug('Downloading new feed from %u', url)
                    results = feedparser.parse(url)
                    if 'bozo_exception' in results and not results['entries']:
                        raise results['bozo_exception']
                except feedparser.sgmllib.SGMLParseError:
                    self.log.exception('Uncaught exception from feedparser:')
                    raise callbacks.Error('Invalid (unparsable) RSS feed.')
                except socket.timeout:
                    return error('Timeout downloading feed.')
                except Exception as e:
                    # These seem mostly harmless.  We'll need reports of a
                    # kind that isn't.
                    self.log.debug('Allowing bozo_exception %r through.', e)
                if results.get('feed', {}) and self.getHeadlines(results):
                    self.cachedFeeds[url] = results
                    self.lastRequest[url] = time.time()
                else:
                    self.log.debug('Not caching results; feed is empty.')
            try:
                return self.cachedFeeds[url]
            except KeyError:
                wait = self.registryValue('waitPeriod')
                # If there's a problem retrieving the feed, we should back off
                # for a little bit before retrying so that there is time for
                # the error to be resolved.
                self.lastRequest[url] = time.time() - .5 * wait
                return error('Unable to download feed.')
        finally:
            self.releaseLock(url)
示例#22
0
import resource as R
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from cStringIO import StringIO

try:
    import sandbox as S
except ImportError:
    print('You need pysandbox in order to run SupySandbox plugin '
          '[http://github.com/haypo/pysandbox].')
    raise
except SyntaxError:
    raise callbacks.Error('the pysandbox is not compatible with your Python '
                          'version.')


class SandboxError(Exception):
    pass


def createSandboxConfig():
    cfg = S.SandboxConfig(
        'stdout',
        'stderr',
        'regex',
        'unicodedata',  # flow wants u'\{ATOM SYMBOL}' :-)
        'future',
        #'code',
        'time',
示例#23
0
    import html.entities as htmlentitydefs
    from imp import reload
try:
    from supybot.i18n import PluginInternationalization
    from supybot.i18n import internationalizeDocstring
    _ = PluginInternationalization('Twitter')
except:
    # This are useless functions that's allow to run the plugin on a bot
    # without the i18n plugin
    _ = lambda x: x
    internationalizeDocstring = lambda x: x

try:
    import twitter
except ImportError:
    raise callbacks.Error('You need the python-twitter library.')
except Exception as e:
    raise callbacks.Error('Unknown exception importing twitter: %r' % e)
reload(twitter)
if not hasattr(twitter, '__version__') or \
        twitter.__version__.split('.') < ['0', '8', '0']:
    raise ImportError('You current version of python-twitter is to old, '
                      'you need at least version 0.8.0, because older '
                      'versions do not support OAuth authentication.')


class ExtendedApi(twitter.Api):
    """Api with retweet support."""
    def PostRetweet(self, id):
        '''Retweet a tweet with the Retweet API
示例#24
0
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
try:
    from supybot.i18n import PluginInternationalization
    _ = PluginInternationalization('PypySandbox')
except ImportError:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x

if not hasattr(subprocess, 'TimeoutExpired'):
    raise callbacks.Error('Python >= 3.3 is required.')
if not hasattr(tempfile, 'TemporaryDirectory'):
    # You have some weird setup...
    raise callbacks.Error('Python >= 3.2 is required.')


class TimeoutException(Exception):
    pass


SOURCE_PREFIX = """
try:
    """

SOURCE_SUFFIX = """
except Exception as e:
示例#25
0
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
try:
    from supybot.i18n import PluginInternationalization
    _ = PluginInternationalization('Markovgen')
except ImportError:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x

try:
    import markovgen
except ImportError:
    raise callbacks.Error('Cannot load markovgen library. Make sure you '
                          'installed it (%s -m pip install markovgen).' %
                          sys.executable)
from imp import reload as r
r(markovgen)

MATCH_MESSAGE_STRIPNICK = re.compile('^(<[^ ]+> )?(?P<message>.*)$')

CHANNELLOGER_REGEXP_BASE = re.compile('^[^ ]*  (<[^ ]+> )?(?P<message>.*)$')
CHANNELLOGER_REGEXP_STRIPNICK = re.compile(
    '^[^ ]*  (<[^ ]+> )?(<[^ ]+> )?(?P<message>.*)$')


def get_channelloger_extracter(stripRelayedNick):
    @markovgen.mixed_encoding_extracting
    def channelloger_extracter(x):
        regexp = CHANNELLOGER_REGEXP_STRIPNICK if stripRelayedNick else \
示例#26
0
 def _checkNotChannel(self, irc, msg, password='******'):
     if password and irc.isChannel(msg.args[0]):
         raise callbacks.Error(conf.supybot.replies.requiresPrivacy())
示例#27
0
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
try:
    from supybot.i18n import PluginInternationalization
    _ = PluginInternationalization('Markovgen')
except ImportError:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x

try:
    import markovgen
except ImportError:
    raise callbacks.Error('Cannot load markovgen library. Make sure you '
                          'installed it.')
from imp import reload as r
r(markovgen)

MATCH_MESSAGE_STRIPNICK = re.compile('^(<[^ ]+> )?(?P<message>.*)$')

CHANNELLOGER_REGEXP_BASE = re.compile('^[^ ]*  (<[^ ]+> )?(?P<message>.*)$')
CHANNELLOGER_REGEXP_STRIPNICK = re.compile(
    '^[^ ]*  (<[^ ]+> )?(<[^ ]+> )?(?P<message>.*)$')


def get_channelloger_extracter(stripRelayedNick):
    @markovgen.mixed_encoding_extracting
    def channelloger_extracter(x):
        regexp = CHANNELLOGER_REGEXP_STRIPNICK if stripRelayedNick else \
                CHANNELLOGER_REGEXP_BASE
示例#28
0
from supybot.i18n import PluginInternationalization
_ = PluginInternationalization('Aka')

try:
    import sqlite3
except ImportError:
    sqlite3 = None
try:
    import sqlalchemy
    import sqlalchemy.ext
    import sqlalchemy.ext.declarative
except ImportError:
    sqlalchemy = None

if not (sqlite3 or sqlalchemy):
    raise callbacks.Error('You have to install python-sqlite3 or '
            'python-sqlalchemy in order to load this plugin.')

available_db = {}

class Alias(object):
    __slots__ = ('name', 'alias', 'locked', 'locked_by', 'locked_at')
    def __init__(self, name, alias):
        self.name = name
        self.alias = alias
        self.locked = False
        self.locked_by = None
        self.locked_at = None
    def __repr__(self):
        return "<Alias('%r', '%r')>" % (self.name, self.alias)
if sqlite3:
    class SQLiteAkaDB(object):
示例#29
0
    import html.entities as htmlentitydefs
    from imp import reload
try:
    from supybot.i18n import PluginInternationalization
    from supybot.i18n import internationalizeDocstring
    _ = PluginInternationalization('Twitter')
except:
    # This are useless functions that's allow to run the plugin on a bot
    # without the i18n plugin
    _ = lambda x: x
    internationalizeDocstring = lambda x: x

try:
    import twitter
except ImportError:
    raise callbacks.Error('You need the python-twitter library.')
reload(twitter)
if not hasattr(twitter, '__version__') or \
        twitter.__version__.split('.') < ['0', '8', '0']:
    raise ImportError('You current version of python-twitter is to old, '
                      'you need at least version 0.8.0, because older '
                      'versions do not support OAuth authentication.')


class ExtendedApi(twitter.Api):
    """Api with retweet support."""
    def PostRetweet(self, id):
        '''Retweet a tweet with the Retweet API

        The twitter.Api instance must be authenticated.
示例#30
0
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
try:
    from supybot.i18n import PluginInternationalization
    _ = PluginInternationalization('SilencePlugin')
except:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x

if not hasattr(callbacks.Commands, 'pre_command_callbacks'):
    raise callbacks.Error('Your version of Supybot is not compatible with '
                          'this plugin (it does not have support for '
                          'pre-command-call callbacks).')

plugin_class_name_tag = 'SilencePlugin__originated_from'


class IrcMsg(ircmsgs.IrcMsg):
    def __init__(self2, *args, **kwargs):
        super(IrcMsg, self2).__init__(*args, **kwargs)
        plugin = None
        f = sys._getframe().f_back
        while f:
            if 'irc' in f.f_locals and \
                    isinstance(f.f_locals['self'], callbacks.Commands):
                plugin = f.f_locals['self']
                break