Пример #1
0
func loadWatched(manga *Manga) {
	db, err := ioutil.ReadFile("manga.db")
	if err != nil {
		logger.Error(err.Error())
		return
	}
	err = json.Unmarshal(db, manga)
	if err != nil {
		logger.Error(err.Error())
		return
	}
}
Пример #2
0
func parseRSS(rss []byte, source string) (map[string]MangaEntry, error) {
	src := strings.Split(lib.Sanitise(string(rss[bytes.Index(rss, []byte("<item>")):])), "</item>")
	src = src[0 : len(src)-1]
	entries := map[string]MangaEntry{}
	var title, tmpDate string
	for _, line := range src {
		if line == "" {
			continue
		}
		title = line[strings.Index(line, "<title>")+7 : strings.Index(line, "</title>")]
		title = html.UnescapeString(title)
		if source == "mangafox" {
			title = html.UnescapeString(title) // one more time - mangafox double escape sometimes -.-
		}
		tmpDate = line[strings.Index(line, "<pubDate>")+9 : strings.Index(line, "</pubDate>")]
		date, err := time.Parse("Mon, 2 Jan 2006 15:04:05 -0700", tmpDate)
		if err != nil {
			logger.Error(err.Error())
			return nil, errors.New("parseRSS failed to parse time : " + tmpDate)
		}
		entries[strings.ToLower(title)] = MangaEntry{
			Title: title,
			Link:  line[strings.Index(line, "<link>")+6 : strings.Index(line, "</link>")],
			Date:  date.Unix(),
			Desc:  line[strings.Index(line, "<description>")+13 : strings.Index(line, "</description>")],
		}
	}
	return entries, nil
}
Пример #3
0
func GetTitle(rawuri string) string {
	var index int
	ext := rawuri[strings.LastIndex(rawuri, "//")+2:]
	if index = strings.LastIndex(ext, "/"); index > 0 {
		ext = ext[index+1:]
		if index = strings.Index(ext, "."); index > -1 {
			ext = ext[index+1:]
			allow := []string{"htm", "html", "asp", "aspx", "php", "php3", "php5"}
			if !lib.HasElementString(allow, ext) {
				logger.Debug(fmt.Sprintf("[web.GetTitle()] Not an OK file extension: %s -> %s",
					rawuri, ext))
				return ""
			}
		}
	}
	body, err := Get(&rawuri)
	if err != "" {
		return ""
	}
	r, regErr := regexp.Compile("<title?[^>]+>([^<]+)<\\/title>")
	if regErr != nil {
		logger.Error("[web.GetTitle()] Couldn't compile regex title regex")
		return ""
	}
	if title := r.FindString(string(body)); title != "" {
		rooturl := rawuri[strings.Index(rawuri, "//")+2:]
		if index = strings.Index(rooturl, "/"); index > -1 {
			rooturl = rooturl[:index]
		}
		return fmt.Sprintf("%s ~ %s", html.UnescapeString(lib.StripHtml(title)), rooturl)
	}
	return ""
}
Пример #4
0
func Register(bot *irc.IRC) {
	defer logger.Info(lib.TimeTrack(lib.TimeNow(), "Loading the Urban Dictionary plugin"))

	events.CmdListen(&events.CmdListener{
		Commands: []string{"urbandictionary", "ud"},
		Help:     "Looks up Urban Dictionary entries. NSFW",
		Syntax:   bot.Config.Prefix + "ud <term> - Example: " + bot.Config.Prefix + "ud scrobble",
		Callback: func(input *events.Params) {
			uri := fmt.Sprintf("http://api.urbandictionary.com/v0/define?term=%s", url.QueryEscape(input.Data))
			body, err := web.Get(&uri)
			if err != "" {
				bot.Say(input.Context, err)
				return
			}
			ud := &UDResponse{}
			jserr := json.Unmarshal(body, &ud)
			if jserr != nil {
				logger.Error("Couldn't parse UD's JSON: " + jserr.Error())
				return
			}
			if ud.Result == "no_results" {
				bot.Say(input.Context, fmt.Sprintf("\"%s\" is not a thing on Urban Dictionary.", input.Data))
				return
			}
			var resp string = ""
			var max int = 3
			if len(ud.List) < max {
				max = len(ud.List)
			}
			for i := 0; i < max; i++ {
				resp += fmt.Sprintf("%d) %s, ", i+1, ud.List[i].Definition)
			}
			bot.Say(input.Context, ud.List[0].Word+" ~ "+lib.SingleSpace(resp[0:len(resp)-2]))
		}})
}
Пример #5
0
func NewStringListDB(filename string) *StringListDB {
	var err error
	var index int
	var data []byte
	var entries []string
	nDB := new(StringListDB)
	nDB.Filename = filename
	nDB.Entry = map[string]string{}
	data, err = ioutil.ReadFile("db/" + nDB.Filename)
	if err != nil {
		logger.Error(fmt.Sprintf("[storage.NewStringListDB()] Couldn't read db/%s -> %s", nDB.Filename, err.Error()))
		return nDB
	}
	if len(data) > 0 {
		entries = strings.Split(string(data), "\n")
		for _, line := range entries {
			if line == "" {
				continue
			}
			index = strings.Index(line, " ")
			nDB.Entry[line[:index]] = line[index+1:]
		}
	}
	return nDB
}
Пример #6
0
func getFileContents(filename string) [][]byte {
	wordList, err := ioutil.ReadFile("data/words/" + filename + ".txt")
	if err != nil {
		logger.Error(err.Error())
		return nil
	}
	return bytes.Split(wordList, []byte("\n"))
}
Пример #7
0
func saveWatched(manga *Manga) {
	out, err := json.Marshal(*manga)
	if err != nil {
		logger.Error(err.Error())
		return
	}
	ioutil.WriteFile("manga.db", out, 0666)
	logger.Info("Saved Manga watch list.")
}
Пример #8
0
func EvListenComplex(event *ComplexEventListener) {
	r, err := regexp.Compile(event.Regex)
	if err != nil {
		logger.Error(fmt.Sprintf("EvListenComplex: Couldn't compile %s's Regex: %s",
			event.Handle, event.Regex))
		return
	}
	event.r = *r
	complexListeners[event.Event] = append(complexListeners[event.Event], event)
}
Пример #9
0
func (sdb *StringDB) Save() {
	var err error
	var data []byte
	data, err = json.Marshal(&sdb.Entry)
	if err != nil {
		logger.Error(fmt.Sprintf("[StringDB.Save()] Couldn't Marshal %s JSON -> %s", sdb.Filename, err.Error()))
		return
	}
	if len(data) > 0 {
		err = ioutil.WriteFile("db/"+sdb.Filename, data, 0666)
	} else {
		err = ioutil.WriteFile("db/"+sdb.Filename, []byte{}, 0666)
	}
	if err != nil {
		logger.Error(fmt.Sprintf("[StringDB.Save()] Couldn't save db/%s -> %s", sdb.Filename, err.Error()))
		return
	}
	logger.Info(fmt.Sprintf("Saved db/%s ..", sdb.Filename))
}
Пример #10
0
func NewStringDB(filename string) *StringDB {
	var err error
	var data []byte
	nDB := new(StringDB)
	nDB.Filename = filename
	nDB.Entry = map[string]string{}
	data, err = ioutil.ReadFile("db/" + nDB.Filename)
	if err != nil {
		logger.Error(fmt.Sprintf("[storage.NewStringDB()] Couldn't read db/%s -> %s", nDB.Filename, err.Error()))
		return nDB
	}
	if len(data) > 0 {
		if err = json.Unmarshal(data, &nDB.Entry); err != nil {
			logger.Error(fmt.Sprintf("[storage.Open()] Couldn't Unmarshal json in db/%s -> %s", nDB.Filename, err.Error()))
			return nDB
		}
	}
	return nDB
}
Пример #11
0
func (irc *IRC) Connect() bufio.Reader {
	conn, err := net.Dial("tcp", irc.Config.Server+":"+irc.Config.Port)
	irc.Conn = conn
	if err != nil {
		logger.Error("Connection error")
		os.Exit(1)
	}
	irc.Send(fmt.Sprintf("NICK %s", irc.Config.Nicknames[0]))
	irc.Send(fmt.Sprintf("USER %s localhost * :%s", irc.Config.Username, irc.Config.Realname))

	out := bufio.NewReader(irc.Conn)
	return *out
}
Пример #12
0
func Register(bot *irc.IRC) {
	defer logger.Info(lib.TimeTrack(time.Now(), "Loading the YouTube plugin"))

	events.CmdListen(&events.CmdListener{
		Commands: []string{"youtube", "yt"},
		Help:     "YouTubes stuff.",
		Syntax:   bot.Config.Prefix + "yt <search terms> - Example: " + bot.Config.Prefix + "yt we like big booty bitches",
		Callback: func(input *events.Params) {
			ytr := &YouTubeResults{}
			uri := fmt.Sprintf("http://gdata.youtube.com/feeds/api/videos?q=%s&max-results=1&v=2&alt=json",
				url.QueryEscape(input.Data))
			body, err := web.Get(&uri)
			if err != "" {
				logger.Error("YouTube Failed: " + err)
				bot.Say(input.Context, "Woops.")
				return
			}
			errr := json.Unmarshal(body, &ytr)
			if errr != nil {
				logger.Error("Couldn't parse youtube's JSON:" + errr.Error())
				bot.Say(input.Context, "Herp. Check logs")
				return
			}
			if len(ytr.Feed.Entry) == 0 {
				bot.Say(input.Context, fmt.Sprintf("\"%s\" is not a thing on YouTube.", input.Data))
				return
			}
			yt := &ytr.Feed.Entry[0]
			duration, errr := time.ParseDuration(yt.Info.Duration["seconds"] + "s")
			resp := fmt.Sprintf("%s ~ [%s] %s - %s views ~ http://youtu.be/%s ~ %s",
				*yt.Title["$t"], &duration, yt.Info.Date["$t"][0:10],
				lib.CommaNum(yt.Stats["viewCount"]), yt.Info.ID["$t"],
				yt.Info.Description["$t"])
			bot.Say(input.Context, resp)
			resp = ""
			ytr = nil
		}})
}
Пример #13
0
func (irc *IRC) Start() {
	out := irc.Connect()
	sem <- 1
	for {
		<-sem
		line, prefix, err := out.ReadLine()
		if err != nil {
			logger.Error("Connection error: " + err.Error())
			os.Exit(4)
		}
		if prefix == true {
			sem <- 1
			continue
		}
		go irc.handleData(line)
	}
}
Пример #14
0
func (sl *StringListDB) Save() {
	var err error
	var entries string
	if len(sl.Entry) > 0 {
		for key, entry := range sl.Entry {
			entries += fmt.Sprintf("%s %s\n", key, entry)
		}
		entries = entries[:len(entries)-1] // no trailing \n
		err = ioutil.WriteFile("db/"+sl.Filename, []byte(entries), 0666)
	} else {
		err = ioutil.WriteFile("db/"+sl.Filename, []byte{}, 0666)
	}
	if err != nil {
		logger.Error(fmt.Sprintf("[StringListDB.Save()] Couldn't save to db/%s -> %s", sl.Filename, err.Error()))
		return
	}
	logger.Info(fmt.Sprintf("Saved db/%s ..", sl.Filename))
}
Пример #15
0
func ReplaceVars(aliasStr string) string {
	r, err := regexp.Compile("\\$\\{([a-z0-9]+)\\}")
	if err != nil {
		logger.Error(fmt.Sprintf("Couldn't compile VarReg regexp: %s", err.Error()))
		return aliasStr
	}
	for i := 0; i < 10; i++ {
		match := r.FindString(aliasStr)
		if match != "" {
			variable := Vars.GetOne(match[2 : len(match)-1])
			if variable == match {
				aliasStr = fmt.Sprintf("%s -> Error: %q variable refers to itself.", aliasStr, variable)
				return aliasStr
			}
			if variable != "" {
				aliasStr = strings.Replace(aliasStr, match, variable, -1)
			}
		} else {
			return aliasStr
		}
	}
	return aliasStr
}
Пример #16
0
// misc
func (irc *IRC) findParams(params *events.Params, line string, args []string) {
	var command string
	var index int
	if strings.Index(args[0], "!") == -1 { // server message?
		params.Context = args[3]
		params.Nick = args[0][1:]
		params.Args = args[1:]
		params.Data = line
		return
	}
	params.Context = args[2]
	params.Nick = args[0][1:strings.Index(args[0], "!")]
	params.Address = args[0][strings.Index(args[0], "!")+1:]
	switch args[1] {
	case "NOTICE":
		fallthrough
	case "PRIVMSG":
		if args[2][0:1] != "#" { // queries
			params.Context = params.Nick
		}
		if args[3][1:2] == irc.Config.Prefix && args[3][2:3] != "" {
			command = args[3][2:]
			if alias.DB.HasKey(command) { // temporary, need alias/args parser
				aliasEntry := alias.DB.GetOne(command)
				index = strings.Index(aliasEntry, " ")
				params.Command = aliasEntry[:index]
				if strings.Index(aliasEntry, "${") > -1 {
					aliasEntry = alias.ReplaceVars(aliasEntry)
				}
				if strings.Index(aliasEntry, "{{") > -1 {
					var aEvent alias.Event
					aEvent.Populate(params, args[4:len(args)], &aliasEntry)
					var out bytes.Buffer
					t, err := template.New(command).Funcs(aEvent.TmplFuncs()).Parse(aliasEntry[index+1:])
					if err != nil {
						params.Data = fmt.Sprintf("Couldn't parse %q template: %s", aliasEntry, err.Error())
						logger.Error(params.Data)
						return
					}
					err = t.Execute(&out, aEvent)
					if err != nil {
						params.Data = fmt.Sprintf("Couldn't execute %q template: %s", aliasEntry, err.Error())
						logger.Error(params.Data)
						return
					}
					params.Data = out.String()
					params.Args = strings.Fields(params.Data)
				} else {
					params.Data = aliasEntry[index+1:]
					params.Args = strings.Fields(params.Data)
				}
			} else {
				params.Command = command
				params.Args = args[4:len(args)]
				params.Data = strings.Join(params.Args, " ")
			}
		} else {
			params.Data = strings.Join(args[3:len(args)], " ")[1:]
		}
	case "NICK":
		params.Newnick = args[2][1:]
	case "JOIN":
		if params.Context[0:1] == ":" {
			params.Context = params.Context[1:]
		}
	case "PART":
		if len(args) > 3 {
			params.Message = strings.Join(args[3:], " ")[1:]
		}
		if params.Context[0:1] == ":" { // Y U NO CONSISTENT
			params.Context = params.Context[1:]
		}
	case "QUIT":
		params.Message = strings.Join(args[2:], " ")[1:]
	case "KICK":
		params.Kicknick = args[3]
		params.Message = strings.Join(args[4:], " ")[1:]
	case "MODE": // can't think why this is needed for now, dump its mojo in message
		params.Message = strings.Join(args[3:], " ")
	case "TOPIC":
		params.Message = strings.Join(args[3:], " ")[1:]
	}
	if params.Args == nil {
		params.Args = args
	}
	if params.Data == "" {
		params.Data = line
	}
	//fmt.Println(params)
}
Пример #17
0
func catchPanic(listenType string, handle string) {
	if e := recover(); e != nil {
		logger.Error(fmt.Sprintf("Caught panic in %s \"%s\": %s", listenType, handle, e))
	}
}
Пример #18
0
func checkUpdates(bot *irc.IRC, source string, context string) {
	var manga Manga
	var uri, message string
	var watched map[string]MangaEntry
	loadWatched(&manga)
	switch source {
	case "mangafox":
		uri = "http://mangafox.me/rss/latest_manga_chapters.xml"
		watched = manga.MangaFox
	case "mangastream":
		uri = "http://mangastream.com/rss"
		watched = manga.MangaStream
	}

	data, err := web.Get(&uri)
	if err != "" {
		logger.Error(err)
		return
	}

	var entries map[string]MangaEntry
	entries, perr := parseRSS(data, source)
	if perr != nil {
		logger.Error(perr.Error())
		return
	}
	keys := getKeys(source)
	updates := make([]irc.RatedMessage, 0)
	var method string
	var newEntry MangaEntry
	for title, entry := range entries {
		for _, key := range keys {
			if strings.Index(title, key) > -1 {
				if entry.Date > watched[key].Date {
					// update found
					switch source {
					case "mangastream":
						message = fmt.Sprintf("%s is out! \\o/ ~ %s ~ %q",
							entry.Title, entry.Link, entry.Desc)
						newEntry = MangaEntry{
							Manga:    entry.Title[:len(key)],
							Title:    entry.Title,
							Date:     entry.Date,
							Desc:     entry.Desc,
							Link:     entry.Link,
							Announce: watched[key].Announce,
						}
					case "mangafox":
						message = fmt.Sprintf("%s is out! \\o/ ~ %s", entry.Title, entry.Link)
						newEntry = MangaEntry{
							Manga:    entry.Title[:len(key)],
							Title:    entry.Title,
							Date:     entry.Date,
							Link:     entry.Link,
							Announce: watched[key].Announce,
						}
					}
					delete(watched, key)
					watched[key] = newEntry
					if context != "" && !lib.HasElementString(watched[key].Announce, context) {
						if context[0:1] == "#" {
							method = "say"
						} else {
							method = "notice"
						}
						updates = append(updates, irc.RatedMessage{
							Method:  method,
							Target:  context,
							Message: message,
						})
					}
					for _, target := range watched[key].Announce {
						if target[0:1] == "#" {
							method = "say"
						} else {
							method = "notice"
						}
						updates = append(updates, irc.RatedMessage{
							Method:  method,
							Target:  target,
							Message: message,
						})
					}
				}
			}
		}
	}
	if len(updates) > 0 {
		bot.Rated(&updates)
		saveWatched(&manga)
	} else if context != "" {
		bot.Say(context, "Nothing new. :\\")
	}
}