Ejemplo n.º 1
0
def init():
    global perm, db

    perm = 'USER'

    db = {}
    db['file'] = datadir + os.sep + name + '.sqlite'
    db['url'] = "http://ams-9.net/data/" + name + '.sqlite'
    db['refresh'] = 86400

    # read config
    if config[name + '_perm']:
        perm = config[name + '_perm']

    rlog(10, name, 'perm set to: %s' % perm)

    if config[name + '_database']:
        db['file'] = config[name + '_database']

    rlog(10, name, 'database set to: %s' % db['file'])

    # update the database
    if not os.path.exists(db['file']):
        db['age'] = ''
    else:
        age = os.stat(db['file'])[ST_MTIME]
        db['age'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                  time.gmtime(age))

    fetch_database()
    db['jid'] = periodical.addjob(db['refresh'], 0, fetch_database, name)

    # register commands
    cmnds.add("route", handle_addr, perm)
    examples.add("route", 'lookup an IP', name + ' 66.66.66.66')
Ejemplo n.º 2
0
def init():
    global lastline
    lastline = LastLine()
    callbacks.add('PRIVMSG', lastline.privmsgcb, lastline.precb)
    rebefore.add(10, sed_expression, handle_sed, 'USER', allowqueue=False)
    examples.add('s', 'Perform substitution on last message spoken.', 's/foo/bar/')
    return 1
Ejemplo n.º 3
0
def init():
    global lastline
    lastline = LastLine()
    callbacks.add('PRIVMSG', lastline.privmsgcb, lastline.precb)
    rebefore.add(10, sed_expression, handle_sed, 'USER', allowqueue=False)
    examples.add('s', 'Perform substitution on last message spoken.',
                 's/foo/bar/')
    return 1
Ejemplo n.º 4
0
def init():
    global seen
    seen = Seen()
    callbacks.add("PRIVMSG", seen.privmsgcb)
    callbacks.add("JOIN", seen.joincb)
    callbacks.add("PART", seen.partcb)
    callbacks.add("QUIT", seen.quitcb)
    cmnds.add("seen", seen.handle_seen, ["USER", "CLOUD"])
    examples.add("seen", "show last spoken txt of <nikc>", "seen dunker")
    return 1
Ejemplo n.º 5
0
def init():
    global seen
    seen = Seen()
    callbacks.add('PRIVMSG', seen.privmsgcb)
    callbacks.add('JOIN', seen.joincb)
    callbacks.add('PART', seen.partcb)
    callbacks.add('QUIT', seen.quitcb)
    cmnds.add('seen', seen.handle_seen, ['USER', 'CLOUD'])
    examples.add('seen', 'show last spoken txt of <nikc>', 'seen dunker')
    return 1
Ejemplo n.º 6
0
    def __init__(self):
        self.__basename__ = self.__class__.__name__
        self.plugname = calledfrom(sys._getframe())
        Persist.__init__(self, os.path.join(datadir, "%s-config" % \
self.plugname), {})
        self.__callbacks = {}
        cmndname = "%s-cfg" % self.plugname
        rlog(-3, 'persistconfig', 'added command %s (%s)' % (cmndname, \
self.plugname))
        cmnds[cmndname] = Command(self.cmnd_cfg, 'OPER', self.plugname, \
threaded=True)	
        examples.add(cmndname, "plugin configuration", cmndname)
        cmndnamesave = cmndname + "save"
        cmnds[cmndnamesave] = Command(self.cmnd_cfgsave, 'OPER', \
self.plugname, threaded=True)	
        examples.add(cmndnamesave, "save plugin configuration", cmndnamesave)
Ejemplo n.º 7
0
    def __init__(self):
        self.hide = []
        self.plugname = calledfrom(sys._getframe())
        Config.__init__(self, datadir + os.sep + 'plugs' + os.sep + self.plugname, "config")

        if self.plugname not in config['loadlist']:
             return

        cmndname = "%s-cfg" % self.plugname
        rlog(-3, 'persistconfig', 'added command %s (%s)' % (cmndname, \
self.plugname))
        cmnds[cmndname] = Command(self.cmnd_cfg, 'OPER', self.plugname, \
threaded=True)	
        examples.add(cmndname, "plugin configuration", cmndname)
        cmndnamesave = cmndname + "save"
        cmnds[cmndnamesave] = Command(self.cmnd_cfgsave, 'OPER', \
self.plugname, threaded=True)	
        examples.add(cmndnamesave, "save plugin configuration", cmndnamesave)
Ejemplo n.º 8
0
    def __init__(self):
        self.hide = []
        self.plugname = calledfrom(sys._getframe())
        Config.__init__(self,
                        datadir + os.sep + 'plugs' + os.sep + self.plugname,
                        "config")

        if self.plugname not in config['loadlist']:
            return

        cmndname = "%s-cfg" % self.plugname
        rlog(-3, 'persistconfig', 'added command %s (%s)' % (cmndname, \
self.plugname))
        cmnds[cmndname] = Command(self.cmnd_cfg, 'OPER', self.plugname, \
threaded=True)
        examples.add(cmndname, "plugin configuration", cmndname)
        cmndnamesave = cmndname + "save"
        cmnds[cmndnamesave] = Command(self.cmnd_cfgsave, 'OPER', \
self.plugname, threaded=True)
        examples.add(cmndnamesave, "save plugin configuration", cmndnamesave)
Ejemplo n.º 9
0
def handle_karmaget(bot, ievent):
    """ karma-get <item> .. show karma of item """
    if not ievent.rest:
        ievent.missing('<item>')
        return
    else:
        item = ievent.rest
    result = karma.get(item)
    if result:
        ievent.reply("%s has karma %s" % (item, str(result)))
    else:
        ievent.reply("%s has no karma yet" % item)


cmnds.add('karma-get', handle_karmaget, ['USER', 'WEB', 'ANONKARMA', 'CLOUD'])
examples.add('karma-get', 'karma-get <item> .. show karma of <item>', \
'karma-get dunker')
aliases.data['karma'] = 'karma-get'


def nolimit():
    global nolimiter
    nolimiter = True


tests.start(nolimit).add('gozerbot++').add('karma-get gozerbot',
                                           'gozerbot has karma (\d+)')


def handle_karmadel(bot, ievent):
    """ karma-del <item> .. delete karma item """
    if not ievent.rest:
