parent
e804febfdc
commit
2864692c7d
@ -1,341 +0,0 @@
|
|||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"github.com/taoshihan1991/imaptool/models"
|
|
||||||
"github.com/taoshihan1991/imaptool/ws"
|
|
||||||
"log"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type vistor struct {
|
|
||||||
conn *websocket.Conn
|
|
||||||
name string
|
|
||||||
id string
|
|
||||||
avator string
|
|
||||||
to_id string
|
|
||||||
}
|
|
||||||
type Message struct {
|
|
||||||
conn *websocket.Conn
|
|
||||||
c *gin.Context
|
|
||||||
content []byte
|
|
||||||
messageType int
|
|
||||||
}
|
|
||||||
|
|
||||||
var clientList = make(map[string]*vistor)
|
|
||||||
var kefuList = make(map[string][]*websocket.Conn)
|
|
||||||
var message = make(chan *Message)
|
|
||||||
|
|
||||||
type TypeMessage struct {
|
|
||||||
Type interface{} `json:"type"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}
|
|
||||||
type ClientMessage struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Avator string `json:"avator"`
|
|
||||||
Id string `json:"id"`
|
|
||||||
VisitorId string `json:"visitor_id"`
|
|
||||||
Group string `json:"group"`
|
|
||||||
Time string `json:"time"`
|
|
||||||
ToId string `json:"to_id"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
City string `json:"city"`
|
|
||||||
ClientIp string `json:"client_ip"`
|
|
||||||
Refer string `json:"refer"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//定时检测客户端是否在线
|
|
||||||
func init() {
|
|
||||||
upgrader = websocket.Upgrader{
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 1024,
|
|
||||||
}
|
|
||||||
//go UpdateVisitorStatusCron()
|
|
||||||
//go singleBroadcaster()
|
|
||||||
//go sendPingOnlineUsers()
|
|
||||||
//sendPingToClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewChatServer(c *gin.Context) {
|
|
||||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Print("upgrade:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
//接受消息
|
|
||||||
var receive []byte
|
|
||||||
var recevString string
|
|
||||||
messageType, receive, err := conn.ReadMessage()
|
|
||||||
if err != nil {
|
|
||||||
for uid, visitor := range clientList {
|
|
||||||
if visitor.conn == conn {
|
|
||||||
log.Println("删除用户", uid)
|
|
||||||
delete(clientList, uid)
|
|
||||||
models.UpdateVisitorStatus(uid, 0)
|
|
||||||
userInfo := make(map[string]string)
|
|
||||||
userInfo["uid"] = uid
|
|
||||||
userInfo["name"] = visitor.name
|
|
||||||
msg := TypeMessage{
|
|
||||||
Type: "userOffline",
|
|
||||||
Data: userInfo,
|
|
||||||
}
|
|
||||||
str, _ := json.Marshal(msg)
|
|
||||||
kefuConns := kefuList[visitor.to_id]
|
|
||||||
if kefuConns != nil {
|
|
||||||
for _, kefuConn := range kefuConns {
|
|
||||||
kefuConn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//新版
|
|
||||||
mKefuConns := ws.KefuList[visitor.to_id]
|
|
||||||
if mKefuConns != nil {
|
|
||||||
for _, kefu := range mKefuConns {
|
|
||||||
kefu.Conn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendPingOnlineUsers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
recevString = string(receive)
|
|
||||||
log.Println("客户端:", recevString)
|
|
||||||
message <- &Message{
|
|
||||||
conn: conn,
|
|
||||||
content: receive,
|
|
||||||
c: c,
|
|
||||||
messageType: messageType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送给客户客服上线
|
|
||||||
func SendKefuOnline(clientMsg ClientMessage, conn *websocket.Conn) {
|
|
||||||
sendMsg := TypeMessage{
|
|
||||||
Type: "kfOnline",
|
|
||||||
Data: ClientMessage{
|
|
||||||
Name: clientMsg.Name,
|
|
||||||
Avator: clientMsg.Avator,
|
|
||||||
Id: clientMsg.Id,
|
|
||||||
Group: clientMsg.Group,
|
|
||||||
Time: time.Now().Format("2006-01-02 15:04:05"),
|
|
||||||
Content: "客服上线",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
jsonStrByte, _ := json.Marshal(sendMsg)
|
|
||||||
conn.WriteMessage(websocket.TextMessage, jsonStrByte)
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送通知
|
|
||||||
func SendNotice(msg string, conn *websocket.Conn) {
|
|
||||||
sendMsg := TypeMessage{
|
|
||||||
Type: "notice",
|
|
||||||
Data: msg,
|
|
||||||
}
|
|
||||||
jsonStrByte, _ := json.Marshal(sendMsg)
|
|
||||||
conn.WriteMessage(websocket.TextMessage, jsonStrByte)
|
|
||||||
}
|
|
||||||
|
|
||||||
//定时给客户端发送消息判断客户端是否在线
|
|
||||||
func sendPingToClient() {
|
|
||||||
msg := TypeMessage{
|
|
||||||
Type: "ping",
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
str, _ := json.Marshal(msg)
|
|
||||||
for uid, user := range clientList {
|
|
||||||
err := user.conn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
if err != nil {
|
|
||||||
delete(clientList, uid)
|
|
||||||
models.UpdateVisitorStatus(uid, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for kefuId, kfConns := range kefuList {
|
|
||||||
|
|
||||||
var newkfConns = make([]*websocket.Conn, 0)
|
|
||||||
for _, kefuConn := range kfConns {
|
|
||||||
if kefuConn == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err := kefuConn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
if err == nil {
|
|
||||||
newkfConns = append(newkfConns, kefuConn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if newkfConns == nil {
|
|
||||||
delete(kefuList, kefuId)
|
|
||||||
} else {
|
|
||||||
kefuList[kefuId] = newkfConns
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(15 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//定时给更新数据库状态
|
|
||||||
func UpdateVisitorStatusCron() {
|
|
||||||
for {
|
|
||||||
visitors := models.FindVisitorsOnline()
|
|
||||||
for _, visitor := range visitors {
|
|
||||||
if visitor.VisitorId == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_, ok := clientList[visitor.VisitorId]
|
|
||||||
if !ok {
|
|
||||||
models.UpdateVisitorStatus(visitor.VisitorId, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(60 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//定时推送当前在线用户
|
|
||||||
func sendPingOnlineUsers() {
|
|
||||||
var visitorIds []string
|
|
||||||
for visitorId, _ := range clientList {
|
|
||||||
visitorIds = append(visitorIds, visitorId)
|
|
||||||
}
|
|
||||||
sort.Strings(visitorIds)
|
|
||||||
|
|
||||||
for kefuId, kfConns := range kefuList {
|
|
||||||
|
|
||||||
result := make([]map[string]string, 0)
|
|
||||||
for _, visitorId := range visitorIds {
|
|
||||||
user := clientList[visitorId]
|
|
||||||
userInfo := make(map[string]string)
|
|
||||||
userInfo["uid"] = user.id
|
|
||||||
userInfo["username"] = user.name
|
|
||||||
userInfo["avator"] = user.avator
|
|
||||||
if user.to_id == kefuId {
|
|
||||||
result = append(result, userInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg := TypeMessage{
|
|
||||||
Type: "allUsers",
|
|
||||||
Data: result,
|
|
||||||
}
|
|
||||||
str, _ := json.Marshal(msg)
|
|
||||||
var newkfConns = make([]*websocket.Conn, 0)
|
|
||||||
for _, kefuConn := range kfConns {
|
|
||||||
err := kefuConn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
if err == nil {
|
|
||||||
newkfConns = append(newkfConns, kefuConn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(newkfConns) == 0 {
|
|
||||||
delete(kefuList, kefuId)
|
|
||||||
} else {
|
|
||||||
kefuList[kefuId] = newkfConns
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//后端广播发送消息
|
|
||||||
//func singleBroadcaster() {
|
|
||||||
// for {
|
|
||||||
// message := <-message
|
|
||||||
// //log.Println("debug:",message)
|
|
||||||
//
|
|
||||||
// var typeMsg TypeMessage
|
|
||||||
// var clientMsg ClientMessage
|
|
||||||
// json.Unmarshal(message.content, &typeMsg)
|
|
||||||
// conn := message.conn
|
|
||||||
// if typeMsg.Type == nil || typeMsg.Data == nil {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// msgType := typeMsg.Type.(string)
|
|
||||||
// msgData, _ := json.Marshal(typeMsg.Data)
|
|
||||||
// switch msgType {
|
|
||||||
// //用户上线
|
|
||||||
// case "userInit":
|
|
||||||
// json.Unmarshal(msgData, &clientMsg)
|
|
||||||
// vistorInfo := models.FindVisitorByVistorId(clientMsg.VisitorId)
|
|
||||||
// if vistorInfo.VisitorId == "" {
|
|
||||||
// SendNotice("访客数据不存在", conn)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// //用户id对应的连接
|
|
||||||
// user := &vistor{
|
|
||||||
// conn: conn,
|
|
||||||
// name: clientMsg.Name,
|
|
||||||
// avator: clientMsg.Avator,
|
|
||||||
// id: clientMsg.VisitorId,
|
|
||||||
// to_id: clientMsg.ToId,
|
|
||||||
// }
|
|
||||||
// clientList[clientMsg.VisitorId] = user
|
|
||||||
// //插入数据表
|
|
||||||
// models.UpdateVisitor(clientMsg.VisitorId, 1, clientMsg.ClientIp, message.c.ClientIP(), clientMsg.Refer, "")
|
|
||||||
// //models.CreateVisitor(clientMsg.Name,clientMsg.Avator,message.c.ClientIP(),clientMsg.ToId,clientMsg.VisitorId,clientMsg.Refer,clientMsg.City,clientMsg.ClientIp)
|
|
||||||
// userInfo := make(map[string]string)
|
|
||||||
// userInfo["uid"] = user.id
|
|
||||||
// userInfo["username"] = user.name
|
|
||||||
// userInfo["avator"] = user.avator
|
|
||||||
// msg := TypeMessage{
|
|
||||||
// Type: "userOnline",
|
|
||||||
// Data: userInfo,
|
|
||||||
// }
|
|
||||||
// str, _ := json.Marshal(msg)
|
|
||||||
//
|
|
||||||
// //新版
|
|
||||||
// mKefuConns := ws.KefuList[user.to_id]
|
|
||||||
// if mKefuConns != nil {
|
|
||||||
// for _, kefu := range mKefuConns {
|
|
||||||
// kefu.Conn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //兼容旧版
|
|
||||||
// kefuConns := kefuList[user.to_id]
|
|
||||||
// if kefuConns != nil {
|
|
||||||
// for k, kefuConn := range kefuConns {
|
|
||||||
// log.Println(k, "xxxxxxxx")
|
|
||||||
// kefuConn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //客户上线发微信通知
|
|
||||||
// go SendServerJiang(userInfo["username"])
|
|
||||||
// sendPingOnlineUsers()
|
|
||||||
// //客服上线
|
|
||||||
// case "kfOnline":
|
|
||||||
// json.Unmarshal(msgData, &clientMsg)
|
|
||||||
// //客服id对应的连接
|
|
||||||
// var newKefuConns = []*websocket.Conn{conn}
|
|
||||||
// kefuConns := kefuList[clientMsg.Id]
|
|
||||||
// if kefuConns != nil {
|
|
||||||
// newKefuConns = append(newKefuConns, kefuConns...)
|
|
||||||
// }
|
|
||||||
// log.Println(newKefuConns)
|
|
||||||
// kefuList[clientMsg.Id] = newKefuConns
|
|
||||||
// //发送给客户
|
|
||||||
// if len(clientList) == 0 {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// sendPingOnlineUsers()
|
|
||||||
// //客服接手
|
|
||||||
// case "kfConnect":
|
|
||||||
// json.Unmarshal(msgData, &clientMsg)
|
|
||||||
// visitor, ok := clientList[clientMsg.ToId]
|
|
||||||
// if visitor == nil || !ok {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// SendKefuOnline(clientMsg, visitor.conn)
|
|
||||||
// //心跳
|
|
||||||
// case "ping":
|
|
||||||
// msg := TypeMessage{
|
|
||||||
// Type: "pong",
|
|
||||||
// }
|
|
||||||
// str, _ := json.Marshal(msg)
|
|
||||||
// conn.WriteMessage(websocket.TextMessage, str)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -1,262 +0,0 @@
|
|||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/taoshihan1991/imaptool/config"
|
|
||||||
"github.com/taoshihan1991/imaptool/tmpl"
|
|
||||||
"github.com/taoshihan1991/imaptool/tools"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const PageSize = 20
|
|
||||||
|
|
||||||
func GetFolders(c *gin.Context) {
|
|
||||||
fid := c.Query("fid")
|
|
||||||
currentPage, _ := strconv.Atoi(c.Query("page"))
|
|
||||||
if fid == "" {
|
|
||||||
fid = "INBOX"
|
|
||||||
}
|
|
||||||
if currentPage == 0 {
|
|
||||||
currentPage = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
mailServer := config.CreateMailServer()
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(2)
|
|
||||||
result := make(map[string]interface{})
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
folders := tools.GetFolders(mailServer.Server, mailServer.Email, mailServer.Password, fid)
|
|
||||||
result["folders"] = folders
|
|
||||||
result["total"] = folders[fid]
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
mails := tools.GetFolderMail(mailServer.Server, mailServer.Email, mailServer.Password, fid, currentPage, PageSize)
|
|
||||||
result["mails"] = mails
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
result["pagesize"] = PageSize
|
|
||||||
result["fid"] = fid
|
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
|
||||||
"code": 200,
|
|
||||||
"msg": "ok",
|
|
||||||
"result": result,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func GetFolderList(c *gin.Context) {
|
|
||||||
fid := c.Query("fid")
|
|
||||||
if fid == "" {
|
|
||||||
fid = "INBOX"
|
|
||||||
}
|
|
||||||
|
|
||||||
mailServer := config.CreateMailServer()
|
|
||||||
|
|
||||||
result := make(map[string]interface{})
|
|
||||||
folders := tools.GetFolders(mailServer.Server, mailServer.Email, mailServer.Password, fid)
|
|
||||||
result["folders"] = folders
|
|
||||||
result["total"] = folders[fid]
|
|
||||||
result["fid"] = fid
|
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
|
||||||
"code": 200,
|
|
||||||
"msg": "ok",
|
|
||||||
"result": result,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//输出列表
|
|
||||||
func ActionFolder(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fid := tools.GetUrlArg(r, "fid")
|
|
||||||
currentPage, _ := strconv.Atoi(tools.GetUrlArg(r, "page"))
|
|
||||||
if fid == "" {
|
|
||||||
fid = "INBOX"
|
|
||||||
}
|
|
||||||
if currentPage == 0 {
|
|
||||||
currentPage = 1
|
|
||||||
}
|
|
||||||
render := tmpl.NewFolderHtml(w)
|
|
||||||
render.CurrentPage = currentPage
|
|
||||||
render.Fid = fid
|
|
||||||
render.Display("list", render)
|
|
||||||
}
|
|
||||||
|
|
||||||
//写信界面
|
|
||||||
func ActionWrite(w http.ResponseWriter, r *http.Request) {
|
|
||||||
render := tmpl.NewRender(w)
|
|
||||||
render.SetLeft("mail_left")
|
|
||||||
render.Display("write", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
//读信界面
|
|
||||||
func ActionDetail(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fid := tools.GetUrlArg(r, "fid")
|
|
||||||
id, _ := strconv.Atoi(tools.GetUrlArg(r, "id"))
|
|
||||||
|
|
||||||
render := tmpl.NewDetailHtml(w)
|
|
||||||
render.SetLeft("mail_left")
|
|
||||||
render.Fid = fid
|
|
||||||
render.Id = uint32(id)
|
|
||||||
render.Display("mail_detail", render)
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取邮件夹接口
|
|
||||||
func FolderDir(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fid := tools.GetUrlArg(r, "fid")
|
|
||||||
|
|
||||||
if fid == "" {
|
|
||||||
fid = "INBOX"
|
|
||||||
}
|
|
||||||
|
|
||||||
mailServer := tools.GetMailServerFromCookie(r)
|
|
||||||
w.Header().Set("content-type", "text/json;charset=utf-8;")
|
|
||||||
|
|
||||||
if mailServer == nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "验证失败"})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result := make(map[string]interface{})
|
|
||||||
folders := tools.GetFolders(mailServer.Server, mailServer.Email, mailServer.Password, fid)
|
|
||||||
result["folders"] = folders
|
|
||||||
result["total"] = folders[fid]
|
|
||||||
result["fid"] = fid
|
|
||||||
msg, _ := json.Marshal(tools.JsonListResult{
|
|
||||||
JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"},
|
|
||||||
Result: result,
|
|
||||||
})
|
|
||||||
w.Write(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
//邮件夹接口
|
|
||||||
func FoldersList(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fid := tools.GetUrlArg(r, "fid")
|
|
||||||
currentPage, _ := strconv.Atoi(tools.GetUrlArg(r, "page"))
|
|
||||||
|
|
||||||
if fid == "" {
|
|
||||||
fid = "INBOX"
|
|
||||||
}
|
|
||||||
if currentPage == 0 {
|
|
||||||
currentPage = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
mailServer := tools.GetMailServerFromCookie(r)
|
|
||||||
w.Header().Set("content-type", "text/json;charset=utf-8;")
|
|
||||||
|
|
||||||
if mailServer == nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "验证失败"})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(2)
|
|
||||||
result := make(map[string]interface{})
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
folders := tools.GetFolders(mailServer.Server, mailServer.Email, mailServer.Password, fid)
|
|
||||||
result["folders"] = folders
|
|
||||||
result["total"] = folders[fid]
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
mails := tools.GetFolderMail(mailServer.Server, mailServer.Email, mailServer.Password, fid, currentPage, PageSize)
|
|
||||||
result["mails"] = mails
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
result["pagesize"] = PageSize
|
|
||||||
result["fid"] = fid
|
|
||||||
|
|
||||||
msg, _ := json.Marshal(tools.JsonListResult{
|
|
||||||
JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"},
|
|
||||||
Result: result,
|
|
||||||
})
|
|
||||||
w.Write(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
//邮件接口
|
|
||||||
func FolderMail(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fid := tools.GetUrlArg(r, "fid")
|
|
||||||
id, _ := strconv.Atoi(tools.GetUrlArg(r, "id"))
|
|
||||||
mailServer := tools.GetMailServerFromCookie(r)
|
|
||||||
w.Header().Set("content-type", "text/json;charset=utf-8;")
|
|
||||||
|
|
||||||
if mailServer == nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "验证失败"})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
result := make(map[string]interface{})
|
|
||||||
wg.Add(2)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
folders := tools.GetFolders(mailServer.Server, mailServer.Email, mailServer.Password, fid)
|
|
||||||
result["folders"] = folders
|
|
||||||
result["total"] = folders[fid]
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
mail := tools.GetMessage(mailServer.Server, mailServer.Email, mailServer.Password, fid, uint32(id))
|
|
||||||
result["from"] = mail.From
|
|
||||||
result["to"] = mail.To
|
|
||||||
result["subject"] = mail.Subject
|
|
||||||
result["date"] = mail.Date
|
|
||||||
result["html"] = mail.Body
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
result["fid"] = fid
|
|
||||||
|
|
||||||
msg, _ := json.Marshal(tools.JsonListResult{
|
|
||||||
JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"},
|
|
||||||
Result: result,
|
|
||||||
})
|
|
||||||
w.Write(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送邮件接口
|
|
||||||
func FolderSend(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("content-type", "text/json;charset=utf-8;")
|
|
||||||
mailServer := tools.GetMailServerFromCookie(r)
|
|
||||||
|
|
||||||
if mailServer == nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "验证失败"})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败," + err.Error()})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var sendData tools.SmtpBody
|
|
||||||
err = json.Unmarshal(bodyBytes, &sendData)
|
|
||||||
if err != nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败," + err.Error()})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
smtpServer := sendData.Smtp
|
|
||||||
smtpFrom := mailServer.Email
|
|
||||||
smtpTo := sendData.To
|
|
||||||
smtpBody := sendData.Body
|
|
||||||
smtpPass := mailServer.Password
|
|
||||||
smtpSubject := sendData.Subject
|
|
||||||
err = tools.SendSmtp(smtpServer, smtpFrom, smtpPass, smtpTo, smtpSubject, smtpBody)
|
|
||||||
if err != nil {
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: err.Error()})
|
|
||||||
w.Write(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msg, _ := json.Marshal(tools.JsonResult{Code: 200, Msg: "发送成功!"})
|
|
||||||
w.Write(msg)
|
|
||||||
}
|
|
@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="renderer" content="webkit">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<title>{{.Title}}</title>
|
||||||
|
<meta name="keywords" content="{{.Keywords}}" />
|
||||||
|
<meta name="description" content="{{.Desc}}" />
|
||||||
|
{{.CssJs}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{.Content}}
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,9 @@
|
|||||||
|
{{template "header" }}
|
||||||
|
<div id="app" style="width:100%">
|
||||||
|
<template>
|
||||||
|
正在开发...
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
{{template "setting_bottom" .}}
|
@ -1,16 +1,37 @@
|
|||||||
package tmpl
|
package tmpl
|
||||||
|
|
||||||
import "net/http"
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/taoshihan1991/imaptool/models"
|
||||||
|
"html"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
type DetailHtml struct {
|
func PageDetail(c *gin.Context) {
|
||||||
*CommonHtml
|
if c.Request.RequestURI == "/favicon.ico" {
|
||||||
Fid string
|
return
|
||||||
Id uint32
|
}
|
||||||
}
|
page := c.Param("page")
|
||||||
|
lang, _ := c.Get("lang")
|
||||||
func NewDetailHtml(w http.ResponseWriter) *DetailHtml {
|
about := models.FindAboutByPageLanguage(page, lang.(string))
|
||||||
obj := new(DetailHtml)
|
cssJs := html.UnescapeString(about.CssJs)
|
||||||
parent := NewRender(w)
|
title := about.TitleCn
|
||||||
obj.CommonHtml = parent
|
keywords := about.KeywordsCn
|
||||||
return obj
|
desc := html.UnescapeString(about.DescCn)
|
||||||
|
content := html.UnescapeString(about.HtmlCn)
|
||||||
|
if lang == "en" {
|
||||||
|
title = about.TitleEn
|
||||||
|
keywords = about.KeywordsEn
|
||||||
|
desc = html.UnescapeString(about.DescEn)
|
||||||
|
content = html.UnescapeString(about.HtmlEn)
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "detail.html", gin.H{
|
||||||
|
"Lang": lang,
|
||||||
|
"Title": title,
|
||||||
|
"Keywords": keywords,
|
||||||
|
"Desc": desc,
|
||||||
|
"Content": template.HTML(content),
|
||||||
|
"CssJs": template.HTML(cssJs),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,363 +0,0 @@
|
|||||||
package tools
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/axgle/mahonia"
|
|
||||||
"github.com/emersion/go-imap"
|
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/emersion/go-message/mail"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"mime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
//验证邮箱密码
|
|
||||||
func CheckEmailPassword(server string, email string, password string) bool {
|
|
||||||
if !strings.Contains(server, ":") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var c *client.Client
|
|
||||||
serverSlice := strings.Split(server, ":")
|
|
||||||
port, _ := strconv.Atoi(serverSlice[1])
|
|
||||||
if port != 993 && port != 143 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 不要忘了退出
|
|
||||||
//defer c.Logout()
|
|
||||||
|
|
||||||
// 登陆
|
|
||||||
c = connect(server, email, password)
|
|
||||||
if c == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取连接
|
|
||||||
func connect(server string, email string, password string) *client.Client {
|
|
||||||
var c *client.Client
|
|
||||||
var err error
|
|
||||||
serverSlice := strings.Split(server, ":")
|
|
||||||
uri := serverSlice[0]
|
|
||||||
port, _ := strconv.Atoi(serverSlice[1])
|
|
||||||
if port != 993 && port != 143 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if port == 993 {
|
|
||||||
c, err = client.DialTLS(fmt.Sprintf("%s:%d", uri, port), nil)
|
|
||||||
} else {
|
|
||||||
c, err = client.Dial(fmt.Sprintf("%s:%d", uri, port))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 登陆
|
|
||||||
if err := c.Login(email, password); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取邮件总数
|
|
||||||
func GetMailNum(server string, email string, password string) map[string]int {
|
|
||||||
var c *client.Client
|
|
||||||
//defer c.Logout()
|
|
||||||
c = connect(server, email, password)
|
|
||||||
if c == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// 列邮箱
|
|
||||||
mailboxes := make(chan *imap.MailboxInfo, 10)
|
|
||||||
done := make(chan error, 1)
|
|
||||||
go func() {
|
|
||||||
done <- c.List("", "*", mailboxes)
|
|
||||||
}()
|
|
||||||
//// 存储邮件夹
|
|
||||||
var folders = make(map[string]int)
|
|
||||||
for m := range mailboxes {
|
|
||||||
folders[m.Name] = 0
|
|
||||||
}
|
|
||||||
for m, _ := range folders {
|
|
||||||
mbox, _ := c.Select(m, true)
|
|
||||||
if mbox != nil {
|
|
||||||
folders[m] = int(mbox.Messages)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return folders
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取邮件夹
|
|
||||||
func GetFolders(server string, email string, password string, folder string) map[string]int {
|
|
||||||
var c *client.Client
|
|
||||||
//defer c.Logout()
|
|
||||||
c = connect(server, email, password)
|
|
||||||
if c == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// 列邮箱
|
|
||||||
mailboxes := make(chan *imap.MailboxInfo, 10)
|
|
||||||
done := make(chan error, 1)
|
|
||||||
go func() {
|
|
||||||
done <- c.List("", "*", mailboxes)
|
|
||||||
}()
|
|
||||||
// 存储邮件夹
|
|
||||||
var folders = make(map[string]int)
|
|
||||||
for m := range mailboxes {
|
|
||||||
folders[m.Name] = 0
|
|
||||||
}
|
|
||||||
for m, _ := range folders {
|
|
||||||
if m == folder {
|
|
||||||
mbox, _ := c.Select(m, true)
|
|
||||||
if mbox != nil {
|
|
||||||
folders[m] = int(mbox.Messages)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//log.Println(folders)
|
|
||||||
return folders
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取邮件夹邮件
|
|
||||||
func GetFolderMail(server string, email string, password string, folder string, currentPage int, pagesize int) []*MailItem {
|
|
||||||
var c *client.Client
|
|
||||||
//defer c.Logout()
|
|
||||||
c = connect(server, email, password)
|
|
||||||
if c == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mbox, _ := c.Select(folder, true)
|
|
||||||
to := mbox.Messages - uint32((currentPage-1)*pagesize)
|
|
||||||
from := to - uint32(pagesize)
|
|
||||||
if to <= uint32(pagesize) {
|
|
||||||
from = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
seqset := new(imap.SeqSet)
|
|
||||||
seqset.AddRange(from, to)
|
|
||||||
|
|
||||||
messages := make(chan *imap.Message, pagesize)
|
|
||||||
done := make(chan error, 1)
|
|
||||||
fetchItem := imap.FetchItem(imap.FetchEnvelope)
|
|
||||||
items := make([]imap.FetchItem, 0)
|
|
||||||
items = append(items, fetchItem)
|
|
||||||
go func() {
|
|
||||||
done <- c.Fetch(seqset, items, messages)
|
|
||||||
}()
|
|
||||||
var mailPagelist = new(MailPageList)
|
|
||||||
|
|
||||||
dec := GetDecoder()
|
|
||||||
|
|
||||||
for msg := range messages {
|
|
||||||
log.Println(msg.Envelope.Date)
|
|
||||||
|
|
||||||
ret, err := dec.Decode(msg.Envelope.Subject)
|
|
||||||
if err != nil {
|
|
||||||
ret, _ = dec.DecodeHeader(msg.Envelope.Subject)
|
|
||||||
}
|
|
||||||
var mailitem = new(MailItem)
|
|
||||||
|
|
||||||
mailitem.Subject = ret
|
|
||||||
mailitem.Id = msg.SeqNum
|
|
||||||
mailitem.Fid = folder
|
|
||||||
mailitem.Date = msg.Envelope.Date.String()
|
|
||||||
from := ""
|
|
||||||
for _, s := range msg.Envelope.Sender {
|
|
||||||
from += s.Address()
|
|
||||||
}
|
|
||||||
mailitem.From = from
|
|
||||||
mailPagelist.MailItems = append(mailPagelist.MailItems, mailitem)
|
|
||||||
}
|
|
||||||
return mailPagelist.MailItems
|
|
||||||
}
|
|
||||||
func GetMessage(server string, email string, password string, folder string, id uint32) *MailItem {
|
|
||||||
var c *client.Client
|
|
||||||
//defer c.Logout()
|
|
||||||
c = connect(server, email, password)
|
|
||||||
if c == nil {
|
|
||||||
//return nil
|
|
||||||
}
|
|
||||||
// Select INBOX
|
|
||||||
mbox, err := c.Select(folder, false)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the last message
|
|
||||||
if mbox.Messages == 0 {
|
|
||||||
log.Fatal("No message in mailbox")
|
|
||||||
}
|
|
||||||
seqSet := new(imap.SeqSet)
|
|
||||||
seqSet.AddNum(id)
|
|
||||||
|
|
||||||
// Get the whole message body
|
|
||||||
section := &imap.BodySectionName{}
|
|
||||||
items := []imap.FetchItem{section.FetchItem()}
|
|
||||||
|
|
||||||
messages := make(chan *imap.Message, 1)
|
|
||||||
go func() {
|
|
||||||
if err := c.Fetch(seqSet, items, messages); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
msg := <-messages
|
|
||||||
if msg == nil {
|
|
||||||
log.Fatal("Server didn't returned message")
|
|
||||||
}
|
|
||||||
|
|
||||||
r := msg.GetBody(section)
|
|
||||||
|
|
||||||
if r == nil {
|
|
||||||
log.Fatal("Server didn't returned message body")
|
|
||||||
}
|
|
||||||
var mailitem = new(MailItem)
|
|
||||||
|
|
||||||
// Create a new mail reader
|
|
||||||
mr, _ := mail.CreateReader(r)
|
|
||||||
|
|
||||||
// Print some info about the message
|
|
||||||
header := mr.Header
|
|
||||||
date, _ := header.Date()
|
|
||||||
|
|
||||||
mailitem.Date = date.String()
|
|
||||||
|
|
||||||
var f string
|
|
||||||
dec := GetDecoder()
|
|
||||||
|
|
||||||
if from, err := header.AddressList("From"); err == nil {
|
|
||||||
for _, address := range from {
|
|
||||||
fromStr := address.String()
|
|
||||||
temp, _ := dec.DecodeHeader(fromStr)
|
|
||||||
f += " " + temp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mailitem.From = f
|
|
||||||
log.Println("From:", mailitem.From)
|
|
||||||
|
|
||||||
var t string
|
|
||||||
if to, err := header.AddressList("To"); err == nil {
|
|
||||||
log.Println("To:", to)
|
|
||||||
for _, address := range to {
|
|
||||||
toStr := address.String()
|
|
||||||
temp, _ := dec.DecodeHeader(toStr)
|
|
||||||
t += " " + temp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mailitem.To = t
|
|
||||||
|
|
||||||
subject, _ := header.Subject()
|
|
||||||
s, err := dec.Decode(subject)
|
|
||||||
if err != nil {
|
|
||||||
s, _ = dec.DecodeHeader(subject)
|
|
||||||
}
|
|
||||||
log.Println("Subject:", s)
|
|
||||||
mailitem.Subject = s
|
|
||||||
// Process each message's part
|
|
||||||
var bodyMap = make(map[string]string)
|
|
||||||
bodyMap["text/plain"] = ""
|
|
||||||
bodyMap["text/html"] = ""
|
|
||||||
|
|
||||||
for {
|
|
||||||
p, err := mr.NextPart()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
//log.Fatal(err)
|
|
||||||
}
|
|
||||||
switch h := p.Header.(type) {
|
|
||||||
case *mail.InlineHeader:
|
|
||||||
// This is the message's text (can be plain-text or HTML)
|
|
||||||
|
|
||||||
b, _ := ioutil.ReadAll(p.Body)
|
|
||||||
ct := p.Header.Get("Content-Type")
|
|
||||||
if strings.Contains(ct, "text/plain") {
|
|
||||||
bodyMap["text/plain"] += Encoding(string(b), ct)
|
|
||||||
} else {
|
|
||||||
bodyMap["text/html"] += Encoding(string(b), ct)
|
|
||||||
}
|
|
||||||
//body,_:=dec.Decode(string(b))
|
|
||||||
case *mail.AttachmentHeader:
|
|
||||||
// This is an attachment
|
|
||||||
filename, _ := h.Filename()
|
|
||||||
log.Println("Got attachment: ", filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if bodyMap["text/html"] != "" {
|
|
||||||
mailitem.Body = bodyMap["text/html"]
|
|
||||||
} else {
|
|
||||||
mailitem.Body = bodyMap["text/plain"]
|
|
||||||
}
|
|
||||||
//log.Println(mailitem.Body)
|
|
||||||
return mailitem
|
|
||||||
}
|
|
||||||
func GetDecoder() *mime.WordDecoder {
|
|
||||||
dec := new(mime.WordDecoder)
|
|
||||||
dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
|
|
||||||
charset = strings.ToLower(charset)
|
|
||||||
switch charset {
|
|
||||||
case "gb2312":
|
|
||||||
content, err := ioutil.ReadAll(input)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//ret:=bytes.NewReader(content)
|
|
||||||
//ret:=transform.NewReader(bytes.NewReader(content), simplifiedchinese.HZGB2312.NewEncoder())
|
|
||||||
|
|
||||||
utf8str := ConvertToStr(string(content), "gbk", "utf-8")
|
|
||||||
t := bytes.NewReader([]byte(utf8str))
|
|
||||||
//ret:=utf8.DecodeRune(t)
|
|
||||||
//log.Println(ret)
|
|
||||||
return t, nil
|
|
||||||
case "gbk":
|
|
||||||
content, err := ioutil.ReadAll(input)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//ret:=bytes.NewReader(content)
|
|
||||||
//ret:=transform.NewReader(bytes.NewReader(content), simplifiedchinese.HZGB2312.NewEncoder())
|
|
||||||
|
|
||||||
utf8str := ConvertToStr(string(content), "gbk", "utf-8")
|
|
||||||
t := bytes.NewReader([]byte(utf8str))
|
|
||||||
//ret:=utf8.DecodeRune(t)
|
|
||||||
//log.Println(ret)
|
|
||||||
return t, nil
|
|
||||||
case "gb18030":
|
|
||||||
content, err := ioutil.ReadAll(input)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//ret:=bytes.NewReader(content)
|
|
||||||
//ret:=transform.NewReader(bytes.NewReader(content), simplifiedchinese.HZGB2312.NewEncoder())
|
|
||||||
|
|
||||||
utf8str := ConvertToStr(string(content), "gbk", "utf-8")
|
|
||||||
t := bytes.NewReader([]byte(utf8str))
|
|
||||||
//ret:=utf8.DecodeRune(t)
|
|
||||||
//log.Println(ret)
|
|
||||||
return t, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unhandle charset:%s", charset)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dec
|
|
||||||
}
|
|
||||||
|
|
||||||
// 任意编码转特定编码
|
|
||||||
func ConvertToStr(src string, srcCode string, tagCode string) string {
|
|
||||||
result := mahonia.NewDecoder(srcCode).ConvertString(src)
|
|
||||||
//srcCoder := mahonia.NewDecoder(srcCode)
|
|
||||||
//srcResult := srcCoder.ConvertString(src)
|
|
||||||
//tagCoder := mahonia.NewDecoder(tagCode)
|
|
||||||
//_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
|
|
||||||
//result := string(cdata)
|
|
||||||
return result
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
package tools
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/emersion/go-imap"
|
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/emersion/go-message/mail"
|
|
||||||
)
|
|
||||||
|
|
||||||
//全局变量
|
|
||||||
//imap服务地址,邮箱,密码
|
|
||||||
var (
|
|
||||||
server, email, password string
|
|
||||||
folders map[int]string
|
|
||||||
)
|
|
||||||
|
|
||||||
func testmain() {
|
|
||||||
|
|
||||||
//获取参数中的数据
|
|
||||||
flag.StringVar(&server, "server", "", "imap服务地址(包含端口)")
|
|
||||||
flag.StringVar(&email, "email", "", "邮箱名")
|
|
||||||
flag.StringVar(&password, "password", "", "密码")
|
|
||||||
flag.Parse()
|
|
||||||
if flag.NFlag() < 3 {
|
|
||||||
flag.PrintDefaults()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if server == "" || email == "" || password == "" {
|
|
||||||
log.Fatal("服务器地址,用户名,密码,参数必填")
|
|
||||||
}
|
|
||||||
log.Println("正在连接服务器...")
|
|
||||||
//支持加密和非加密端口
|
|
||||||
if !strings.Contains(server, ":") {
|
|
||||||
log.Fatal("服务器地址端口号错误:", server)
|
|
||||||
}
|
|
||||||
serverSlice := strings.Split(server, ":")
|
|
||||||
uri := serverSlice[0]
|
|
||||||
port, _ := strconv.Atoi(serverSlice[1])
|
|
||||||
if port != 993 && port != 143 {
|
|
||||||
log.Fatal("服务器地址端口号错误:", port)
|
|
||||||
}
|
|
||||||
// 连接到服务器
|
|
||||||
var c *client.Client
|
|
||||||
var err error
|
|
||||||
if port == 993 {
|
|
||||||
c, err = client.DialTLS(fmt.Sprintf("%s:%d", uri, port), nil)
|
|
||||||
} else {
|
|
||||||
c, err = client.Dial(fmt.Sprintf("%s:%d", uri, port))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Println("连接成功")
|
|
||||||
|
|
||||||
// 不要忘了退出
|
|
||||||
defer c.Logout()
|
|
||||||
|
|
||||||
// 登陆
|
|
||||||
if err := c.Login(email, password); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Println("成功登陆")
|
|
||||||
|
|
||||||
// 列邮箱
|
|
||||||
mailboxes := make(chan *imap.MailboxInfo, 10)
|
|
||||||
done := make(chan error, 1)
|
|
||||||
go func() {
|
|
||||||
done <- c.List("", "*", mailboxes)
|
|
||||||
}()
|
|
||||||
// 存储邮件夹
|
|
||||||
folders = make(map[int]string)
|
|
||||||
i := 1
|
|
||||||
for m := range mailboxes {
|
|
||||||
log.Println("* ", i, m.Name)
|
|
||||||
folders[i] = m.Name
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
log.Println("输入邮件夹序号:")
|
|
||||||
inLine := readLineFromInput()
|
|
||||||
folderNum, _ := strconv.Atoi(inLine)
|
|
||||||
currentFolder := folders[folderNum]
|
|
||||||
|
|
||||||
if err := <-done; err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select 邮件夹
|
|
||||||
mbox, err := c.Select(currentFolder, false)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Printf("%s的邮件个数:%d \r\n", currentFolder, mbox.Messages)
|
|
||||||
|
|
||||||
// 获取最新的信
|
|
||||||
log.Println("读取最新的几封信(all全部):")
|
|
||||||
inLine = readLineFromInput()
|
|
||||||
var maxNum uint32
|
|
||||||
if inLine == "all" {
|
|
||||||
maxNum = mbox.Messages
|
|
||||||
} else {
|
|
||||||
tempNum, _ := strconv.Atoi(inLine)
|
|
||||||
maxNum = uint32(tempNum)
|
|
||||||
}
|
|
||||||
|
|
||||||
from := uint32(1)
|
|
||||||
to := mbox.Messages
|
|
||||||
if mbox.Messages >= maxNum {
|
|
||||||
// 我们在这使用无符号整型, 这是再获取from的id
|
|
||||||
from = mbox.Messages - maxNum + 1
|
|
||||||
} else {
|
|
||||||
log.Fatal("超出了邮件封数!")
|
|
||||||
}
|
|
||||||
seqset := new(imap.SeqSet)
|
|
||||||
seqset.AddRange(from, to)
|
|
||||||
|
|
||||||
messages := make(chan *imap.Message, 10)
|
|
||||||
done = make(chan error, 1)
|
|
||||||
go func() {
|
|
||||||
done <- c.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, messages)
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.Printf("最新的 %d 封信:", maxNum)
|
|
||||||
for msg := range messages {
|
|
||||||
log.Printf("* %d:%s\n", to, msg.Envelope.Subject)
|
|
||||||
to--
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := <-done; err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
log.Println("读取第几封信信体:")
|
|
||||||
|
|
||||||
inLine = readLineFromInput()
|
|
||||||
mesIndex, _ := strconv.Atoi(inLine)
|
|
||||||
mesSeqSet := new(imap.SeqSet)
|
|
||||||
mesSeqSet.AddNum(uint32(mesIndex))
|
|
||||||
//获取整封信体
|
|
||||||
var section imap.BodySectionName
|
|
||||||
items := []imap.FetchItem{section.FetchItem()}
|
|
||||||
|
|
||||||
bodyMsg := make(chan *imap.Message, 1)
|
|
||||||
go func() {
|
|
||||||
if err := c.Fetch(mesSeqSet, items, bodyMsg); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
msg := <-bodyMsg
|
|
||||||
if msg == nil {
|
|
||||||
log.Fatal("服务器没有返回信息")
|
|
||||||
}
|
|
||||||
r := msg.GetBody(§ion)
|
|
||||||
if r == nil {
|
|
||||||
log.Fatal("服务器没有返回 message body")
|
|
||||||
}
|
|
||||||
mr, err := mail.CreateReader(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//打印信息
|
|
||||||
header := mr.Header
|
|
||||||
if date, err := header.Date(); err == nil {
|
|
||||||
log.Println("Date:", date)
|
|
||||||
}
|
|
||||||
if from, err := header.AddressList("From"); err == nil {
|
|
||||||
log.Println("From:", from)
|
|
||||||
}
|
|
||||||
if to, err := header.AddressList("To"); err == nil {
|
|
||||||
log.Println("To:", to)
|
|
||||||
}
|
|
||||||
if subject, err := header.Subject(); err == nil {
|
|
||||||
log.Println("Subject:", subject)
|
|
||||||
}
|
|
||||||
// Process each message's part
|
|
||||||
for {
|
|
||||||
p, err := mr.NextPart()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch h := p.Header.(type) {
|
|
||||||
case *mail.InlineHeader:
|
|
||||||
// This is the message's text (can be plain-text or HTML)
|
|
||||||
b, _ := ioutil.ReadAll(p.Body)
|
|
||||||
log.Printf("Got text: %s\n", string(b))
|
|
||||||
case *mail.AttachmentHeader:
|
|
||||||
// This is an attachment
|
|
||||||
filename, _ := h.Filename()
|
|
||||||
log.Printf("Got attachment: %s\n", filename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Printf("读取第 %d 封信, 结束!\n", mesIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//从输入中读取一行
|
|
||||||
func readLineFromInput() string {
|
|
||||||
str := ""
|
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
|
||||||
for scanner.Scan() {
|
|
||||||
str = scanner.Text() // Println will add back the final '\n'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
Loading…
Reference in new issue