Skip to content
Permalink
Browse files

cleaned up progress

  • Loading branch information...
evmar committed Oct 28, 2011
1 parent e68e229 commit b138210b1ebae217c20d5ae7bbb8e6f569bca188
Showing with 55 additions and 31 deletions.
  1. +55 −31 imapsync/main.go
@@ -20,18 +20,23 @@ func check(err os.Error) {
}
}

type progressMessage struct {
cur, total int
text string
}

type UI struct {
statusChan chan string
statusChan chan interface{}
netmon *netmonReader
}

func (ui *UI) status(format string, args ...interface{}) {
if ui.statusChan != nil {
ui.statusChan <- fmt.Sprintf(format, args...)
} else {
fmt.Printf(format, args...)
fmt.Printf("\n")
}
func (ui *UI) log(format string, args ...interface{}) {
ui.statusChan <- fmt.Sprintf(format, args...)
}

func (ui *UI) progress(cur, total int, format string, args ...interface{}) {
message := &progressMessage{cur, total, fmt.Sprintf(format, args...)}
ui.statusChan <- message
}

func loadAuth(path string) (string, string) {
@@ -68,7 +73,7 @@ func readExtra(im *imap.IMAP) {
func (ui *UI) connect(useNetmon bool) *imap.IMAP {
user, pass := loadAuth("auth")

ui.status("connecting...")
ui.log("connecting...")
conn, err := tls.Dial("tcp", "imap.gmail.com:993", nil)
check(err)

@@ -85,91 +90,111 @@ func (ui *UI) connect(useNetmon bool) *imap.IMAP {

hello, err := im.Start()
check(err)
ui.status("server hello: %s", hello)
ui.log("server hello: %s", hello)

ui.status("logging in...")
ui.log("logging in...")
resp, caps, err := im.Auth(user, pass)
check(err)
ui.status("%s", resp)
ui.status("server capabilities: %s", caps)
ui.log("%s", resp)
ui.log("server capabilities: %s", caps)

return im
}

func (ui *UI) fetch(im *imap.IMAP, mailbox string) {
ui.status("opening %s...", mailbox)
ui.log("opening %s...", mailbox)
examine, err := im.Examine(mailbox)
check(err)
ui.status("mailbox status: %+v", examine)
ui.log("mailbox status: %+v", examine)
readExtra(im)

f, err := os.Create(mailbox + ".mbox")
check(err)
mbox := newMbox(f)

query := fmt.Sprintf("1:%d", examine.Exists)
ui.status("fetching messages %s", query)
ui.log("requesting messages %s", query)

ch, err := im.FetchAsync(query, []string{"RFC822"})
check(err)

envelopeDate := time.LocalTime().Format(time.ANSIC)

i := 1
i := 0
total := examine.Exists
ui.progress(i, total, "fetching messages", i, total)
L:
for {
r := <-ch
switch r := r.(type) {
case *imap.ResponseFetch:
mbox.writeMessage("imapsync@none", envelopeDate, r.Rfc822)
ui.status("got message %d/%d", i, examine.Exists)
i++
ui.progress(i, total, "fetching messages")
case *imap.ResponseStatus:
ui.status("complete %v\n", r)
ui.log("complete %v\n", r)
break L
}
}
readExtra(im)
}

func (ui *UI) runFetch(im *imap.IMAP, mailbox string) {
ui.statusChan = make(chan string)
func (ui *UI) runFetch(mailbox string) {
ui.statusChan = make(chan interface{})
go func() {
defer func() {
if e := recover(); e != nil {
log.Printf("paniced %s", e)
ui.statusChan <- e
}
}()
im := ui.connect(true)
ui.fetch(im, mailbox)
close(ui.statusChan)
}()

ticker := time.NewTicker(1000 * 1000 * 1000)
overprint := false
status := ""
overprintLast := false
for ui.statusChan != nil {
overprint := true
select {
case s, stillOpen := <-ui.statusChan:
if s != status {
overprint = false
switch s := s.(type) {
case string:
status = s
overprint = false
case *progressMessage:
status = fmt.Sprintf("%s [%d/%d]", s.text, s.cur, s.total)
overprint = true
default:
if s != nil {
status = s.(os.Error).String()
ui.statusChan = nil
ticker.Stop()
}
}
if !stillOpen {
ui.statusChan = nil
ticker.Stop()
}
case <-ticker.C:
ui.netmon.Tick()
if ui.netmon != nil {
ui.netmon.Tick()
}
}
if overprint {

if overprintLast {
fmt.Printf("\r\x1B[K")
} else {
fmt.Printf("\n")
}
if status != "" {
fmt.Printf("[%.1fk/s] %s", ui.netmon.Bandwidth() / 1000.0, status)
overprintLast = overprint
fmt.Printf("%s", status)
if overprint && ui.netmon != nil {
fmt.Printf(" [%.1fk/s]", ui.netmon.Bandwidth() / 1000.0)
}
}
fmt.Printf("\n")
}

func usage() {
@@ -208,8 +233,7 @@ func main() {
fmt.Printf("must specify mailbox to fetch\n")
os.Exit(1)
}
im := ui.connect(true)
ui.runFetch(im, args[0])
ui.runFetch(args[0])
default:
usage()
}

0 comments on commit b138210

Please sign in to comment.
You can’t perform that action at this time.