Ejemplo n.º 10
0
__copyright__ = 'this file is in the public domain'
__revision__ = '$Id: m8b.py 1120 2006-12-30 12:00:00Z deck $'

from gozerbot.generic import handle_exception
from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.plughelp import plughelp
from gozerbot.tests import tests
import re, random

plughelp.add('8b', 'Ask the magic 8 ball')

balltxt = [
    "Signs point to yes.", "Yes.", "Most likely.", "Without a doubt.",
    "Yes - definitely.", "As I see it, yes.", "You may rely on it.",
    "Outlook good.", "It is certain.", "It is decidedly so.",
    "Reply hazy, try again.", "Better not tell you now.", "Ask again later.",
    "Concentrate and ask again.", "Cannot predict now.", "My sources say no.",
    "Very doubtful.", "My reply is no.", "Outlook not so good.",
    "Don't count on it."
]


def handle_8b(bot, ievent):
    ievent.reply(random.choice(balltxt))


cmnds.add('8b', handle_8b, 'USER')
examples.add('8b', 'show what the magic 8 ball has to say', '8b')
tests.add('8b')
Ejemplo n.º 11
0
    for i, j in options:
        if i == '-r':
            doregex = True

    res = []

    if doregex:
        try:
            reg = re.compile(' '.join(rest))
        except Exception, ex:
            ievent.reply("can't compile regex: %s" % str(ex))
            return
        for i in result:
            if not re.search(reg, i):
                res.append(i)
    else:
        for i in result:
            if ievent.rest not in str(i):
                res.append(i)

    if not res:
        ievent.reply('no result')
    else:
        ievent.reply(res, dot=True)


