Beispiel #1
0
func main() {

	// Parse flags from command line
	flag.Parse()
	log := logging.InitFromFlags()

	// setup logging
	log.SetLogLevel(2)

	if _, err := os.Stat(*config_file); err != nil {

		generate_config_file(*config_file)
		log.Error("You must edit the " + *config_file + " file before continuing")
		os.Exit(0)
	}

	//generate a config file if it isn't found
	if *generate_config {
		generate_config_file(*config_file)
		log.Error("You must edit the " + *config_file + " file before continuing")
		os.Exit(0)
	}

	// handle configuration

	log.Info("Read configuration file: " + *config_file)
	settings := yaml.New()
	settings.Read(*config_file)

	if *channel == "" {
		*channel = settings.Get("connection/channel").(string)
		log.Debug("Read channel from config file: " + *channel)
	} else {
		log.Debug("Read channel from flag: " + *channel)
	}

	if *nick == "" {
		*nick = settings.Get("connection/nick").(string)
		log.Debug("Read nick from config file: " + *nick)
	} else {
		log.Debug("Read nick from flag: " + *nick)
	}

	if *realname == "" {
		*realname = settings.Get("connection/realname").(string)
		log.Debug("Read realname from config file: " + *realname)
	} else {
		log.Debug("Read realname from flag: " + *realname)
	}

	if *irc_server == "" {
		*irc_server = settings.Get("connection/irc_server").(string)
		log.Debug("Read irc_server from config file: " + *irc_server)
	} else {
		log.Debug("Read irc_server from flag: " + *irc_server)
	}

	if *rejoin_on_kick == true {
		*rejoin_on_kick = settings.Get("bot_config/rejoin_on_kick").(bool)
		log.Debug("Read rejoin_on_kick from config file: %t ", *rejoin_on_kick)
	} else {
		log.Debug("Read rejoin_on_kick from flag: %t ", *rejoin_on_kick)
	}

	// bitly

	shorturl_enabled := settings.Get("bitly/shorturls_enabled").(bool)
	bitly_username := settings.Get("bitly/username").(string)
	bitly_api_key := settings.Get("bitly/api_key").(string)
	if shorturl_enabled {
		bitly.SetUser(bitly_username)
		bitly.SetKey(bitly_api_key)
	}

	owner_nick := to.String(settings.Get("bot_config/owner"))
	friends := to.List(settings.Get("bot_config/friends"))
	trusted_identities := make([]string, 0)
	trusted_identities = append(trusted_identities, owner_nick)
	for _, value := range friends {
		trusted_identities = append(trusted_identities, value.(string))
	}

	// set up bot command event registry
	bot_command_registry := event.NewRegistry()
	reallyquit := false

	// Bot command handlers
	// addfriend
	addfriend_state := make(chan string)
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if line.Src == owner_nick {
			channel := line.Args[0]
			if len(commands) > 1 {
				target := commands[1]
				log.Debug("adding friend: %q", target)
				conn.Whois(target)
				log.Debug("triggering channel: %q", target)
				addfriend_state <- target

			} else {
				conn.Privmsg(channel, line.Nick+": use !addfriend <friend nick>")
			}
		}
	}), "addfriend")

	//save
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if line.Src == owner_nick {
			channel := line.Args[0]
			conn.Privmsg(channel, line.Nick+": saving settings")
			settings.Set("bot_config/friends", friends)
			settings.Write(*config_file)
			log.Info("%q", to.List(settings.Get("bot_config/friends")))
		}
	}), "save")

	//reload
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if line.Src == owner_nick {
			channel := line.Args[0]
			conn.Privmsg(channel, line.Nick+": reloading settings")
			friends := to.List(settings.Get("bot_config/friends"))
			trusted_identities = make([]string, 0)
			trusted_identities = append(trusted_identities, owner_nick)
			for _, value := range friends {
				trusted_identities = append(trusted_identities, value.(string))
			}
			log.Info("%q", to.List(settings.Get("bot_config/friends")))
		}
	}), "reload")

	// op
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if Trust(line.Src, trusted_identities) {
			channel := line.Args[0]
			if len(commands) > 1 {
				target := commands[1]
				log.Info("Oping user: "******"+o "+target)
			} else {
				log.Info("Oping user: "******"+o "+line.Nick)
			}
		}
	}), "op")

	//deop
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if Trust(line.Src, trusted_identities) {
			channel := line.Args[0]
			if len(commands) > 1 {
				target := commands[1]
				conn.Mode(channel, "-o "+target)
			} else {
				conn.Mode(channel, "-o "+line.Nick)
			}
		}
	}), "deop")

	// kick
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if Trust(line.Src, trusted_identities) {
			channel := line.Args[0]
			if len(commands) > 1 {
				target := commands[1]
				kick_message := "get out"
				if len(commands) > 2 {
					//this doesn't work. Need to fix.
					kick_message = commands[2]
				}
				//do'nt kick if owner
				if target != strings.Split(owner_nick, "!")[0] {
					//don't kick if self
					if *nick != target {
						conn.Kick(channel, target, kick_message)
					} else {
						conn.Privmsg(channel, line.Nick+": why would i kick myself?")
					}
				} else {
					conn.Privmsg(channel, line.Nick+": why would i kick my lovely friend "+target+"?")

				}
			} else {
				conn.Privmsg(channel, line.Nick+": invalid command")
			}
		}
	}), "kick")

	//quit
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		if line.Src == owner_nick {
			quit_message := "i died"
			reallyquit = true
			if len(commands) > 1 {
				quit_message = commands[1]
			}
			conn.Quit(quit_message)
		}
	}), "quit")

	//urlshortener
	bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) {
		log.Info("URLS event")
		channel := line.Args[0]
		for _, long_url := range commands {
			work_url := long_url
			work_urlr := regexp.MustCompile(`^[\w-]+://([^/?]+)(/(?:[^/?]+/)*)?([^./?][^/?]+?)?(\.[^.?]*)?(\?.*)?$`)
			url_parts := work_urlr.FindAllStringSubmatch(work_url, -1)
			domain := url_parts[0][1]
			ext := url_parts[0][4]

			forbidden_extensions := "png|gif|jpg|mp3|avi|md|zip"
			extension_regex := regexp.MustCompile(`(` + forbidden_extensions + `)`)
			extension_test := extension_regex.FindAllStringSubmatch(ext, -1)

			title := ""
			url_util_channel := make(chan string)
			if extension_test == nil {
				go grab_title(work_url, url_util_channel)
				title = <-url_util_channel
			}

			go shorten_url(work_url, url_util_channel, bitly_username, bitly_api_key)
			short_url := <-url_util_channel
			output := ""
			if short_url != long_url {

				output = output + "<" + short_url + "> (at " + domain + ") "
			}
			if title != "" {
				output = output + " " + title
			}
			conn.Privmsg(channel, output)
		}
	}), "urlshortener")

	// create new IRC connection
	log.Info("create new IRC connection")
	irc_client := irc.SimpleClient(*nick, *realname)

	// IRC HANDLERS!

	irc_client.EnableStateTracking()
	irc_client.AddHandler("connected",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("connected as " + *nick)
			conn.Join(*channel)
		})

	// Set up a handler to notify of disconnect events.
	quit := make(chan bool)
	irc_client.AddHandler("disconnected",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("disconnected")
			quit <- true
		})

	//Handle Private messages
	irc_client.AddHandler("PRIVMSG",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("privmsg")
			irc_input := strings.ToLower(line.Args[1])
			if strings.HasPrefix(irc_input, *command_char) {
				irc_command := strings.Split(irc_input[1:], " ")
				bot_command_registry.Dispatch(irc_command[0], conn, line, irc_command)
			}
			url_regex := regexp.MustCompile(`\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))`)
			urls := url_regex.FindAllString(irc_input, -1)
			if len(urls) > 0 {
				bot_command_registry.Dispatch("urlshortener", conn, line, urls)
			}

		})

	//handle kick by rejoining kicked channel
	irc_client.AddHandler("KICK",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("Kicked from " + line.Args[0])
			if *rejoin_on_kick {
				log.Info("rejoining " + line.Args[0])
				conn.Join(line.Args[0])
			}
		})

	//notify on 332 - topic reply on join to channel
	irc_client.AddHandler("332",
		func(conn *irc.Conn, line *irc.Line) {
			log.Debug("Topic is %q, on %q ", line.Args[2], line.Args[1])
		})

	//notify on MODE
	irc_client.AddHandler("MODE",
		func(conn *irc.Conn, line *irc.Line) {
			for _, v := range line.Args {
				log.Info("mode: %q ", v)
			}
		})

	//notify on WHOIS
	irc_client.AddHandler("311",
		func(conn *irc.Conn, line *irc.Line) {
			addedfriend := <-addfriend_state
			log.Info("addfriend channel: %q", addedfriend)
			if addedfriend == line.Args[1] {
				friend := line.Args[1] + "!" + line.Args[2] + "@" + line.Args[3]
				log.Debug("added friend " + friend)
				trusted_identities = append(trusted_identities, friend)
				friends = append(friends, friend)
				log.Debug("friends: %q", friends)
				conn.Privmsg(strings.Split(owner_nick, "!")[0], line.Nick+": added "+line.Args[1]+" as friend")
				//addfriend_state <- ""
			} else {
				log.Info("addfriend channel is empty: %q", addedfriend)

			}
		})

	//notify on join
	irc_client.AddHandler("JOIN",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("Joined " + line.Args[0])
		})

	//handle topic changes
	irc_client.AddHandler("TOPIC",
		func(conn *irc.Conn, line *irc.Line) {
			log.Info("Topic on " + line.Args[0] + " changed to: " + line.Args[1])
		})

	// set up a goroutine to read commands from stdin

	if *generate_config == false {

		for !reallyquit {
			// connect to server
			if err := irc_client.Connect(*irc_server); err != nil {
				fmt.Printf("Connection error: %s\n", err)
				return
			}

			// wait on quit channel
			<-quit
		}
	}
}
Beispiel #2
0
func (self *Build) load(pkg string, ctx *Context) {
	var err error
	var version string

	minjs, _ := regexp.Compile(`\.js$`)

	if ctx.Loaded[pkg] == true {
		return
	} else {
		ctx.Loaded[pkg] = true
	}

	if strings.Contains(pkg, ":") {
		i := strings.LastIndex(pkg, ":")
		version = pkg[i+1:]
		pkg = pkg[0:i]
	}

	filename := PluginsRoot + tango.PS + pkg + tango.PS + "package.yaml"

	_, err = os.Stat(filename)

	if err == nil {

		info, err := yaml.Open(filename)

		if err == nil {

			if version == "" {
				version = to.String(info.Get("latest"))
			}

			files := to.Map(info.Get(fmt.Sprintf("packages/%s", version)))

			if files == nil {
				ctx.Buf.Write([]byte(fmt.Sprintf("/* Package \"%s\" with version \"%s\" was not found. */\n", pkg, version)))
			} else {

				if files["requires"] != nil {
					for _, req := range to.List(files["requires"]) {
						self.load(req.(string), ctx)
					}
				}

				ctx.Buf.Write([]byte(fmt.Sprintf("/* %s: %s. %s */\n", pkg, to.String(info.Get("name")), to.String(info.Get("copyright")))))

				if files["source"] != nil {
					for _, jsfile := range to.List(files["source"]) {
						minfile := minjs.ReplaceAllString(jsfile.(string), ".min.js")
						ctx.Buf.Write(self.read(PluginsRoot + tango.PS + pkg + tango.PS + minfile))
						ctx.Buf.Write([]byte(fmt.Sprintf("\n")))
					}
				}

				ctx.Buf.Write([]byte(fmt.Sprintf("\n\n")))

				if files["style"] != nil {

					styles := to.List(files["style"])

					cssfiles := make([]string, len(styles))

					for i, _ := range styles {
						cssfiles[i] = fmt.Sprintf("plugins/%s/%s", pkg, styles[i].(string))
					}

					css, _ := json.Marshal(cssfiles)

					ctx.Buf.Write([]byte(fmt.Sprintf("$.foo.styles.apply($.foo, %s);\n", string(css))))
				}

			}

			ctx.Buf.Write([]byte(fmt.Sprintf("\n\n")))

		} else {
			ctx.Buf.Write([]byte(fmt.Sprintf("/* Package \"%s\": metadata error. */\n", pkg)))
		}
	} else {
		ctx.Buf.Write([]byte(fmt.Sprintf("/* Package \"%s\": missing. */\n", pkg)))
	}

}