Пример #1
0
func (c *Controller) NewPhoto() (string, error) {

	c.r.ParseForm()

	userId := int64(utils.StrToFloat64(c.r.FormValue("user_id")))

	data, err := c.OneRow("SELECT photo_block_id, photo_max_miner_id, miners_keepers FROM miners_data WHERE user_id = ?", userId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// получим ID майнеров, у которых лежат фото нужного нам юзера
	minersIds := utils.GetMinersKeepers(data["photo_block_id"], data["photo_max_miner_id"], data["miners_keepers"], true)

	// берем 1 случайный из 10-и ID майнеров
	k := utils.RandInt(0, len(minersIds))
	minerId := minersIds[k]
	host, err := c.Single("SELECT http_host FROM miners_data WHERE miner_id  =  ?", minerId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	result, err := json.Marshal(map[string]string{"face": host + "public/face_" + utils.Int64ToStr(userId) + ".jpg", "profile": host + "public/profile_" + utils.Int64ToStr(userId) + ".jpg"})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return string(result), nil
}
Пример #2
0
func Connector(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	if _, err := os.Stat(*utils.Dir + "/nodes.inc"); os.IsNotExist(err) {
		data, err := static.Asset("static/nodes.inc")
		if err != nil {
			log.Error("%v", err)
		}
		err = ioutil.WriteFile(*utils.Dir+"/nodes.inc", []byte(data), 0644)
		if err != nil {
			log.Error("%v", err)
		}
	}

	GoroutineName := "Connector"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 600
	} else {
		d.sleepTime = 30
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

	// соединения для чата иногда отваливаются, поэтому в цикле мониторим состояние
	go func() {
		for {
			if myUserIdForChat == 0 {
				utils.Sleep(1)
				continue
			}
			if len(utils.ChatOutConnections) < 5 || len(utils.ChatInConnections) < 5 {
				go d.chatConnector()
			}
			utils.Sleep(30)
		}
	}()

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		nodeConfig, err := d.GetNodeConfig()
		if len(nodeConfig["local_gate_ip"]) > 0 {
			utils.Sleep(2)
			continue
		}

		var delMiners []string
		var hosts []map[string]string
		var nodeCount int64
		idArray := make(map[int]int64)
		nodesInc := make(map[string]string)

		// ровно стольким нодам мы будем слать хэши блоков и тр-ий
		var maxHosts = consts.OUT_CONNECTIONS
		if utils.StrToInt64(nodeConfig["out_connections"]) > 0 {
			maxHosts = utils.StrToInt(nodeConfig["out_connections"])
		}
		log.Info("%v", maxHosts)

		collective, err := d.GetCommunityUsers()
		if err != nil {
			log.Error("%v", err)
			return
		}
		if len(collective) == 0 {
			myUserId, err := d.GetMyUserId("")
			if err != nil {
				log.Error("%v", err)
				return
			}
			collective = append(collective, myUserId)
			myUserIdForChat = myUserId
		} else {
			myUserIdForChat, err = d.Single(`SELECT pool_admin_user_id FROM config`).Int64()
			if err != nil {
				log.Error("%v", err)
				return
			}
		}

		// в сингл-моде будет только $my_miners_ids[0]
		myMinersIds, err := d.GetMyMinersIds(collective)
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue
		}
		log.Info("%v", myMinersIds)
		nodesBan, err := d.GetMap(`
				SELECT tcp_host, ban_start
				FROM nodes_ban
				LEFT JOIN miners_data ON miners_data.user_id = nodes_ban.user_id
				`, "tcp_host", "ban_start")
		log.Info("%v", nodesBan)
		nodesConnections, err := d.GetAll(`
				SELECT nodes_connection.host,
							 nodes_connection.user_id,
							 ban_start,
							 miner_id
				FROM nodes_connection
				LEFT JOIN nodes_ban ON nodes_ban.user_id = nodes_connection.user_id
				LEFT JOIN miners_data ON miners_data.user_id = nodes_connection.user_id
				`, -1)
		//fmt.Println("nodesConnections", nodesConnections)
		log.Debug("nodesConnections: %v", nodesConnections)
		for _, data := range nodesConnections {

			// проверим, не нужно нам выйти, т.к. обновилась версия софта
			if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
				break BEGIN
			}

			/*// проверим соотвествие хоста и user_id
			ok, err := d.Single("SELECT user_id FROM miners_data WHERE user_id  = ? AND tcp_host  =  ?", data["user_id"], data["host"]).Int64()
			if err != nil {
				utils.Sleep(1)
				continue BEGIN
			}
			if ok == 0 {
				err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ? OR user_id = ?", data["host"], data["user_id"])
				if err != nil {
					utils.Sleep(1)
					continue BEGIN
				}
			}*/

			// если нода забанена недавно
			if utils.StrToInt64(data["ban_start"]) > utils.Time()-consts.NODE_BAN_TIME {
				delMiners = append(delMiners, data["miner_id"])
				err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ? OR user_id = ?", data["host"], data["user_id"])
				if err != nil {
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				continue
			}

			hosts = append(hosts, map[string]string{"host": data["host"], "user_id": data["user_id"]})
			nodesInc[data["host"]] = data["user_id"]
			nodeCount++
		}

		log.Debug("hosts: %v", hosts)
		/*
			ch := make(chan *answerType)
			for _, host := range hosts {
				userId := utils.StrToInt64(host["user_id"])
				go func(userId int64, host string) {
					ch_ := make(chan *answerType, 1)
					go func() {
						log.Debug("host: %v / userId: %v", host, userId)
						ch_ <- check(host, userId)
					}()
					select {
					case reachable := <-ch_:
						ch <- reachable
					case <-time.After(consts.WAIT_CONFIRMED_NODES * time.Second):
						ch <- &answerType{userId: userId, answer: 0}
					}
				}(userId, host["host"])
			}

			log.Debug("%v", "hosts", hosts)

			var newHosts []map[string]string
			var countOk int
			// если нода не отвечает, то удалем её из таблы nodes_connection
			for i := 0; i < len(hosts); i++ {
				result := <-ch
				if result.answer == 0 {
					log.Info("delete %v", result.userId)
					err = d.ExecSql("DELETE FROM nodes_connection WHERE user_id = ?", result.userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
					}
					for _, data := range hosts {
						if utils.StrToInt64(data["user_id"]) != result.userId {
							newHosts = append(newHosts, data)
						}
					}
				} else {
					countOk++
				}
				log.Info("answer: %v", result)
			}
		*/
		var countOk int
		hosts = checkHosts(hosts, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		// добьем недостающие хосты до $max_hosts
		var newHostsForCheck []map[string]string
		if len(hosts) < maxHosts {
			need := maxHosts - len(hosts)
			max, err := d.Single("SELECT max(miner_id) FROM miners").Int()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			i0 := 0
			for {
				rand := 1
				if max > 1 {
					rand = utils.RandInt(1, max+1)
				}
				idArray[rand] = 1
				i0++
				if i0 > 30 || len(idArray) >= need || len(idArray) >= max {
					break
				}
			}
			log.Info("%v", "idArray", idArray)
			// удалим себя
			for _, id := range myMinersIds {
				delete(idArray, int(id))
			}
			// Удалим забаннные хосты
			for _, id := range delMiners {
				delete(idArray, utils.StrToInt(id))
			}
			log.Info("%v", "idArray", idArray)
			ids := ""
			if len(idArray) > 0 {
				for id, _ := range idArray {
					ids += utils.IntToStr(id) + ","
				}
				ids = ids[:len(ids)-1]
				minersHosts, err := d.GetMap(`
						SELECT tcp_host, user_id
						FROM miners_data
						WHERE miner_id IN (`+ids+`)`, "tcp_host", "user_id")
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				for host, userId := range minersHosts {
					if len(nodesBan[host]) > 0 {
						if utils.StrToInt64(nodesBan[host]) > utils.Time()-consts.NODE_BAN_TIME {
							continue
						}
					}
					//hosts = append(hosts, map[string]string{"host": host, "user_id": userId})
					/*err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}
					log.Debug(host)*/
					newHostsForCheck = append(newHostsForCheck, map[string]string{"user_id": userId, "host": host})
					/*err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host, userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}*/
				}
			}
		}

		hosts = checkHosts(newHostsForCheck, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		log.Debug("%v", "hosts", hosts)
		// если хосты не набрались из miner_data, то берем из файла
		if len(hosts) < 10 {
			hostsData_, err := ioutil.ReadFile(*utils.Dir + "/nodes.inc")
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			hostsData := strings.Split(string(hostsData_), "\n")
			log.Debug("%v", "hostsData_", hostsData_)
			log.Debug("%v", "hostsData", hostsData)
			max := 0
			log.Debug("maxHosts: %v", maxHosts)
			if len(hosts) > maxHosts-1 {
				max = maxHosts
			} else {
				max = len(hostsData)
			}
			log.Debug("max: %v", max)
			for i := 0; i < max; i++ {
				r := utils.RandInt(0, max)
				if len(hostsData) <= r {
					continue
				}
				hostUserId := strings.Split(hostsData[r], ";")
				if len(hostUserId) == 1 {
					continue
				}
				host, userId := hostUserId[0], hostUserId[1]
				if utils.InSliceInt64(utils.StrToInt64(userId), collective) {
					continue
				}
				if len(nodesBan[host]) > 0 {
					if utils.StrToInt64(nodesBan[host]) > utils.Time()-consts.NODE_BAN_TIME {
						continue
					}
				}
				/*
					err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}
					log.Debug(host)
					/*err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host, userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}*/
				newHostsForCheck = append(newHostsForCheck, map[string]string{"user_id": userId, "host": host})

				nodesInc[host] = userId

			}
		}

		hosts = checkHosts(newHostsForCheck, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		for _, host := range hosts {
			err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host["host"])
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host["host"], host["user_id"])
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}
		if nodeCount > 5 {
			nodesFile := ""
			for k, v := range nodesInc {
				nodesFile += k + ";" + v + "\n"
			}
			nodesFile = nodesFile[:len(nodesFile)-1]
			err := ioutil.WriteFile(*utils.Dir+"/nodes.inc", []byte(nodesFile), 0644)
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}

		var sleepTime int
		if countOk < 2 {
			sleepTime = 5
		} else {
			sleepTime = d.sleepTime
		}

		if d.dSleep(sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}
Пример #3
0
/*
 * просто шлем всем, кто есть в nodes_connection хэши блока и тр-ий
 * если мы не майнер, то шлем всю тр-ию целиком, блоки слать не можем
 * если майнер - то шлем только хэши, т.к. у нас есть хост, откуда всё можно скачать
 * */
func Disseminator(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "Disseminator"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 300
	} else {
		d.sleepTime = 1
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		var hosts []map[string]string
		var nodeData map[string]string
		nodeConfig, err := d.GetNodeConfig()
		if len(nodeConfig["local_gate_ip"]) == 0 {
			// обычный режим
			hosts, err = d.GetAll(`
					SELECT miners_data.user_id, miners_data.tcp_host as host, node_public_key
					FROM nodes_connection
					LEFT JOIN miners_data ON nodes_connection.user_id = miners_data.user_id
					`, -1)
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue
			}
			if len(hosts) == 0 {
				if d.dSleep(d.sleepTime) {
					break BEGIN
				}
				log.Debug("len(hosts) == 0")
				continue
			}
		} else {
			// защищенный режим
			nodeData, err = d.OneRow("SELECT node_public_key, tcp_host FROM miners_data WHERE user_id  =  ?", nodeConfig["static_node_user_id"]).String()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue
			}
			hosts = append(hosts, map[string]string{"host": nodeConfig["local_gate_ip"], "node_public_key": nodeData["node_public_key"], "user_id": nodeConfig["static_node_user_id"]})
		}

		myUsersIds, err := d.GetMyUsersIds(false, false)
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue
		}
		myMinersIds, err := d.GetMyMinersIds(myUsersIds)
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue
		}
		log.Debug("%v", myUsersIds)
		log.Debug("%v", myMinersIds)

		// если среди тр-ий есть смена нодовского ключа, то слать через отправку хэшей с последющей отдачей данных может не получиться
		// т.к. при некорректном нодовском ключе придет зашифрованый запрос на отдачу данных, а мы его не сможем расшифровать т.к. ключ у нас неверный
		var changeNodeKey int64
		if len(myUsersIds) > 0 {
			changeNodeKey, err = d.Single(`
				SELECT count(*)
				FROM transactions
				WHERE type = ? AND
							 user_id IN (`+strings.Join(utils.SliceInt64ToString(myUsersIds), ",")+`)
				`, utils.TypeInt("ChangeNodeKey")).Int64()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}

		var dataType int64 // это тип для того, чтобы принимающая сторона могла понять, как именно надо обрабатывать присланные данные

		// если я майнер и работаю в обычном режиме, то должен слать хэши
		if len(myMinersIds) > 0 && len(nodeConfig["local_gate_ip"]) == 0 && changeNodeKey == 0 {

			log.Debug("0")

			dataType = 1

			// определим, от кого будем слать
			r := utils.RandInt(0, len(myMinersIds))
			myMinerId := myMinersIds[r]
			myUserId, err := d.Single("SELECT user_id FROM miners_data WHERE miner_id  =  ?", myMinerId).Int64()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			// возьмем хэш текущего блока и номер блока
			// для теста ролбеков отключим на время
			data, err := d.OneRow("SELECT block_id, hash, head_hash FROM info_block WHERE sent  =  0").Bytes()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			err = d.ExecSql("UPDATE info_block SET sent = 1")
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			/*
			 * Составляем данные на отправку
			 * */
			// 5 байт = наш user_id. Но они будут не первые, т.к. m_curl допишет вперед user_id получателя (нужно для пулов)
			toBeSent := utils.DecToBin(myUserId, 5)
			if len(data) > 0 { // блок
				// если 5-й байт = 0, то на приемнике будем читать блок, если = 1 , то сразу хэши тр-ий
				toBeSent = append(toBeSent, utils.DecToBin(0, 1)...)
				toBeSent = append(toBeSent, utils.DecToBin(utils.BytesToInt64(data["block_id"]), 3)...)
				toBeSent = append(toBeSent, data["hash"]...)
				toBeSent = append(toBeSent, data["head_hash"]...)
				err = d.ExecSql("UPDATE info_block SET sent = 1")
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
			} else { // тр-ии без блока
				toBeSent = append(toBeSent, utils.DecToBin(1, 1)...)
			}

			// возьмем хэши тр-ий
			//utils.WriteSelectiveLog("SELECT hash, high_rate FROM transactions WHERE sent = 0 AND for_self_use = 0")
			transactions, err := d.GetAll("SELECT hash, high_rate FROM transactions WHERE sent = 0 AND for_self_use = 0", -1)
			if err != nil {
				utils.WriteSelectiveLog(err)
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			// нет ни транзакций, ни блока для отправки...
			if len(transactions) == 0 && len(toBeSent) < 10 {
				//utils.WriteSelectiveLog("len(transactions) == 0")
				//log.Debug("len(transactions) == 0")
				if d.dSleep(d.sleepTime) {
					break BEGIN
				}
				log.Debug("len(transactions) == 0 && len(toBeSent) == 0")
				continue BEGIN
			}
			for _, data := range transactions {
				hexHash := utils.BinToHex([]byte(data["hash"]))
				toBeSent = append(toBeSent, utils.DecToBin(utils.StrToInt64(data["high_rate"]), 1)...)
				toBeSent = append(toBeSent, []byte(data["hash"])...)
				utils.WriteSelectiveLog("UPDATE transactions SET sent = 1 WHERE hex(hash) = " + string(hexHash))
				affect, err := d.ExecSqlGetAffect("UPDATE transactions SET sent = 1 WHERE hex(hash) = ?", hexHash)
				if err != nil {
					utils.WriteSelectiveLog(err)
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect))
			}

			// отправляем блок и хэши тр-ий, если есть что отправлять
			if len(toBeSent) > 0 {
				for _, host := range hosts {
					go d.DisseminatorType1(host["host"], utils.StrToInt64(host["user_id"]), host["node_public_key"], toBeSent, dataType)
				}
			}
		} else {

			log.Debug("1")

			var remoteNodeHost string
			// если просто юзер или работаю в защищенном режиме, то шлю тр-ии целиком. слать блоки не имею права.
			if len(nodeConfig["local_gate_ip"]) > 0 {
				dataType = 3
				remoteNodeHost = nodeData["host"]
			} else {
				dataType = 2
				remoteNodeHost = ""
			}

			log.Debug("dataType: %d", dataType)

			var toBeSent []byte // сюда пишем все тр-ии, которые будем слать другим нодам
			// возьмем хэши и сами тр-ии
			utils.WriteSelectiveLog("SELECT hash, data FROM transactions WHERE sent  =  0")
			rows, err := d.Query("SELECT hash, data FROM transactions WHERE sent  =  0")
			if err != nil {
				utils.WriteSelectiveLog(err)
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			for rows.Next() {
				var hash, data []byte
				err = rows.Scan(&hash, &data)
				if err != nil {
					rows.Close()
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				log.Debug("hash %x", hash)
				hashHex := utils.BinToHex(hash)
				utils.WriteSelectiveLog("UPDATE transactions SET sent = 1 WHERE hex(hash) = " + string(hashHex))
				affect, err := d.ExecSqlGetAffect("UPDATE transactions SET sent = 1 WHERE hex(hash) = ?", hashHex)
				if err != nil {
					utils.WriteSelectiveLog(err)
					rows.Close()
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect))
				toBeSent = append(toBeSent, data...)
			}
			rows.Close()

			// шлем тр-ии
			if len(toBeSent) > 0 {
				for _, host := range hosts {

					userId := utils.StrToInt64(host["user_id"])
					go func(host string, userId int64, node_public_key string) {

						log.Debug("host %v / userId %v", host, userId)

						conn, err := utils.TcpConn(host)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						defer conn.Close()

						randTestblockHash, err := d.Single("SELECT head_hash FROM queue_testblock").String()
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						// получаем IV + ключ + зашифрованный текст
						encryptedData, _, _, err := utils.EncryptData(toBeSent, []byte(node_public_key), randTestblockHash)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}

						// вначале шлем тип данных, чтобы принимающая сторона могла понять, как именно надо обрабатывать присланные данные
						_, err = conn.Write(utils.DecToBin(dataType, 1))
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}

						// т.к. на приеме может быть пул, то нужно дописать в начало user_id, чьим нодовским ключем шифруем
						/*_, err = conn.Write(utils.DecToBin(userId, 5))
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}*/
						encryptedData = append(utils.DecToBin(userId, 5), encryptedData...)

						// это может быть защищенное локальное соедниение (dataType = 3) и принимающему ноду нужно знать, куда дальше слать данные и чьим они зашифрованы ключем
						if len(remoteNodeHost) > 0 {
							/*
								_, err = conn.Write([]byte(remoteNodeHost))
								if err != nil {
									log.Error("%v", utils.ErrInfo(err))
									return
								}*/
							encryptedData = append([]byte(remoteNodeHost), encryptedData...)
						}

						log.Debug("encryptedData %x", encryptedData)

						// в 4-х байтах пишем размер данных, которые пошлем далее
						size := utils.DecToBin(len(encryptedData), 4)
						_, err = conn.Write(size)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						// далее шлем сами данные
						_, err = conn.Write(encryptedData)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}

					}(host["host"], userId, host["node_public_key"])
				}
			}
		}

		d.dbUnlock()

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}
Пример #4
0
func makeTemplate(html, name string, tData interface{}) (string, error) {

	defer func() {
		if r := recover(); r != nil {
			log.Error("makeTemplate Recovered", r)
			fmt.Println(r)
		}
	}()

	data, err := static.Asset("static/templates/" + html + ".html")
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	signatures, err := static.Asset("static/templates/signatures.html")
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	alert_success, err := static.Asset("static/templates/alert_success.html")
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	funcMap := template.FuncMap{
		"makeCurrencyName": func(currencyId int64) string {
			if currencyId >= 1000 {
				return ""
			} else {
				return "d"
			}
		},
		"div": func(a, b interface{}) float64 {
			return utils.InterfaceToFloat64(a) / utils.InterfaceToFloat64(b)
		},
		"mult": func(a, b interface{}) float64 {
			return utils.InterfaceToFloat64(a) * utils.InterfaceToFloat64(b)
		},
		"round": func(a interface{}, num int) float64 {
			return utils.Round(utils.InterfaceToFloat64(a), num)
		},
		"len": func(s []map[string]string) int {
			return len(s)
		},
		"lenMap": func(s map[string]string) int {
			return len(s)
		},
		"sum": func(a, b interface{}) float64 {
			return utils.InterfaceToFloat64(a) + utils.InterfaceToFloat64(b)
		},
		"minus": func(a, b interface{}) float64 {
			return utils.InterfaceToFloat64(a) - utils.InterfaceToFloat64(b)
		},
		"noescape": func(s string) template.HTML {
			return template.HTML(s)
		},
		"js": func(s string) template.JS {
			return template.JS(s)
		},
		"join": func(s []string, sep string) string {
			return strings.Join(s, sep)
		},
		"strToInt64": func(text string) int64 {
			return utils.StrToInt64(text)
		},
		"strToInt": func(text string) int {
			return utils.StrToInt(text)
		},
		"bin2hex": func(text string) string {
			return string(utils.BinToHex([]byte(text)))
		},
		"int64ToStr": func(text int64) string {
			return utils.Int64ToStr(text)
		},
		"rand": func() int {
			return utils.RandInt(0, 99999999)
		},
		"append": func(args ...interface{}) string {
			var result string
			for _, value := range args {
				switch value.(type) {
				case int64:
					result += utils.Int64ToStr(value.(int64))
				case float64:
					result += utils.Float64ToStr(value.(float64))
				case string:
					result += value.(string)
				}
			}
			return result
		},
		"replaceCurrency": func(text, name string) string {
			return strings.Replace(text, "[currency]", name, -1)
		},
		"replaceCurrencyName": func(text, name string) string {
			return strings.Replace(text, "[currency]", "D"+name, -1)
		},
		"cfCategoryLang": func(lang map[string]string, name string) string {
			return lang["cf_category_"+name]
		},
		"progressBarLang": func(lang map[string]string, name string) string {
			return lang["progress_bar_pct_"+name]
		},
		"checkProjectPs": func(ProjectPs map[string]string, id string) bool {
			if len(ProjectPs["ps"+id]) > 0 {
				return true
			} else {
				return false
			}
		},
		"cfPageTypeLang": func(lang map[string]string, name string) string {
			return lang["cf_"+name]
		},
		"notificationsLang": func(lang map[string]string, name string) string {
			return lang["notifications_"+name]
		},
	}
	t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data)))
	t = template.Must(t.Parse(string(alert_success)))
	t = template.Must(t.Parse(string(signatures)))
	b := new(bytes.Buffer)
	err = t.ExecuteTemplate(b, name, tData)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return b.String(), nil
}
Пример #5
0
func (c *Controller) Voting() (string, error) {

	txType := "VotesComplex"
	txTypeId := utils.TypeInt(txType)
	timeNow := utils.Time()

	waitVoting := make(map[int64]string)
	promisedAmountCurrencyList := make(map[int64]map[string]string)

	// голосовать майнер может только после того, как пройдет  miner_newbie_time сек
	regTime, err := c.Single("SELECT reg_time FROM miners_data WHERE user_id  =  ?", c.SessUserId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	minerNewbie := ""
	if regTime > utils.Time()-c.Variables.Int64["miner_newbie_time"] && c.SessUserId != 1 {
		minerNewbie = strings.Replace(c.Lang["hold_time_wait2"], "[sec]", utils.TimeLeft(c.Variables.Int64["miner_newbie_time"]-(utils.Time()-regTime), c.Lang), -1)
	} else {
		// валюты
		rows, err := c.Query(c.FormatQuery(`
				SELECT currency_id,
							  name,
							  full_name,
							  start_time
				FROM promised_amount
					LEFT JOIN currency ON currency.id = promised_amount.currency_id
				WHERE user_id = ? AND
							 status IN ('mining', 'repaid') AND
							 start_time > 0 AND
							 del_block_id = 0
				GROUP BY currency_id
				`), c.SessUserId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		defer rows.Close()
		for rows.Next() {
			var currency_id, start_time int64
			var name, full_name string
			err = rows.Scan(&currency_id, &name, &full_name, &start_time)
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			// после добавления обещанной суммы должно пройти не менее min_hold_time_promise_amount сек, чтобы за неё можно было голосовать
			if start_time > utils.Time()-c.Variables.Int64["min_hold_time_promise_amount"] {
				waitVoting[currency_id] = strings.Replace(c.Lang["hold_time_wait"], "[sec]", utils.TimeLeft(c.Variables.Int64["min_hold_time_promise_amount"]-(utils.Time()-start_time), c.Lang), -1)
				continue
			}
			// если по данной валюте еще не набралось >1000 майнеров, то за неё голосовать нельзя.
			countMiners, err := c.Single(`
					SELECT count(user_id)
					FROM promised_amount
					WHERE start_time < ? AND
								 del_block_id = 0 AND
								 status IN ('mining', 'repaid') AND
								 currency_id = ? AND
								 del_block_id = 0
					GROUP BY  user_id
					`, utils.Time()-c.Variables.Int64["min_hold_time_promise_amount"], currency_id).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			if countMiners < c.Variables.Int64["min_miners_of_voting"] {
				waitVoting[currency_id] = strings.Replace(c.Lang["min_miners_count"], "[miners_count]", utils.Int64ToStr(c.Variables.Int64["min_miners_of_voting"]), -1)
				waitVoting[currency_id] = strings.Replace(waitVoting[currency_id], "[remaining]", utils.Int64ToStr(c.Variables.Int64["min_miners_of_voting"]-countMiners), -1)
				continue
			}
			// голосовать можно не чаще 1 раза в 2 недели
			voteTime, err := c.Single("SELECT time FROM log_time_votes_complex WHERE user_id  =  ? AND time > ?", c.SessUserId, utils.Time()-c.Variables.Int64["limit_votes_complex_period"]).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			if voteTime > 0 {
				waitVoting[currency_id] = strings.Replace(c.Lang["wait_voting"], "[sec]", utils.TimeLeft(c.Variables.Int64["limit_votes_complex_period"]-(utils.Time()-voteTime), c.Lang), -1)
				continue
			}

			// получим наши предыдущие голоса
			votesUserPct, err := c.Single("SELECT pct FROM votes_user_pct WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, currency_id).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}

			votesMinerPct, err := c.Single("SELECT pct FROM votes_miner_pct WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, currency_id).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}

			votesMaxOtherCurrencies, err := c.Single("SELECT count FROM votes_max_other_currencies WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, currency_id).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}

			votesMaxPromisedAmount, err := c.Single("SELECT amount FROM votes_max_promised_amount WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, currency_id).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			promisedAmountCurrencyList[currency_id] = make(map[string]string)
			promisedAmountCurrencyList[currency_id]["votes_user_pct"] = utils.Int64ToStr(votesUserPct)
			promisedAmountCurrencyList[currency_id]["votes_miner_pct"] = utils.Int64ToStr(votesMinerPct)
			promisedAmountCurrencyList[currency_id]["votes_max_other_currencies"] = utils.Int64ToStr(votesMaxOtherCurrencies)
			promisedAmountCurrencyList[currency_id]["votes_max_promised_amount"] = utils.Int64ToStr(votesMaxPromisedAmount)
			promisedAmountCurrencyList[currency_id]["name"] = name
		}
	}

	referral, err := c.OneRow("SELECT first, second, third FROM votes_referral WHERE user_id  =  ?", c.SessUserId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if len(referral) == 0 {
		referral["first"] = int64(utils.RandInt(0, 30))
		referral["second"] = int64(utils.RandInt(0, 30))
		referral["third"] = int64(utils.RandInt(0, 30))
	}

	maxCurrencyId, err := c.Single("SELECT max(id) FROM currency").Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	allMaxPromisedAmount := []int64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, 20000000, 50000000, 100000000, 200000000, 500000000, 1000000000}

	allPct := utils.GetPctArray()
	pctArray := utils.GetPctArray()
	jsPct := "{"
	for year, sec := range pctArray {
		jsPct += fmt.Sprintf(`%v: '%v',`, year, sec)
	}
	jsPct = jsPct[:len(jsPct)-1] + "}"

	lastTx, err := c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"VotesComplex"}), 1, c.TimeFormat)
	lastTxFormatted := ""
	if len(lastTx) > 0 {
		lastTxFormatted, _ = utils.MakeLastTx(lastTx, c.Lang)
	}

	refs := []string{"first", "second", "third"}
	refsNums := []int{0, 5, 10, 15, 20, 25, 30}

	TemplateStr, err := makeTemplate("voting", "voting", &VotingPage{
		Alert:                      c.Alert,
		Lang:                       c.Lang,
		CountSignArr:               c.CountSignArr,
		ShowSignData:               c.ShowSignData,
		UserId:                     c.SessUserId,
		TimeNow:                    timeNow,
		TxType:                     txType,
		TxTypeId:                   txTypeId,
		SignData:                   "",
		PromisedAmountCurrencyList: promisedAmountCurrencyList,
		MaxOtherCurrenciesCount:    []int{0, 1, 2, 3, 4},
		RefsNums:                   refsNums,
		Referral:                   referral,
		MinerNewbie:                minerNewbie,
		MaxCurrencyId:              maxCurrencyId,
		AllMaxPromisedAmount:       allMaxPromisedAmount,
		AllPct:                     allPct,
		LastTxFormatted:            lastTxFormatted,
		WaitVoting:                 waitVoting,
		CurrencyList:               c.CurrencyList,
		JsPct:                      jsPct,
		Refs:                       refs})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
Пример #6
0
func (c *Controller) Assignments() (string, error) {

	var randArr []int64
	// Нельзя завершить голосование юзеров раньше чем через сутки, даже если набрано нужное кол-во голосов.
	// В голосовании нодов ждать сутки не требуется, т.к. там нельзя поставить поддельных нодов

	// Модерация новых майнеров
	// берем тех, кто прошел проверку нодов (type='node_voting')
	num, err := c.Single("SELECT count(id) FROM votes_miners WHERE votes_end  =  0 AND type  =  'user_voting'").Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if num > 0 {
		randArr = append(randArr, 1)
	}

	// Модерация promised_amount
	// вначале получим ID валют, которые мы можем проверять.
	currency, err := c.GetList("SELECT currency_id FROM promised_amount WHERE status IN ('mining', 'repaid') AND user_id = ?", c.SessUserId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	addSql := ""
	currencyIds := strings.Join(currency, ",")
	if len(currencyIds) > 0 || c.SessUserId == 1 {
		if c.SessUserId != 1 {
			addSql = "AND currency_id IN (" + currencyIds + ")"
		}
		num, err := c.Single("SELECT count(id) FROM promised_amount WHERE status  =  'pending' AND del_block_id  =  0 " + addSql + "").Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if num > 0 {
			randArr = append(randArr, 2)
		}
	}

	log.Debug("randArr %v", randArr)

	var AssignType int64
	if len(randArr) > 0 {
		AssignType = randArr[utils.RandInt(0, len(randArr))]
	}

	cloneHosts := make(map[int64][]string)
	var photoHosts []string
	examplePoints := make(map[string]string)
	tplName := "assignments"
	tplTitle := "assignments"

	var txType string
	var txTypeId int64
	var timeNow int64
	var myRace, myCountry, mainQuestion, newPromiseAmount, videoHost string
	var promisedAmountData, userInfo map[string]string

	switch AssignType {
	case 1:

		// ***********************************
		// задания по модерации новых майнеров
		// ***********************************
		txType = "VotesMiner"
		txTypeId = utils.TypeInt(txType)
		timeNow = utils.Time()

		userInfo, err = c.OneRow(`
				SELECT miners_data.user_id,
							 votes_miners.id as vote_id,
							 face_coords,
							 profile_coords,
							 video_type,
							 video_url_id,
							 photo_block_id,
							 photo_max_miner_id,
							 miners_keepers,
							 http_host
				FROM votes_miners
				LEFT JOIN miners_data ON miners_data.user_id = votes_miners.user_id
				LEFT JOIN `+c.MyPrefix+`my_tasks ON `+c.MyPrefix+`my_tasks.id = votes_miners.id
				WHERE 	votes_end = 0 AND
						votes_miners.type = 'user_voting' AND
						(`+c.MyPrefix+`my_tasks.time IS NULL OR (`+c.MyPrefix+`my_tasks.time < ? AND `+c.MyPrefix+`my_tasks.type  =  'miner'))
				`, utils.Time()-consts.ASSIGN_TIME).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if len(userInfo) == 0 {
			tplName = "assignments"
			break
		}

		examplePoints, err = c.GetPoints(c.Lang)
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// получим ID майнеров, у которых лежат фото нужного нам юзера
		minersIds := utils.GetMinersKeepers(userInfo["photo_block_id"], userInfo["photo_max_miner_id"], userInfo["miners_keepers"], true)
		if len(minersIds) > 0 {
			photoHosts, err = c.GetList("SELECT http_host FROM miners_data WHERE miner_id  IN (" + utils.JoinInts(minersIds, ",") + ")").String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}

		// отрезки майнера, которого проверяем
		relations, err := c.OneRow("SELECT * FROM faces WHERE user_id  =  ?", userInfo["user_id"]).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// получим допустимые расхождения между точками и совместимость версий
		data_, err := c.OneRow("SELECT tolerances, compatibility FROM spots_compatibility").String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		tolerances := make(map[string]map[string]string)
		if err := json.Unmarshal([]byte(data_["tolerances"]), &tolerances); err != nil {
			return "", utils.ErrInfo(err)
		}
		var compatibility []int
		if err := json.Unmarshal([]byte(data_["compatibility"]), &compatibility); err != nil {
			return "", utils.ErrInfo(err)
		}

		// формируем кусок SQL-запроса для соотношений отрезков
		addSqlTolerances := ""
		typesArr := []string{"face", "profile"}
		for i := 0; i < len(typesArr); i++ {
			for j := 1; j <= len(tolerances[typesArr[i]]); j++ {
				currentRelations := utils.StrToFloat64(relations[typesArr[i][:1]+utils.IntToStr(j)])
				diff := utils.StrToFloat64(tolerances[typesArr[i]][utils.IntToStr(j)]) * currentRelations
				if diff == 0 {
					continue
				}
				min := currentRelations - diff
				max := currentRelations + diff
				addSqlTolerances += typesArr[i][:1] + utils.IntToStr(j) + ">" + utils.Float64ToStr(min) + " AND " + typesArr[i][:1] + utils.IntToStr(j) + " < " + utils.Float64ToStr(max) + " AND "
			}
		}
		addSqlTolerances = addSqlTolerances[:len(addSqlTolerances)-4]

		// формируем кусок SQL-запроса для совместимости версий
		addSqlCompatibility := ""
		for i := 0; i < len(compatibility); i++ {
			addSqlCompatibility += fmt.Sprintf(`%d,`, compatibility[i])
		}
		addSqlCompatibility = addSqlCompatibility[:len(addSqlCompatibility)-1]

		// получаем из БД похожие фото
		rows, err := c.Query(c.FormatQuery(`
				SELECT miners_data.user_id,
							 photo_block_id,
							 photo_max_miner_id,
							 miners_keepers
				FROM faces
				LEFT JOIN miners_data ON
						miners_data.user_id = faces.user_id
				WHERE `+addSqlTolerances+` AND
							version IN (`+addSqlCompatibility+`) AND
				             faces.status = 'used' AND
				             miners_data.user_id != ?
				LIMIT 100
				`), userInfo["user_id"])
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		defer rows.Close()
		for rows.Next() {
			var photo_block_id, photo_max_miner_id, miners_keepers string
			var user_id int64
			err = rows.Scan(&user_id, &photo_block_id, &photo_max_miner_id, &miners_keepers)
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			// майнеры, у которых можно получить фото нужного нам юзера
			minersIds := utils.GetMinersKeepers(photo_block_id, photo_max_miner_id, miners_keepers, true)
			if len(minersIds) > 0 {
				photoHosts, err = c.GetList("SELECT http_host FROM miners_data WHERE miner_id  IN (" + utils.JoinInts(minersIds, ",") + ")").String()
				if err != nil {
					return "", utils.ErrInfo(err)
				}
			}
			cloneHosts[user_id] = photoHosts
		}

		data, err := c.OneRow("SELECT race, country FROM " + c.MyPrefix + "my_table").Int64()
		myRace = c.Races[data["race"]]
		myCountry = consts.Countries[int(data["country"])]

		tplName = "assignments_new_miner"
		tplTitle = "assignmentsNewMiner"

	case 2:
		promisedAmountData, err = c.OneRow(`
				SELECT id,
							 currency_id,
							 amount,
							 user_id,
							 video_type,
							 video_url_id
				FROM promised_amount
				WHERE status =  'pending' AND
							 del_block_id = 0
				` + addSql + `
		`).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		promisedAmountData["currency_name"] = c.CurrencyList[utils.StrToInt64(promisedAmountData["currency_id"])]

		// проверим, не голосовали ли мы за это в последние 30 минут
		repeated, err := c.Single("SELECT id FROM "+c.MyPrefix+"my_tasks WHERE type  =  'promised_amount' AND id  =  ? AND time > ?", promisedAmountData["id"], utils.Time()-consts.ASSIGN_TIME).Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if repeated > 0 {
			tplName = "assignments"
			tplTitle = "assignments"
			break
		}

		// если нету видео на ютубе, то получаем host юзера, где брать видео
		if promisedAmountData["video_url_id"] == "null" {
			videoHost, err = c.Single("SELECT http_host FROM miners_data WHERE user_id  =  ?", promisedAmountData["user_id"]).String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}

		// каждый раз обязательно проверяем, где находится юзер
		userInfo, err = c.OneRow(`
				SELECT latitude,
							 user_id,
							 longitude,
							 photo_block_id,
							 photo_max_miner_id,
							 miners_keepers,
							 http_host
				FROM miners_data
				WHERE user_id = ?
				`, promisedAmountData["user_id"]).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// получим ID майнеров, у которых лежат фото нужного нам юзера
		minersIds := utils.GetMinersKeepers(userInfo["photo_block_id"], userInfo["photo_max_miner_id"], userInfo["miners_keepers"], true)
		if len(minersIds) > 0 {
			photoHosts, err = c.GetList("SELECT http_host FROM miners_data WHERE miner_id  IN (" + utils.JoinInts(minersIds, ",") + ")").String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}

		txType = "VotesPromisedAmount"
		txTypeId = utils.TypeInt(txType)
		timeNow = utils.Time()

		newPromiseAmount = strings.Replace(c.Lang["new_promise_amount"], "[amount]", promisedAmountData["amount"], -1)
		newPromiseAmount = strings.Replace(newPromiseAmount, "[currency]", promisedAmountData["currency_name"], -1)

		mainQuestion = strings.Replace(c.Lang["main_question"], "[amount]", promisedAmountData["amount"], -1)
		mainQuestion = strings.Replace(mainQuestion, "[currency]", promisedAmountData["currency_name"], -1)

		tplName = "assignments_promised_amount"
		tplTitle = "assignmentsPromisedAmount"

	default:
		tplName = "assignments"
		tplTitle = "assignments"
	}

	TemplateStr, err := makeTemplate(tplName, tplTitle, &AssignmentsPage{
		Alert:              c.Alert,
		Lang:               c.Lang,
		CountSignArr:       c.CountSignArr,
		ShowSignData:       c.ShowSignData,
		UserId:             c.SessUserId,
		TimeNow:            timeNow,
		TxType:             txType,
		TxTypeId:           txTypeId,
		SignData:           "",
		CurrencyList:       c.CurrencyList,
		MainQuestion:       mainQuestion,
		NewPromiseAmount:   newPromiseAmount,
		MyRace:             myRace,
		MyCountry:          myCountry,
		ExamplePoints:      examplePoints,
		VideoHost:          videoHost,
		PhotoHosts:         photoHosts,
		PromisedAmountData: promisedAmountData,
		UserInfo:           userInfo,
		CloneHosts:         cloneHosts})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
Пример #7
0
func (c *Controller) Upgrade3() (string, error) {

	log.Debug("Upgrade3")

	userProfile := *utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg"
	userFace := *utils.Dir + "/public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg"

	if _, err := os.Stat(userProfile); os.IsNotExist(err) {
		userProfile = ""
	} else {
		userProfile = "public/" + utils.Int64ToStr(c.SessUserId) + "_user_profile.jpg?r=" + utils.IntToStr(utils.RandInt(0, 99999))
	}
	if _, err := os.Stat(userFace); os.IsNotExist(err) {
		userFace = ""
	} else {
		userFace = "public/" + utils.Int64ToStr(c.SessUserId) + "_user_face.jpg?r=" + utils.IntToStr(utils.RandInt(0, 99999))
	}

	log.Debug("userProfile: %s", userProfile)
	log.Debug("userFace: %s", userFace)

	// текущий набор точек для шаблонов
	examplePoints, err := c.GetPoints(c.Lang)
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// точки, которые юзер уже отмечал
	data, err := c.OneRow("SELECT face_coords, profile_coords FROM " + c.MyPrefix + "my_table").String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	faceCoords := ""
	profileCoords := ""
	if len(data["face_coords"]) > 0 {
		faceCoords = data["face_coords"]
		profileCoords = data["profile_coords"]
	}

	saveAndGotoStep := strings.Replace(c.Lang["save_and_goto_step"], "[num]", "5", -1)
	upgradeMenu := utils.MakeUpgradeMenu(3)

	TemplateStr, err := makeTemplate("upgrade_3", "upgrade3", &upgrade3Page{
		Alert:           c.Alert,
		Lang:            c.Lang,
		CountSignArr:    c.CountSignArr,
		ShowSignData:    c.ShowSignData,
		SaveAndGotoStep: saveAndGotoStep,
		UpgradeMenu:     upgradeMenu,
		UserId:          c.SessUserId,
		FaceCoords:      faceCoords,
		ProfileCoords:   profileCoords,
		UserProfile:     userProfile,
		UserFace:        userFace,
		ExamplePoints:   examplePoints,
		IOS:             utils.IOS(),
		Mobile:          utils.Mobile()})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}