cmnds.add('not', handle_not, ['USER', 'WEB', 'CLOUD'], threaded=True)
examples.add('not', 'reverse grep used in pipelines', 'list | not todo')
tests.add('list | not core')
Ejemplo n.º 12
0
        Check if the given ip is part of the network.

        >>> net = Network('192.0.2.0/24')
        >>> net.has_key('192.168.2.0')
        False
        >>> net.has_key('192.0.2.42')
        True
        '''
        return self.__contains__(ip)

    def size(self):
        '''
        Number of ip's within the network.
        '''
        return 2 ** ((self.version() == 4 and 32 or 128) - self.mask)

def handle_ipcalc(bot, ievent):
    if not ievent.args:
        ievent.missing('<ip>[/<size>]')
        return
    try:
        net = Network(ievent.args[0])
    except ValueError, e:
        ievent.reply('error: %s' % e)
        return
    ievent.reply('version: %d, address: %s, network size: %d, network address: %s, netmask: %s, first host in network: %s, last host in network: %s, network info: %s' % \
        (net.version(), str(net), net.mask, net.network(), net.netmask(), net.host_first(), net.host_last(), net.info()))

cmnds.add('ipcalc', handle_ipcalc, 'USER')
examples.add('ipcalc', 'ip calculator', 'ipcalc 127.0.0.1/12')
Ejemplo n.º 13
0
        return
    # check if alarm txt is provided
    txt = striptime(alarmtxt).strip()
    if not txt:
        ievent.reply('i need txt to remind you')
        return
    if time.time() > alarmtime:
        ievent.reply("we are already past %s" % time.ctime(alarmtime))
        return
    # add alarm
    nrid = alarms.add(bot.name, ievent.nick, alarmtime, txt, ievent.printto)
    ievent.reply("alarm %s set at %s" % (nrid, time.ctime(alarmtime)))

cmnds.add('alarm', handle_alarmadd, 'USER', allowqueue=False)
examples.add('alarm', 'say txt at a specific time or time diff', \
'1) alarm 12:00 lunchtime 2) alarm 3-11-2008 0:01 birthday ! 3) alarm +180 \
egg ready')
tests.add('alarm 23:59 sleeptime', 'alarm (\d+) set at').add('alarm-del %s')

def handle_alarmlist(bot, ievent):
    """ alarm-list .. list all alarms """
    result = []
    for alarmdata in alarms.data:
        i = Alarmitem(d=alarmdata)
        result.append("%s) %s: %s - %s " % (i.idnr, i.nick, \
time.ctime(i.time), i.txt))
    if result:
        ievent.reply("alarmlist: ", result, dot=True)
    else:
        ievent.reply('no alarms')
Ejemplo n.º 14
0
                try:
                    wind_km = round(int(wind[-6:-4]) * 1.609344)
                except ValueError:
                    wind_km = ""

                if (not condition == ""):
                    condition = " Oh, and it's " + condition + "."

                resultstr = "As of %s, %s (%s) has a temperature of %sC/%sF with %s. %s (%s km/h).%s" % (time, city, zip, temp_c, temp_f, humidity, wind, wind_km, condition)
        elif ievent.command == "forecast":
            forecasts = gweather.getElementsByTagName('forecast_conditions')
            for forecast in forecasts:
                condition = forecast.getElementsByTagName('condition')[0].attributes["data"].value
                low_f = forecast.getElementsByTagName('low')[0].attributes["data"].value
                high_f = forecast.getElementsByTagName('high')[0].attributes["data"].value
                day = forecast.getElementsByTagName('day_of_week')[0].attributes["data"].value
                low_c = round((int(low_f) - 32) * 5.0 / 9.0)
                high_c = round((int(high_f) - 32) * 5.0 / 9.0)
                resultstr += "[%s: F(%sl/%sh) C(%sl/%sh) %s]" % (day, low_f, high_f, low_c, high_c, condition)
    if not resultstr:
        ievent.reply('%s not found!' % loc)
        return
    else:
        ievent.reply(resultstr)

cmnds.add('weather', handle_weather, 'USER', options={'--u': ''})
aliasset('forecast', 'weather')
examples.add('weather', 'get weather for <LOCATION> or <nick>', '1) weather London, \
England 2) weather dunker')
Ejemplo n.º 15
0
def handle_hostname(bot, ievent):
    """ hostname <ipnr> .. get hostname of ip number"""
    try:
        item = ievent.args[0]
    except IndexError:
        ievent.missing('<ipnr>')
        return
    try:
        hostname = socket.gethostbyaddr(item)
        ievent.reply(hostname[0])
    except:
        ievent.reply("can't match " + str(item))

cmnds.add('host', handle_hostname, 'USER')
examples.add('host', 'get hostname for ip', 'host 194.109.129.219')

def handle_ip(bot, ievent):
    """ ip <hostname> .. get ip of hostname """
    try:
        item = ievent.args[0]
    except IndexError:
        ievent.missing('<hostname>')
        return
    try:
        ipnr = socket.gethostbyname(item)
        ievent.reply(ipnr)
    except:
        ievent.reply("can't match " + str(item))

cmnds.add('ip', handle_ip, 'USER')
Ejemplo n.º 16
0
    elif not ievent.rest:
        ievent.missing('<text>')
        return
    else:
        result = [ievent.rest, ]
    credentials = twitteruser.get(ievent.user)
    try:
        api = twitterapi(username=credentials[0], password=credentials[1])
        for txt in result:
            status = api.PostUpdate(txt[:119])
        ievent.reply('twitter posted to http://twitter.com/%s ' % (credentials[0],))
    except (TwitterError, urllib2.HTTPError), e:
        ievent.reply('twitter failed: %s' % (str(e),))

cmnds.add('twitter', handle_twitter, 'USER')
examples.add('twitter', 'adds a message to your twitter account', 
    'twitter just found the http://gozerbot.org project')

def handle_twitter_friends(bot, ievent):
    if not ievent.user in twitteruser:
        ievent.reply('you need a twitter account for this command, '
                     'use "!twitter-id <username> <password>" '
                     'first (in a private message!)')
    else:
        credentials = twitteruser.get(ievent.user)
        try:
            api = twitterapi(username=credentials[0], password=credentials[1])
            users = api.GetFriends()
            users = ['%s (%s)' % (u.name, u.screen_name) for u in users]
            if users:
                users.sort()
                ievent.reply('your twitter friends: ', users, dot=True)
Ejemplo n.º 17
0
callbacks.add('ALL', logcb, prelog)
jcallbacks.add('Message', logcb, prelog)


def handle_logon(bot, ievent):
    """ log-on .. enable logging in channel the command was given in """
    if not ievent.channel in logs.loglist:
        logs.loglist.append(ievent.channel)
        ievent.reply('logging enabled in %s' % ievent.channel)
    else:
        ievent.reply('%s already in loglist' % ievent.channel)


cmnds.add('log-on', handle_logon, 'OPER')
examples.add('log-on', 'enable logging of the channel in which the command \
was given', 'log-on')


def handle_logoff(bot, ievent):
    """ log-off .. disable logging in channel the command was given in"""
    try:
        logs.loglist.remove(ievent.channel)
        ievent.reply('logging disabled in %s' % ievent.channel)
    except ValueError:
        ievent.reply('%s not in loglist' % ievent.channel)


cmnds.add('log-off', handle_logoff, 'OPER')
examples.add(
    'log-off', 'disable logging of the channel in which the command \
was given', 'log-off')
Ejemplo n.º 18
0
Archivo: ring.py Proyecto: NLNOG/ircbot
	self.results{server} = result


def handle_ping(bot,ievent):
    """ ring-ping a host """
    try:
	arg = ievent.args[0]
    except IndexError:
	ievent.missing('<host>')
	return

    results = Results(servers)
    # start the servers
    for server in servers:
	Ping(results).start()

    while len(results) > len(servers):
	sleep 0.1

    for result in results:
	if result == None:
	    ievent.reply("%s not found" % arg)
	    return

    ievent.reply(prepare_string(result))

cmnds.add(name + "-ping", handle_ping, 'USER')
examples.add(name, 'ping a host', name + '-ping kame.org')

Ejemplo n.º 19
0
from gozerbot.aliases import aliases
from gozerbot.plughelp import plughelp
from gozerplugs.quote import quotes

plughelp.add('grab', 'grab the last quote of an user')

def handle_quotegrab(bot, ievent):
    """ grab the last last from the given user """
    try:
        from gozerplugs.seen import seen
        assert(seen)
    except (ImportError, AssertionError, NameError):
        ievent.reply("seen plugin not enabled")
        return
    if not quotes:
        ievent.reply('quotes plugin not enabled')
        return
    if not ievent.args:
        ievent.reply('missing <user> argument')
        return
    nick = ievent.args[0].lower()
    if not seen.data.has_key(nick):
        ievent.reply('nothing said by %s recently' % nick)
        return
    idnr = quotes.add(nick, ievent.userhost, seen.data[nick]['text'])
    ievent.reply('grabbed %s from %s' % (idnr, nick))

cmnds.add('quote-grab', handle_quotegrab, ['USER', 'QUOTEADD'], allowqueue=False)
examples.add('quote-grab', 'quote-grab <user> .. add quote', 'quote-grab mekker')
aliases.data['grab'] = 'quote-grab'
Ejemplo n.º 20
0
from gozerbot.plugins import plugins
from gozerbot.aliases import aliasset
from gozerbot.plughelp import plughelp
from gozerbot.tests import tests

plughelp.add('code', 'the code plugin provides code related commands')


def handle_showexceptions(bot, ievent):
    """ show exception list. """

    ievent.reply(str(exceptionlist))


cmnds.add('code-exceptions', handle_showexceptions, 'OPER')
examples.add('code-exceptions', 'show exception list', 'code-exceptions')
aliasset('exceptions', 'code-exceptions')
tests.add('code-exceptions')


def handle_funcnames(bot, ievent):
    """ show function names of a plugin. """

    try:
        plugname = ievent.args[0]
    except IndexError:
        ievent.missing('<plugname>')
        return

    if not plugins.exist(plugname):
        ievent.reply('no %s plugin exists' % plugname)
Ejemplo n.º 21
0
        gozerbot.utils.log.logcallbacks.remove(logcallback)

def handle_powernick(bot, ievent):
    global state
    nick = ievent.nick
    if not partyline.is_on(nick):
        ievent.reply('%s is not joined on the partylist .. make a dcc chat\
 connection to the bot' % nick)
        return
    username = users.getname(ievent.userhost)
    state['nicks'][username] = nick
    state.save()
    ievent.reply('powernick set to %s' % nick)

cmnds.add('powernick', handle_powernick, 'OPER')
examples.add('powernick', 'set powernick (gets /msg of bot logs)', 'powernick')

def handle_powernickdel(bot, ievent):
    global state
    username = users.getname(ievent.userhost)
    try:
        del state['nicks'][username]
        state.save()
        ievent.reply('powernick removed')
    except (ValueError, KeyError):
         ievent.reply('no powernick set')
 
cmnds.add('powernick-del', handle_powernickdel, 'OPER')
examples.add('powernick-del', 'remove powernick (gets', 'powernick-del')

def handle_powernicklist(bot, ievent):
Ejemplo n.º 22
0
# gozerplugs/trac.py
#
#

from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.aliases import aliasset


def handle_tracwiki(bot, ievent):
    if not ievent.rest:
        ievent.missing("<item>")
        return
    ievent.reply('http://trac.edgewall.org/wiki/%s' % ievent.rest)


cmnds.add('trac-wiki', handle_tracwiki, 'USER')
examples.add('trac-wiki', 'give t.e.o wiki url', 'trac-wiki TracAdmin')
aliasset('wiki', 'trac-wiki')
Ejemplo n.º 23
0
    if not ievent.args or not ievent.args[0].isdigit():
        ievent.reply('<job id>')
        return

    for job in periodical.jobs:
        if job.id() == int(ievent.args[0]):
            next = job.next
            if type(next) in [types.FloatType, types.IntType]:
                next = datetime.datetime(*time.localtime(next)[:7])
            ievent.reply('%s, fires at %s' % (job.__repr__(), str(next)))
            return

    ievent.reply('job not found')

cmnds.add('job', handle_job, 'USER')
examples.add('job', 'show job data of <jobid> ', 'job 1')
tests.add('job 1')

def handle_joblist(bot, ievent):

    """ show job list. """

    try:
        group = ievent.args[0]
    except IndexError:
        group = None
    result = []

    for job in periodical.jobs:
        if group and not job.group == group:
            continue
Ejemplo n.º 24
0
        ievent.reply("can't get userhost of %s" % nick)
        return

    allowed = users.allowed(userhost, 'OPER', log=False)

    if allowed:
        ievent.reply("can't ignore OPER")
        return

    addignore(userhost, nrseconds)
    ievent.reply("ignoring %s for %s seconds" % (nick, nrseconds))


cmnds.add('ignore', handle_ignore, ['OPER', 'IGNORE'], speed=1)
examples.add('ignore',
             'ignore <nick> <seconds> .. ignore <nick> for <seconds>',
             'ignore test 3600')
tests.add('ignore bottest 3', 'bottest').add('ignore-del bottest')


def handle_ignoredel(bot, ievent):
    """ remove nick from ignore list. """

    try:
        nick = ievent.args[0]
    except IndexError:
        ievent.missing('<nick>')
        return

    userhost = getwho(bot, nick)
Ejemplo n.º 25
0
def handle_autovoiceon(bot, ievent):
    """ autovoice-on .. enable autovoice for channel the command was given \
        in """
    try:
        bot.channels[ievent.channel]["autovoice"] = 1
    except TypeError:
        ievent.reply("no %s in channel database" % ievent.channel)
        return
    ievent.reply("autovoice enabled on %s" % ievent.channel)


cmnds.add("autovoice-on", handle_autovoiceon, "OPER")
examples.add(
    "autovoice-on",
    "enable autovoice on channel in which the \
command is given",
    "autovoice-on",
)


def handle_autovoiceoff(bot, ievent):
    """ autovoice-off .. disable autovoice for the channel the command was \
        given in """
    bot.channels[ievent.channel]["autovoice"] = 0
    ievent.reply("autovoice disabled on %s" % ievent.channel)


cmnds.add("autovoice-off", handle_autovoiceoff, "OPER")
examples.add(
    "autovoice-off",
    "disable autovoice on channel in which \
Ejemplo n.º 26
0
maroc
super maroc
charras malana
royal cream
'''.strip().splitlines()

