Example #1
0
func TestImap(t *testing.T) {
	var user, pw string
	if mock {
		testDial = fakeDial
		user = "******"
		pw = "password"
	} else {
		acct := google.Acct("*****@*****.**")
		user = acct.Email
		pw = acct.Password
	}
	c, err := NewClient(TLS, "imap.gmail.com", user, pw, "")
	if err != nil {
		t.Fatal(err)
	}

	inbox := c.Inbox()
	msgs := inbox.Msgs()

	for _, m := range msgs {
		if m.UID == 611764547<<32|57046 {
			//			c.io.lock()
			//			c.cmd(c.boxByName[`[Gmail]/All Mail`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.inbox, `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.boxByName[`To Read`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.cmd(c.boxByName[`[Gmail]/All Mail`], `UID SEARCH X-GM-RAW "label:[email protected] in:inbox in:unread -in:muted"`)
			//			c.fetch(m.Root.Child[0], "")
			//			c.io.unlock()
			fmt.Println("--")
			fmt.Println("From:", m.Hdr.From)
			fmt.Println("To:", m.Hdr.To)
			fmt.Println("Subject:", m.Hdr.Subject)
			fmt.Println("M-Date:", m.Date)
			fmt.Println("Date:", m.Hdr.Date)
			fmt.Println()
			fmt.Println(string(m.Root.Child[0].Text()))
			fmt.Println("--")
		}
	}
	c.Close()
}
Example #2
0
func main() {
	flag.BoolVar(&imap.Debug, "imapdebug", false, "imap debugging trace")
	flag.Parse()

	acct = google.Acct(*acctName)

	if args := flag.Args(); len(args) > 0 {
		for i := range args {
			args[i] = "-to=" + args[i]
		}
		cmd := exec.Command("gmailsend", append([]string{"-a", acct.Email, "-i"}, args...)...)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			fmt.Fprintf(os.Stderr, "!%s\n", err)
			os.Exit(1)
		}
		return
	}

	c, err := imap.NewClient(imap.TLS, "imap.gmail.com", acct.Email, acct.Password, "")
	if err != nil {
		log.Fatal(err)
	}
	isGmail = c.IsGmail()
	threaded = isGmail

	if *search != "" {
		b, err := c.GmailSearch(*search)
		if err != nil {
			log.Fatal(err)
		}
		inbox = b
	} else {
		inbox = c.Inbox()
		if err := inbox.Check(); err != nil {
			log.Fatal(err)
		}
	}

	msgs = inbox.Msgs()
	maxfrom = 12
	for i, m := range msgs {
		msgNum[m] = i
		if n := len(from(m.Hdr)); n > maxfrom {
			maxfrom = n
		}
	}
	if maxfrom > 20 {
		maxfrom = 20
	}
	subjlen = 80 - maxfrom

	rethread()

	interrupts := make(chan os.Signal, 1)
	signal.Notify(interrupts, syscall.SIGINT)

	go func() {
		for _ = range interrupts {
			fmt.Fprintf(os.Stderr, "!interrupt\n")
			interrupted = true
		}
	}()

	for {
		if dot != nil {
			fmt.Fprintf(bout, "%d", msgNum[dot.Msg]+1)
			if dot != &dot.Msg.Root {
				fmt.Fprintf(bout, ".%s", dot.ID)
			}
		}
		fmt.Fprintf(bout, ": ")
		bout.Flush()

		line, err := bin.ReadString('\n')
		if err != nil {
			break
		}

		cmd, err := parsecmd(line)
		if err != nil {
			fmt.Fprintf(bout, "!%s\n", err)
			continue
		}

		if cmd.Targ != nil || cmd.Targs == nil && cmd.A2 == 0 {
			x := cmd.F(cmd, cmd.Targ)
			if x != nil {
				dot = x
			}
		} else {
			targs := cmd.Targs
			if targs == nil {
				delta := +1
				if cmd.A1 > cmd.A2 {
					delta = -1
				}
				for i := cmd.A1; i <= cmd.A2; i += delta {
					if i < 1 || i > len(msgs) {
						continue
					}
					targs = append(targs, msgs[i-1])
				}
			}
			if cmd.Thread {
				if !isGmail {
					fmt.Fprintf(bout, "!need gmail for threaded command\n")
					continue
				}
				byThread := make(map[uint64][]*imap.Msg)
				for _, m := range msgs {
					t := m.GmailThread
					byThread[t] = append(byThread[t], m)
				}
				for _, m := range targs {
					t := m.GmailThread
					if byThread[t] != nil {
						if cmd.TF != nil {
							if x := cmd.TF(cmd, byThread[t]); x != nil {
								dot = x
							}
						} else {
							for _, mm := range byThread[t] {
								x := cmd.F(cmd, &mm.Root)
								if x != nil {
									dot = x
								}
							}
						}
					}
					delete(byThread, t)
				}
				continue
			}
			for _, m := range targs {
				if cmd.Delete {
					dcmd(cmd, &m.Root)
					if cmd.Name == "p" {
						// dp is a special case: it advances to the next message before the p.
						next := nextMsg(m)
						if next == nil {
							fmt.Fprintf(bout, "!address\n")
							dot = &m.Root
							break
						}
						m = next
					}
				}
				x := cmd.F(cmd, &m.Root)
				if x != nil {
					dot = x
				}
				// TODO: Break loop on interrupt.
			}
		}
	}
	qcmd(nil, nil)
}
Example #3
0
func main() {
	flag.Usage = usage
	flag.Parse()

	acct = google.Acct(*acctName)

	aw, err := acme.New()
	if err != nil {
		log.Fatal(err)
	}
	aw.Name("Chat/" + acct.Nick + "/")

	client, err = xmpp.NewClient("talk.google.com:443", acct.Email, acct.Password)
	if err != nil {
		log.Fatal(err)
	}

	w := &Window{Win: aw, typ: "main", name: "Chat/" + acct.Nick + "/"}
	data, err := ioutil.ReadFile(google.Dir() + "/chat." + acct.Nick)
	if err != nil {
		log.Fatal(err)
	}
	if err == nil {
		w.Write("body", data)
	}
	mainWin = w
	active[w.name] = w
	go w.readAcme()
	client.Roster()
	setStatus(status)
	go w.readChat()
	lastActivity = time.Now()

	tick := time.Tick(0.5e9)
Loop:
	for len(active) > 0 {
		select {
		case w := <-acmeChan:
			if w == nil {
				// Sync with reader.
				continue
			}
			if w.err != nil {
				if active[w.name] == nil {
					continue
				}
				log.Fatal(w.err)
			}
			if *acmeDebug {
				fmt.Fprintf(os.Stderr, "%s %c%c %d,%d %q\n", w.name, w.C1, w.C2, w.Q0, w.Q1, w.Text)
			}
			if w.C1 == 'M' || w.C1 == 'K' {
				lastActivity = time.Now()
				if status != xmpp.Available {
					setStatus(xmpp.Available)
				}
			}
			if (w.C2 == 'x' || w.C2 == 'X') && string(w.Text) == "Del" {
				// TODO: Hangup connection for w.typ == "acct"?
				delete(active, w.name)
				w.Del(true)
				continue Loop
			}

			switch w.typ {
			case "main":
				switch w.C2 {
				case 'L': // Button 3 in body: load chat window for contact.
					w.expand()
					fallthrough
				case 'l': // Button 3 in tag
					arg := string(w.Text)
					showContact(arg)
					continue Loop
				}
			case "chat":
				if w.C1 == 'F' && w.C2 == 'I' {
					continue Loop
				}
				if w.C1 != 'M' && w.C1 != 'K' {
					break
				}
				if w.blinky {
					w.blinky = false
					w.Fprintf("ctl", "dirty\n")
				}
				switch w.C2 {
				case 'X', 'x':
					if string(w.Text) == "Ack" {
						w.Fprintf("ctl", "clean\n")
					}
				case 'I':
					w.sendMsg()
					continue Loop
				}
			}
			w.WriteEvent(w.Event)

		case msg := <-msgChan:
			w := msg.w
			if msg.err != nil {
				w.Fprintf("body", "ERROR: %s\n", msg.err)
				continue Loop
			}
			you := msg.Remote
			if i := strings.Index(you, "/"); i >= 0 {
				you = you[:i]
			}
			switch msg.Type {
			case "chat":
				w := showContact(you)
				text := strings.TrimSpace(msg.Text)
				if text == "" {
					// Probably a composing notification.
					continue
				}
				w.message("> %s\n", text)
				w.blinky = true
				w.dirty = true

			case "presence":
				pr := msg.Presence
				pr, new := savePresence(pr, you)
				if !new {
					continue
				}
				w := lookContact(you)
				if w != nil {
					w.status(pr)
				}
				mainStatus(pr, you)
			}

		case t := <-tick:
			switch status {
			case xmpp.Available:
				if t.Sub(lastActivity) > awayTime {
					setStatus(xmpp.Away)
				}
			case xmpp.Away:
				if t.Sub(lastActivity) > extendedAwayTime {
					setStatus(xmpp.ExtendedAway)
				}
			}
			for _, w := range active {
				if w.blinky {
					w.dirty = !w.dirty
					if w.dirty {
						w.Fprintf("ctl", "dirty\n")
					} else {
						w.Fprintf("ctl", "clean\n")
					}
				}
			}
		}
	}
}