Giter VIP home page Giter VIP logo

tenyks's Introduction

Build Status

  _                   _         
 | |                 | |        
 | |_ ___ _ __  _   _| | _____  
 | __/ _ \ '_ \| | | | |/ / __| 
 | ||  __/ | | | |_| |   <\__ \  The IRC bot for hackers.
  \__\___|_| |_|\__, |_|\_\___/ 
                 __/ |          
                |___/           

Tenyks is a computer program designed to relay messages between connections to IRC networks and custom built services written in any number of languages. More detailed, Tenyks is a service oriented IRC bot rewritten in Go. Service/core communication is handled by ZeroMQ 4 PubSub via json payloads.

The core acts like a relay between IRC channels and remote services. When a message comes in from IRC, that message is turned into a json data structure, then sent over the pipe on a Pub/Sub channel that services can subscribe to. Services then parse or pattern match the message, and possibly respond back via the same method.

This design, while not anything new, is very flexible because one can write their service in any number of languages. The current service implementation used for proof of concept is written in Python. You can find that here. It's also beneficial because you can take down or bring up services without the need to restart the bot or implement a complicated hot pluggable core. Services that crash also don't run the risk of taking everything else down with it.

Installation and whatnot

Building

Current supported Go version is 1.7. All packages are vendored with Godep and stored in the repository. I update these occasionally. Make sure you have a functioning Go 1.7 environment.

  1. Install ZeroMQ4 (reference your OSs package install documentation) and make sure libzmq exists on the system.
  2. go get github.com/kyleterry/tenyks
  3. cd ${GOPATH}/src/github.com/kyleterry/tenyks
  4. make - this will run tests and build
  5. sudo make install - otherwise you can find it in ./bin/tenyks
  6. cp config.json.example config.json
  7. Edit config.json to your liking.

Uninstall

Why would you ever want to do that?

cd ${GOPATH}/src/github.com/kyleterry/tenyks
sudo make uninstall

Docker

There is a Docker image on Docker hub called kyleterry/tenyks. No configuration is available in the image so you need to use it as a base image. You can pass your own configuration in like so:

FROM kyleterry/tenyks:latest
COPY my-config.json /etc/tenyks/config.json

Then you can build your image: docker build -t myuser/tenyks . and run it with: docker run -d -P --name tenyks myuser/tenyks.

Binary Release

You can find binary builds on bintray.

I cross compile for Linux {arm,386,amd64} and Darwin {386,amd64}.

Configuration

Configuration is just json. The included example contains everything you need to get started. You just need to swap out the server information.

cp config.json.example ${HOME}/tenyks-config.json

Running

tenyks ${HOME}/tenyks-config.json

If a config file is excluded when running, Tenyks will look for configuration in /etc/tenyks/config.json first, then ${HOME}/.config/tenyks/config.json then it will give up. These are defined in tenyks/tenyks.go and added with ConfigSearch.AddPath(). If you feel more paths should be searched, please feel free to add it and submit a pull request.

Vagrant

If you want to play right fucking now, you can just use vagrant: vagrant up and then vagrant ssh. Tenyks should be built and available in your $PATH. There is also an IRC server running you can connect to server on 192.168.33.66 with your IRC client.

Just run tenyks & && disown from the vagrant box and start playing.

Testing

I'm a horrible person. There aren't tests yet. I'll get right on this.... There are only a few tests.

Builtins

Tenyks comes with very few commands that the core responds to directly. You can get a list of services and get help for those services.

tenyks: !services will list services that have registered with the bot through the service registration API..
tenyks: !help will show a quick help menu of all the commands available to tenyks.
tenyks: !help servicename will ask the service to sent their help message to the user.

Services

Libraries

To Services

Example JSON payload sent to services:

{
    "target":"#tenyks",
    "command":"PRIVMSG",
    "mask":"unaffiliated/vhost-",
    "direct":true,
    "nick":"vhost-",
    "host":"unaffiliated/vhost-",
    "full_message":":vhost-!~vhost@unaffiliated/vhost- PRIVMSG #tenyks :tenyks-demo: weather 97217",
    "user":"~vhost",
    "from_channel":true,
    "connection":"freenode",
    "payload":"weather 97217",
    "meta":{
        "name":"Tenyks",
        "version":"1.0"
    }
}

