var Acro = commander.Cmd("acro", func(s *commander.Source, r *commander.Response, cmd string, args []string) { usage := func() { r.Private() r.Printf("Usage: ACRO [#channel] {start|join|vote #|<submission>}") } originalArgs := args if len(args) == 0 { usage() return } var channel string if args[0][0] == '#' { channel = args[0] args = args[1:] } else { channel = s.Message().Args[0] if len(channel) == 0 || channel[0] != '#' { usage() return } } gamename := s.Server().Name() + "/" + channel var game *Game if g, ok := games[gamename]; ok { game = g } else { game = &Game{ server: s.Server(), channel: channel, } games[gamename] = game } if len(args) == 0 { usage() return } cmd, args = strings.ToLower(args[0]), args[1:] log.Printf("(%s) !acro %s %v", game, cmd, args) switch cmd { case "start": if game.started { r.Private() r.Printf("Acro has already been started in %s", channel) return } // Make sure the game keeps up with the server game.server = s.Server() // Start the game game.start() case "join": r.Private() if !game.started { r.Printf("You need to start the game before you can join it!") return } j := new(join) j.nick = s.ID().Nick j.ret = make(chan string) game.commands <- j r.Private() for msg := range j.ret { r.Printf(msg) } case "vote": if !game.started { r.Private() r.Printf("You can't vote right now. Try starting a new game?") return } if len(args) < 1 { r.Private() r.Printf("Which acronym did you want to vote for?") return } idx, err := strconv.Atoi(args[0]) if err != nil { r.Private() r.Printf("I don't recognize %s as a number: %s", args[0], err) return } v := new(vote) v.nick = s.ID().Nick v.idx = idx - 1 v.ret = make(chan string) game.commands <- v r.Private() for msg := range v.ret { r.Printf(msg) } default: args = originalArgs fallthrough case "submit": if !game.started { r.Private() r.Printf("You can't submit an acronym right now. Try starting a new game?") return } sub := new(submission) sub.acro = strings.Join(args, " ") sub.nick = s.ID().Nick sub.ret = make(chan string) game.commands <- sub r.Private() for msg := range sub.ret { r.Printf(msg) } } }).Args(1, -1).Help(`Play Acro!
"github.com/kylelemons/blightbot/bot" "github.com/kylelemons/blightbot/commander" "github.com/kylelemons/gopaste/subscribe" ) var ( chans = flag.String("paste-chans", "", "Channels to send paste notifications on") ) func nopaste(s *commander.Source, r *commander.Response, cmd string, args []string) { r.Public() r.Printf("If you need to paste more than 3 lines, use gp: go get github.com/kylelemons/gopaste/gp") } var NoPaste = commander.Cmd("nopaste", nopaste).Help(`Print a message pointing to the gopaste tool`) var servers = struct { sync.Mutex m map[string]*bot.Server }{m: map[string]*bot.Server{}} func addServer(event string, serv *bot.Server, msg *bot.Message) { servers.Lock() defer servers.Unlock() servers.m[serv.Name()] = serv } func delServer(event string, serv *bot.Server, msg *bot.Message) { servers.Lock()
resp.Private() resp.Printf("Hmm, that doesn't look like a package name...") return } } uri := url.URL{ Scheme: "http", Host: ThirdPartyHost, Path: "/", RawQuery: url.Values{"q": {pkg}}.Encode(), } r, err := http.Head(uri.String()) // If the query did not redirect, then GoPkgDoc could not find the package. if err != nil || r.StatusCode != http.StatusOK || r.Request.URL.Path == "/" { resp.Public() resp.Printf("Hmm, I can't find %q. You can look for it on %s", pkg, ThirdPartyIndex) return } resp.Public() resp.Printf("3pkg: %s", r.Request.URL.String()) } var TPDoc = commander.Cmd("3pkg", tpdoc).Help(`Retrieve the URL for a third-party package Usage: 3PKG <pkgname> Thanks to Gary Burd for his awesome gopkgdoc site! http://gopkgdoc.appspot.com/`)
var CL = commander.Cmd("cl", func(src *commander.Source, resp *commander.Response, cmd string, args []string) { // Reasonable default is private resp.Private() if len(args) < 1 { args = append(args, "") } cmd = strings.ToLower(args[0]) log.Printf("CMD %q, ARGS %v", cmd, args) switch cmd { case "latest": case "summary": case "detail": default: // Well, we don't know what we're being asked to do... resp.Private() resp.Printf("Usage: CL {latest|summary}") return } u := "https://code.google.com/feeds/p/" + ProjectID + "/" + ProjectVCS + "changes/basic" r, err := http.Get(u) if err != nil { resp.Public() resp.Printf("Sorry, `cl` seems to be having issues...") log.Printf("http get: %s", err) return } defer r.Body.Close() x := new(bytes.Buffer) io.Copy(x, r.Body) var feed Feed if err := xml.NewDecoder(x).Decode(&feed); err != nil { resp.Public() resp.Printf("Sorry, `cl` seems to be having issues...") log.Printf("xml decode: %s", err) return } var data struct { Summary struct { Daily int Plus string Authors map[string]int } Latest Entry } data.Summary.Plus = "+" data.Summary.Authors = map[string]int{} for entryIdx, e := range feed.Entry { if entryIdx == 0 { title := e.Title // Split at translated newline if idx := strings.Index(title, " "); idx >= 0 { title = title[:idx] } // Split at weird chars (usually a .) if idx := strings.IndexFunc(title, func(r rune) bool { switch { case r >= 'a' && r <= 'z': return false case r >= 'A' && r <= 'Z': return false case r >= '0' && r <= '9': return false case r == '-' || r == '_': return false case r == ':' || r == ' ': return false } return true }); idx >= 0 { title = title[:idx] } data.Latest = e data.Latest.Title = title } if time.Since(e.Updated) > 24*time.Hour { data.Summary.Plus = "" break } name := e.Author.Name if idx := strings.Index(name, " <"); idx >= 0 { name = name[:idx] } data.Summary.Authors[name]++ data.Summary.Daily++ } b := new(bytes.Buffer) if t, ok := cltemplates[cmd]; ok { if err := t.Execute(b, data); err != nil { resp.Public() resp.Printf("Sorry, `cl` seems to be having issues...") log.Printf("execute: %s", err) return } resp.Public() for lineno, line := range strings.Split(b.String(), "\n") { if lineno == 2 { resp.Printf("... (see online for more)") return } resp.Printf(line) } } else { resp.Printf("Sorry, `cl` seems to be having, well, issues...") log.Printf("couldn't find template for %q...", cmd) return } }).Help(`List or summarize recent commits
func (ds DashSorter) Len() int { return len(ds) } func (ds DashSorter) Less(i, j int) bool { return strings.IndexRune(ds[i], '-') < strings.IndexRune(ds[j], '-') } func (ds DashSorter) Swap(i, j int) { ds[i], ds[j] = ds[j], ds[i] } func dochelp(cmd, text, searchFor string) string { opts := "" for site := range DocSites { opts += "[--" + site + "] " } return fmt.Sprintf("%s\nUsage: %s %s<%s>", text, strings.ToUpper(cmd), opts, searchFor) } var ( Pkg = commander.Cmd("pkg", godoc).Help(dochelp("pkg", "Retrieve the URLs for go packages", "package")) Cmd = commander.Cmd("cmd", godoc).Help(dochelp("cmd", "Retrieve the URLs for go commands", "command")) FAQ = commander.Cmd("faq", godoc).Help(dochelp("faq", "Retrieve the URLs for FAQ sections", "search terms")) Go1 = commander.Cmd("go1", godoc).Help(dochelp("go1", "Retrieve the URLs for Go1 Release Notes sections", "search terms")) EGo = commander.Cmd("ego", godoc).Help(dochelp("ego", "Retrieve the URLs for Effective Go sections", "search terms")) Doc = commander.Cmd("doc", godoc).Help(dochelp("doc", "Search the (cached) online documents", "search terms")) Spec = commander.Cmd("spec", godoc).Help(dochelp("spec", "Retrieve the URLs for Specification sections", "search terms")) Compat = commander.Cmd("compat", godoc).Help(dochelp("compat", "Retrieve the URLs for Go1 Compatibility Notes sections", "search terms")) ) func StartPolling() { go func() { for { generate() time.Sleep(RefreshDocEvery) }
var Issue = commander.Cmd("issue", func(src *commander.Source, resp *commander.Response, cmd string, args []string) { if len(args) < 1 { args = append(args, "") } query := url.Values{} cmd = strings.ToLower(args[0]) log.Printf("CMD %q, ARGS %v", cmd, args) switch cmd { case "search": if len(args) < 2 { resp.Private() resp.Printf("Usage: ISSUE search <query>") return } query.Set("can", "open") query.Set("max-results", "500") query.Set("q", strings.Join(args[1:], " ")) case "detail": if len(args) < 2 { resp.Private() resp.Printf("Usage: ISSUE detail #####") return } query.Set("id", args[1]) query.Set("max-results", "1") default: // First, try an ID if _, err := strconv.Atoi(cmd); err == nil { query.Set("id", cmd) cmd = "id" break } // Next, try an abbreviated query if q, ok := ShortQueries[cmd]; ok { query.Set("can", "open") query.Set("max-results", "500") query.Set("q", q) cmd = "search" break } // Well, we don't know what we're being asked to do... resp.Private() resp.Printf("Usage: ISSUE {#####|search|detail|<status>|<priority>} ...") return } u := "https://code.google.com/feeds/issues/p/" + ProjectID + "/issues/full?" + query.Encode() log.Printf("Issue search: %q", u) r, err := http.Get(u) if err != nil { resp.Public() resp.Printf("Sorry, `issue` seems to be having, well, issues...") log.Printf("http get: %s", err) return } defer r.Body.Close() var feed Feed if err := xml.NewDecoder(r.Body).Decode(&feed); err != nil { resp.Public() resp.Printf("Sorry, `issue` seems to be having, well, issues...") log.Printf("xml decode: %s", err) return } sort.Sort(ByLatest(feed.Entry)) for entryIdx, e := range feed.Entry { if entryIdx >= 5 { break } b := new(bytes.Buffer) if t, ok := issuetemplates[cmd]; ok { if err := t.Execute(b, e); err != nil { resp.Printf("Sorry, `issue` seems to be having, well, issues...") log.Printf("template execute: %s", err) return } switch cmd { case "detail": resp.Private() default: resp.Public() } for lineno, line := range strings.Split(b.String(), "\n") { if lineno == 10 { resp.Printf("... (see online for more)") return } resp.Printf(line) } } else { resp.Printf("Sorry, `issue` seems to be having, well, issues...") log.Printf("couldn't find template for %q...", cmd) return } } }).Help(`List or search Go issues