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
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/taoshihan1991/imaptool/models"
|
||||
"html"
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type DetailHtml struct {
|
||||
*CommonHtml
|
||||
Fid string
|
||||
Id uint32
|
||||
}
|
||||
|
||||
func NewDetailHtml(w http.ResponseWriter) *DetailHtml {
|
||||
obj := new(DetailHtml)
|
||||
parent := NewRender(w)
|
||||
obj.CommonHtml = parent
|
||||
return obj
|
||||
func PageDetail(c *gin.Context) {
|
||||
if c.Request.RequestURI == "/favicon.ico" {
|
||||
return
|
||||
}
|
||||
page := c.Param("page")
|
||||
lang, _ := c.Get("lang")
|
||||
about := models.FindAboutByPageLanguage(page, lang.(string))
|
||||
cssJs := html.UnescapeString(about.CssJs)
|
||||
title := about.TitleCn
|
||||
keywords := about.KeywordsCn
|
||||
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