main.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/go-gomail/gomail"
  6. "gopkg.in/mgo.v2/bson"
  7. "jy/mongodbutil"
  8. "log"
  9. mu "mfw/util"
  10. "net"
  11. "net/rpc"
  12. "path"
  13. "qfw/common/src/qfw/util"
  14. qu "qfw/util"
  15. "strconv"
  16. "strings"
  17. "sync"
  18. "time"
  19. )
  20. var udpclient mu.UdpClient //udp对象
  21. var Sysconfig map[string]interface{}
  22. var MgoIP, MgoDB, MgoC, MgoFileFiled string
  23. var ChanB chan bool
  24. var PageSize int
  25. func init() {
  26. qu.ReadConfig(&Sysconfig)
  27. MgoIP = qu.ObjToString(Sysconfig["mongodb_one_ip"])
  28. MgoDB = qu.ObjToString(Sysconfig["mongodb_one_db"])
  29. MgoC = qu.ObjToString(Sysconfig["mongodb_one_c"])
  30. PageSize = qu.IntAllDef(Sysconfig["PageSize"],2000)
  31. MgoFileFiled = qu.ObjToStringDef(Sysconfig["mongodb_one_filefiled"], "projectinfo")
  32. if strings.TrimSpace(MgoIP) == "" || strings.TrimSpace(MgoDB) == "" || strings.TrimSpace(MgoC) == "" ||PageSize <=0{
  33. log.Println("获取配置文件参数失败", Sysconfig)
  34. return
  35. }
  36. mongodbutil.Mgo = mongodbutil.MgoFactory(qu.IntAllDef(Sysconfig["dbsize"], 5), 10, 120, MgoIP, MgoDB)
  37. log.Println(mongodbutil.Mgo.Get().Ping())
  38. ChanB = make(chan bool, qu.IntAllDef(Sysconfig["channelsize"], 5))
  39. }
  40. func main() {
  41. log.Println(Sysconfig)
  42. udpclient = mu.UdpClient{Local: Sysconfig["udpip"].(string) + ":" + Sysconfig["udpport"].(string), BufSize: 1024}
  43. udpclient.Listen(processUdpMsg)
  44. log.Printf("Udp listening port: %s:%s\n", Sysconfig["udpip"], Sysconfig["udpport"])
  45. b := make(chan bool, 1)
  46. <-b
  47. }
  48. // "file2text": "192.168.3.207:1234",
  49. func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
  50. defer qu.Catch()
  51. switch act {
  52. case mu.OP_TYPE_DATA:
  53. var mapInfo map[string]interface{}
  54. err := json.Unmarshal(data, &mapInfo)
  55. if err != nil {
  56. log.Println("json err :", err, string(data))
  57. return
  58. }
  59. log.Println("updocr接收数据:",mapInfo)
  60. stime :=time.Now()
  61. gid := strings.TrimSpace(mapInfo["gtid"].(string))
  62. rgid := gid
  63. lid := strings.TrimSpace(mapInfo["lteid"].(string))
  64. //err = udpclient.WriteUdp([]byte("updocr接收数据成功"), mu.OP_TYPE_DATA, &net.UDPAddr{
  65. // IP: net.ParseIP(Sysconfig["toudpip"].(string)),
  66. // Port: qu.IntAll(Sysconfig["toudpport"]),
  67. //})
  68. ////forfunc(lid)
  69. //log.Println("接收数据成功,发送到:",Sysconfig["toudpip"].(string),Sysconfig["toudpport"],err)
  70. if bson.IsObjectIdHex(gid) && bson.IsObjectIdHex(lid) {
  71. var jsq int64
  72. query := bson.M{"_id": bson.M{"$gt": bson.ObjectIdHex(gid),"$lte": bson.ObjectIdHex(lid),}}
  73. log.Println("query---:", query)
  74. sum :=mongodbutil.Mgo.Count(MgoC,query)
  75. log.Println("sum:", sum)
  76. pageNum := (sum + PageSize - 1) / PageSize
  77. limit := PageSize
  78. if sum < PageSize {
  79. limit = sum
  80. }
  81. for i := 0; i < pageNum; i++ {
  82. query = bson.M{"_id": bson.M{"$gt": bson.ObjectIdHex(gid), "$lte": bson.ObjectIdHex(lid)}}
  83. log.Println("page=", i+1,"query=", query,limit)
  84. list, b := mongodbutil.Mgo.Find(MgoC,query,nil,bson.M{"_id": 1,MgoFileFiled:1},false,0, limit)
  85. if !b{
  86. log.Println("查询失败")
  87. continue
  88. }
  89. for _,v:=range *list {
  90. gid = qu.BsonIdToSId(v["_id"])
  91. jsq++
  92. updateNum :=0
  93. qmap := qu.ObjToMap(v)
  94. mid := (*qmap)["_id"]
  95. if v, ok := (*qmap)[MgoFileFiled].(map[string]interface{}); !ok {
  96. //log.Println(mid, "mgo 没有字段", MgoFileFiled)
  97. continue
  98. } else {
  99. switch v["attachments"].(type) {
  100. case map[string]interface{}:
  101. att := v["attachments"].(map[string]interface{})
  102. for attk, vaatt := range att {
  103. if fileinfo, ok := vaatt.(map[string]interface{}); !ok {
  104. //log.Println(mid, "mgo 结构体转换失败", vaatt)
  105. continue
  106. } else {
  107. ChanB <- true
  108. if qu.ObjToString(fileinfo["fid"]) ==""{
  109. <-ChanB
  110. //log.Println(mid, "mgo ", MgoFileFiled,"没有fid ")
  111. continue
  112. }
  113. //if (strings.Contains(qu.ObjToString(fileinfo["url"]),"fs.qmx.top")|| strings.Contains(qu.ObjToString(fileinfo["url"]),"fj1.jianyu360.com"))&& (strings.TrimSpace(qu.ObjToString(fileinfo["content"]))==""||strings.Contains(qu.ObjToString(fileinfo["content"]),"error") ){
  114. // save(mid,attk, qmap, &fileinfo,&updateNum)
  115. // <-ChanB
  116. //}else {
  117. // <-ChanB
  118. //}
  119. //if qu.ObjToString(fileinfo["update"]) ==""{
  120. // <-ChanB
  121. // log.Println(mid, "mgo ", MgoFileFiled,"没有update ")
  122. // continue
  123. //}
  124. save(mid,attk, qmap, &fileinfo,&updateNum)
  125. <-ChanB
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. //发送udp信号
  133. by, _ := json.Marshal(map[string]interface{}{
  134. "gtid": rgid,
  135. "lteid": lid,
  136. "stype": "fujian",
  137. })
  138. err := udpclient.WriteUdp(by, mu.OP_TYPE_DATA, &net.UDPAddr{
  139. IP: net.ParseIP(Sysconfig["toudpip"].(string)),
  140. Port: qu.IntAll(Sysconfig["toudpport"]),
  141. })
  142. //识别完以后再次查询数据库,进行下一轮识别
  143. log.Println("处理查询数据结束...",jsq,time.Now().Sub(stime))
  144. SendMail(rgid+"--->"+lid+"处理完成")
  145. //进行下一轮识别
  146. forfunc(lid)
  147. log.Println("发送到:",Sysconfig["toudpip"].(string),Sysconfig["toudpport"],err)
  148. } else {
  149. log.Println("开始id或结束id参数错误:", string(data))
  150. }
  151. case mu.OP_NOOP: //下个节点回应
  152. log.Println("接收成功", string(data))
  153. }
  154. }
  155. func save(mid interface{},attk string, qmap, fileinfo *map[string]interface{},updatenum *int) {
  156. defer qu.Catch()
  157. type FileData struct {
  158. ObjId string //Id
  159. OrgUrl string //源下载地址
  160. Fid string
  161. Name string
  162. Type string //文件类型png、jpg、tif、swf(ocr识别);pdf,doc,docx,xls
  163. Content string //识别内容
  164. }
  165. client, err := rpc.DialHTTP("tcp", qu.ObjToString(Sysconfig["file2text"]))
  166. if err != nil {
  167. log.Println(mid, "rpc err :", err)
  168. return
  169. }
  170. defer client.Close()
  171. var reply []byte
  172. //bs, _ := ioutil.ReadFile("1.docx")
  173. var fffpath string
  174. fffpath = path.Ext(qu.ObjToString((*fileinfo)["filename"]))
  175. if strings.TrimSpace(fffpath) == ""{
  176. fffpath = qu.ObjToString((*fileinfo)["ftype"])
  177. }else {
  178. fffpath = fffpath[1:]
  179. }
  180. fileData := &FileData{
  181. ObjId:mid.(bson.ObjectId).String(),
  182. OrgUrl: qu.ObjToString((*fileinfo)["url"]),
  183. Name: qu.ObjToString((*fileinfo)["filename"]),
  184. Fid: qu.ObjToString((*fileinfo)["fid"]), //附件id
  185. Type: fffpath,
  186. }
  187. //log.Println(mid, fileData)
  188. err = client.Call("FileToText.FileToContext", fileData, &reply)
  189. if err != nil {
  190. log.Println(mid, "call ocr error:", err)
  191. return
  192. }
  193. //fileinfo["ftype"] = "doc"
  194. //reply = []byte("jdsfkldasjflkj")
  195. //fileinfo["ftype"] = "zip"
  196. //testfiles := []map[string]interface {
  197. //}{
  198. // {"Name": "test4.doc", "Content": "test4context", "Type": "doc", "Size": "40M"},
  199. // {"Name": "test5.pdf", "Content": "test5context", "Type": "pdf", "Size": "50M"},
  200. // {"Name": "test6.xlsx", "Content": "test6context", "Type": "xlsx", "Size": "60M"},
  201. //}
  202. //reply, _ = json.Marshal(testfiles)
  203. if len(reply) == 0{
  204. log.Println(mid, "rpc返回数据为空:",qu.ObjToString((*fileinfo)["fid"]), string(reply))
  205. return
  206. }
  207. //log.Println(mid, string(reply))
  208. rdata := make(map[string]interface{})
  209. if err := json.Unmarshal(reply, &rdata); err != nil {
  210. log.Println(mid, "rpc返回数据解析失败:",qu.ObjToString((*fileinfo)["fid"]), err)
  211. return
  212. }
  213. if rdata["err"] == nil || rdata["err"] == "null" || rdata["err"] == "" {
  214. if qu.ObjToString((*fileinfo)["ftype"]) == "rar" || qu.ObjToString((*fileinfo)["ftype"]) == "zip" {
  215. (*fileinfo)["content"] = rdata["contextc"]
  216. } else {
  217. (*fileinfo)["content"] = rdata["context"]
  218. }
  219. (*fileinfo)["expend"] = rdata["expend"]
  220. delete(*fileinfo,"update")
  221. //log.Println((*fileinfo))
  222. (*qmap)[MgoFileFiled].(map[string]interface{})["attachments"].(map[string]interface{})[attk]=*fileinfo
  223. //asdf := (*qmap)[MgoFileFiled].(map[string]interface{})
  224. //qwer := asdf["attachments"].(map[string]interface{})
  225. //qwer[attk] =*fileinfo
  226. //log.Println((*qmap)[MgoFileFiled])
  227. updateBool := mongodbutil.Mgo.UpdateById(MgoC, mid, bson.M{
  228. "$set": bson.M{
  229. MgoFileFiled: (*qmap)[MgoFileFiled],
  230. },
  231. })
  232. if updateBool{
  233. *updatenum++
  234. mongodbutil.Mgo.UpdateById(MgoC, mid, bson.M{
  235. "$set": bson.M{
  236. "updatefileNum": &updatenum,
  237. },})
  238. log.Println(mid, "mongo更新数据成功")
  239. }else {
  240. log.Println(mid, "mongo更新数据失败",qu.ObjToString((*fileinfo)["fid"]))
  241. }
  242. nowHour := time.Now().Hour()
  243. rdlock.Lock()
  244. if nowHour != hourNum{
  245. log.Println("send email:",SendMail(fmt.Sprint(updateBool,mid)))
  246. hourNum = nowHour
  247. }
  248. rdlock.Unlock()
  249. } else {
  250. log.Println(mid, "调用rpc服务解析异常:",mid,qu.ObjToString((*fileinfo)["fid"]), rdata["err"])
  251. }
  252. }
  253. var hourNum int
  254. var rdlock sync.RWMutex
  255. func SendMail( body string ) error {
  256. //定义邮箱服务器连接信息,如果是阿里邮箱 pass填密码,qq邮箱填授权码
  257. mailConn := map[string]string {
  258. "user": "550838476@qq.com",
  259. "pass": "",
  260. "host": "smtp.qq.com",
  261. "port": "465",
  262. }
  263. port, _ := strconv.Atoi(mailConn["port"]) //转换端口类型为int
  264. m := gomail.NewMessage()
  265. m.SetHeader("From","Get to" + "<" + mailConn["user"] + ">") //这种方式可以添加别名,即“XD Game”, 也可以直接用<code>m.SetHeader("From",mailConn["user"])</code> 读者可以自行实验下效果
  266. m.SetHeader("To", []string{"550838476@qq.com"}...) //发送给多个用户
  267. m.SetHeader("Subject", "MongoId") //设置邮件主题
  268. m.SetBody("text/html","服务器:"+ body) //设置邮件正文
  269. d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"])
  270. err := d.DialAndSend(m)
  271. return err
  272. }
  273. func forfunc(lid string) {
  274. for {
  275. //查询最后一个id
  276. lastObjectId, _ := mongodbutil.Mgo.Find(MgoC,nil,"-_id",bson.M{"_id":1},true,-1,-1)
  277. lastId,ok := (*lastObjectId)[0]["_id"].(bson.ObjectId)
  278. log.Println("lastID:",lastId)
  279. //查询最后一个id出错重新查询
  280. if!ok{//转换失败
  281. log.Println("查询异常",*lastObjectId)
  282. time.Sleep(time.Minute)
  283. continue
  284. }
  285. //查询最后一个id等于上一轮的id就重新查询
  286. if lastId.Hex() == lid {
  287. log.Println("没有新数据",lastId.Hex())
  288. SendMail(time.Now().String()+"没有最新数据,当前最后一条数据id:"+lastId.Hex())
  289. time.Sleep(time.Hour)
  290. continue
  291. }
  292. //不相等说明有新数据,进行下次处理
  293. m := map[string]string{
  294. "gtid":lid,//上一轮结束的最后id
  295. "lteid":lastId.Hex(),//新一轮查询出来的id
  296. }
  297. bytes, _ := json.Marshal(m)
  298. //发送udp
  299. err := udpclient.WriteUdp(bytes,mu.OP_TYPE_DATA,&net.UDPAddr{
  300. IP: net.ParseIP( util.ObjToString(Sysconfig["udpip"])),
  301. Port: util.IntAll(Sysconfig["udpport"]),
  302. })
  303. if err != nil{
  304. log.Println("发送udp失败",err,string(bytes))
  305. time.Sleep(time.Minute)
  306. continue
  307. }
  308. SendMail(time.Now().String()+fmt.Sprint("发送udp成功,gtid:",lid,",lteid:",lastId.Hex()))
  309. log.Println("发送udp成功,gtid:",lid,",lteid:",lastId.Hex())
  310. break//发送完后终止循环
  311. }
  312. }