To Tenyks for IRC

Example JSON response from a service to Tenyks destined for IRC

{
    "target":"#tenyks",
    "command":"PRIVMSG",
    "from_channel":true,
    "connection":"freenode",
    "payload":"Portland, OR is 63.4 F (17.4 C) and Overcast; windchill is NA; winds are Calm",
    "meta":{
        "name":"TenyksWunderground",
        "version":"1.1"
    }
}

Service Registration

Registering your service with the bot will let people ask Tenyks which services are online and available for use. Registering is not requires; anything listening on the pubsub channel can respond without registration.

Each service should have a unique UUID set in it's REGISTER message. An example of a valid register message is below:

{
    "command":"REGISTER",
    "meta":{
        "name":"TenyksWunderground",
        "version":"1.1",
        "UUID": "uuid4 here",
        "description": "Fetched weather for someone who asks"
    }
}

Service going offline

If the service is shutting down, you should send a BYE message so Tenyks doesn't have to timeout the service after PINGs go unresponsive:

{
    "command":"BYE",
    "meta":{
        "name":"TenyksWunderground",
        "version":"1.1",
        "UUID": "uuid4 here",
        "description": "Fetched weather for someone who asks"
    }
}

Commands for registration that go to services

Services can register with Tenyks. This will allow you to list the services currently online from the bot. This is not persistent. If you shut down the bot, then all the service UUIDs that were registered go away.

The commands sent to services are:

{
  "command": "HELLO",
  "payload": "!tenyks"
}

HELLO will tell services that Tenyks has come online and they can register if they want to.

{
  "command": "PING",
  "payload": "!tenyks"
}

PING will expect services to respond with PONG.

List and Help commands are coming soon.

Lets make a service!

This service is in python and uses the tenyks-service package. You can install that with pip: pip install tenyksservice.

from tenyksservice import TenyksService, run_service, FilterChain


class Hello(TenyksService):
    irc_message_filters = {
        'hello': FilterChain([r"^(?i)(hi|hello|sup|hey), I'm (?P<name>(.*))$"],
                             direct_only=False),
        # This is will respond to /msg tenyks this is private
        'private': FilterChain([r"^this is private$"],
                             private_only=True)
    }

    def handle_hello(self, data, match):
        name = match.groupdict()['name']
        self.logger.debug('Saying hello to {name}'.format(name=name))
        self.send('How are you {name}?!'.format(name=name), data)

    def handle_private(self, data, match):
        self.send('Hello, private message sender', data)


def main():
    run_service(Hello)


if __name__ == '__main__':
    main()

Okay, we need to generate some settings for our new service.

tenyks-service-mkconfig hello >> hello_settings.py

Now lets run it: python main.py hello_settings.py

If you now join the channel that tenyks is in and say "tenyks: hello, I'm Alice" then tenyks should respond with "How are you Alice?!".

More Examples

There is a repository with some services on my Github called tenyks-contrib. These are all using the older tenyksclient class and will probably work out of the box with Tenyks. I'm going to work on moving them to the newer tenyks-service class.

A good example of something more dynamic is the Weather service.

Credit where credit is due

Service oriented anything isn't new. This idea came from an old coworker of mine. I just wanted to do something slightly different. There are also plenty of other plugin style bots (such as hubot and eggdrop). Every open source project needs love, so check those out as well.

tenyks's People

Contributors

cblgh avatar kyleterry avatar pilate avatar qpfiffer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tenyks's Issues

Clean up settings

The settings environment is a bit messy. Clean it up and make it robust.

UnicodeError in while Logging

People keep spamming unicode and it fucks up tenyks' logging.

Traceback (most recent call last):
  File "/srv/xaxi/.virtualenvs/tenyks/local/lib/python2.7/site-packages/gevent-0.13.8-py2.7-linux-x86_64.egg/gevent/greenlet.py", line 390, in run
    result = self._run(*self.args, **self.kwargs)
  File "/srv/xaxi/.virtualenvs/tenyks/local/lib/python2.7/site-packages/tenyks-0.1.24-py2.7.egg/tenyks/connection.py", line 109, in recv_loop
    self.logger.debug('<- IRC: {data}'.format(data=data))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 66-69: ordinal not in range(128)

