status-curses.rb
Path: srv/status-curses.rb
Modified: Sun Apr 06 11:50:25 MDT 2003
Required files
ncurses    optparse    shellwords    util/config    util/logging    util/tmdisplay    util/try    util/statusbar    util/clientutils    xmlrpc/client   
Methods
centeroffs    getmaxx    main    sbarupdate    start    wrap   
Classes and Modules
Class StatCursesOpts
Included modules
Try Clientutils
Public Instance methods
centeroffs(width, str)

Offset by which to indent text to center it.

width
width of field in which to center text
str
text to center
# File srv/status-curses.rb, line 69
def centeroffs(width, str)
  (width - str.length) / 2
end
wrap(s, max)

Wrap text into lines at most max chars long.

# File srv/status-curses.rb, line 74
def wrap(s, max)
  words = s.split(>\s+>)
  s = ""
  sarr = []
  while words.length > 0
    if (s.length + words.first.length + 1 <= max)
      s += (" " + words.shift)
    else
      sarr.push(s)
      s = words.shift
    end
  end
  sarr.push(s) if s.length > 0
  return sarr
end
sbarupdate(win, bar, val)

Update status bar.

# File srv/status-curses.rb, line 91
def sbarupdate(win, bar, val)
  Ncurses.werase(win)
  bar.update(val)
  Ncurses.mvwaddstr(win, 0, 0, bar.to_s)
  Ncurses.wrefresh(win)
end
getmaxx(win)
# File srv/status-curses.rb, line 98
def getmaxx(win)
  y = []
  x = []
  Ncurses::getmaxyx(win, y, x)
  return x.first
end
main(opts, args)

Application starts here.

# File srv/status-curses.rb, line 106
def main(opts, args)
  servname = opts["servname"]
  if servname.nil?
    $stderr.puts("usage: #{APPNAME} -a name [updatesecs]")
    return 1
  end

  proxy = get_client_for("player", servname)
  raise StandardError if proxy.nil?

  sleeptime = args.size > 0 ? args.shift.to_i : 2

  stIdle = "IDLE"
  stPlaying = "PLAYING"

  sbar = StatusBar.new(50,"##.",100)
  Ncurses::initscr
  Ncurses::raw
  Ncurses::nonl
  Ncurses::cbreak
  Ncurses::noecho

  topy = 0
  topwin = Ncurses.newwin(1, getmaxx(Ncurses::stdscr), topy, 0)

  topsepy = topy + 2
  topsep = Ncurses.newwin(1, getmaxx(Ncurses::stdscr), 
			       topsepy, 0)
  staty = topsepy + 3
  statwin = Ncurses.newwin(1, getmaxx(Ncurses::stdscr) - 10,
				staty, 5)

  songy = staty + 3
  songwin = Ncurses.newwin(4, getmaxx(Ncurses::stdscr) - 10,
				songy, 5)

  sboxy = songy + 6
  sboxwin = Ncurses.newwin(4, getmaxx(Ncurses::stdscr) - 8, 
				 sboxy, 4)
  sbarwin = Ncurses::derwin(sboxwin, 1, sbar.to_s.length + 2, 1, 1)
  sbartxt = Ncurses::derwin(sboxwin, 1, sbar.to_s.length + 2, 2, 1)
  timewin = Ncurses::derwin(sboxwin, 2, 6, 1, sbar.to_s.length + 8) 

  [topwin, topsep, statwin, songwin, timewin, sbarwin, sbartxt].each {
    |win|
    Ncurses.werase(win)
  }

  # static text
  Ncurses.wmove(topwin, 0, centeroffs(getmaxx(Ncurses::stdscr), 
				      "Current Status"))
  Ncurses.waddstr(topwin, "Current Status")
  Ncurses.wrefresh(topwin)

  Ncurses.wmove(topsep, 0, 1)
  Ncurses.wstandout(topsep)
  Ncurses.waddstr(topsep, "=" * (getmaxx(Ncurses::stdscr) - 2))
  Ncurses.wstandend(topsep)
  Ncurses.wrefresh(topsep)

  Ncurses.box(sboxwin, Ncurses::ACS_VLINE, Ncurses::ACS_HLINE)
  Ncurses.wrefresh(sboxwin)
  Ncurses.werase(sbartxt)
  Ncurses.mvwaddstr(sbartxt, 0, 0, "0%")
  Ncurses.mvwaddstr(sbartxt, 0, sbar.to_s.length - 4, "100%")
  Ncurses.wrefresh(sbartxt)

  exhandler = proc {
    |s|
    Ncurses.werase(songwin)
    arr = wrap(s, getmaxx(Ncurses::songwin))
    arr.each_with_index {
      |line, i|
      Ncurses.mvwaddstr(songwin, i, 0, line)
    }
  }

  $tryHandler.push_handler(exhandler)

  wantexit = false
  trap("HUP") { wantexit = true }
  trap("INT") { wantexit = true }
  trap("TERM"){ wantexit = true }
  state = stIdle
  sbarupdate(sbarwin, sbar, 0)

  while sleep(sleeptime)
    begin
      break if wantexit
      pcdone = 0
      status = proxy.nil? ? nil : trycall { proxy.status? }
      if status.nil?
	proxy = get_client_for("player", servname)
	if proxy.nil?
	  Ncurses.werase(songwin)
	  Ncurses.waddstr(songwin, "Server unavailable ...")
	end
	sbarupdate(sbarwin, sbar, 0)
	next
      end
      myname = status.shift
      playing = status.shift
      state = playing ? stPlaying : stIdle
      if playing
	file = status.shift
	pcdone = status.shift
	secsdone = status.shift
	msdone = TmDisplay.new(secsdone).ms
	secstotal = status.shift
	mstotal = secstotal > 0 ? TmDisplay.new(secstotal).ms : "??:??"
	tmp = file.split(File::Separator)
	file = tmp[-3, 3] if tmp.length > 3
      else
	pcdone = 0
      end

      statstr = myname + ": " + state
      Ncurses.werase(statwin)
      Ncurses.mvwaddstr(statwin, 0, 
			centeroffs(getmaxx(statwin), statstr),
			statstr)
      Ncurses::wrefresh(statwin)

      pcdonestr = sprintf("=%3d%%=", pcdone)
      Ncurses.mvwaddstr(sbartxt, 0, (sbar.to_s.size / 2) - 3, "#{pcdonestr}")
      Ncurses.wrefresh(sbartxt)
      sbarupdate(sbarwin, sbar, pcdone)
      if !playing
	Ncurses.werase(songwin)
	Ncurses.wrefresh(songwin)
	Ncurses.werase(timewin)
	Ncurses.wrefresh(timewin)
      else
	Ncurses.werase(songwin)
	file.each_with_index {
	  |line, i|
	  Ncurses.mvwaddstr(songwin, i, 0, "| " + line)
	}	  
	Ncurses.wrefresh(songwin)

	Ncurses.werase(timewin)
	Ncurses.mvwaddstr(timewin, 0, 0, msdone)
	Ncurses.mvwaddstr(timewin, 1, 0, mstotal)
	Ncurses.wrefresh(timewin)
      end
    rescue Exception => e
      Ncurses::wclear(songwin)
      Ncurses::mvwaddstr(songwin, 0, 0, "Exception #{e.message}")
      Ncurses::wrefresh(songwin)
    end
  end

  Ncurses::endwin()

  return 0
end
start(av)

Parse command line and call main.

# File srv/status-curses.rb, line 349
def start(av)
  opts = StatCursesOpts.new(USAGE, BANNER)
  main(opts.vals, opts.parse(av))
end