//CountLastMonthBoxes reads the clan member list and then updates the boxes for everyone.
func CountLastMonthBoxes(members ClanMemberList) {
	monthAgo := time.Now().AddDate(0, 0, -30).Format("2006-01-02 00:00:00")
	var BoxCount int
	var SinceDateString string
	database, tx := MakeDBConnection()

	//As people come and go we need to mark the people who have left as inactive.
	//Mark all as inactive and then as we get values for each person in the clan
	//we'll mark them active again.

	mytools.Debug(fmt.Sprint("Comparing box count from up to 30 days ago against current box count for ", len(members.Members), " clan members."))
	_, err := database.Exec("UPDATE members SET active = FALSE")
	mytools.CheckError("Update all to false:", err)

	for i := 0; i < len(members.Members); i++ {
		err = database.QueryRow("SELECT MAX(total)-MIN(total), MIN(date) AS boxes FROM historical WHERE userid=? AND date > ?",
			members.Members[i].Account_id, monthAgo).Scan(&BoxCount, &SinceDateString)
		mytools.CheckError("Query Row", err)
		//convert retrieved date to time object
		SinceDate, err := time.Parse("2006-01-02", SinceDateString)
		mytools.CheckError("Parse date from database: ", err)
		mytools.Debug(fmt.Sprint(members.Members[i].Account_name, " made ", BoxCount, " boxes since ", SinceDateString, " which is ", int(time.Now().Sub(SinceDate).Hours()/24), " days."))

		_, err = database.Exec("REPLACE INTO members (userid,name,lastmonthboxcount,lastmonthdays,lastupdate, active) VALUES (?,?,?,?,?,?)",
			members.Members[i].Account_id, members.Members[i].Account_name, BoxCount, int(time.Now().Sub(SinceDate).Hours()/24), SinceDate, true)
		mytools.CheckError("Update Stats", err)
	}
	err = tx.Commit()
	mytools.CheckError("tx.Commit()", err)
	database.Close()
}
//ShowMeAllTheBoxes handler page displays the historical data
func ShowMeAllTheBoxes(rw http.ResponseWriter, r *http.Request) {
	lastMonth := time.Now().AddDate(0, 0, -30).Format("2006-01-02 00:00:00")
	database, tx := boxcheckerbackend.MakeDBConnection()
	var UserID, LastWeek, AllTime, i int
	var Date string

	mytools.Debug("Retrieving Historical Rows")
	rows, err := database.Query("SELECT * FROM historical WHERE date >= ? ORDER BY userid", lastMonth)
	mytools.CheckError("Query Members Table", err)

	fmt.Fprintln(rw, "This is the raw data for all the box calculations, only the last 30 days is shown.")
	fmt.Fprintln(rw, "UserId		Date		\"This week\"	\"All Time\"")
	i = 1

	for rows.Next() {
		err := rows.Scan(&UserID, &Date, &LastWeek, &AllTime)
		mytools.CheckError("scan row results", err)
		fmt.Fprintln(rw, fmt.Sprint(UserID, "	", Date, "	", LastWeek, "	", AllTime))
		i++
	}
	err = rows.Err()
	mytools.CheckError("after last row", err)
	rows.Close()
	err = tx.Commit()
	mytools.CheckError("tx.Commit()", err)
	database.Close()
}
// HandleRoot runs when someone hits / on the website
func HandleRoot(rw http.ResponseWriter, r *http.Request) {
	//mytools.Debug(fmt.Sprint("/ Request from ", r.RemoteAddr, " at ", time.Now()))
	go mytools.Log("Access", fmt.Sprint("/ Request from ", r.RemoteAddr, " at ", time.Now()))
	page, err := template.ParseFiles("index.html")
	mytools.CheckError("Parsing index Template", err)
	err = page.Execute(rw, "")
	mytools.CheckError("executing template", err)
}
//UpcomingBattles is a page handler.
func UpcomingBattles(rw http.ResponseWriter, r *http.Request) {
	go mytools.Log("Access", fmt.Sprint("/UpcomingBattles Request from ", r.RemoteAddr, " at ", time.Now()))
	var Battles AllBattles
	Battles.SHBattles = battlechecker.GetStrongBattleTimes()
	Battles.NumSHBattles = len(Battles.SHBattles.Battles)
	Battles.CWBattles = battlechecker.GetCWBattleTimes()
	Battles.NumCWBattles = len(Battles.CWBattles.Battles)
	page, err := template.ParseFiles("upcomingbattles.html")
	mytools.CheckError("Parsing Template", err)
	err = page.Execute(rw, Battles)
	mytools.CheckError("executing template", err)
}
//MakeDBConnection does what it says and returns the required bits
func MakeDBConnection() (database *sql.DB, tx *sql.Tx) {
	//database connection routine returns pointer to database and transaction and err
	//defines connection string and then attempts to connect to the database
	//user:[email protected](hostname:port)/databasename
	DBInfo := ReadConfig()
	ds := DBInfo.DBUser + ":" + DBInfo.DBPassword + "@tcp(" + DBInfo.DBURL + ")/" + DBInfo.DBName
	database, err := sql.Open("mysql", ds)
	mytools.CheckError("sql.Open", err)
	err = database.Ping()
	mytools.CheckError("Failed the keep connection alive", err)
	tx, err = database.Begin()
	mytools.CheckError("database.Begin()", err)
	return
}
//LastRun returns the number of days since the last run, not sure if this is used
func LastRun() (DaysSinceLastRun int) {
	var LastDateString string
	Today := time.Now()

	database, _ := MakeDBConnection()
	err := database.QueryRow("SELECT MAX(date) FROM historical").Scan(&LastDateString)
	mytools.CheckError("Finding Highest Date ", err)
	LastDate, err := time.Parse("2006-01-02", LastDateString)
	mytools.CheckError("Parsing Date", err)
	mytools.Debug(fmt.Sprint("Comparing dates ", Today, LastDate))

	DaysSinceLastRun = int(Today.Sub(LastDate).Hours() / 24)
	database.Close()
	return
}
//UpdateLastActive update the last active date for each member in the clan.
func UpdateLastActive(members ClanMemberList) {
	database, _ := MakeDBConnection()
	for _, member := range members.Members {

		_, err := database.Exec("UPDATE members SET lastactivedate = ? WHERE userid = ? ",
			playerchecker.GetPlayerData(member.Account_id).LastBattleTime.Format("2006-01-02"), member.Account_id)
		mytools.CheckError("Update Active Date", err)
	}

	database.Close()
}
//TemplateTest is function I used to learn html/templates
func TemplateTest(rw http.ResponseWriter, r *http.Request) {
	header, err := template.ParseFiles("showmetheboxesheader.html")
	mytools.CheckError("Parsing Header", err)
	body, err := template.ParseFiles("showmetheboxesbody.html")
	mytools.CheckError("Parsing body", err)
	footer, err := template.ParseFiles("showmetheboxesfooter.html")
	mytools.CheckError("Parsing footer", err)

	var row TableRow
	row.Position = 1
	row.Name = "Craig"
	row.BoxCount = 1000
	row.Since = "2015-09-29"
	//	row.AboveAverage = "Oh yeah baby"

	header.Execute(rw, "")
	body.Execute(rw, row)
	row.Position = 2
	body.Execute(rw, row)
	footer.Execute(rw, "")
}
//GetBoxes users the member list and updates their boxes
func GetBoxes(members ClanMemberList) {
	today := time.Now().Format("2006-01-02 00:00:00")
	var boxes, boxchecks int

	database, tx := MakeDBConnection()

	mytools.Debug("Retrieving boxes...")

	for i := 0; i < len(members.Members); i++ {
		thisweek, total := getStrongholdStats(members.Members[i].Account_id)
		boxchecks = 0
		//Start data validation checking
	DirtyGoto: // there's likely a better way to do this but, this is easier.
		//WG API is not really reliable and will return 0s for box counts which makes a mess of the data.
		//After we get the data we need to see if the user has a non-zero box count and if so then
		//send a re-request for the data.  Fail after a few tries.
		if total == 0 { //run a query to see if the member had more than 0 previously
			_ = database.QueryRow("SELECT MAX(total) FROM historical WHERE userid=?", members.Members[i].Account_id).Scan(&boxes)
			if boxes != 0 { //now we have a problem ask WG API for the data again.
				mytools.Debug(fmt.Sprintln("Houston we have a Problem. ", members.Members[i].Account_name, " had ", boxes, " before, but WG just told me he had 0. Rechecking"))
				thisweek, total = getStrongholdStats(members.Members[i].Account_id) //query wg api for fresh box count
				boxchecks++
				if boxchecks > 2 { //tried 3 times, give up
					mytools.Debug(fmt.Sprintln("After 3 tries I'm giving up on getting fresh boxes for ", members.Members[i].Account_name))
					continue //continue the i loop
				}
				goto DirtyGoto // re-check the result of the wg api query
			}
		}
		_, err := database.Exec("INSERT INTO historical (userid,thisweek,total,date) SELECT ?, ?, ?, ? FROM dual WHERE NOT EXISTS (SELECT userid, date FROM historical WHERE userid=? AND date=?)",
			members.Members[i].Account_id, thisweek, total, today, members.Members[i].Account_id, today)
		mytools.CheckError("database.Exec()", err)
	}
	//	mytools.Debug("\nDone collecting boxes.")
	err := tx.Commit()
	mytools.CheckError("tx.Commit()", err)
	database.Close()
}
func GetClanMembers() (members ClanMemberList) {
	url := "https://api.worldoftanks.com/wgn/clans/info/?application_id=b4ac9bb7c9cbb189201c95a778827c24&fields=members&clan_id=1000005061"
	var WGResponse WGJSONClanResponse
	//	mytools.Debug("Retrieving Clan Member List...")

	resp, err := http.Get(url)
	mytools.CheckError("Getting Clan Member List from WG API", err)

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	json.Unmarshal([]byte(body), &WGResponse)

	members = WGResponse.Data["1000005061"]
	//	mytools.Debug(fmt.Sprintln("Retrieved ", len(members.Members), " members."))

	return

}
Example #11
0
//ShowMeTheBoxesOld try to use only one template.
func ShowMeTheBoxesOld(rw http.ResponseWriter, r *http.Request) {
	/*
		Query the database Members table and then cycles through the  ordered results
		and prints out some html templates in a table.
	*/
	go mytools.Log("Access", fmt.Sprint("/ShowMeTheBoxesOld Request from ", r.RemoteAddr, " at ", time.Now()))
	database, tx := boxcheckerbackend.MakeDBConnection()
	var i, j, CurrentMemberCount int
	var AverageBoxes float32
	var PageData ShowMePageData

	//var stats ClanStats
	const white = "#FFFFFF"
	const green = "#99FF99"
	const greenDark = "#7ACC7A"
	const brown = "#CC8845"
	const brownDark = "#996633"
	const red = "#FFCCCC"
	const redDark = "#CCA5A5"

	CurrentMemberCount = len(boxcheckerbackend.GetClanMembers().Members)
	TableRows := make([]TableRow, CurrentMemberCount)

	err := database.QueryRow("SELECT AVG(`lastmonthboxcount`) FROM `members`").Scan(&AverageBoxes)
	mytools.CheckError("AverageBoxes", err)
	PageData.Average = int(AverageBoxes)

	page, err := template.ParseFiles("showmetheboxesold.html")
	mytools.CheckError("Parsing template", err)

	//query database for members table
	rows, err := database.Query("SELECT * FROM members WHERE active = ? ORDER BY lastmonthboxcount DESC", true)

	i = 1
	j = 0

	for rows.Next() {
		TableRows[j].Comment = ""
		TableRows[j].Position = i

		err := rows.Scan(&TableRows[j].UserID, &TableRows[j].Name, &TableRows[j].BoxCount, &TableRows[j].Days, &TableRows[j].Since, &TableRows[j].Active, &TableRows[j].LastActiveDate)
		mytools.CheckError("scan row results", err)
		if TableRows[j].Days > 0 { //avoid div by 0
			TableRows[j].AverageBoxesPerDay = int(TableRows[j].BoxCount / TableRows[j].Days)
		} else {
			TableRows[j].AverageBoxesPerDay = 0
		}
		if TableRows[j].BoxCount > int(AverageBoxes) { //green
			if i%2 == 0 {
				TableRows[j].Colour = greenDark
			} else {
				TableRows[j].Colour = green
			}
		} else { //red rows for below AverageBoxes
			if i%2 == 0 {
				TableRows[j].Colour = redDark
			} else {
				TableRows[j].Colour = red
			}
		}
		if TableRows[j].BoxCount == 0 { //Commence shitter logic for the guys with no boxes
			if i%2 == 0 { //row shading
				TableRows[j].Colour = brownDark
			} else {
				TableRows[j].Colour = brown
			}
			TableRows[j].Comment = "No Box Shitter"
			if TableRows[j].Name == "Powderworx" {
				TableRows[j].Comment = "Head Shitter" //Colour commentary
			}
			TableRows[j].LastActiveDate = playerchecker.GetPlayerData(TableRows[j].UserID).LastBattleTime.Format("2006-01-02")
		}
		//'special' handling logics  first place has no life etc.
		if TableRows[j].BoxCount < PageData.Average { //Nestingthese checks removes the need for an if j>0 check
			if TableRows[j-1].BoxCount > PageData.Average {
				TableRows[j].Comment = "So Close!"
				TableRows[j-1].Comment = "Phew!"
			}
		}
		if TableRows[j].BoxCount == PageData.Average {
			TableRows[j].Comment = "Mr. Average"
		}
		i++
		j++
	}
	TableRows[0].Comment = "No life Super Stah!"

	TableRows[9].Comment = "Top Ten Baby!"

	PageData.Rows = TableRows
	mytools.CheckError("Executing Page", page.Execute(rw, PageData))

	//Clean up
	rows.Close()
	err = tx.Commit()
	mytools.CheckError("tx.Commit()", err)
	database.Close()
}
Example #12
0
//ShowMeTheBoxesNew is a page handler does more than it should
func ShowMeTheBoxesNew(rw http.ResponseWriter, r *http.Request) {
	/*
		Query the database Members table and then cycles through the  ordered results
		and prints out some html templates in a table.
	*/

	go mytools.Log("Access", fmt.Sprint("/ShowMeTheBoxes Request from ", r.RemoteAddr, " at ", time.Now()))
	database, tx := boxcheckerbackend.MakeDBConnection()
	var i, j, CurrentMemberCount int
	var AverageBoxes float32
	var PageData ShowMePageData

	//var stats ClanStats

	CurrentMemberCount = len(boxcheckerbackend.GetClanMembers().Members)
	TableRows := make([]TableRow, CurrentMemberCount)

	err := database.QueryRow("SELECT AVG(`lastmonthboxcount`) FROM `members`").Scan(&AverageBoxes)
	mytools.CheckError("AverageBoxes", err)
	PageData.Average = int(AverageBoxes)

	page, err := template.ParseFiles("showmetheboxes.html")
	mytools.CheckError("Parsing template", err)

	//query database for members table
	rows, err := database.Query("SELECT * FROM members WHERE active = ? ORDER BY lastmonthboxcount DESC", true)

	i = 1
	j = 0

	for rows.Next() {
		TableRows[j].Comment = ""
		TableRows[j].Position = i

		err := rows.Scan(&TableRows[j].UserID, &TableRows[j].Name, &TableRows[j].BoxCount, &TableRows[j].Days, &TableRows[j].Since, &TableRows[j].Active, &TableRows[j].LastActiveDate)
		mytools.CheckError("scan row results", err)
		if TableRows[j].Days > 0 { //avoid div by 0
			TableRows[j].AverageBoxesPerDay = int(TableRows[j].BoxCount / TableRows[j].Days)
		} else {
			TableRows[j].AverageBoxesPerDay = 0
		}
		if TableRows[j].BoxCount > 0 {
			TableRows[j].LastActiveDate = ""
		}
		if TableRows[j].BoxCount == 0 { //Commence shitter logic for the guys with no boxes
			TableRows[j].Comment = "No Box Shitter"
			if TableRows[j].Name == "Powderworx" {
				TableRows[j].Comment = "Head Shitter" //Colour commentary
			}
			//TableRows[j].LastActiveDate = playerchecker.GetPlayerData(TableRows[j].UserID).LastBattleTime.Format("2006-01-02")
		}

		/*		if TableRows[j].BoxCount < PageData.Average { //Nesting these checks removes the need for an if j>0 check
				if TableRows[j-1].BoxCount > PageData.Average {
					TableRows[j].Comment = "So Close!" //almost above average
					TableRows[j-1].Comment = "Phew!"   //barely above average
				}
			}*/
		if TableRows[j].Name == "BluesmanRS" {
			TableRows[j].Comment = "Brasil!"
		}
		i++
		j++
	}
	TableRows[0].Comment = "No life Super Stah!"
	TableRows[9].Comment = "Top Ten Baby!"
	//get the rows into the page data struct then execute the page.
	PageData.Rows = TableRows
	ColourCodeRowsAverage(&PageData)

	mytools.CheckError("Executing Page", page.Execute(rw, PageData))

	//Clean up
	rows.Close()
	err = tx.Commit()
	mytools.CheckError("tx.Commit()", err)
	database.Close()

}