joint_action = '''
rolls a nice %s
passes the %s
gives a large %s joint
puts some %s in the took
fixes a djonko with %s
rolls a blunt with %s
stuffs a waterpipe with %s
smokes %s and gets really high
passes the %s to tashiro
builds a tulp with %s
bakes a %s cake
pulls a %s tea
'''.strip().splitlines()


def handle_joint(bot, ievent):
    """ get a joint  """
    what = random.choice(joint_action) % random.choice(joint)
    bot.action(ievent.channel, what)

cmnds.add('joint', handle_joint, 'USER')
examples.add('joint', 'get a joint', 'joint')

Ejemplo n.º 27
0
        keyword = successorList[0]
        word = random.choice(successorList)
        if not word:
            break
        if word not in output:
            output = output + " "  + word
        order.insert(0, word)
        order = order[:ORDER_K]
    return output.strip()
    
def handle_markovsize(bot, ievent):
    """ markov-size .. returns size of markovchains """
    ievent.reply("I know %s phrases" % str(len(markovchains.keys())))

cmnds.add('markov-size', handle_markovsize, 'OPER')
examples.add('markov-size', 'size of markovchains', 'markov-size')

def handle_markovlearn(bot, ievent):
    """ command to let the bot learn a log or an url .. learned data 
        is not persisted """
    try:
        item = ievent.args[0]
    except IndexError:
        ievent.reply('<channel>|<url>')
        return
    if item.startswith('http://'):
        nrlines = markovlearnurl(item)
        ievent.reply('learned %s lines' % nrlines)
        return
    from gozerplugs.log import logs
    if item in logs.loglist:
Ejemplo n.º 28
0
from gozerbot.aliases import aliasset
from gozerbot.examples import examples
from gozerbot.plughelp import plughelp
import random

plughelp.add("lart", "do the lart")

cfg = PersistConfig()
cfg.define("lartlist", [])


def handle_lart(bot, ievent):
    try:
        who = ievent.args[0]
    except IndexError:
        ievent.missing("<who>")
        return
    try:
        txt = random.choice(cfg.get("lartlist"))
    except IndexError:
        ievent.reply('lart list is empty .. use lart-add to add entries .. use "<who>" as a nick holder')
        return
    txt = txt.replace("<who>", who)
    bot.action(ievent.channel, txt)


cmnds.add("lart", handle_lart, "USER")
examples.add("lart", "echo a lart message", "lart dunker")
aliasset("lart-add", "lart-cfg lartlist add")
aliasset("lart-del", "lart-cfg lartlist remove")
Ejemplo n.º 29
0
plughelp.add('mailexceptions', 'mail list of occured exceptions to \
[email protected]')