A try accept around that area would probably do it.

tenyks fails to connect to ngircd instances running on the same machine

| |                 | |        
 | |_ ___ _ __  _   _| | _____  
 | __/ _ \ '_ \| | | | |/ / __| 
 | ||  __/ | | | |_| |   <\__ \ 
  \__\___|_| |_|\__, |_|\_\___/ 
                 __/ |          
                |___/           

Version: 0.1.24

[Configuration]
        Debug: True
        Redis: redis://localhost:6379 [OK]

[Networks]
        shithouse

2013-09-03 16:23:57,039 tenyks.connection.shithouse:INFO Connecting...
2013-09-03 16:23:57,039 tenyks:INFO Robot <- {"pattern": null, "type": "subscribe", "channel": "tenyks.robot.broadcast_to", "data": 1}
2013-09-03 16:23:57,073 tenyks.connection.shithouse:INFO Successfully connected
2013-09-03 16:24:02,077 tenyks:ERROR shithouse failed to connect or we did not get a response

Thats all it spits out.

ngircd log:

Sep  3 16:24:13 neuroblastoma ngircd[10966]: neuroblastoma:60049 (162.218.239.146) is closing the connection ...
Sep  3 16:24:13 neuroblastoma ngircd[10966]: Shutting down connection 12 (Socket closed!) with neuroblastoma:60049 ...
Sep  3 16:24:13 neuroblastoma ngircd[10966]: Client unregistered (connection 12): Socket closed!
Sep  3 16:24:13 neuroblastoma ngircd[10966]: Connection 12 with neuroblastoma:60049 closed (in: 0.0k, out: 0.0k).
Sep  3 16:26:00 neuroblastoma ngircd[10966]: Accepted connection 12 from 162.218.239.146:60412 on socket 9.

Service registry

Register services that connect to the bot. This isn't for a whitelist or anything, just bookkeeping and good data.

  • Requires a change to tenyksclient on the python side.

freenode connection died and then boom goes the tenyks

tenyks_1 | 2016/11/23 09:00:07 read tcp 172.18.0.3:46093->195.154.200.232:6697: use of closed network connection
tenyks_1 | panic: send on closed channel
tenyks_1 |
tenyks_1 | goroutine 308646 [running]:
tenyks_1 | panic(0x76d1c0, 0xc420442610)
tenyks_1 | /usr/local/go/src/runtime/panic.go:500 +0x1a1
tenyks_1 | github.com/kyleterry/tenyks/irc.(*Connection).SendPing(0xc42016a000, 0x0)
tenyks_1 | /go/src/github.com/kyleterry/tenyks/irc/handlers.go:70 +0x1d1
tenyks_1 | github.com/kyleterry/tenyks/irc.(*Connection).AddHandler.func1(0xc42046ee80, 0x2, 0x2)
tenyks_1 | /go/src/github.com/kyleterry/tenyks/irc/handlers.go:43 +0x6f
tenyks_1 | created by github.com/kyleterry/tenyks/irc.dispatch
tenyks_1 | /go/src/github.com/kyleterry/tenyks/irc/reactor.go:47 +0x29a

Only send PRIVMSG to services over pubsub

Traceback (most recent call last):
File "/home/kyle/.virtualenvs/tenyks/bin/tenyksfeeds", line 8, in

load_entry_point('tenyks-contrib==0.1.24', 'console_scripts', 'tenyksfeeds')()
File "/home/kyle/.virtualenvs/tenyks/lib/python2.7/site-packages/tenyksfeeds/main.py", line 235, in main
run_client(TenyksFeeds)
File "/home/kyle/.virtualenvs/tenyks/lib/python2.7/site-packages/tenyksclient/client.py", line 110, in run_client
client_instance.run()
File "/home/kyle/.virtualenvs/tenyks/lib/python2.7/site-packages/tenyksclient/client.py", line 51, in run
if self.direct_only and not data['direct']:
KeyError: 'direct'

Fix logging

Should have the ability to tell the settings you want logging to go to syslog, console or a file.

Private messages

