func (c *Controller) Statistic() (string, error) { var err error sumWallets := make(map[int64]float64) // получаем кол-во DC на кошельках rows, err := c.Query(` SELECT currency_id, sum(amount) as sum_amount FROM wallets GROUP BY currency_id `) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id int64 var sum_amount float64 err = rows.Scan(¤cy_id, &sum_amount) if err != nil { return "", utils.ErrInfo(err) } sumWallets[currency_id] = sum_amount } // получаем кол-во TDC на обещанных суммах rows, err = c.Query(` SELECT currency_id, sum(tdc_amount) as sum_amount FROM promised_amount GROUP BY currency_id `) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id int64 var sum_amount float64 err = rows.Scan(¤cy_id, &sum_amount) if err != nil { return "", utils.ErrInfo(err) } if sumWallets[currency_id] > 0 { sumWallets[currency_id] += sum_amount } else { sumWallets[currency_id] = sum_amount } } // получаем суммы обещанных сумм sumPromisedAmount, err := c.GetMap(` SELECT currency_id, sum(amount) as sum_amount FROM promised_amount WHERE status = 'mining' AND del_block_id = 0 AND (cash_request_out_time = 0 OR cash_request_out_time > ?) GROUP BY currency_id`, "currency_id", "sum_amount", utils.Time()-c.Variables.Int64["cash_request_time"]) // получаем кол-во майнеров по валютам promisedAmountMiners, err := c.GetMap(` SELECT currency_id, count(user_id) as count FROM ( SELECT currency_id, user_id FROM promised_amount WHERE del_block_id = 0 AND del_mining_block_id = 0 AND status IN ('mining', 'repaid') GROUP BY user_id, currency_id ) as t1 GROUP BY currency_id`, "currency_id", "count") // получаем кол-во анонимных юзеров по валютам walletsUsers, err := c.GetMap(` SELECT currency_id, count(user_id) as count FROM wallets WHERE amount > 0 GROUP BY currency_id`, "currency_id", "count") refPhotos := make(map[int64][]string) // таблица обмена на наличные cashRequests, err := c.GetAll(` SELECT * FROM cash_requests ORDER BY id DESC LIMIT 5`, 5) for i := 0; i < len(cashRequests); i++ { if cashRequests[i]["del_block_id"] != "0" { cashRequests[i]["status"] = "reduction closed" } else if utils.Time()-utils.StrToInt64(cashRequests[i]["time"]) > c.Variables.Int64["cash_request_time"] && cashRequests[i]["status"] != "approved" { cashRequests[i]["status"] = "rejected" } t := time.Unix(utils.StrToInt64(cashRequests[i]["time"]), 0) cashRequests[i]["time"] = t.Format(c.TimeFormat) // ### from_user_id для фоток data, err := c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", cashRequests[i]["from_user_id"]).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) hosts, err := c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } refPhotos[utils.StrToInt64(cashRequests[i]["from_user_id"])] = hosts // ### to_user_id для фоток data, err = c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", cashRequests[i]["to_user_id"]).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) hosts, err = c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } refPhotos[utils.StrToInt64(cashRequests[i]["to_user_id"])] = hosts } var userInfoWallets []utils.DCAmounts var promisedAmountListAccepted []utils.PromisedAmounts var credits map[string]string // поиск инфы о юзере userInfoId := int64(utils.StrToFloat64(c.Parameters["user_info_id"])) if userInfoId > 0 { userInfoWallets, err = c.GetBalances(userInfoId) if err != nil { return "", utils.ErrInfo(err) } // обещанные суммы юзера _, promisedAmountListAccepted, _, err = c.GetPromisedAmounts(userInfoId, c.Variables.Int64["cash_request_time"]) // кредиты credits, err = c.GetMap(` SELECT sum(amount) as amount, currency_id FROM credits WHERE from_user_id = ? AND del_block_id = 0 GROUP BY currency_id`, "amount", "currency_id", userInfoId) } /* * Кол-во юзеров, сменивших ключ * */ countUsers, err := c.Single("SELECT count(user_id) FROM users WHERE log_id > 0").Int64() if err != nil { return "", utils.ErrInfo(err) } /* * %/год * */ currencyPct := make(map[int64]map[string]string) for currencyId, name := range c.CurrencyList { pct, err := c.OneRow("SELECT * FROM pct WHERE currency_id = ? ORDER BY block_id DESC", currencyId).Float64() if err != nil { return "", utils.ErrInfo(err) } currencyPct[currencyId] = make(map[string]string) currencyPct[currencyId]["name"] = name currencyPct[currencyId]["miner"] = utils.Float64ToStr(utils.Round((math.Pow(1+pct["miner"], 120)-1)*100, 6)) currencyPct[currencyId]["user"] = utils.Float64ToStr(utils.Round((math.Pow(1+pct["user"], 120)-1)*100, 6)) } /* * Произошедшие сокращения * */ reduction, err := c.GetAll(` SELECT * FROM reduction ORDER BY time DESC LIMIT 20`, 20) for i := 0; i < len(reduction); i++ { if reduction[i]["type"] != "auto" { reduction[i]["type"] = "voting" } t := time.Unix(utils.StrToInt64(reduction[i]["time"]), 0) reduction[i]["time"] = t.Format(c.TimeFormat) } TemplateStr, err := makeTemplate("statistic", "statistic", &StatisticPage{ Lang: c.Lang, CurrencyList: c.CurrencyListCf, UserInfoId: userInfoId, SumWallets: sumWallets, SumPromisedAmount: sumPromisedAmount, PromisedAmountMiners: promisedAmountMiners, WalletsUsers: walletsUsers, CashRequests: cashRequests, UserInfoWallets: userInfoWallets, Credits: credits, PromisedAmountListAccepted: promisedAmountListAccepted, CountUsers: countUsers, CurrencyPct: currencyPct, Reduction: reduction, RefPhotos: refPhotos, UserId: c.SessUserId}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) NewUser() (string, error) { txType := "NewUser" txTypeId := utils.TypeInt(txType) timeNow := utils.Time() param := utils.ParamType{X: 176, Y: 100, Width: 100, Bg_path: "static/img/k_bg.png"} refPhotos := make(map[int64][]string) myRefsKeys := make(map[int64]map[string]string) if c.SessRestricted == 0 { join := c.MyPrefix + `my_new_users.user_id` if c.ConfigIni["db_type"] == "sqlite" || c.ConfigIni["db_type"] == "postgresql" { join = `"` + c.MyPrefix + `my_new_users".user_id` } rows, err := c.Query(c.FormatQuery(` SELECT users.user_id, private_key, log_id FROM ` + c.MyPrefix + `my_new_users LEFT JOIN users ON users.user_id = ` + join + ` WHERE status = 'approved' `)) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var user_id, log_id int64 var private_key string err = rows.Scan(&user_id, &private_key, &log_id) if err != nil { return "", utils.ErrInfo(err) } // проверим, не сменил ли уже юзер свой ключ StrUserId := utils.Int64ToStr(user_id) if log_id != 0 { myRefsKeys[user_id] = map[string]string{"user_id": StrUserId} } else { myRefsKeys[user_id] = map[string]string{"user_id": StrUserId, "private_key": private_key} md5 := string(utils.Md5(private_key)) kPath := *utils.Dir + "/public/" + md5[0:16] kPathPng := kPath + ".png" kPathTxt := kPath + ".txt" if _, err := os.Stat(kPathPng); os.IsNotExist(err) { privKey := strings.Replace(private_key, "-----BEGIN RSA PRIVATE KEY-----", "", -1) privKey = strings.Replace(privKey, "-----END RSA PRIVATE KEY-----", "", -1) _, err = utils.KeyToImg(privKey, kPathPng, user_id, c.TimeFormat, param) if err != nil { return "", utils.ErrInfo(err) } err := ioutil.WriteFile(kPathTxt, []byte(privKey), 0644) if err != nil { return "", utils.ErrInfo(err) } /*$gd = key_to_img($private_key, $param, $row['user_id']); imagepng($gd, $k_path_png); file_put_contents($k_path_txt, trim($private_key));*/ } } } } refs := make(map[int64]map[int64]float64) // инфа по рефам юзера rows, err := c.Query(c.FormatQuery(` SELECT referral, sum(amount) as amount, currency_id FROM referral_stats WHERE user_id = ? GROUP BY currency_id, referral `), c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var referral, currency_id int64 var amount float64 err = rows.Scan(&referral, &amount, ¤cy_id) if err != nil { return "", utils.ErrInfo(err) } refs[referral] = map[int64]float64{currency_id: amount} } myRefsAmounts := make(map[int64]myRefsType) for refUserId, refData := range refs { data, err := c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", refUserId).String() if err != nil { return "", utils.ErrInfo(err) } // получим ID майнеров, у которых лежат фото нужного нам юзера if len(data) == 0 { continue } minersIds := utils.GetMinersKeepers(data["photo_block_id"], data["photo_max_miner_id"], data["miners_keepers"], true) if len(minersIds) > 0 { hosts, err := c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } myRefsAmounts[refUserId] = myRefsType{Amounts: refData, Hosts: hosts} refPhotos[refUserId] = hosts } } myRefs := make(map[int64]myRefsType) for refUserId, refData := range myRefsAmounts { myRefs[refUserId] = refData } for refUserId, refData := range myRefsKeys { md5 := string(utils.Md5(refData["private_key"])) myRefs[refUserId] = myRefsType{Key: refData["private_key"], KeyUrl: c.NodeConfig["pool_url"] + "public/" + md5[0:16]} } /* * Общая стата по рефам */ globalRefs := make(map[int64]globalRefsType) // берем лидеров по USD rows, err = c.Query(c.FormatQuery(` SELECT user_id, sum(amount) as amount FROM referral_stats WHERE currency_id = 72 GROUP BY user_id ORDER BY amount DESC `)) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var user_id int64 var amount float64 err = rows.Scan(&user_id, &amount) if err != nil { return "", utils.ErrInfo(err) } // вся прибыль с рефов у данного юзера refAmounts, err := c.GetAll(` SELECT ROUND(sum(amount)) as amount, currency_id FROM referral_stats WHERE user_id = ? GROUP BY currency_id `, -1, user_id) if err != nil { return "", utils.ErrInfo(err) } data, err := c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", user_id).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) hosts, err := c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } globalRefs[user_id] = globalRefsType{Amounts: refAmounts, Hosts: hosts} refPhotos[user_id] = hosts } lastTx, err := c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"NewUser"}), 1, c.TimeFormat) lastTxFormatted := "" if len(lastTx) > 0 { lastTxFormatted, _ = utils.MakeLastTx(lastTx, c.Lang) } TemplateStr, err := makeTemplate("new_user", "newUser", &newUserPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, SignData: "", LastTxFormatted: lastTxFormatted, MyRefs: myRefs, GlobalRefs: globalRefs, CurrencyList: c.CurrencyList, RefPhotos: refPhotos, PoolUrl: c.NodeConfig["pool_url"]}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
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 }