def handle_mailexceptions(bot, ievent):
    """ mailexceptions [<email>] .. mail exceptions in log """
    if not len(exceptionlist):
        ievent.reply("no exceptions available")
        return   
    try:
        mailto = ievent.args[0]
    except IndexError:
        mailto = '*****@*****.**'
    try:
        mailserver = mailto.split('@')[1]
    except IndexError:
        ievent.reply("can't determine mailserver from %s" % mailto)
        return
    fromaddr = 'gozerbot@localhost'
    msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, mailto))
    for i in exceptionlist:
        msg += "+++ %s\r\n" % i 
    server = smtplib.SMTP(mailserver)
    server.sendmail(fromaddr, mailto, msg)
    ievent.reply("%s exceptions send to %s" % (len(exceptionlist), mailto))

cmnds.add('mailexceptions', handle_mailexceptions, 'OPER')
examples.add('mailexceptions' , 'mailexceptions [<email>] .. mail exceptions \
log to [email protected] or to provided email', '1) mailexceptions 2) \
mailexception mekker@miep')
Ejemplo n.º 30
0
            reloaded.extend(plugins.reload('gozerplugs', plug))
        except ImportError, ex:
            errors.append(str(ex))
            failed.append(plug)
        except Exception, ex:
            handle_exception()
            errors.append(exceptionmsg())
            failed.append(plug)
    ievent.reply('enabled plugins: ', reloaded, dot=True)
    if failed:
        ievent.reply('failed to reload: ', failed, dot=True)
    if errors:
        ievent.reply('errors: ', errors, dot=True)
  
cmnds.add('plug-enable', handle_plugenable, 'OPER', options={'-a': ''})
examples.add('plug-enable', 'enable a plugin', 'plug-enable karma')
tests.add('plug-enable country', 'country')

def handle_plugdisable(bot, ievent):
    if not ievent.rest:
        ievent.missing('<plugname>')
        return
    plugs = ievent.rest.split()
    disabled = []
    for plug in plugs:
        plugins.unload(plug)
        plugins.disable(plug)
        disabled.append(plug)
    ievent.reply('disabled plugins: ', disabled)

cmnds.add('plug-disable', handle_plugdisable, 'OPER')
Ejemplo n.º 31
0
from gozerbot.plugins import plugins
from gozerbot.fleet import fleet
from gozerbot.plughelp import plughelp
from gozerbot.tests import tests

plughelp.add(
    'size', 'the size command shows the sizes of plugins that \
provide a size() plugin command and the sizes of some basic structures')


def handle_size(bot, ievent):
    """ size .. show size of core datastructures """
    txtlist = []
    txtlist.append("fleet: %s" % fleet.size())
    txtlist.append("users: %s" % users.size())
    txtlist.append("cmnds: %s" % cmnds.size())
    txtlist.append("callbacks: %s" % callbacks.size())
    txtlist.append("rebefore: %s" % rebefore.size())
    txtlist.append("reafter: %s" % reafter.size())
    txtlist.append("aliases: %s" % len(aliases.data))
    txtlist.append("examples: %s" % examples.size())
    plugsizes = plugins.plugsizes()
    if plugsizes:
        txtlist += plugsizes
    ievent.reply(txtlist)


cmnds.add('size', handle_size, ['USER', 'WEB'])
examples.add('size', 'show sizes of various data structures', 'size')
tests.add('size', 'users')
Ejemplo n.º 32
0
                result.append(i)
    except KeyError:
        ievent.reply('no urls known for channel %s' % ievent.channel)
        return
    except Exception, ex:
        ievent.reply(str(ex))
        return
    if result:
        ievent.reply('results matching %s: ' % ievent.rest, result, nr=True)
    else:
        ievent.reply('no result found')
        return


cmnds.add('url-search', handle_urlsearch, ['USER', 'WEB', 'CLOUD'])
examples.add('url-search', 'search matching url entries',
             'url-search gozerbot')


def handle_urlsearchall(bot, ievent):
    if not state:
        ievent.reply('rss state not initialized')
        return
    if not ievent.rest:
        ievent.missing('<what>')
        return
    result = []
    try:
        for i in state['urls'].values():
            for urls in i.values():
                for url in urls:
                    if ievent.rest in url:
Ejemplo n.º 33
0
            txt = i['text']
            break
        except:
            pass
    if not txt:
        return
    #txt = re.sub('\[\[Image:([^\[\]]+|\[\[[^\]]+\]\])*\]\]', '', txt)
    txt = txt.replace('[[', '')
    txt = txt.replace(']]', '')
    txt = re.sub('\s+', ' ', txt)
    return txt

def handle_wikipedia(bot, ievent):
    """ wikipedia <what> .. search wikipedia for <what> """
    if not ievent.rest:
        ievent.missing('<what>')
        return
    res = searchwiki(ievent.rest)
    if not res:
        ievent.reply('no result found')
        return
    txt, url = res
    res = ['%s ===> ' % url, ]
    res += splittxt(striphtml(txt).strip())
    ievent.reply(res)

cmnds.add('wikipedia', handle_wikipedia, 'USER')
examples.add('wikipedia', 'wikipedia ["-" <countrycode>] <what> .. search \
wikipedia for <what>','1) wikipedia gozerbot 2) wikipedia -nl bot')
aliases.data['wiki'] = 'wikipedia'
Ejemplo n.º 34
0
    reason = len(ievent.args) > 1 and ' '.join(
        ievent.args[1:]) or 'Permban requested, bye'
    if userhost:
        host = userhost.split('@')[-1].lower()
        if host == get_bothost(bot):
            ievent.reply('not going to kickban myself')
            return
        bot.sendraw('MODE %s +b *!*@%s' % (ievent.channel, host))
        bot.sendraw('KICK %s %s :%s' %
                    (ievent.channel, ievent.args[0], reason))
    else:
        ievent.reply('can not get userhost of %s' % ievent.args[0])


callbacks.add('367', handle_367)
callbacks.add('MODE', handle_mode)
aliases.data['ban'] = 'ban-add'
aliases.data['bans'] = 'ban-list'
aliases.data['unban'] = 'ban-remove'
aliases.data['kb'] = 'ban-kickban'
aliases.data['kickban'] = 'ban-kickban'
cmnds.add('ban-add', handle_ban_add, 'OPER')
examples.add('ban-add', 'adds a host to the ban list',
             'ban-add *!*@lamers.are.us')