Make it easier for services to handle private messages. If a message is directed at tenyks, automatically modify the data dictionary passed to services so that messages sent will be directed to the user that initiated the private message.

Support a backup nick

Supporting a backup nick if the one first in the list is taken. Might be best to just support a list of arbitrary length.

Crash report

panic: runtime error: send on closed channel

goroutine 524613 [running]:
runtime.panic(0x65e200, 0x7ebb7e)
/usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5
github.com/kyleterry/tenyks/irc.(*Connection).SendPing(0xc20802a000, 0x0)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:70 +0x1ef
github.com/kyleterry/tenyks/irc.func·005(0xc208274fc0, 0x2, 0x2)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:43 +0xa2
created by github.com/kyleterry/tenyks/irc.dispatch
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/reactor.go:47 +0x2f1

goroutine 16 [chan receive, 75179 minutes]:
main.main()
/home/kyle/src/tenyks/tenyks/tenyks.go:117 +0xbc8

goroutine 19 [finalizer wait, 75179 minutes]:
runtime.park(0x414390, 0x7f0088, 0x7eeb69)
/usr/lib/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x7f0088, 0x7eeb69)
/usr/lib/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
/usr/lib/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
/usr/lib/go/src/pkg/runtime/proc.c:1445

goroutine 20 [IO wait]:
net.runtime_pollWait(0x7f8e0d917708, 0x72, 0x0)
/usr/lib/go/src/pkg/runtime/netpoll.goc:146 +0x66
net.(_pollDesc).Wait(0xc208028060, 0x72, 0x0, 0x0)
/usr/lib/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(_pollDesc).WaitRead(0xc208028060, 0x0, 0x0)
/usr/lib/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(_netFD).Read(0xc208028000, 0xc208059000, 0x1000, 0x1000, 0x0, 0x7f8e0d9162b8, 0xb)
/usr/lib/go/src/pkg/net/fd_unix.go:232 +0x34c
net.(_conn).Read(0xc208038020, 0xc208059000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/lib/go/src/pkg/net/net.go:122 +0xe7
bufio.(_Reader).fill(0xc208004120)
/usr/lib/go/src/pkg/bufio/bufio.go:97 +0x1b3
bufio.(_Reader).ReadSlice(0xc208004120, 0x7f8e0d75790a, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go/src/pkg/bufio/bufio.go:298 +0x22c
github.com/garyburd/redigo/redis.(_conn).readLine(0xc2080460a0, 0x0, 0x0, 0x0, 0x0, 0x0)
/home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:195 +0x77
github.com/garyburd/redigo/redis.(_conn).readReply(0xc2080460a0, 0x0, 0x0, 0x0, 0x0)
/home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:268 +0x65
github.com/garyburd/redigo/redis.(_conn).Receive(0xc2080460a0, 0x0, 0x0, 0x0, 0x0)
/home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:351 +0x125
github.com/garyburd/redigo/redis.PubSubConn.Receive(0x7f8e0d917bc0, 0xc2080460a0, 0x0, 0x0)
/home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/pubsub.go:97 +0x66
github.com/kyleterry/tenyks/service.func·001()
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/connection.go:73 +0x172
created by github.com/kyleterry/tenyks/service.(_Connection).recv
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/connection.go:78 +0xd5

goroutine 21 [chan receive]:
github.com/kyleterry/tenyks/service.func·002()
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/connection.go:121 +0x6e
created by github.com/kyleterry/tenyks/service.(*Connection).send
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/connection.go:125 +0xd5

goroutine 268814 [chan receive]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:197 +0x4c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

goroutine 26 [chan receive]:
github.com/kyleterry/tenyks/service.func·003()
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/engine.go:115 +0x7d
created by github.com/kyleterry/tenyks/service.(*PubSubReactor).Start
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/engine.go:119 +0x92

goroutine 28 [chan receive, 1 minutes]:
github.com/kyleterry/tenyks/service.(_ServiceEngine).serviceWatchdog(0xc20803e040)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/engine.go:51 +0x54
created by github.com/kyleterry/tenyks/service.(_ServiceEngine).Start
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/engine.go:33 +0x98

goroutine 29 [chan receive]:
github.com/kyleterry/tenyks/service.(_Connection).PingServices(0xc20804c080)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/handlers.go:116 +0x86
created by github.com/kyleterry/tenyks/service.(_ServiceEngine).Start
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/engine.go:34 +0xb6

goroutine 17 [syscall, 75179 minutes]:
runtime.goexit()
/usr/lib/go/src/pkg/runtime/proc.c:1445

goroutine 62 [select]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:199 +0x12c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

goroutine 464552 [chan receive]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:197 +0x4c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

goroutine 511113 [chan receive]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:197 +0x4c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

goroutine 511107 [chan receive]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:197 +0x4c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

goroutine 511125 [chan receive]:
github.com/kyleterry/tenyks/irc.(_Connection).watchdog(0xc20802a000)
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/connection.go:197 +0x4c
created by github.com/kyleterry/tenyks/irc.(_Connection).ConnectedHandler
/home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/irc/handlers.go:116 +0x5e6

Make sure services with blank UUIDs don't make it into the registry

2014/08/26 18:15:46 Loading configuration from /home/kyle/.config/tenyks/config.json
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x451d6f]

goroutine 42 [running]:
runtime.panic(0x65e200, 0x7ebdf3)
        /usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5
github.com/kyleterry/tenyks/service.(*Connection).ByeServiceHandler(0xc20804c080, 0xc20828e370)
        /home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/handlers.go:83 +0x18f
github.com/kyleterry/tenyks/service.func·004(0xc2081f2240, 0x2, 0x2)
        /home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/handlers.go:16 +0xa2
created by github.com/kyleterry/tenyks/service.(*Connection).ircify
        /home/kyle/src/tenyks/build/src/github.com/kyleterry/tenyks/service/ircify.go:59 +0x3ba

goroutine 16 [chan receive]:
main.main()
        /home/kyle/src/tenyks/tenyks/tenyks.go:117 +0xbc8

goroutine 19 [finalizer wait]:
runtime.park(0x414390, 0x7f0088, 0x7eeb69)
        /usr/lib/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x7f0088, 0x7eeb69)
        /usr/lib/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
        /usr/lib/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
        /usr/lib/go/src/pkg/runtime/proc.c:1445

