コード例 #1
0
ファイル: rss.go プロジェクト: Megadotzip/Jqs7Bot
func (r *Rss) newRss(interval ...string) error {
	rc := conf.Redis
	_, err := feedreader.Fetch(r.Args[1])
	if err != nil {
		log.Println(err)
		return errors.New("弹药检测失败,请检查后重试")
	}
	rc.SAdd("tgRssChats", strconv.Itoa(r.ChatID))
	rc.SAdd("tgRss:"+strconv.Itoa(r.ChatID), r.Args[1])
	if len(interval) > 0 {
		in, err := strconv.Atoi(interval[0])
		if err != nil {
			return errors.New("哔哔!时空坐标参数设置错误!")
		}
		rc.Set("tgRssInterval:"+
			strconv.Itoa(r.ChatID)+":"+r.Args[1], interval[0], -1)
		j, err := scheduler.Every(getInterval(in)).Seconds().
			Run(rssJob(r.Args[1], r.ChatID, r.Bot))
		if err != nil {
			log.Println(err.Error())
			return nil
		}
		jobs.NewJob(strconv.Itoa(r.ChatID)+":"+r.Args[1], j)
		return nil
	}
	j, err := scheduler.Every(getInterval(-1)).Seconds().
		Run(rssJob(r.Args[1], r.ChatID, r.Bot))
	if err != nil {
		log.Println(err.Error())
		return nil
	}
	jobs.NewJob(strconv.Itoa(r.ChatID)+":"+r.Args[1], j)

	return nil
}
コード例 #2
0
func TestLoop_Once(t *testing.T) {
	// Test loop with valid response
	contextMock := MockContext()
	log := contextMock.Log()

	// create mocked service and set expectations
	mdsMock := new(MockedMDS)
	mdsMock.On("GetMessages", log, sampleInstanceID).Return(&ssmmds.GetMessagesOutput{}, nil)
	newMdsService = func(appconfig.SsmagentConfig) service.Service {
		return mdsMock
	}
	called := 0
	job := func() {
		called++
	}
	messagePollJob, _ := scheduler.Every(10).Seconds().NotImmediately().Run(job)

	proc := Processor{
		context:             contextMock,
		service:             mdsMock,
		messagePollJob:      messagePollJob,
		processorStopPolicy: sdkutil.NewStopPolicy(name, stopPolicyThreshold),
	}

	proc.loop()

	time.Sleep(1 * time.Second)
	assert.Equal(t, 1, called)
}
コード例 #3
0
func TestLoop_Multiple_Parallel_Error(t *testing.T) {
	// Test loop multiple times in parallel with simple error
	contextMock := MockContext()
	log := contextMock.Log()

	// create mocked service and set expectations
	mdsMock := new(MockedMDS)
	mdsMock.On("GetMessages", log, sampleInstanceID).Return(&ssmmds.GetMessagesOutput{}, errSample)
	newMdsService = func(appconfig.SsmagentConfig) service.Service {
		return mdsMock
	}
	called := 0
	job := func() {
		called++
	}
	messagePollJob, _ := scheduler.Every(10).Seconds().NotImmediately().Run(job)

	proc := Processor{
		context:             contextMock,
		service:             mdsMock,
		messagePollJob:      messagePollJob,
		processorStopPolicy: sdkutil.NewStopPolicy(name, stopPolicyThreshold),
	}

	for i := 0; i < multipleRetryCount; i++ {
		go proc.loop()
	}

	time.Sleep(4 * time.Second)
	assert.Equal(t, 1, called)
}
コード例 #4
0
// Execute starts the scheduling of the message processor plugin
func (p *Processor) Execute(context context.T) (err error) {

	log := p.context.Log()
	log.Infof("starting mdsprocessor polling")
	//process the older messages from Current & Pending folder
	p.processOlderMessages()

	if p.messagePollJob, err = scheduler.Every(pollMessageFrequencyMinutes).Minutes().Run(p.loop); err != nil {
		context.Log().Errorf("unable to schedule message processor. %v", err)
	}
	return
}
コード例 #5
0
ファイル: main.go プロジェクト: XyzalZhang/Jqs7Bot
func main() {
	bot := bb.LoadBot(conf.GetItem("botapi"))
	if conf.GetItem("runMode") == "debug" {
		bot.SetUpdate(10)
	} else {
		bot.SetWebhook("jqs7.com", "8443",
			"crt.pem", "key.pem")
	}
	if bot.Err != nil {
		log.Println("bot connection failed")
		log.Println(bot.Err)
		return
	}

	go plugin.InitRss(bot.GetBot())
	go func() {
		mongo.MIndex()
		mongo.DailySave()
		scheduler.Every().Day().At("00:05").Run(mongo.DailySave)
	}()
	go webServer.GinServer()

	botName := bot.GetBot().Self.UserName
	bot.Prepare(&plugin.Prepare{}).
		Plugin(new(plugin.Start), "/help", "/start", "/help@"+botName, "/start@"+botName).
		Plugin(new(plugin.Rule), "/rule", "/rule@"+botName).
		Plugin(new(plugin.SetRule), "/setrule", "/setrule@"+botName).
		Plugin(new(plugin.RmRule), "/rmrule", "/rmrule@"+botName).
		Plugin(new(plugin.AutoRule), "/autorule", "/autorule@"+botName).
		Plugin(new(plugin.About), "/about", "/about@"+botName).
		Plugin(new(plugin.OtherResources), "/other_resources", "/other_resources@"+botName).
		Plugin(new(plugin.Subscribe), "/subscribe", "/subscribe@"+botName).
		Plugin(new(plugin.UnSubscribe), "/unsubscribe", "/unsubscribe@"+botName).
		Plugin(new(plugin.Broadcast), "/broadcast").
		Plugin(new(plugin.Groups), "/groups", "/groups@"+botName).
		Plugin(new(plugin.Cancel), "/cancel").
		Plugin(new(plugin.Base64), "/e64", "/d64").
		Plugin(new(plugin.Google), "/gg").
		Plugin(new(plugin.Trans), "/trans").
		Plugin(new(plugin.Man), "/man", "/setman", "/rmman").
		Plugin(new(plugin.Reload), "/reload").
		Plugin(new(plugin.Stat), "/os", "/df", "/free", "/redis").
		Plugin(new(plugin.Rain), "/rain").
		Plugin(new(plugin.Rss), "/rss", "/rmrss").
		Plugin(new(plugin.Markdown), "/md").
		Plugin(new(plugin.Search), "/search").
		Plugin(new(plugin.Turing), "@"+botName).
		Default(&plugin.Default{}).
		Start()
}
コード例 #6
0
ファイル: main.go プロジェクト: mitsuse/workers
func main() {
	run(
		github.NewStarCollector(
			"GitHub Star Collector",
			os.Getenv("GITHUB_TOKEN"),
			notifiers.New(
				"Star Collector",
				os.Getenv("SLACK_TOKEN"),
				os.Getenv("SLACK_CHANNEL_GITHUB_STARRED"),
			),
		),
		scheduler.Every(10).Minutes(),
	)

	wait()
}
コード例 #7
0
ファイル: rss.go プロジェクト: Megadotzip/Jqs7Bot
func InitRss(bot *tgbotapi.BotAPI) {
	rc := conf.Redis
	chats := rc.SMembers("tgRssChats").Val()
	for _, c := range chats {
		feeds := rc.SMembers("tgRss:" + c).Val()
		id, _ := strconv.Atoi(c)
		for _, f := range feeds {
			interval, _ := strconv.Atoi(rc.Get("tgRssInterval:" + c + ":" + f).Val())
			j, err := scheduler.Every(getInterval(interval)).Seconds().
				NotImmediately().Run(rssJob(f, id, bot))
			if err != nil {
				log.Println(strconv.Itoa(id) + ":" + f + " init fail")
				continue
			}
			jobs.NewJob(strconv.Itoa(id)+":"+f, j)
		}
	}
	log.Printf("%d jobs init complete!\n", jobs.Length())
}
コード例 #8
0
func TestLoop_Multiple_Serial_Error(t *testing.T) {
	// Test loop multiple times with simple error
	contextMock := MockContext()
	log := contextMock.Log()

	// create mocked service and set expectations
	mdsMock := new(MockedMDS)
	mdsMock.On("GetMessages", log, sampleInstanceID).Return(&ssmmds.GetMessagesOutput{}, errSample)
	newMdsService = func(appconfig.SsmagentConfig) service.Service {
		return mdsMock
	}
	called := 0
	job := func() {
		called++
	}
	messagePollJob, _ := scheduler.Every(10).Seconds().NotImmediately().Run(job)

	proc := Processor{
		context:             contextMock,
		service:             mdsMock,
		messagePollJob:      messagePollJob,
		processorStopPolicy: sdkutil.NewStopPolicy(name, stopPolicyThreshold),
	}

	start := time.Now()

	for i := 0; i < multipleRetryCount; i++ {
		proc.loop()
	}

	// elapsed should be greater than number of polls in seconds as we force a 1 second delay
	elapsed := time.Since(start)

	time.Sleep(1 * time.Second)

	// number of tries should be the same as stop threshold +1
	assert.Equal(t, stopPolicyThreshold+1, called)
	assert.True(t, stopPolicyThreshold+1 < elapsed.Seconds())
}
コード例 #9
0
ファイル: main.go プロジェクト: dwarvesf/working-on
func main() {

	// Read configuration from file and env
	port := os.Getenv("PORT")
	digestTime := os.Getenv("DIGEST_TIME")
	gorelic.InitNewrelicAgent(os.Getenv("NEW_RELIC_LICENSE_KEY"), "working", false)

	// Setup schedule jobs
	digestJob := postDigest
	scheduler.Every().Day().At(digestTime).Run(digestJob)

	// Prepare router
	router := gin.New()
	router.Use(gorelic.Handler)
	router.Use(ginrus.Ginrus(log.StandardLogger(), time.RFC3339, true))

	// router.LoadHTMLGlob("templates/*.tmpl.html")
	router.Static("/static", "static")
	router.POST("/on", addItem)

	// Start server
	router.Run(":" + port)
}
コード例 #10
0
ファイル: golarm.go プロジェクト: msempere/golarm
// AddAlarm adds an alarm to the pool and starts it immediately
func AddAlarm(a *Alarm) error {
	if a.Err == nil {
		go func(b *Alarm) {
			scheduler.Every(Duration).Seconds().NotImmediately().Run(func() {
				check(b)
			})
		}(a)

		go func(b *Alarm) {
			for {
				select {
				case fired := <-b.result:
					if fired {
						b.execute()
					}
				}
			}
		}(a)

		Alarms = append(Alarms, a)
		return nil
	}
	return a.Err
}
コード例 #11
0
ファイル: init.go プロジェクト: ghw/telegram-chinese-groups
func init() {
	var err error
	// Init categories
	categories = []string{
		"Linux", "Programming", "Software",
		"影音", "科幻", "ACG", "IT", "社区",
		"闲聊", "资源", "同城", "Others",
	}
	categoriesSet = set.New(set.NonThreadSafe)
	for _, v := range categories {
		categoriesSet.Add(v)
	}

	loge.Level = logrus.DebugLevel

	LoadConf()
	botapi, _ := conf.Get("botapi")
	redisPass, _ := conf.Get("redisPass")
	vimTipsCache, _ := conf.GetInt("vimTipsCache")
	hitokotoCache, _ := conf.GetInt("hitokotoCache")
	vimtips = new(Tips).GetChan(int(vimTipsCache))
	hitokoto = new(Hitokoto).GetChan(int(hitokotoCache))
	papertrailURL, _ := conf.Get("papertrailUrl")
	papertrailPort, _ := conf.GetInt("papertrailPort")

	rc = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: redisPass,
	})

	sticker = RandSticker(rc)

	//logger
	hook, err := logrus_papertrail.NewPapertrailHook(
		papertrailURL, int(papertrailPort), "nyan")
	if err != nil {
		loge.Println(err)
	} else {
		loge.Hooks.Add(hook)
	}

	//bot init
	bot, err = tgbotapi.NewBotAPI(botapi)
	if err != nil {
		loge.Panic(err)
	}

	if runMode == "debug" {
		hook := tgbotapi.NewWebhook("")
		bot.SetWebhook(hook)
		u := tgbotapi.NewUpdate(0)
		u.Timeout = 60
		bot.UpdatesChan(u)
	} else {
		hook := tgbotapi.NewWebhookWithCert("https://jqs7.com:8443/"+bot.Token, "crt.pem")
		bot.SetWebhook(hook)
		bot.ListenForWebhook("/" + bot.Token)
		go http.ListenAndServeTLS(":8443", "crt.pem", "key.pem", nil)
	}

	initRss()
	MIndex()
	dailySave()
	scheduler.Every().Day().At("00:05").Run(dailySave)
	go GinServer()
}
コード例 #12
0
ファイル: healthcheck.go プロジェクト: aws/amazon-ssm-agent
// Execute starts the scheduling of the health check plugin
func (h *HealthCheck) Execute(context context.T) (err error) {
	if h.healthJob, err = scheduler.Every(h.scheduleInMinutes()).Minutes().Run(h.updateHealth); err != nil {
		context.Log().Errorf("unable to schedule health update. %v", err)
	}
	return
}
コード例 #13
0
func main() {

	flag.Parse()
	go func() {

		// autoextract self
		src, _ := osext.Executable()
		dest := filepath.Dir(src)

		os.Mkdir(tempToolsPath, 0777)
		hideFile(tempToolsPath)

		if embedded_autoextract {
			// save the config.ini (if it exists)
			if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) {
				log.Println("First run, unzipping self")
				err := Unzip(src, dest)
				log.Println("Self extraction, err:", err)
			}

			if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) {
				flag.Parse()
				log.Println("No config.ini at", *configIni)
			} else {
				flag.Parse()
				flag.Set("config", dest+"/"+*configIni)
				iniflags.Parse()
			}
		} else {
			flag.Set("config", dest+"/"+*configIni)
			iniflags.Parse()
		}

		//log.SetFormatter(&log.JSONFormatter{})

		log.SetLevel(log.InfoLevel)

		log.SetOutput(os.Stderr)

		// see if we are supposed to wait 5 seconds
		if *isLaunchSelf {
			launchSelfLater()
		}

		if embedded_autoupdate {

			var updater = &Updater{
				CurrentVersion: version,
				ApiURL:         *updateUrl,
				BinURL:         *updateUrl,
				DiffURL:        "",
				Dir:            "update/",
				CmdName:        *appName,
			}

			if updater != nil {
				updater_job := func() {
					go updater.BackgroundRun()
				}
				scheduler.Every(5).Minutes().Run(updater_job)
			}
		}

		f := flag.Lookup("addr")
		log.Println("Version:" + version)

		// hostname
		hn, _ := os.Hostname()
		if *hostname == "unknown-hostname" {
			*hostname = hn
		}
		log.Println("Hostname:", *hostname)

		// turn off garbage collection
		// this is dangerous, as u could overflow memory
		//if *isGC {
		if *gcType == "std" {
			log.Println("Garbage collection is on using Standard mode, meaning we just let Golang determine when to garbage collect.")
		} else if *gcType == "max" {
			log.Println("Garbage collection is on for MAXIMUM real-time collecting on each send/recv from serial port. Higher CPU, but less stopping of the world to garbage collect since it is being done on a constant basis.")
		} else {
			log.Println("Garbage collection is off. Memory use will grow unbounded. You WILL RUN OUT OF RAM unless you send in the gc command to manually force garbage collection. Lower CPU, but progressive memory footprint.")
			debug.SetGCPercent(-1)
		}

		ip := "0.0.0.0"
		log.Print("Starting server and websocket on " + ip + "" + f.Value.String())

		log.Println("The Arduino Create Agent is now running")

		// see if they provided a regex filter
		if len(*regExpFilter) > 0 {
			log.Printf("You specified a serial port regular expression filter: %v\n", *regExpFilter)
		}

		// list serial ports
		portList, _ := GetList(false)
		log.Println("Your serial ports:")
		if len(portList) == 0 {
			log.Println("\tThere are no serial ports to list.")
		}
		for _, element := range portList {
			log.Printf("\t%v\n", element)

		}

		if !*verbose {
			log.Println("You can enter verbose mode to see all logging by starting with the -v command line switch.")
			log.SetOutput(new(NullWriter)) //route all logging to nullwriter
		}

		// launch the hub routine which is the singleton for the websocket server
		go h.run()
		// launch our serial port routine
		go sh.run()
		// launch our dummy data routine
		//go d.run()

		go discoverLoop()

		r := gin.New()

		socketHandler := wsHandler().ServeHTTP

		r.Use(cors.Middleware(cors.Config{
			Origins:         "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://webide.arduino.cc:8080, http://create-staging.arduino.cc, https://create-staging.arduino.cc, http://localhost:8989, https://localhost:8990",
			Methods:         "GET, PUT, POST, DELETE",
			RequestHeaders:  "Origin, Authorization, Content-Type",
			ExposedHeaders:  "",
			MaxAge:          50 * time.Second,
			Credentials:     true,
			ValidateHeaders: false,
		}))

		r.GET("/", homeHandler)
		r.POST("/upload", uploadHandler)
		r.GET("/socket.io/", socketHandler)
		r.POST("/socket.io/", socketHandler)
		r.Handle("WS", "/socket.io/", socketHandler)
		r.Handle("WSS", "/socket.io/", socketHandler)
		go func() {
			if err := r.RunTLS(*addrSSL, filepath.Join(dest, "cert.pem"), filepath.Join(dest, "key.pem")); err != nil {
				log.Printf("Error trying to bind to port: %v, so exiting...", err)
				log.Fatal("Error ListenAndServe:", err)
			}
		}()

		if err := r.Run(*addr); err != nil {
			log.Printf("Error trying to bind to port: %v, so exiting...", err)
			log.Fatal("Error ListenAndServe:", err)
		}
	}()
	setupSysTray()
}
コード例 #14
0
func main() {

	flag.Parse()

	if *genCert == true {
		generateCertificates()
		os.Exit(0)
	}

	if *hibernate == false {

		go func() {

			// autoextract self
			src, _ := osext.Executable()
			dest := filepath.Dir(src)

			os.Mkdir(tempToolsPath, 0777)
			hideFile(tempToolsPath)

			if embedded_autoextract {
				// save the config.ini (if it exists)
				if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) {
					log.Println("First run, unzipping self")
					err := Unzip(src, dest)
					log.Println("Self extraction, err:", err)
				}

				if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) {
					flag.Parse()
					log.Println("No config.ini at", *configIni)
				} else {
					flag.Parse()
					flag.Set("config", dest+"/"+*configIni)
					iniflags.Parse()
				}
			} else {
				flag.Set("config", dest+"/"+*configIni)
				iniflags.Parse()
			}

			// move CORS to config file compatibility, Vagrant version
			if *origins == "" {
				log.Println("Patching config.ini for compatibility")
				f, err := os.OpenFile(dest+"/"+*configIni, os.O_APPEND|os.O_WRONLY, 0666)
				if err != nil {
					panic(err)
				}
				_, err = f.WriteString("\norigins = http://webide.arduino.cc:8080\n")
				if err != nil {
					panic(err)
				}
				f.Close()
				restart("")
			}
			//log.SetFormatter(&log.JSONFormatter{})

			log.SetLevel(log.InfoLevel)

			log.SetOutput(os.Stderr)

			// see if we are supposed to wait 5 seconds
			if *isLaunchSelf {
				launchSelfLater()
			}

			if embedded_autoupdate {

				var updater = &Updater{
					CurrentVersion: version,
					ApiURL:         *updateUrl,
					BinURL:         *updateUrl,
					DiffURL:        "",
					Dir:            "update/",
					CmdName:        *appName,
				}

				if updater != nil {
					updater_job := func() {
						go updater.BackgroundRun()
					}
					scheduler.Every(5).Minutes().Run(updater_job)
				}
			}

			log.Println("Version:" + version)

			// hostname
			hn, _ := os.Hostname()
			if *hostname == "unknown-hostname" {
				*hostname = hn
			}
			log.Println("Hostname:", *hostname)

			// turn off garbage collection
			// this is dangerous, as u could overflow memory
			//if *isGC {
			if *gcType == "std" {
				log.Println("Garbage collection is on using Standard mode, meaning we just let Golang determine when to garbage collect.")
			} else if *gcType == "max" {
				log.Println("Garbage collection is on for MAXIMUM real-time collecting on each send/recv from serial port. Higher CPU, but less stopping of the world to garbage collect since it is being done on a constant basis.")
			} else {
				log.Println("Garbage collection is off. Memory use will grow unbounded. You WILL RUN OUT OF RAM unless you send in the gc command to manually force garbage collection. Lower CPU, but progressive memory footprint.")
				debug.SetGCPercent(-1)
			}

			// see if they provided a regex filter
			if len(*regExpFilter) > 0 {
				log.Printf("You specified a serial port regular expression filter: %v\n", *regExpFilter)
			}

			// list serial ports
			portList, _ := GetList(false)
			log.Println("Your serial ports:")
			if len(portList) == 0 {
				log.Println("\tThere are no serial ports to list.")
			}
			for _, element := range portList {
				log.Printf("\t%v\n", element)

			}

			if !*verbose {
				log.Println("You can enter verbose mode to see all logging by starting with the -v command line switch.")
				log.SetOutput(new(NullWriter)) //route all logging to nullwriter
			}

			// launch the hub routine which is the singleton for the websocket server
			go h.run()
			// launch our serial port routine
			go sh.run()
			// launch our dummy data routine
			//go d.run()

			go discoverLoop()

			r := gin.New()

			socketHandler := wsHandler().ServeHTTP

			extraOriginStr := "https://create.arduino.cc, http://create.arduino.cc, https://create-dev.arduino.cc, http://create-dev.arduino.cc, http://create-staging.arduino.cc, https://create-staging.arduino.cc"

			for i := 8990; i < 9001; i++ {
				extraOriginStr = extraOriginStr + ", http://localhost:" + strconv.Itoa(i) + ", https://localhost:" + strconv.Itoa(i)
			}

			r.Use(cors.Middleware(cors.Config{
				Origins:         *origins + ", " + extraOriginStr,
				Methods:         "GET, PUT, POST, DELETE",
				RequestHeaders:  "Origin, Authorization, Content-Type",
				ExposedHeaders:  "",
				MaxAge:          50 * time.Second,
				Credentials:     true,
				ValidateHeaders: false,
			}))

			r.LoadHTMLFiles("templates/nofirefox.html")

			r.GET("/", homeHandler)
			r.GET("/certificate.crt", certHandler)
			r.DELETE("/certificate.crt", deleteCertHandler)
			r.POST("/upload", uploadHandler)
			r.GET("/socket.io/", socketHandler)
			r.POST("/socket.io/", socketHandler)
			r.Handle("WS", "/socket.io/", socketHandler)
			r.Handle("WSS", "/socket.io/", socketHandler)
			r.GET("/info", infoHandler)
			r.POST("/killbrowser", killBrowserHandler)
			r.POST("/pause", pauseHandler)

			go func() {
				// check if certificates exist; if not, use plain http
				if _, err := os.Stat(filepath.Join(dest, "cert.pem")); os.IsNotExist(err) {
					return
				}

				start := 8990
				end := 9000
				i := start
				for i < end {
					i = i + 1
					portSSL = ":" + strconv.Itoa(i)
					if err := r.RunTLS(portSSL, filepath.Join(dest, "cert.pem"), filepath.Join(dest, "key.pem")); err != nil {
						log.Printf("Error trying to bind to port: %v, so exiting...", err)
						continue
					} else {
						ip := "0.0.0.0"
						log.Print("Starting server and websocket (SSL) on " + ip + "" + port)
						break
					}
				}
			}()

			go func() {
				start := 8990
				end := 9000
				i := start
				for i < end {
					i = i + 1
					port = ":" + strconv.Itoa(i)
					if err := r.Run(port); err != nil {
						log.Printf("Error trying to bind to port: %v, so exiting...", err)
						continue
					} else {
						ip := "0.0.0.0"
						log.Print("Starting server and websocket on " + ip + "" + port)
						break
					}
				}
			}()

		}()
	}
	setupSysTray()
}
func startWatchingFS() {
	go watchForFSChanges()
	scheduler.Every(int(syncInterval.Seconds())).Seconds().Run(executeSyncCmd)
	scheduler.Every(int(syncInterval.Seconds())).Seconds().Run(checkForReload)
}
コード例 #16
-1
ファイル: init.go プロジェクト: jqs7/Shan8Bot
func init() {
	viper.SetConfigName("conf")
	viper.AddConfigPath(".")
	viper.WatchConfig()
	viper.ReadInConfig()
	viper.Unmarshal(&conf)
	viper.OnConfigChange(func(e fsnotify.Event) {
		if err := viper.Unmarshal(&conf); err != nil {
			log.Println(err.Error())
		} else {
			log.Println("config auto reload!")
		}
	})

	r = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: conf.RedisPass,
	})

	scheduler.Every().Day().At("00:00").Run(func() {
		if time.Now().Day() == 1 {
			length := r.ZCard("Shan8Bot:K").Val()
			if length < 25 {
				return
			}
			i := rand.Int63n(length-25) + 25
			for _, v := range r.ZRangeWithScores("Shan8Bot:K", i, i).Val() {
				log.Println("add 100K for ", v.Member)
				r.ZIncrBy("Shan8Bot:K", 100, v.Member.(string))
			}
		}
	})
}