示例#1
0
//doLiveGraph builds a graph in the terminal window that
//updates every graphUpdate seconds
//It will build up to maxGraphs graphs with one time-series
//per graph
func doLiveGraph(res *wavefront.QueryResponse, query *wavefront.Querying, period int64) {

	err := ui.Init()
	if err != nil {
		log.Fatal(err)
	}
	defer ui.Close()

	if maxGraphs > len(res.TimeSeries) {
		maxGraphs = len(res.TimeSeries)
	}

	var wDivisor, hDivisor int
	switch maxGraphs {
	case 1:
		wDivisor = 1
		hDivisor = 1
	case 2:
		wDivisor = 2
		hDivisor = 1
	case 3, 4:
		wDivisor = 2
		hDivisor = 2
	}

	height := ui.TermHeight() / hDivisor
	width := ui.TermWidth() / wDivisor
	xVals, yVals := calculateCoords(maxGraphs, ui.TermWidth()/wDivisor, ui.TermHeight()/hDivisor)
	graphs := buildGraphs(res, height, width, xVals, yVals)

	ui.Render(graphs...)
	ui.Handle("/sys/kbd/q", func(ui.Event) {
		// press q to quit
		ui.StopLoop()
	})

	ui.Handle("/sys/kbd/C-c", func(ui.Event) {
		// handle Ctrl + c combination
		ui.StopLoop()
	})

	ui.Handle("/timer/1s", func(e ui.Event) {
		query.SetEndTime(time.Now())
		query.SetStartTime(period)
		res, err := query.Execute()
		if err != nil {
			log.Fatal(err)
		}
		graphs := buildGraphs(res, height, width, xVals, yVals)
		ui.Render(graphs...)
	})

	ui.Loop()

}
示例#2
0
func (p *TicketShowPage) Create() {
	log.Debugf("TicketShowPage.Create(): self:        %s (%p)", p.Id(), p)
	log.Debugf("TicketShowPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage)
	p.opts = getJiraOpts()
	if p.TicketId == "" {
		p.TicketId = ticketListPage.GetSelectedTicketId()
	}
	if p.MaxWrapWidth == 0 {
		if m := p.opts["max_wrap"]; m != nil {
			p.MaxWrapWidth = uint(m.(int64))
		} else {
			p.MaxWrapWidth = defaultMaxWrapWidth
		}
	}
	ui.Clear()
	ls := ui.NewList()
	if p.statusBar == nil {
		p.statusBar = new(StatusBar)
	}
	if p.commandBar == nil {
		p.commandBar = commandBar
	}
	p.uiList = ls
	if p.Template == "" {
		if templateOpt := p.opts["template"]; templateOpt == nil {
			p.Template = "jira_ui_view"
		} else {
			p.Template = templateOpt.(string)
		}
	}
	innerWidth := uint(ui.TermWidth()) - 3
	if innerWidth < p.MaxWrapWidth {
		p.WrapWidth = innerWidth
	} else {
		p.WrapWidth = p.MaxWrapWidth
	}
	if p.apiBody == nil {
		p.apiBody, _ = FetchJiraTicket(p.TicketId)
	}
	p.cachedResults = WrapText(JiraTicketAsStrings(p.apiBody, p.Template), p.WrapWidth)
	p.displayLines = make([]string, len(p.cachedResults))
	if p.selectedLine >= len(p.cachedResults) {
		p.selectedLine = len(p.cachedResults) - 1
	}
	ls.ItemFgColor = ui.ColorYellow
	ls.Height = ui.TermHeight() - 2
	ls.Width = ui.TermWidth()
	ls.Border = true
	ls.BorderLabel = fmt.Sprintf("%s %s", p.TicketId, p.ticketTrailAsString())
	ls.Y = 0
	p.statusBar.Create()
	p.commandBar.Create()
	p.Update()
}
示例#3
0
func (p *LabelListPage) Create() {
	ui.Clear()
	ls := ui.NewList()
	p.uiList = ls
	if p.statusBar == nil {
		p.statusBar = new(StatusBar)
	}
	if p.commandBar == nil {
		p.commandBar = commandBar
	}
	queryName := p.ActiveQuery.Name
	queryJQL := p.ActiveQuery.JQL
	p.labelCounts = countLabelsFromQuery(queryJQL)
	p.cachedResults = p.labelsAsSortedList()
	p.isPopulated = true
	p.displayLines = make([]string, len(p.cachedResults))
	ls.ItemFgColor = ui.ColorYellow
	ls.BorderLabel = fmt.Sprintf("Label view -- %s: %s", queryName, queryJQL)
	ls.Height = ui.TermHeight() - 2
	ls.Width = ui.TermWidth()
	ls.Y = 0
	p.statusBar.Create()
	p.commandBar.Create()
	p.Update()
}
示例#4
0
文件: editui.go 项目: sqp/godock
func (ed *Editor) resize() {
	termui.Body.Width = termui.TermWidth()

	ed.applets.Height = termui.TermHeight() - 2 + 1 // offset 1 for border
	ed.desc.Y = ed.locked.Y + ed.locked.Height - 1  // offset 1 for border
	ed.desc.Height = termui.TermHeight() - ed.desc.Y - 2
	ed.title.Y = termui.TermHeight() - 2

	ed.title.Width = termui.TermWidth() + 1                     // offset 1 for border
	ed.appinfo.Width = termui.TermWidth() - ed.appinfo.X + 1    // offset 1 for border
	ed.locked.Width = termui.TermWidth() - ed.applets.Width + 1 // offset 1 for border
	ed.desc.Width = termui.TermWidth() - ed.applets.Width + 1   // offset 1 for border
	ed.desc.WrapLength = ed.desc.Width

	termui.Render(ed.applets, ed.fields, ed.appinfo, ed.locked, ed.desc, ed.title)
}
示例#5
0
文件: ui.go 项目: bigwhoop/podcastd
func init() {
	err := termui.Init()
	if err != nil {
		panic(err)
	}

	termui.UseTheme("default")

	ui = NewUi()

	refreshTicker := time.NewTicker(time.Millisecond * 50)
	evt := termui.EventCh()

	ui.refresh()

	go func() {
		for {
			select {
			case e := <-evt:
				if e.Type == termui.EventKey && e.Ch == 'q' {
					os.Exit(1)
				}
				if e.Type == termui.EventResize {
					ui.gridWidth = termui.TermWidth()
					ui.refresh()
				}
			case <-refreshTicker.C:
				ui.refresh()
			}
		}
	}()
}
示例#6
0
func (p *TicketListPage) Create() {
	log.Debugf("TicketListPage.Create(): self:        %s (%p)", p.Id(), p)
	log.Debugf("TicketListPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage)
	ui.Clear()
	ls := ui.NewList()
	p.uiList = ls
	if p.statusBar == nil {
		p.statusBar = new(StatusBar)
	}
	if p.commandBar == nil {
		p.commandBar = commandBar
	}
	query := p.ActiveQuery.JQL
	if sort := p.ActiveSort.JQL; sort != "" {
		re := regexp.MustCompile(`(?i)\s+ORDER\s+BY.+$`)
		query = re.ReplaceAllString(query, ``) + " " + sort
	}
	if len(p.cachedResults) == 0 {
		p.cachedResults = JiraQueryAsStrings(query, p.ActiveQuery.Template)
	}
	if p.selectedLine >= len(p.cachedResults) {
		p.selectedLine = len(p.cachedResults) - 1
	}
	p.displayLines = make([]string, len(p.cachedResults))
	ls.ItemFgColor = ui.ColorYellow
	ls.BorderLabel = fmt.Sprintf("%s: %s", p.ActiveQuery.Name, p.ActiveQuery.JQL)
	ls.Height = ui.TermHeight() - 2
	ls.Width = ui.TermWidth()
	ls.Y = 0
	p.statusBar.Create()
	p.commandBar.Create()
	p.Update()
}
示例#7
0
文件: ui.go 项目: bigwhoop/podcastd
func NewUi() Ui {
	headerWidget := termui.NewPar(fmt.Sprintf("podcastd v%s\nCopyright 2015 Philippe Gerber\nhttps://github.com/bigwhoop/podcastd", VERSION))
	headerWidget.Height = 5
	headerWidget.HasBorder = false
	headerWidget.PaddingTop = 1
	headerWidget.PaddingBottom = 1
	headerWidget.PaddingLeft = 1

	infoWidget := termui.NewPar("")
	infoWidget.HasBorder = false
	infoWidget.Text = fmt.Sprintf("Press 'q' to quit")

	feedsWidget := termui.NewList()
	feedsWidget.Border.Label = "Feeds"

	return Ui{
		termui.TermWidth(),
		headerWidget,
		infoWidget,
		feedsWidget,
		make(map[string]bool, 0),
		make([]*termui.Gauge, 0),
		make(map[string]curl.ProgressStatus, 0),
	}
}
示例#8
0
文件: readmail.go 项目: llvtt/gomail
func readMessage(message *imap.MessageInfo) {
	set := new(imap.SeqSet)
	set.AddNum(message.Seq)
	cmd, err := imap.Wait(c.Fetch(set, BODY_PART_NAME))
	panicMaybe(err)

	reader, err := messageReader(cmd.Data[0].MessageInfo())
	panicMaybe(err)

	scanner := bufio.NewScanner(reader)
	var lines []string
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	messageBodyStr := strings.Join(lines[:min(len(lines), ui.TermHeight()-2)], "\n")

	if len(messageBodyStr) <= 0 {
		LOG.Printf("Message body was empty or could not be retrieved: +%v\n", err)
		return
	}

	msgBox := ui.NewPar(messageBodyStr)
	msgBox.Border.Label = "Reading Message"
	msgBox.Height = ui.TermHeight()
	msgBox.Width = ui.TermWidth()
	msgBox.Y = 0
	ui.Render(msgBox)

	topLineIndex := 0

	redraw := make(chan bool)

	for {
		select {
		case e := <-ui.EventCh():
			switch e.Key {
			case ui.KeyArrowDown:
				topLineIndex = max(0, min(
					len(lines)-msgBox.Height/2,
					topLineIndex+1))
				go func() { redraw <- true }()
			case ui.KeyArrowUp:
				topLineIndex = max(0, topLineIndex-1)
				go func() { redraw <- true }()
			case ui.KeyEsc:
				// back to "list messages"
				return
			}
		case <-redraw:
			messageBodyStr = strings.Join(lines[topLineIndex+1:], "\n")
			msgBox.Text = messageBodyStr
			ui.Render(msgBox)
		}
	}
}
示例#9
0
func (p *CommandBar) Create() {
	ls := ui.NewList()
	p.uiList = ls
	ls.ItemFgColor = ui.ColorGreen
	ls.Border = false
	ls.Height = 1
	ls.Width = ui.TermWidth()
	ls.X = 0
	ls.Y = ui.TermHeight() - 1
	p.Update()
}
示例#10
0
文件: ui.go 项目: marktai/T9-Terminal
func adjustDimensions() {
	termui.Body.Width = termui.TermWidth()
	height := termui.TermHeight()
	parMap["moveHistory"].Height = height - 23 - 4
	parMap["output"].Height = height - 23
	if height < 31 {
		parMap["board"].Height = height - 8
		parMap["moveHistory"].Height = 2
		parMap["output"].Height = 6
	}
}
示例#11
0
文件: spark.go 项目: catalyzeio/cli
func sparkLinesEventLoop() {
	ui.Handle("/sys/kbd/q", func(ui.Event) {
		ui.StopLoop()
	})
	ui.Handle("/sys/wnd/resize", func(e ui.Event) {
		ui.Body.Width = ui.TermWidth()
		ui.Body.Align()
		ui.Render(ui.Body)
	})

	ui.Loop() // blocking call
}
示例#12
0
文件: gom.go 项目: x0ry/gom
func main() {
	flag.Parse()
	if err := ui.Init(); err != nil {
		panic(err)
	}
	defer ui.Close()
	draw()
	ui.Handle("/sys/kbd", func(e ui.Event) {
		ev := e.Data.(ui.EvtKbd)
		switch ev.KeyStr {
		case ":":
			promptMsg = ":"
		case "C-8":
			if l := len(promptMsg); l != 0 {
				promptMsg = promptMsg[:l-1]
			}
		case "<enter>":
			handleInput()
			promptMsg = ""
		case "<left>":
		case "<up>":
			if reportPage > 0 {
				reportPage--
			}
		case "<right>":
		case "<down>":
			reportPage++
		case "<escape>":
			promptMsg = ""
		default:
			// TODO: filter irrelevant keys such as up, down, etc.
			promptMsg += ev.KeyStr
		}
		refresh()
	})
	ui.Handle("/sys/kbd/C-c", func(ui.Event) {
		ui.StopLoop()
	})
	ui.Handle("/timer/1s", func(ui.Event) {
		loadProfile(false)
		loadStats()
		refresh()
	})
	ui.Handle("/sys/wnd/resize", func(e ui.Event) {
		ui.Body.Width = ui.TermWidth()
		refresh()
	})

	ui.Body.Align()
	ui.Render(ui.Body)
	ui.Loop()
}
示例#13
0
func (p *StatusBar) Create() {
	ls := ui.NewList()
	p.uiList = ls
	ls.ItemFgColor = ui.ColorWhite
	ls.ItemBgColor = ui.ColorRed
	ls.Bg = ui.ColorRed
	ls.Border = false
	ls.Height = 1
	ls.Width = ui.TermWidth()
	ls.X = 0
	ls.Y = ui.TermHeight() - 2
	p.Update()
}
示例#14
0
func (p *BaseListPage) Create() {
	ui.Clear()
	ls := ui.NewList()
	p.uiList = ls
	p.cachedResults = make([]string, 0)
	p.displayLines = make([]string, len(p.cachedResults))
	ls.ItemFgColor = ui.ColorYellow
	ls.BorderLabel = "Updating, please wait"
	ls.Height = ui.TermHeight()
	ls.Width = ui.TermWidth()
	ls.Y = 0
	p.Update()
}
示例#15
0
func (p *BaseInputBox) Create() {
	ls := ui.NewList()
	var strs []string
	p.uiList = ls
	ls.Items = strs
	ls.ItemFgColor = ui.ColorGreen
	ls.BorderFg = ui.ColorRed
	ls.Height = 1
	ls.Width = 30
	ls.Overflow = "wrap"
	ls.X = ui.TermWidth()/2 - ls.Width/2
	ls.Y = ui.TermHeight()/2 - ls.Height/2
	p.Update()
}
示例#16
0
func (p *PasswordInputBox) Create() {
	ls := ui.NewList()
	p.uiList = ls
	var strs []string
	ls.Items = strs
	ls.ItemFgColor = ui.ColorGreen
	ls.BorderLabel = "Enter Password:"
	ls.BorderFg = ui.ColorRed
	ls.Height = 3
	ls.Width = 30
	ls.X = ui.TermWidth()/2 - ls.Width/2
	ls.Y = ui.TermHeight()/2 - ls.Height/2
	p.Update()
}
示例#17
0
文件: main.go 项目: bnadland/r
func showSubreddit(subredditName string) error {
	r := geddit.NewSession("r by /u/bnadland")

	submissions, err := r.SubredditSubmissions(subredditName, geddit.HotSubmissions, geddit.ListingOptions{})
	if err != nil {
		return err
	}

	isActive := true

	cursor := 3
	for isActive {

		entries := []string{}
		for i, submission := range submissions {
			entries = append(entries, fmt.Sprintf("%s %s", isActiveCursor(cursor, i), submission.Title))
		}

		ls := termui.NewList()
		ls.Items = entries
		ls.ItemFgColor = termui.ColorDefault
		ls.Border.Label = fmt.Sprintf("Subreddit: %s", subredditName)
		ls.Height = termui.TermHeight()
		ls.Width = termui.TermWidth()
		ls.Y = 0
		termui.Render(ls)
		event := <-termui.EventCh()
		if event.Type == termui.EventKey {
			switch event.Key {
			case termui.KeyArrowLeft:
				isActive = false
			case termui.KeyArrowDown:
				cursor = cursor + 1
				if cursor > len(submissions) {
					cursor = len(submissions)
				}
			case termui.KeyArrowUp:
				cursor = cursor - 1
				if cursor < 0 {
					cursor = 0
				}
			}
		}
	}
	return nil
}
示例#18
0
func main() {
	if len(os.Args) < 2 {
		log.Fatal("Usage: ", os.Args[0], " <sparkyfish server hostname/IP>[:port]")
	}

	dest := os.Args[1]
	i := last(dest, ':')
	if i < 0 {
		dest = fmt.Sprint(dest, ":7121")
	}

	// Initialize our screen
	err := termui.Init()
	if err != nil {
		panic(err)
	}

	if termui.TermWidth() < 60 || termui.TermHeight() < 28 {
		fmt.Println("sparkyfish needs a terminal window at least 60x28 to run.")
		os.Exit(1)
	}

	defer termui.Close()

	// 'q' quits the program
	termui.Handle("/sys/kbd/q", func(termui.Event) {
		termui.StopLoop()
	})
	// 'Q' also works
	termui.Handle("/sys/kbd/Q", func(termui.Event) {
		termui.StopLoop()
	})

	sc := newsparkyClient()
	sc.serverHostname = dest

	sc.prepareChannels()

	sc.wr = newwidgetRenderer()

	// Begin our tests
	go sc.runTestSequence()

	termui.Loop()
}
示例#19
0
func (p *SortOrderPage) Create() {
	ls := ui.NewList()
	p.uiList = ls
	p.selectedLine = 0
	p.firstDisplayLine = 0
	if len(p.cachedResults) == 0 {
		p.cachedResults = getSorts()
		p.displayLines = make([]string, len(p.cachedResults))
	}
	ls.ItemFgColor = ui.ColorGreen
	ls.BorderLabel = "Sort By..."
	ls.BorderFg = ui.ColorRed
	ls.Height = 10
	ls.Width = 50
	ls.X = ui.TermWidth()/2 - ls.Width/2
	ls.Y = ui.TermHeight()/2 - ls.Height/2
	p.Update()
}
示例#20
0
func maintainSparkLines(redraw chan bool, quit chan bool) {
	evt := ui.EventCh()
	for {
		select {
		case e := <-evt:
			if e.Type == ui.EventKey && e.Ch == 'q' {
				quit <- true
				return
			}
			if e.Type == ui.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- true }()
			}
		case <-redraw:
			ui.Render(ui.Body)
		}
	}
}
示例#21
0
文件: gom.go 项目: ZhiqinYang/gom
func loadStats() {
	var max = ui.TermWidth()
	s, err := fetchStats()
	if err != nil {
		displayMsg(fmt.Sprintf("error fetching stats: %v", err))
		return
	}
	displayMsg("")
	var cnts = []struct {
		cnt      int
		titleFmt string
	}{
		{s.Goroutine, "goroutines (%d)"},
		{s.Thread, "threads (%d)"},
	}
	for i, v := range cnts {
		if n := len(sp.Lines[i].Data); n > max {
			sp.Lines[i].Data = sp.Lines[i].Data[n-max : n]
		}
		sp.Lines[i].Title = fmt.Sprintf(v.titleFmt, v.cnt)
		sp.Lines[i].Data = append(sp.Lines[i].Data, v.cnt)
	}
}
示例#22
0
func (p *HelpPage) Create() {
	ui.Clear()
	ls := ui.NewList()
	p.uiList = ls
	if p.statusBar == nil {
		p.statusBar = new(StatusBar)
	}
	if p.commandBar == nil {
		p.commandBar = commandBar
	}
	if len(p.cachedResults) == 0 {
		p.cachedResults = HelpTextAsStrings(nil, "jira_ui_help")
	}
	p.displayLines = make([]string, len(p.cachedResults))
	ls.ItemFgColor = ui.ColorYellow
	ls.BorderLabel = "Help"
	ls.Height = ui.TermHeight() - 2
	ls.Width = ui.TermWidth()
	ls.Y = 0
	p.statusBar.Create()
	p.commandBar.Create()
	p.Update()
}
示例#23
0
func (p *QueryPage) Create() {
	log.Debugf("QueryPage.Create(): self:        %s (%p)", p.Id(), p)
	log.Debugf("QueryPage.Create(): currentPage: %s (%p)", currentPage.Id(), currentPage)
	ui.Clear()
	ls := ui.NewList()
	p.uiList = ls
	if p.statusBar == nil {
		p.statusBar = new(StatusBar)
	}
	if p.commandBar == nil {
		p.commandBar = commandBar
	}
	p.cachedResults = getQueries()
	p.displayLines = make([]string, len(p.cachedResults))
	ls.ItemFgColor = ui.ColorYellow
	ls.BorderLabel = "Queries"
	ls.Height = ui.TermHeight() - 2
	ls.Width = ui.TermWidth()
	ls.Y = 0
	p.statusBar.Create()
	p.commandBar.Create()
	p.Update()
}
示例#24
0
// Relayout recalculates widgets sizes and coords.
func (t *TermUISingle) Relayout() {
	tw, th := termui.TermWidth(), termui.TermHeight()
	h := th

	// First row: Title and Status pars
	firstRowH := 3
	t.Title.Height = firstRowH
	t.Title.Width = tw / 2
	if tw%2 == 1 {
		t.Title.Width++
	}
	t.Status.Height = firstRowH
	t.Status.Width = tw / 2
	t.Status.X = t.Title.X + t.Title.Width
	h -= firstRowH

	// Second row: lists
	secondRowH := 3
	num := len(t.Pars)
	parW := tw / num
	for i, par := range t.Pars {
		par.Y = th - h
		par.Width = parW
		par.Height = secondRowH
		par.X = i * parW
	}
	if num*parW < tw {
		t.Pars[num-1].Width = tw - ((num - 1) * parW)
	}
	h -= secondRowH

	// Third row: Sparklines
	t.Sparkline.Width = tw
	t.Sparkline.Height = h
	t.Sparkline.Y = th - h
}
示例#25
0
func main() {

	//set log file
	logFileName := "btc.log"

	logFile, logErr := os.OpenFile(logFileName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
	if logErr != nil {
		fmt.Println("Fail to find", *logFile, "cServer start Failed")
		return
	}

	log.SetOutput(logFile)
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

	log.Printf("cpu num %d", runtime.NumCPU())
	runtime.GOMAXPROCS(runtime.NumCPU())

	if err := ui.Init(); err != nil {
		log.Printf("ui init err : %s", err)
		return
	}

	defer ui.Close()

	par = ui.NewPar("Last Price")
	par.Height = 3
	par.TextFgColor = ui.ColorWhite
	par.BorderLabel = "Last Price"

	infoPar = ui.NewPar("Price Info")
	infoPar.Height = 3
	infoPar.TextFgColor = ui.ColorWhite
	infoPar.BorderLabel = "Price Info"

	currentTime := time.Now().Format("2006-01-02 15:04:05")

	timePar := ui.NewPar(currentTime)
	timePar.Height = 3
	timePar.TextFgColor = ui.ColorYellow
	timePar.BorderLabel = "Current Time"

	strItems := []string{}
	delegateList = ui.NewList()
	delegateList.Items = strItems
	delegateList.ItemFgColor = ui.ColorYellow
	delegateList.BorderLabel = "Delegate List"
	delegateList.Height = 23

	dealList = ui.NewList()
	dealList.Items = strItems
	dealList.ItemFgColor = ui.ColorYellow
	dealList.Height = 23
	dealList.BorderLabel = "Deal List"

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(6, 0, par),
			ui.NewCol(6, 0, timePar)))

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(12, 0, infoPar)))

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(6, 0, delegateList),
			ui.NewCol(6, 0, dealList)))

	ui.Body.Align()
	ui.Render(ui.Body)

	// websocket connect
	log.Printf("connecting to %s", url)
	c, _, err := websocket.DefaultDialer.Dial(url, nil)
	if err != nil {
		log.Fatal("dial:", err)
	}

	defer c.Close()

	// message done chan
	done := make(chan struct{})

	exit := func() {
		err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
		if err != nil {
			log.Printf("write close: %s", err)
		} else {
			select {
			case <-done:
			case <-time.After(time.Second):
			}

			c.Close()
		}
		ui.StopLoop()
	}

	ui.Handle("/sys/kbd/q", func(ui.Event) {
		exit()
	})

	ui.Handle("/sys/kbd/p", func(ui.Event) {
		if !uiPaused {
			uiPaused = true
		} else {
			uiPaused = false
		}
	})

	ui.Handle("/sys/wnd/resize", func(e ui.Event) {
		ui.Body.Width = ui.TermWidth()
		ui.Body.Align()
		ui.Render(ui.Body)
	})

	ui.Handle("/timer/1s", func(e ui.Event) {
		currentTime := time.Now().Format("2006-01-02 15:04:05")
		timePar.Text = currentTime
	})

	go func() {
		for {
			//or use message
			if !uiPaused {
				time.Sleep(time.Millisecond * 50)
				ui.Render(ui.Body)
			} else {
				time.Sleep(time.Millisecond * 200)
			}
		}
	}()

	//----------------------- stocket message --------------

	msgChan := make(chan []byte)

	//获取消息
	go func() {
		defer c.Close()
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Printf("read err: %s", err)
				return
			}

			msgChan <- message
		}
	}()

	//订阅消息
	sendSubChannel(c)

	//heart check via pingChan
	go func() {
		defer close(pingChan)

		for {
			if c.WriteMessage(websocket.TextMessage, []byte("{\"event\": \"ping\"}")); err != nil {
				log.Printf("send ping message err: %s", err)
				break
			}

			log.Println("send ping message")
			select {
			case <-pingChan:
				log.Println("server is alive")
				//收到数据 1s 后继续发送心跳
				time.Sleep(time.Second)
			case <-time.After(time.Second * 1):
				//超时 重新连接 socket
				reConnectTimes := 0

				for {
					if reConnectTimes > 5 {
						log.Fatal("websocket connect failed")
						break
					}

					_c, _, err := websocket.DefaultDialer.Dial(url, nil)
					if err != nil {
						log.Println("re-connect websocket faild dial:", err)
						log.Println("after 3s retry connect websocket")
						reConnectTimes++
						time.Sleep(time.Second * 3)
					} else {
						log.Println("re-connect websocket success")
						c = _c

						sendSubChannel(c)
						break
					}
				}
			}
		}
	}()

	//开启10个worker 处理消息
	for i := 0; i < 10; i++ {
		go processMessage(msgChan)
	}

	//开始阻塞 循环terminal ui
	ui.Loop()
}
示例#26
0
// monitor starts a terminal UI based monitoring tool for the requested metrics.
func monitor(ctx *cli.Context) {
	var (
		client comms.EthereumClient
		err    error
	)
	// Attach to an Ethereum node over IPC or RPC
	endpoint := ctx.String(monitorCommandAttachFlag.Name)
	if client, err = comms.ClientFromEndpoint(endpoint, codec.JSON); err != nil {
		utils.Fatalf("Unable to attach to geth node: %v", err)
	}
	defer client.Close()

	xeth := rpc.NewXeth(client)

	// Retrieve all the available metrics and resolve the user pattens
	metrics, err := retrieveMetrics(xeth)
	if err != nil {
		utils.Fatalf("Failed to retrieve system metrics: %v", err)
	}
	monitored := resolveMetrics(metrics, ctx.Args())
	if len(monitored) == 0 {
		list := expandMetrics(metrics, "")
		sort.Strings(list)

		if len(list) > 0 {
			utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - "))
		} else {
			utils.Fatalf("No metrics collected by geth (--%s).\n", utils.MetricsEnabledFlag.Name)
		}
	}
	sort.Strings(monitored)
	if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 {
		utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - "))
	}
	// Create and configure the chart UI defaults
	if err := termui.Init(); err != nil {
		utils.Fatalf("Unable to initialize terminal UI: %v", err)
	}
	defer termui.Close()

	termui.UseTheme("helloworld")

	rows := len(monitored)
	if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
		rows = max
	}
	cols := (len(monitored) + rows - 1) / rows
	for i := 0; i < rows; i++ {
		termui.Body.AddRows(termui.NewRow())
	}
	// Create each individual data chart
	footer := termui.NewPar("")
	footer.HasBorder = true
	footer.Height = 3

	charts := make([]*termui.LineChart, len(monitored))
	units := make([]int, len(monitored))
	data := make([][]float64, len(monitored))
	for i := 0; i < len(monitored); i++ {
		charts[i] = createChart((termui.TermHeight() - footer.Height) / rows)
		row := termui.Body.Rows[i%rows]
		row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i]))
	}
	termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer)))

	refreshCharts(xeth, monitored, data, units, charts, ctx, footer)
	termui.Body.Align()
	termui.Render(termui.Body)

	// Watch for various system events, and periodically refresh the charts
	refresh := time.Tick(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second)
	for {
		select {
		case event := <-termui.EventCh():
			if event.Type == termui.EventKey && event.Key == termui.KeyCtrlC {
				return
			}
			if event.Type == termui.EventResize {
				termui.Body.Width = termui.TermWidth()
				for _, chart := range charts {
					chart.Height = (termui.TermHeight() - footer.Height) / rows
				}
				termui.Body.Align()
				termui.Render(termui.Body)
			}
		case <-refresh:
			if refreshCharts(xeth, monitored, data, units, charts, ctx, footer) {
				termui.Body.Align()
			}
			termui.Render(termui.Body)
		}
	}
}
示例#27
0
文件: main.go 项目: arscan/gosf
func main() {
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()

	sinps := (func() []float64 {
		n := 400
		ps := make([]float64, n)
		for i := range ps {
			ps[i] = 1 + math.Sin(float64(i)/5)
		}
		return ps
	})()
	sinpsint := (func() []int {
		ps := make([]int, len(sinps))
		for i, v := range sinps {
			ps[i] = int(100*v + 10)
		}
		return ps
	})()

	// ui.UseTheme("helloworld")

	spark := ui.Sparkline{}
	spark.Height = 8
	spdata := sinpsint
	spark.Data = spdata[:100]
	spark.LineColor = ui.ColorCyan
	spark.TitleColor = ui.ColorWhite

	sp := ui.NewSparklines(spark)
	sp.Height = 11
	sp.Border.Label = "Sparkline"

	lc := ui.NewLineChart()
	lc.Border.Label = "braille-mode Line Chart"
	lc.Data = sinps
	lc.Height = 11
	lc.AxesColor = ui.ColorWhite
	lc.LineColor = ui.ColorYellow | ui.AttrBold

	gs := make([]*ui.Gauge, 3)
	for i := range gs {
		gs[i] = ui.NewGauge()
		gs[i].Height = 2
		gs[i].HasBorder = false
		gs[i].Percent = i * 10
		gs[i].PaddingBottom = 1
		gs[i].BarColor = ui.ColorRed
	}

	ls := ui.NewList()
	ls.HasBorder = false
	ls.Items = []string{
		"[1] Downloading File 1",
		"", // == \newline
		"[2] Downloading File 2",
		"",
		"[3] Uploading File 3",
	}
	ls.Height = 5

	par := ui.NewPar("<> This row has 3 columns\n<- Widgets can be stacked up like left side\n<- Stacked widgets are treated as a single widget")
	par.Height = 5
	par.Border.Label = "Demonstration"

	// build layout
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(6, 0, sp),
			ui.NewCol(6, 0, lc)),
		ui.NewRow(
			ui.NewCol(3, 0, ls),
			ui.NewCol(3, 0, gs[0], gs[1], gs[2]),
			ui.NewCol(6, 0, par)))

	// calculate layout
	ui.Body.Align()

	done := make(chan bool)
	redraw := make(chan bool)

	/*
		update := func() {
			for i := 0; i < 103; i++ {
				for _, g := range gs {
					g.Percent = (g.Percent + 3) % 100
				}

				sp.Lines[0].Data = spdata[:100+i]
				lc.Data = sinps[2*i:]

				time.Sleep(time.Second / 2)
				redraw <- true
			}
			done <- true
		}
	*/

	evt := ui.EventCh()

	ui.Render(ui.Body)
	// go update()

	for {
		select {
		case e := <-evt:
			if e.Type == ui.EventKey && e.Ch == 'q' {
				return
			}
			if e.Type == ui.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
				go func() { redraw <- true }()
			}
		case <-done:
			return
		case <-redraw:
			ui.Render(ui.Body)
		}
	}
}
示例#28
0
文件: main.go 项目: heatxsink/pwsafe
func main() {
	pfile := flag.String("f", "", "psafe3 file")
	flag.Parse()

	fmt.Printf("Password: "******"Last Saved: %s\nLast Saved By %s @ %s",
		safe.Headers.LastSave.Format("2006-01-02 15:04:05"),
		safe.Headers.User, safe.Headers.Host))
	rightpar.Height = 2
	rightpar.HasBorder = false

	leftpar := termui.NewPar(fmt.Sprintf("File Name: %s\nLast Program: %s",
		filepath.Base(*pfile),
		safe.Headers.ProgramSave))
	leftpar.Height = 2
	leftpar.HasBorder = false

	recordlist := termui.NewList()
	recordlist.Height = termui.TermHeight() - 5
	recordlist.Items = getRecordList(safe)
	recordlist.Border.Label = fmt.Sprintf("Records (%d)", len(safe.Records))

	recorddetail := termui.NewPar("")
	recorddetail.Height = recordlist.Height
	recorddetail.Border.Label = "Record Information"

	inputbox := termui.NewPar("")
	inputbox.Height = 3
	inputbox.Border.Label = "Input Box ([Enter] to save, [Esc] to cancel)"
	inputrow := termui.NewRow(termui.NewCol(12, 0, inputbox))

	commandinfo := termui.NewPar(strings.Join([]string{
		"Select record by typing the index number. Edit field by typing field marker.",
	}, "\n"))
	commandinfo.Height = 3
	commandinfo.Border.Label = "Help"
	commandrow := termui.NewRow(termui.NewCol(12, 0, commandinfo))

	termui.Body.AddRows(
		termui.NewRow(
			termui.NewCol(6, 0, leftpar),
			termui.NewCol(6, 0, rightpar),
		),
		termui.NewRow(
			termui.NewCol(6, 0, recordlist),
			termui.NewCol(6, 0, recorddetail),
		),
		commandrow,
	)

	termui.Body.Align()
	termui.Render(termui.Body)

	evt := termui.EventCh()

	inputMode := false
	valBuffer := bytes.Buffer{}
	numBuffer := bytes.Buffer{}
	var selRecord *pwsafe.Record
	var selField *string
	var inputPrompt string
	var startIndex int