cmnds.add('ban-list', handle_ban_list, 'OPER', threaded=True)
cmnds.add('ban-remove', handle_ban_remove, 'OPER', threaded=True)
examples.add('ban-remove', 'removes a host from the ban list', 'ban-remove 1')
cmnds.add('ban-kickban', handle_kickban_add, 'OPER')
examples.add('ban-kickban', 'kickbans the given nick',
             'kickban Lam0r Get out of here')
Ejemplo n.º 35
0
    if elapsed:
        ievent.reply("%s is idle for %s" % (who, elapsed))
        return
    else:
        ievent.reply("%s is not idle" % who)
        return


cmnds.add('idle', handle_idle, ['USER', 'WEB', 'CLOUD'])
aliases.data['st'] = 'idle'


def handle_idle2(bot, ievent):
    """ show how idle a channel has been """
    chan = ievent.channel
    try:
        elapsed = elapsedstring(time.time() -
                                idle.data[jsonstring((bot.name, chan))])
    except KeyError:
        ievent.reply("nobody said anything on channel %s yet" % chan)
        return
    if elapsed:
        ievent.reply("channel %s is idle for %s" % (chan, elapsed))
    else:
        ievent.reply("channel %s is not idle" % chan)


examples.add(
    'idle', 'idle [<nick>] .. show how idle the channel is or show \
how idle <nick> is', '1) idle 2) idle test')
Ejemplo n.º 36
0
# plugs/echo.py
#
#
""" simple echo command """

__copyright__ = 'this file is in the public domain'

from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.plughelp import plughelp

plughelp.add('echo', 'simply write back what you tell it')


def handle_echo(bot, ievent):
    """ say back what is being said """
    ievent.reply(ievent.rest)


cmnds.add('echo', handle_echo, 'USER')
examples.add('echo', "echo Hello World!", 'echo')
Ejemplo n.º 37
0
# gozerplugs/trac.py
#
#

from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.aliases import aliasset

def handle_tracwiki(bot, ievent):
    if not ievent.rest:
        ievent.missing("<item>")
        return
    ievent.reply('http://trac.edgewall.org/wiki/%s' % ievent.rest)

cmnds.add('trac-wiki', handle_tracwiki, 'USER')
examples.add('trac-wiki', 'give t.e.o wiki url', 'trac-wiki TracAdmin')
aliasset('wiki', 'trac-wiki')
        
Ejemplo n.º 38
0
plughelp.add('tell', 'the tell command sends the output of a command to \
another user')

def handle_tell(bot, ievent):
    """ send output of command to another user """
    if ievent.msg:
        ievent.reply('tell can only be used in a channel')
        return 
    try:
        nick, cmnd = ievent.rest.split(' ', 1)
    except ValueError:
        ievent.missing('<nick> <command>')
        return
    ievent.txt = cmnd
    #if not plugins.woulddispatch(bot, ievent):
    #    ievent.reply("can't execute %s" % cmnd)
    #    return  
    result = plugins.cmnd(bot, ievent)
    if not result:
        ievent.reply("no result for %s" % cmnd)
        return
    ievent.reply("%s sends your this: " % ievent.nick, result, nick=nick, \
dot=True)
    ievent.reply("%s item(s) send" % len(result))

cmnds.add('tell', handle_tell, 'USER', threaded=True)
examples.add('tell', 'tell <nick> <command> .. send output of command to \
another user', 'tell dunker version')
tests.add('tell dunker version', 'GOZERBOT')
Ejemplo n.º 39
0
    chan = ievent.channel.lower()

    try:
        p = bot.channels[chan]['perms']
    except (KeyError, TypeError):
        ievent.reply("channel %s has no permissions set" % chan)
        return

    if p:
        ievent.reply('permissions of channel %s: ' % chan, p, dot=True)
    else:
        ievent.reply("channel %s has no permissions set" % chan)
    
cmnds.add('chanperm', handle_chanperm, 'OPER')
examples.add('chanperm', 'show channel permissions', 'chanperm')
tests.add('chanperm-add mekker chan #dunkbots').add('chanperm chan #dunkbots', 'MEKKER').add('chanperm-del chan #dunkbots mekker')

def handle_chanpermadd(bot, ievent):

    """ add channel permission. """

    try:
        perm = ievent.args[0].upper()
    except IndexError:
        ievent.missing('<perm>')
        return

    if perm in ['OPER', 'USER']:
        ievent.reply("can't set channel permission to %s" % perm)
        return
Ejemplo n.º 40
0

def handle_rssadd(bot, ievent):
    """ rss-add <name> <url> .. add a rss item """
    try:
        (name, url) = ievent.args
    except ValueError:
        ievent.missing('<name> <url>')
        return
    watcher.add(name, url)
    ievent.reply('rss item added')


cmnds.add('rss-add', handle_rssadd, 'OPER')
examples.add(
    'rss-add', 'rss-add <name> <url> to the rsswatcher', 'rss-add \
gozerbot http://gozerbot.org/hg/gozerbot/?cmd=changelog;style=rss')


def handle_rssdel(bot, ievent):
    """ rss-del <name> .. delete a rss item """
    try:
        name = ievent.args[0]
    except IndexError:
        ievent.missing('<name>')
        return
    if watcher.byname(name):
        watcher.stopwatch(name)
        watcher.delete(name)
        ievent.reply('rss item deleted')
    else:
Ejemplo n.º 41
0
balltxt=[
    "Signs point to yes.",
    "Yes.",
    "Most likely.",
    "Without a doubt.",
    "Yes - definitely.",
    "As I see it, yes.",
    "You may rely on it.",
    "Outlook good.",
    "It is certain.",
    "It is decidedly so.",
    "Reply hazy, try again.",
    "Better not tell you now.",
    "Ask again later.",
    "Concentrate and ask again.",
    "Cannot predict now.",
    "My sources say no.",
    "Very doubtful.",
    "My reply is no.",
    "Outlook not so good.",
    "Don't count on it."
    ]

def handle_8b(bot, ievent):
    ievent.reply(random.choice(balltxt))

cmnds.add('8b', handle_8b, 'USER')
examples.add('8b', 'show what the magic 8 ball has to say', '8b')
tests.add('8b')
Ejemplo n.º 42
0
# gozerplugs/beats.py
#
#

