예제 #1
0
파일: utm.go 프로젝트: Supme/gonder
func Run() {
	l, err := os.OpenFile(models.FromRootDir("log/utm.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		log.Println("error opening utm log file: %v", err)
	}
	defer l.Close()

	multi := io.MultiWriter(l, os.Stdout)

	utmlog = log.New(multi, "", log.Ldate|log.Ltime)

	utm := http.NewServeMux()

	utm.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		mem := new(runtime.MemStats)
		runtime.ReadMemStats(mem)
		w.Write([]byte("Welcome to San Tropez! (Conn: " + strconv.Itoa(models.Db.Stats().OpenConnections) + " Allocate: " + strconv.FormatUint(mem.Alloc, 10) + ")"))
	})

	utm.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		w.Write([]byte("# " + models.Config.Version + "\nUser-agent: *\nDisallow: /data/\nDisallow: /files/\nDisallow: /unsubscribe/\nDisallow: /unsubscribe\nDisallow: /redirect/\nDisallow: /web/\nDisallow: /open/\n"))
	})

	utm.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "image/x-icon")
		ico, _ := base64.StdEncoding.DecodeString("AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAByGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/8q2uP9yGSL/yra4/3IZIv/Ktrj/yra4/3IZIv9yGSL/yra4/8q2uP9yGSL/yra4/3IZIv/Ktrj/chki/3IZIv/Ktrj/chki/+je3/9yGSL/yra4/3IZIv/Ktrj/chki/8q2uP9yGSL/chki/8q2uP9yGSL/yra4/3IZIv9yGSL/yra4/+je3//Ktrj/chki/8q2uP9yGSL/yra4/3IZIv/Ktrj/yra4/3IZIv/Ktrj/yra4/3IZIv9yGSL/chki/+je3/9yGSL/yra4/3IZIv/Ktrj/chki/8q2uP9yGSL/yra4/3IZIv9yGSL/yra4/3IZIv/Ktrj/chki/3IZIv/Ktrj/chki/8q2uP9yGSL/yra4/8q2uP9yGSL/chki/8q2uP/Ktrj/chki/8q2uP/Ktrj/yra4/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/+je3//o3t//6N7f/+je3//o3t//6N7f/+je3/9yGSL/6N7f/+je3//o3t//6N7f/+je3//o3t//chki/3IZIv/o3t//yra4/8q2uP/Ktrj/yra4/8q2uP/Ktrj/chki/8q2uP/Ktrj/yra4/8q2uP/Ktrj/6N7f/3IZIv9yGSL/6N7f/8q2uP9yGSL/chki/3IZIv/Ktrj/6N7f/3IZIv/Ktrj/yra4/3IZIv9yGSL/yra4/+je3/9yGSL/chki/+je3//Ktrj/chki/8q2uP/o3t//6N7f/8q2uP9yGSL/6N7f/+je3/9yGSL/chki/8q2uP/o3t//chki/3IZIv/o3t//yra4/3IZIv/o3t//yra4/8q2uP/Ktrj/chki/8q2uP/Ktrj/chki/3IZIv/Ktrj/6N7f/3IZIv9yGSL/6N7f/+je3/9yGSL/chki/3IZIv9yGSL/chki/3IZIv/Ktrj/yra4/8q2uP/Ktrj/6N7f/+je3/9yGSL/chki/+je3//o3t//6N7f/+je3//o3t//6N7f/+je3/9yGSL/6N7f/+je3//o3t//6N7f/+je3//o3t//chki/3IZIv/Ktrj/yra4/8q2uP/Ktrj/yra4/8q2uP/Ktrj/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/chki/3IZIv9yGSL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")
		w.Write(ico)
	})

	utm.Handle("/files/", http.StripPrefix("/files/", http.FileServer(http.Dir(models.FromRootDir("files/")))))

	utm.HandleFunc("/unsubscribe/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			w.Header().Set("Content-Type", "text/html; charset=utf-8")
			message, data, err := models.DecodeData(strings.Split(r.URL.Path, "/")[2])
			if err != nil {
				utmlog.Println(err)
				http.Error(w, "", http.StatusInternalServerError)
				return
			}
			if data == "mail" {
				if err := message.Unsubscribe(map[string]string{"Unsubscribed": "from header link"}); err != nil {
					utmlog.Println(err)
					http.Error(w, "", http.StatusInternalServerError)
					return
				} else {
					if t, err := template.ParseFiles(message.UnsubscribeTemplateDir() + "/success.html"); err != nil {
						utmlog.Println(err)
						http.Error(w, "", http.StatusInternalServerError)
						return
					} else {
						t.Execute(w, map[string]string{
							"campaignId":  message.CampaignId,
							"recipientId": message.RecipientId,
						})
					}
				}
			}
			if data == "web" {
				if t, err := template.ParseFiles(message.UnsubscribeTemplateDir() + "/accept.html"); err != nil {
					utmlog.Println(err)
					http.Error(w, "", http.StatusInternalServerError)
					return
				} else {
					t.Execute(w, map[string]string{
						"campaignId":  message.CampaignId,
						"recipientId": message.RecipientId,
					})
				}
			}
		}
	})

	utm.HandleFunc("/unsubscribe", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		if r.Method == "POST" {
			var message models.Message
			err := message.New(r.PostFormValue("recipientId"))
			if err != nil {
				utmlog.Println(err)
				http.Error(w, "", http.StatusInternalServerError)
				return
			}
			if message.CampaignId != r.PostFormValue("campaignId") {
				utmlog.Println(err)
				http.Error(w, "Not valid request", http.StatusInternalServerError)
				return
			}
			if t, err := template.ParseFiles(message.UnsubscribeTemplateDir() + "/success.html"); err != nil {
				utmlog.Println(err)
				http.Error(w, "", http.StatusInternalServerError)
				return
			} else {
				var extra = map[string]string{}
				for name, value := range r.PostForm {
					if name != "campaignId" && name != "recipientId" && name != "unsubscribe" {
						extra[name] = strings.Join(value, "|")
					}
				}
				if err := message.Unsubscribe(extra); err != nil {
					utmlog.Println(err)
					http.Error(w, "", http.StatusInternalServerError)
					return
				}
				t.Execute(w, map[string]string{
					"campaignId":  message.CampaignId,
					"recipientId": message.RecipientId,
				})
			}
		}
	})

	utm.HandleFunc("/redirect/", func(w http.ResponseWriter, r *http.Request) {
		message, data, err := models.DecodeData(strings.Split(r.URL.Path, "/")[2])
		if err != nil {
			utmlog.Println(err)
			http.Error(w, "", http.StatusInternalServerError)
			return
		}
		models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, ?)", message.CampaignId, message.RecipientId, data)
		models.Db.Exec("UPDATE `recipient` SET `web_agent`= ? WHERE `id`=? AND `web_agent` IS NULL", models.GetIP(r)+" "+r.UserAgent(), message.RecipientId)
		url := regexp.MustCompile(`\s*?(\[.*?\])\s*?`).Split(data, 2)
		http.Redirect(w, r, strings.TrimSpace(url[len(url)-1]), http.StatusFound)
	})

	utm.HandleFunc("/web/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		message, _, err := models.DecodeData(strings.Split(r.URL.Path, "/")[2])
		if err != nil {
			utmlog.Println(err)
			http.Error(w, "", http.StatusInternalServerError)
			return
		}
		models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, 'web_version')", message.CampaignId, message.RecipientId)
		models.Db.Exec("UPDATE `recipient` SET `web_agent`= ? WHERE `id`=? AND `web_agent` IS NULL", models.GetIP(r)+" "+r.UserAgent(), message.RecipientId)
		data, err := message.RenderMessage()
		if err != nil {
			utmlog.Println(err)
			http.Error(w, "", http.StatusInternalServerError)
			return
		}
		w.Write([]byte(data))
	})

	utm.HandleFunc("/open/", func(w http.ResponseWriter, r *http.Request) {
		message, _, err := models.DecodeData(strings.Split(r.URL.Path, "/")[2])
		if err != nil {
			utmlog.Println(err)
			http.Error(w, "", http.StatusInternalServerError)
			return
		}
		models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, 'open_trace')", message.CampaignId, message.RecipientId)
		models.Db.Exec("UPDATE `recipient` SET `client_agent`= ? WHERE `id`=? AND `client_agent` IS NULL", models.GetIP(r)+" "+r.UserAgent(), message.RecipientId)
		//w.Header().Set("Content-Type", "image/png")
		//png, _ := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUxpcU3H2DoAAAABdFJOUwBA5thmAAAADUlEQVQY02NgGAXIAAABEAAB7JfjegAAAABJRU5ErkJggg==iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUxpcU3H2DoAAAABdFJOUwBA5thmAAAAEklEQVQ4y2NgGAWjYBSMAuwAAAQgAAFWu83mAAAAAElFTkSuQmCC")
		//w.Write(png)
		w.Header().Set("Content-Type", "image/gif")
		gif, _ := base64.StdEncoding.DecodeString("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
		w.Write(gif)
	})

	// Old statistic todo delete later
	utm.HandleFunc("/data/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			var param *oldJson

			data, err := base64.URLEncoding.DecodeString(strings.Split(strings.Split(r.URL.Path, "/")[2], ".")[0])
			if err != nil {
				utmlog.Println(err)
				http.Error(w, "", http.StatusInternalServerError)
				return
			}

			err = json.Unmarshal([]byte(data), &param)
			if err != nil {
				utmlog.Println(err)
				http.Error(w, "", http.StatusInternalServerError)
				return
			}

			userAgent := models.GetIP(r) + " " + r.UserAgent()

			if param.Opened != "" {
				models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, ?)", param.Campaign, param.Recipient, "open_trace")
				models.Db.Exec("UPDATE `recipient` SET `client_agent`= ? WHERE `id`=? AND `client_agent` IS NULL", userAgent, param.Recipient)
				w.Header().Set("Content-Type", "image/gif")
				gif, _ := base64.StdEncoding.DecodeString("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
				w.Write(gif)
			} else if param.Url != "" {
				models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, ?)", param.Campaign, param.Recipient, param.Url)
				models.Db.Exec("UPDATE `recipient` SET `web_agent`= ? WHERE `id`=? AND `web_agent` IS NULL", userAgent, param.Recipient)
				http.Redirect(w, r, param.Url, http.StatusFound)
			} else if param.Webver != "" {
				w.Header().Set("Content-Type", "text/html; charset=utf-8")
				models.Db.Exec("INSERT INTO jumping (campaign_id, recipient_id, url) VALUES (?, ?, ?)", param.Campaign, param.Recipient, "web_version")
				models.Db.Exec("UPDATE `recipient` SET `web_agent`= ? WHERE `id`=? AND `web_agent` IS NULL", userAgent, param.Recipient)
				var m models.Message
				m.New(param.Recipient)
				message, err := m.RenderMessage()
				if err != nil {
					utmlog.Println(err)
					http.Error(w, "", http.StatusInternalServerError)
					return
				}
				w.Write([]byte(message))
			} else if param.Unsubscribe != "" {
				w.Header().Set("Content-Type", "text/html; charset=utf-8")
				var name string
				models.Db.QueryRow("SELECT `group`.`template` FROM `campaign` INNER JOIN `group` ON `campaign`.`group_id`=`group`.`id` WHERE `group`.`template` IS NOT NULL AND `campaign`.`id`=?", param.Campaign).Scan(&name)
				if name == "" {
					name = "default"
				} else {
					if _, err := os.Stat(models.FromRootDir("templates/" + name + "/accept.html")); err != nil {
						name = "default"
					}
					if _, err := os.Stat(models.FromRootDir("templates/" + name + "/success.html")); err != nil {
						name = "default"
					}
				}
				if t, err := template.ParseFiles(models.FromRootDir("templates/" + name + "/accept.html")); err != nil {
					utmlog.Println(err)
					http.Error(w, "", http.StatusInternalServerError)
					return
				} else {
					t.Execute(w, map[string]string{
						"campaignId":  param.Campaign,
						"recipientId": param.Recipient,
					})
				}
			}
		}
	})
	// /Old statistic todo delete later

	utmlog.Println("UTM listening on port " + models.Config.StatPort + "...")
	utmlog.Fatal(http.ListenAndServe(":"+models.Config.StatPort, muxLog(utm)))
}
예제 #2
0
파일: recipient.go 프로젝트: Supme/gonder
// Send mail for recipient this campaign data
func (r recipient) send(c *campaign, iface, host string) string {
	start := time.Now()

	data := new(MailData)
	data.Iface, data.Host = iface, host
	data.From_email = c.from_email
	data.From_name = c.from_name
	data.Attachments = c.attachments
	data.To_email = r.to_email
	data.To_name = r.to_name

	message := new(models.Message)
	message.CampaignId = c.id
	message.RecipientId = r.id
	message.CampaignSubject = c.subject
	message.CampaignTemplate = c.body
	message.RecipientEmail = r.to_email
	message.RecipientName = r.to_name

	var rs string
	m, e := message.RenderMessage()
	if e == nil {
		data.Subject = message.CampaignSubject
		data.Html = m
		var extraHeader bytes.Buffer
		extraHeader.WriteString("List-Unsubscribe: " + message.UnsubscribeMailLink() + "\nPrecedence: bulk\n")
		extraHeader.WriteString("Message-ID: <" + strconv.FormatInt(time.Now().Unix(), 10) + c.id + "." + r.id + "@" + data.Host + ">" + "\n")
		extraHeader.WriteString("X-Postmaster-Msgtype: campaign" + c.id + "\n")
		data.Extra_header = extraHeader.String()

		var res error
		if models.Config.RealSend {
			// Send mail
			res = data.Send()
		} else {
			wait := time.Duration(rand.Int()/10000000000) * time.Nanosecond
			time.Sleep(wait)
			res = errors.New("Test send")
		}

		if res == nil {
			rs = "Ok"
		} else {
			rs = res.Error()
		}
	} else {
		rs = e.Error()
	}

	camplog.Printf("Campaign %s for recipient id %s email %s is %s send time %s", c.id, r.id, data.To_email, rs, time.Since(start))
	return rs
}