Main:
	for {
		select {
		case e := <-evt:
			if !inputMode && e.Type == termui.EventKey {
				switch e.Ch {
				case 'q':
					break Main
				case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
					numBuffer.WriteRune(e.Ch)
				case '#':
					selIndex, _ := strconv.ParseInt(numBuffer.String(), 10, 64)
					selRecord = &safe.Records[selIndex]
					selField = nil
					numBuffer.Reset()
				case 'j':
					startIndex++
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
				case 'k':
					if startIndex > 1 {
						startIndex--
						rlist := getRecordList(safe)
						recordlist.Items = rlist[startIndex:]
					}
				case 'a':
					selIndex := len(safe.Records)
					safe.Records = append(safe.Records, pwsafe.Record{})
					selRecord = &safe.Records[selIndex]
					selRecord.UUID = uuid.NewV1()
					selRecord.CreationTime = time.Now()
					selField = nil
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
					recordlist.Border.Label = fmt.Sprintf("Records (%d)", len(safe.Records))
				case 'g':
					selField = &selRecord.Group
					inputPrompt = "Group: "
					inputMode = true
					valBuffer.WriteString(selRecord.Group)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 't':
					selField = &selRecord.Title
					inputPrompt = "Title: "
					inputMode = true
					valBuffer.WriteString(selRecord.Title)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'u':
					selField = &selRecord.Username
					inputPrompt = "Username: "******"Password: "******"Url: "
					inputMode = true
					valBuffer.WriteString(selRecord.Url)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'n':
					selField = &selRecord.Notes
					inputPrompt = "Notes: "
					inputMode = true
					valBuffer.WriteString(selRecord.Notes)
					inputbox.Text = inputPrompt + valBuffer.String()
				case 'e':
					selField = &selRecord.Email
					inputPrompt = "Email: "
					inputMode = true
					valBuffer.WriteString(selRecord.Email)
					inputbox.Text = inputPrompt + valBuffer.String()
				}
			} else if inputMode && e.Type == termui.EventKey {
				if e.Key == termui.KeyEnter {
					if selField != nil {
						*selField = valBuffer.String()
					}
					valBuffer.Reset()
					inputMode = false
					inputbox.Text = ""
					rlist := getRecordList(safe)
					recordlist.Items = rlist[startIndex:]
				} else if e.Key == termui.KeyEsc {
					valBuffer.Reset()
					inputMode = false
					inputbox.Text = ""
				} else if e.Key == termui.KeySpace {
					valBuffer.WriteRune(' ')
				} else if e.Key == termui.KeyBackspace || e.Ch == '' {
					s := valBuffer.String()
					valBuffer = bytes.Buffer{}
					if len(s) > 0 {
						s = s[0 : len(s)-1]
					}
					valBuffer.WriteString(s)
					inputbox.Text = inputPrompt + valBuffer.String()
				} else {
					valBuffer.WriteRune(e.Ch)
					inputbox.Text = inputPrompt + valBuffer.String()
				}
			}
			if e.Type == termui.EventResize {
				termui.Body.Width = termui.TermWidth()
				termui.Body.Align()
			}

			if selRecord != nil {
				recorddetail.Text = getRecordDetail(*selRecord)
			}

			if inputMode {
				termui.Body.Rows[2] = inputrow
			} else {
				termui.Body.Rows[2] = commandrow
			}
			termui.Body.Align()
			termui.Render(termui.Body)
		}
	}

	oerr := pwsafe.OutputFile(*pfile, string(pw), *safe)
	if oerr != nil {
		log.Fatalln(oerr)
	}

}
示例#29
0
// monitor starts a terminal UI based monitoring tool for the requested metrics.
func monitor(ctx *cli.Context) error {
	var (
		client rpc.Client
		err    error
	)
	// Attach to an Expanse node over IPC or RPC
	endpoint := ctx.String(monitorCommandAttachFlag.Name)
	if client, err = utils.NewRemoteRPCClientFromString(endpoint); err != nil {
		utils.Fatalf("Unable to attach to gexp node: %v", err)
	}
	defer client.Close()

	// Retrieve all the available metrics and resolve the user pattens
	metrics, err := retrieveMetrics(client)
	if err != nil {
		utils.Fatalf("Failed to retrieve system metrics: %v", err)
	}
	monitored := resolveMetrics(metrics, ctx.Args())
	if len(monitored) == 0 {
		list := expandMetrics(metrics, "")
		sort.Strings(list)

		if len(list) > 0 {
			utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - "))
		} else {
			utils.Fatalf("No metrics collected by gexp (--%s).\n", utils.MetricsEnabledFlag.Name)
		}
	}
	sort.Strings(monitored)
	if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 {
		utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - "))
	}
	// Create and configure the chart UI defaults
	if err := termui.Init(); err != nil {
		utils.Fatalf("Unable to initialize terminal UI: %v", err)
	}
	defer termui.Close()

	rows := len(monitored)
	if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
		rows = max
	}
	cols := (len(monitored) + rows - 1) / rows
	for i := 0; i < rows; i++ {
		termui.Body.AddRows(termui.NewRow())
	}
	// Create each individual data chart
	footer := termui.NewPar("")
	footer.Block.Border = true
	footer.Height = 3

	charts := make([]*termui.LineChart, len(monitored))
	units := make([]int, len(monitored))
	data := make([][]float64, len(monitored))
	for i := 0; i < len(monitored); i++ {
		charts[i] = createChart((termui.TermHeight() - footer.Height) / rows)
		row := termui.Body.Rows[i%rows]
		row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i]))
	}
	termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer)))

	refreshCharts(client, monitored, data, units, charts, ctx, footer)
	termui.Body.Align()
	termui.Render(termui.Body)

	// Watch for various system events, and periodically refresh the charts
	termui.Handle("/sys/kbd/C-c", func(termui.Event) {
		termui.StopLoop()
	})
	termui.Handle("/sys/wnd/resize", func(termui.Event) {
		termui.Body.Width = termui.TermWidth()
		for _, chart := range charts {
			chart.Height = (termui.TermHeight() - footer.Height) / rows
		}
		termui.Body.Align()
		termui.Render(termui.Body)
	})
	go func() {
		tick := time.NewTicker(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second)
		for range tick.C {
			if refreshCharts(client, monitored, data, units, charts, ctx, footer) {
				termui.Body.Align()
			}
			termui.Render(termui.Body)
		}
	}()
	termui.Loop()
	return nil
}
示例#30
0
func main() {
	// Init
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()

	// Theme Setting
	ui.UseTheme("helloworld")

	// Setup the CPU Gauge
	cpuGauge := ui.NewGauge()
	cpuGauge.Height = 2
	cpuGauge.BarColor = ui.ColorRed
	cpuGauge.HasBorder = false
	cpuGauge.PaddingBottom = 1
	go UpdateGenericGauge(cpuGauge, GetCPUPercentage)

	// Setup the RAM Gauge
	ramGauge := ui.NewGauge()
	ramGauge.Height = 2
	ramGauge.BarColor = ui.ColorGreen
	ramGauge.HasBorder = false
	ramGauge.PaddingBottom = 1
	go UpdateGenericGauge(ramGauge, GetRAMPercentage)

	// Setup the Label list
	ls := ui.NewList()
	ls.HasBorder = false
	ls.Items = []string{
		"CPU",
		"",
		"RAM",
	}
	ls.Height = 5

	// Setup the CPU Line Chart
	cpuLineChart := ui.NewLineChart()
	cpuLineChart.Width = 50
	cpuLineChart.Height = 11
	cpuLineChart.Border.Label = "CPU Usage"
	cpuLineChart.AxesColor = ui.ColorWhite
	cpuLineChart.LineColor = ui.ColorGreen | ui.AttrBold
	go UpdateGenericChart(cpuLineChart, GetCPUPercentage)

	// Setup the RAM Line Chart
	ramLineChart := ui.NewLineChart()
	ramLineChart.Width = 50
	ramLineChart.Height = 11
	ramLineChart.Border.Label = "RAM Usage"
	ramLineChart.AxesColor = ui.ColorWhite
	ramLineChart.LineColor = ui.ColorGreen | ui.AttrBold
	go UpdateGenericChart(ramLineChart, GetRAMPercentage)

	// Setup the layout
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(3, 0, cpuGauge, ramGauge),
			ui.NewCol(3, 0, ls),
		),
		ui.NewRow(
			ui.NewCol(6, 0, cpuLineChart),
			ui.NewCol(6, 0, ramLineChart),
		),
	)

	// Align
	ui.Body.Align()

	// Create the event polling system
	evt := make(chan tm.Event)
	go func() {
		for {
			evt <- tm.PollEvent()
		}
	}()

	for {
		select {
		case e := <-evt:
			if e.Type == tm.EventKey && e.Ch == 'q' {
				return
			}
			if e.Type == tm.EventResize {
				ui.Body.Width = ui.TermWidth()
				ui.Body.Align()
			}
		default:
			ui.Render(ui.Body)
			time.Sleep(time.Second / 2)
		}
	}
}