""" internet time .beats """

__copyright__ = 'this file is in the public domain'

from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.plughelp import plughelp
from gozerbot.plughelp import plughelp
from gozerbot.tests import tests
import time, math

plughelp.add('beats', 'show internet time')

def handle_beats(bot, ievent):
    """ beats .. show current internet time """
    beats = ((time.time() + 3600) % 86400) / 86.4
    beats = int(math.floor(beats))
    ievent.reply('@' + str(beats))

cmnds.add('beats', handle_beats, 'USER')
examples.add('beats', 'show current internet time', 'beats')
tests.add('beats' , '@')
Ejemplo n.º 43
0
        first = i[0].upper()
        rest = i[1:]
        if i.startswith('-'):
            if len(i) != 3:
                ievent.reply('invalid option')
                return
            lang = i[1:]
            continue
        what += "%s%s " % (first, rest)
    what = what.strip().replace(' ', '_')
    url = 'http://wowwiki.com/wiki/Special:Export/%s' % quote(what.encode('utf-8'))
    url2 = 'http://wowwiki.com/wiki/%s' % quote(what.encode('utf-8'))
    txt = getwikidata(url, ievent)
    if not txt:
        return
    if '#REDIRECT' in txt or '#redirect' in txt:
        redir = ' '.join(txt.split()[1:])
        url = 'http://wowwiki.com/wiki/Special:Export/%s' % quote(redir.encode('utf-8'))
        url2 = 'http://wowwiki.com/wiki/%s' % quote(redir.encode('utf-8'))
        txt = getwikidata(url, ievent)
    if not txt:
        return
    res = ['%s ===> ' % url2, ]
    res += splittxt(striphtml(txt).strip())
    ievent.reply(res)

cmnds.add('wowwiki', handle_wowwiki, 'USER')
examples.add('wowwiki', 'wowwiki <what> .. search wowwiki for <what>','1) wowwiki \
gozerbot')
aliases.data['wow'] = 'wowwiki'
Ejemplo n.º 44
0
    "out-of-the-box", "enterprise", "integrated", "impactful", "wireless",
    "transparent", "next-generation", "cutting-edge", "user-centric",
    "visionary", "customized", "ubiquitous", "plug-and-play", "collaborative",
    "compelling", "holistic", "rich"
]

noun = [
    "synergies", "web-readiness", "paradigms", "markets", "partnerships",
    "infrastructures", "platforms", "initiatives", "channels", "eyeballs",
    "communities", "ROI", "solutions", "e-tailers", "e-services",
    "action-items", "portals", "niches", "technologies", "content", "vortals",
    "supply-chains", "convergence", "relationships", "architectures",
    "interfaces", "e-markets", "e-commerce", "systems", "bandwidth",
    "infomediaries", "models", "mindshare", "deliverables", "users", "schemas",
    "networks", "applications", "metrics", "e-business", "functionalities",
    "experiences", "web services", "methodologies"
]


def rarr(arr):
    return randint(0, len(arr) - 1)


def handle_buzz(bot, ievent):
    ievent.reply("%s %s %s" %
                 (verb[rarr(verb)], adj[rarr(adj)], noun[rarr(noun)]))


cmnds.add('buzz', handle_buzz, 'USER')
examples.add('buzz', 'generate buzz', 'buzz')
Ejemplo n.º 45
0
	("84", "VIETNAM", ""),
	("106", "VIRGIN IS BRITISH", ""),
	("123", "VIRGIN IS USA", ""),
	("967", "YEMAN", ""),
	("381", "YUGOSLAVIA", ""),
	("666", "NUMBER OF THE BEAST", ""),
]

def handle_tel(bot, ievent):
    if not ievent.rest:
        ievent.missing('<what>')
        return
    l = ievent.rest.upper()
    res = None
    for c in codes:
	if l in c:
	    res = "%s has dialing prefix %s" % (c[1], c[0])
	    break
    if not res:
	# match part of
	for c in codes:
	    if l in c[1]:
		res = "%s has dialing prefix %s" % (c[1], c[0])
		break
    if not res:
	res = "%s not found" % l
    ievent.reply(res)

cmnds.add('tel', handle_tel, 'USER')
examples.add('tel', 'show country telephone code', 'tel 31')
Ejemplo n.º 46
0
plughelp.add('inform', 'inform <nick> the output of a command')


def handle_inform(bot, ievent):
    """ prepend nick: to the output of command to another user """
    if ievent.msg:
        ievent.reply('inform can only be used in a channel')
        return

    try:
        nick, cmnd = ievent.rest.split(' ', 1)
    except ValueError:
        ievent.missing('<nick> <command>')
        return

    ievent.txt = cmnd
    result = plugins.cmnd(bot, ievent)

    if not result:
        ievent.reply("no result for %s" % cmnd)
        return

    ievent.reply("%s: " % nick, result, dot=True)


cmnds.add('inform', handle_inform, 'USER', threaded=True)
examples.add('inform',
             'inform <nick> <command> .. inform <nick> the output of command',
             'inform dunker version')
tests.add('inform dunker version', 'dunker')
Ejemplo n.º 47
0
        except ImportError, ex:
            errors.append(str(ex))
            failed.append(plug)
        except Exception, ex:
            handle_exception()
            errors.append(exceptionmsg())
            failed.append(plug)
    ievent.reply('enabled plugins: ', reloaded, dot=True)
    if failed:
        ievent.reply('failed to reload: ', failed, dot=True)
    if errors:
        ievent.reply('errors: ', errors, dot=True)


cmnds.add('plug-enable', handle_plugenable, 'OPER', options={'-a': ''})
examples.add('plug-enable', 'enable a plugin', 'plug-enable karma')
tests.add('plug-enable country', 'country')


def handle_plugdisable(bot, ievent):
    if not ievent.rest:
        ievent.missing('<plugname>')
        return
    plugs = ievent.rest.split()
    disabled = []
    for plug in plugs:
        plugins.unload(plug)
        plugins.disable(plug)
        disabled.append(plug)
    ievent.reply('disabled plugins: ', disabled)
Ejemplo n.º 48
0
         else:
             ievent.reply('there are already infoitems in the main database .. not upgrading')
             ievent.reply('use the -f option to force an upgrade')
             return
    ievent.reply('upgrading infoitems')
    nritems = upgrade()
    ievent.reply('%s items upgraded' % nritems)