goroutine 20 [IO wait]:
net.runtime_pollWait(0x7f8914814708, 0x72, 0x0)
        /usr/lib/go/src/pkg/runtime/netpoll.goc:146 +0x66
net.(*pollDesc).Wait(0xc208028060, 0x72, 0x0, 0x0)
        /usr/lib/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(*pollDesc).WaitRead(0xc208028060, 0x0, 0x0)
        /usr/lib/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(*netFD).Read(0xc208028000, 0xc208059000, 0x1000, 0x1000, 0x0, 0x7f89148132b8, 0xb)
        /usr/lib/go/src/pkg/net/fd_unix.go:232 +0x34c
net.(*conn).Read(0xc208038020, 0xc208059000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /usr/lib/go/src/pkg/net/net.go:122 +0xe7
bufio.(*Reader).fill(0xc208004120)
        /usr/lib/go/src/pkg/bufio/bufio.go:97 +0x1b3
bufio.(*Reader).ReadSlice(0xc208004120, 0x7f891465490a, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/lib/go/src/pkg/bufio/bufio.go:298 +0x22c
github.com/garyburd/redigo/redis.(*conn).readLine(0xc2080460a0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:195 +0x77
github.com/garyburd/redigo/redis.(*conn).readReply(0xc2080460a0, 0x0, 0x0, 0x0, 0x0)
        /home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:268 +0x65
github.com/garyburd/redigo/redis.(*conn).Receive(0xc2080460a0, 0x0, 0x0, 0x0, 0x0)
        /home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/conn.go:351 +0x125
github.com/garyburd/redigo/redis.PubSubConn.Receive(0x7f8914814aa8, 0xc2080460a0, 0x0, 0x0)
        /home/kyle/src/tenyks/build/src/github.com/garyburd/redigo/redis/pubsub.go:97 +0x66
github.com/kyleterry/tenyks/service.func·001()

Makefile references a directory that doesn't exist?

eric@34f81a644855:~/tenyks$ make
===> Fetching dependencies
GOPATH=/home/eric/tenyks/build go get -d -u -v \
    github.com/garyburd/redigo/redis \
    github.com/op/go-logging \
    code.google.com/p/gomock/gomock \
    code.google.com/p/go-uuid/uuid
github.com/garyburd/redigo (download)
github.com/op/go-logging (download)
code.google.com/p/gomock (download)
code.google.com/p/go-uuid (download)
===> Linking relative packages to GOPATH
===> Building
go build -o ./bin/tenyks ./tenyks
can't load package: package ./tenyks: open /home/eric/tenyks/tenyks: no such file or directory
make: *** [build] Error 1
eric@34f81a644855:~/tenyks$

Tenyks services cannot "hear" Tenyks

IRC does not relay back what you say. So services ignore things that Tenyks sends to the channels that could be useful. Figure out a way to resolve this and flag in the payload that it comes from the bot itself.

No such service needs love

00:59:25 tenyks | No such service %!s(uint8=104)
00:59:25 tenyks | No such service %!s(uint8=104)
00:59:25 tenyks | No such service %!s(uint8=104)
WHY

Unicode Audit

#20 will solve this issue for Python 3, but Python 2 support will need to handle Unicode.

tenyksctl

Add a tenyksctl command for controlling irc connections and channels.

Crash via invalid redis message

127.0.0.1:6379> PUBLISH tenyks.robot.broadcast "{'target': '#tenkys', 'command': 'PRIVMSG', 'payload': 'test', 'connection': 'localhost', 'meta': {'name': 'Tenyks', 'version': '1.0'}}"

2014/11/23 05:11:04 ircify.go:50: [service] Error parsing message: invalid character '\'' looking for beginning of object key string

Move away from json

Some payloads are big. I could compress it, but I could also use something like msgpack AND compress it.

The great restructure

I've learned a lot about Go since initially porting Tenyks to it. Restructure some of the internals and rework concurrency to be less error and bug prone.

!info data race

==================
WARNING: DATA RACE
Write by goroutine 20:
  github.com/kyleterry/tenyks/irc.func·004()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/connection.go:163 +0x308

Previous read by goroutine 31:
  github.com/kyleterry/tenyks/irc.(*Connection).GetInfo()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/connection.go:260 +0x2ee
  github.com/kyleterry/tenyks/service.(*Connection).InfoIrcHandler()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/service/handlers.go:136 +0x40e
  github.com/kyleterry/tenyks/service.*Connection.InfoIrcHandler·fm()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/service/connection.go:54 +0x47
  github.com/kyleterry/tenyks/irc.func·006()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/handlers.go:43 +0xf0

Goroutine 20 (running) created at:
  github.com/kyleterry/tenyks/irc.(*Connection).send()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/connection.go:171 +0xf7
  github.com/kyleterry/tenyks/irc.func·003()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/connection.go:126 +0x9a9

Goroutine 31 (finished) created at:
  github.com/kyleterry/tenyks/irc.dispatch()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/reactor.go:47 +0x48a
  github.com/kyleterry/tenyks/irc.ConnectionReactor()
      /home/kyle/src/go/src/github.com/kyleterry/tenyks/irc/reactor.go:28 +0x536
==================

Unit Testing

Get good coverage for important parts of Tenyks.

Look into a broadcast worker limit

Look into limiting the number of concurrent broadcast_workers in core. Possibly do some load testing to see if high concurrency is going to be a problem.

Build breaks in go:tip (1.5)

Using worker: worker-linux-027f0490-2.bb.travis-ci.org:travis-linux-2

Build system information
Build language: go
Build image provisioning date and time
Wed Feb  4 18:22:50 UTC 2015
Operating System Details
Distributor ID: Ubuntu
Description:    Ubuntu 12.04 LTS
Release:    12.04
Codename:   precise
Linux Version
2.6.32-042stab090.5
Cookbooks Version
23bb455 https://github.com/travis-ci/travis-cookbooks/tree/23bb455
GCC version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

LLVM version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Pre-installed Ruby versions
ruby-1.9.3-p551
Pre-installed Node.js versions
v0.10.36
Pre-installed Go versions
1.4.1
Redis version
redis-server 2.8.19
riak version
2.0.2
MongoDB version
MongoDB 2.4.12
CouchDB version
couchdb 1.6.1
Neo4j version
1.9.4
Cassandra version
2.0.9
RabbitMQ Version
3.4.3
ElasticSearch version
1.4.0
Installed Sphinx versions
2.0.10
2.1.9
2.2.6
Default Sphinx version
2.2.6
Installed Firefox version
firefox 31.0esr
PhantomJS version
1.9.8
ant -version
Apache Ant(TM) version 1.8.2 compiled on December 3 2011
mvn -version
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T17:29:23+00:00)
Maven home: /usr/local/maven
Java version: 1.7.0_76, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-7-oracle/jre
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-042stab090.5", arch: "amd64", family: "unix"

$ git clone --depth=50 --branch=master git://github.com/kyleterry/tenyks.git kyleterry/tenyks
Cloning into 'kyleterry/tenyks'...
remote: Counting objects: 360, done.
remote: Compressing objects: 100% (192/192), done.
remote: Total 360 (delta 178), reused 312 (delta 146), pack-reused 0
Receiving objects: 100% (360/360), 216.36 KiB | 0 bytes/s, done.
Resolving deltas: 100% (178/178), done.
Checking connectivity... done.
$ cd kyleterry/tenyks
$ git checkout -qf 3de7f1d07ca3ac335cfef32050bafcf2d5ade3ae
Installing gimme from https://raw.githubusercontent.com/meatballhat/gimme/v0.2.3/gimme
$ eval "$(gimme tip)"
go version devel +80864cf Fri May 29 04:33:15 2015 +0000 linux/amd64
$ export GOPATH=$HOME/gopath
$ export PATH=$HOME/gopath/bin:$PATH
$ mkdir -p $HOME/gopath/src/github.com/kyleterry/tenyks
$ rsync -az ${TRAVIS_BUILD_DIR}/ $HOME/gopath/src/github.com/kyleterry/tenyks/
$ export TRAVIS_BUILD_DIR=$HOME/gopath/src/github.com/kyleterry/tenyks
$ cd $HOME/gopath/src/github.com/kyleterry/tenyks
$ gimme version
v0.2.3
$ go version
go version devel +80864cf Fri May 29 04:33:15 2015 +0000 linux/amd64
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/travis/gopath"
GORACE=""
GOROOT="/home/travis/.gimme/versions/go"
GOTOOLDIR="/home/travis/.gimme/versions/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
$ go get ./...
$ go get code.google.com/p/gomock/gomock
$ go test ./...
?       github.com/kyleterry/tenyks [no test files]
ok      github.com/kyleterry/tenyks/config  0.004s
?       github.com/kyleterry/tenyks/control [no test files]
2015/05/29 06:09:23 [mockirc] Disconnect called
2015/05/29 06:09:23 [mockirc] Starting send loop
2015/05/29 06:09:23 [mockirc] Stopping send loop
2015/05/29 06:09:23 accept tcp [::]:26661: use of closed network connection
2015/05/29 06:09:24 [mockirc] Bootstrapping connection
2015/05/29 06:09:24 [mockirc] Starting send loop
2015/05/29 06:09:24 <nil>
2015/05/29 06:09:24 USER tenyks localhost something :tenyks
2015/05/29 06:09:24 [mockirc] Sending PING to server 
2015/05/29 06:09:25 <nil>
2015/05/29 06:09:25 Nothing to do for NICK tenyks
2015/05/29 06:09:25 NICK tenyks
2015/05/29 06:09:25 <nil>
2015/05/29 06:09:25 PING 
2015/05/29 06:09:25 [mockirc] Disconnect called
2015/05/29 06:09:25 accept tcp [::]:26661: use of closed network connection
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x5844b0]

goroutine 24 [running]:
github.com/kyleterry/tenyks/mockirc.(*MockIRC).connectionWorker(0xc2080205a0, 0x0, 0x0)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:97 +0x410
created by github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:69 +0x152

goroutine 1 [chan receive]:
testing.RunTests(0x784a88, 0x86f940, 0xa, 0xa, 0x1)
    /home/travis/.gimme/versions/go/src/testing/testing.go:563 +0xa7e
testing.(*M).Run(0xc208051f38, 0xc208014ae0)
    /home/travis/.gimme/versions/go/src/testing/testing.go:492 +0x73
main.main()
    github.com/kyleterry/tenyks/irc/_test/_testmain.go:72 +0x119

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /home/travis/.gimme/versions/go/src/runtime/asm_amd64.s:1670 +0x1

goroutine 16 [chan receive]:
github.com/kyleterry/tenyks/mockirc.(*MockIRC).Stop(0xc2080205a0, 0x0, 0x0)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:88 +0xd7
github.com/kyleterry/tenyks/irc.TestCanHandshakeAndWorkWithIRC(0xc20801e5a0)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/irc/connection_test.go:128 +0xaa7
testing.tRunner(0xc20801e5a0, 0x86f9a0)
    /home/travis/.gimme/versions/go/src/testing/testing.go:454 +0x9b
created by testing.RunTests
    /home/travis/.gimme/versions/go/src/testing/testing.go:562 +0xa3e

goroutine 19 [runnable]:
github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1.1.1(0xc2080205a0, 0xc20801ca80)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:58 +0x170
created by github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1.1
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:60 +0x64

goroutine 11 [chan send]:
github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1.1.1(0xc208020370, 0xc20801c720)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:58 +0x170
created by github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1.1
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:60 +0x64

goroutine 21 [IO wait]:
net.runtime_pollWait(0x7f844149f5f8, 0x72, 0xc20800a240)
    /home/travis/.gimme/versions/go/src/runtime/netpoll.go:157 +0x63
net.(*pollDesc).Wait(0xc20801b560, 0x72, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/net/fd_poll_runtime.go:73 +0x41
net.(*pollDesc).WaitRead(0xc20801b560, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/net/fd_poll_runtime.go:78 +0x3d
net.(*netFD).Read(0xc20801b500, 0xc2080b2000, 0x1000, 0x1000, 0x0, 0x7f844149a050, 0xc20800a240)
    /home/travis/.gimme/versions/go/src/net/fd_unix.go:233 +0x23d
net.(*conn).Read(0xc208030138, 0xc2080b2000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/net/net.go:124 +0xe7
bufio.(*Reader).fill(0xc20801cb40)
    /home/travis/.gimme/versions/go/src/bufio/bufio.go:97 +0x1ec
bufio.(*Reader).ReadSlice(0xc20801cb40, 0x584d0a, 0x0, 0x0, 0x0, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/bufio/bufio.go:328 +0x21d
bufio.(*Reader).ReadBytes(0xc20801cb40, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/bufio/bufio.go:407 +0xae
bufio.(*Reader).ReadString(0xc20801cb40, 0xc20800ba0a, 0x0, 0x0, 0x0, 0x0)
    /home/travis/.gimme/versions/go/src/bufio/bufio.go:447 +0x50
github.com/kyleterry/tenyks/mockirc.(*MockIRC).connectionWorker(0xc2080205a0, 0x7f844149f860, 0xc208030138)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:99 +0x264
created by github.com/kyleterry/tenyks/mockirc.(*MockIRC).Start.func1
    /home/travis/gopath/src/github.com/kyleterry/tenyks/mockirc/mockirc.go:69 +0x152

goroutine 23 [chan receive]:
github.com/kyleterry/tenyks/irc.(*Connection).send.func1(0xc20809c380, 0xc20801cc60)
    /home/travis/gopath/src/github.com/kyleterry/tenyks/irc/connection.go:170 +0x2e8
created by github.com/kyleterry/tenyks/irc.(*Connection).send
    /home/travis/gopath/src/github.com/kyleterry/tenyks/irc/connection.go:174 +0x64
FAIL    github.com/kyleterry/tenyks/irc 3.010s
ok      github.com/kyleterry/tenyks/mockirc 0.004s
?       github.com/kyleterry/tenyks/service [no test files]
?       github.com/kyleterry/tenyks/tenyksctl   [no test files]
?       github.com/kyleterry/tenyks/version [no test files]

The command "go test ./..." exited with 1.

Done. Your build exited with 1.

Dockerfiles for Local Development

Tenyks dev suuuucks to setup. Would be cool to have a dockerfile that just builds a local environment (IRC server, Redis, etc.) and just lets you connect and go.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.