cmnds.add('info-upgrade', handle_infoupgrade, 'OPER', options={'-f': ''})

def handle_infosize(bot, ievent):
    """ info-size .. show number of information items """
    ievent.reply("we have %s infoitems" % info.size())

cmnds.add('info-size', handle_infosize, ['USER', 'WEB', 'CLOUD'])
examples.add('info-size', 'show number of infoitems', 'info-size')
tests.add('info-size', 'we have (\d+) infoitems')

def handle_addinfoitem(bot, ievent):
    """ <keyword> = <description> .. add information item """
    try:
        (what, description) = ievent.groups
    except ValueError:
        ievent.reply('i need <item> <description>')
        return
    if len(description) < 3:
        ievent.reply('i need at least 3 chars for the description')
        return
    what = what.strip()
    ret = info.add(what, description, ievent.userhost, time.time())
    if ret:
Ejemplo n.º 49
0
import requests
from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.plughelp import plughelp
from gozerbot.tests import tests

# add help

plughelp.add('asn', 'lookup ASN via peeringdb')

def handle_asn(bot, ievent):
    asnumber_in = ""
    try: what = ievent.args[0]
    except IndexError: ievent.missing("<asn>"); return
    try:
         asnumber_in = what
         url = "https://stat.ripe.net/data/as-overview/data.json?resource=" + asnumber_in
         resp = requests.get(url=url)
         pdb_json = json.loads(resp.text)
         network_name = pdb_json['data'][0]['holder']
         resultstring = "AS Number: %s has name: %s" % (asnumber_in, network_name)
         ievent.reply(resultstring)
    except Exception, ex: ievent.reply("Invalid ASN") ; return


cmnds.add('asn', handle_asn, 'USER')
examples.add('asn', 'Lookup as number on ripestat', 'asn 8315')
tests.add('asn 8315')

### In elkaar gerost door phreak ergens in 2020.
Ejemplo n.º 50
0
    """ get a coffee """
    rand = random.randint(0,len(coffee)-1)
    bot.action(ievent.channel,coffee[rand])    

def handle_tea(bot, ievent):
    """ get a tea """
    rand = random.randint(0,len(tea)-1)
    bot.action(ievent.channel,tea[rand])
    
def handle_beer(bot, ievent):
    """ get a beer  """
    rand = random.randint(0,len(beer)-1)
    bot.action(ievent.channel,beer[rand])

cmnds.add('coffee', handle_coffee, 'USER')
examples.add('coffee', 'get a coffee quote', 'coffee')

cmnds.add('tea', handle_tea, 'USER')
examples.add('tea', 'get an tea', 'tea')

cmnds.add('beer', handle_beer, 'USER')
examples.add('beer', 'get a beer', 'beer')

coffeetxt = """ pours a cup of coffee with two sweets..
pours a cup of espresso for you
gives you a glass of irish coffee
gives you a cappuccino
"""

teatxt = """ tea is for pussies!
"""
Ejemplo n.º 51
0
        return
    if not awaydict.data.has_key((name, bot.name, ievent.channel)):
        return
    ievent.reply("welcome back %s" % ievent.nick)
    try:
        del awaydict.data[(name, bot.name, ievent.channel)]
        awaydict.save()
    except KeyError:
        pass

def handle_awayenable(bot, ievent):
    """ away-enable .. enable away """
    awaydict.data['enable'] = 1
    awaydict.save()
    plugins.reload('gozerplugs', 'away')
    ievent.reply('away enabled')

cmnds.add('away-enable', handle_awayenable, 'OPER')
examples.add('away-enable' , 'enable the away plugin', 'away-enable')

def handle_awaydisable(bot, ievent):
    """ away-disable .. disable away """
    awaydict.data['enable'] = 0
    awaydict.save()
    plugins.reload('gozerplugs', 'away')
    ievent.reply('away disabled')

cmnds.add('away-disable', handle_awaydisable, 'OPER')
examples.add('away-disable', 'disable the away plugin', 'away-disable')
tests.add('away-enable --chan #dunkbots', 'enabled').fakein(':[email protected] PRIVMSG #dunkbots :&').fakein(':[email protected] PRIVMSG #dunkbots :re').add('away-disable --chan #dunkbots', 'disabled')
Ejemplo n.º 52
0
    elif len(ievent.args) < 3:
        ievent.missing('<from language> <to language> <text>')
        return
    else:
        text = ' '.join(ievent.args[2:])
    try:
        result = translate.translate(ievent.args[0], ievent.args[1], text)
        if result:
            ievent.reply(html_unescape(result))
        else:
            ievent.reply('translation failed (no result)')
    except TranslateLanguageException, e:
        ievent.reply(str(e))

cmnds.add('translate', handle_translate, 'USER')
examples.add('translate', 'translate between languages', 'translate English Dutch how do you do')

def handle_translate_langs(bot, ievent):
    langs = []
    for lang in translate.lang:
        lang = lang.split('/')
        for l in lang:
            if not l in langs:
                langs.append(l)
    langs.sort()
    ievent.reply('available languages: %s' % ', '.join(langs))

cmnds.add('translate-lang', handle_translate_langs, 'USER')

trmap = {
    'de': 'German',
Ejemplo n.º 53
0
    try:
        project, desc = ievent.rest.split(' ', 1)
    except ValueError:
        project = ievent.rest
        desc = None
    project = project.strip().lower()
    if hasproject(username, project) or hascontrib(username, project):
        ievent.reply('project %s already exists' % project)
        return
    if desc:
        desc = desc.strip()
    addproject(username, project, desc)
    ievent.reply('project %s added' % (project))

cmnds.add('pt-add', handle_projectadd, 'USER')
examples.add('pt-add', 'pt-add <projectname> [<description>] .. \
add a project to the project tracker', 'pt-add gc Gozerbot coden ;]')

def handle_projectlist(bot, ievent):
    """ show available projects """
    username = users.getname(ievent.userhost)
    result = []
    l = getprojects(username)
    for project in l:
        desc = getdesc(username, project)
        if desc:
            result.append('%s (%s)' % (desc, project))
        else:
            result.append(project)
    l = getcontrib(username)
    for project in l:
        owner = getowner(username, project)