import Fluent import Vapor struct StatsController: RouteCollection { func boot(routes: RoutesBuilder) throws { let statsRoute = routes.grouped("cod-tracker","api", "stats") statsRoute.get("allMatches", use: index) statsRoute.get("totalWins", use: totalWins) statsRoute.get("totalLosses", use: totalLosses) statsRoute.get("overall", use: overall) statsRoute.get("march", use: getMarchStats) statsRoute.get("all", use: all) //beaconsRoute.get("overallStats", use: index) //beaconsRoute.post("", use: create) // beaconsRoute.delete(":beaconID", use: delete) } func index(req: Request) throws -> EventLoopFuture<[Match]> { return Match.query(on: req.db).all() } func totalWins(req: Request) throws -> EventLoopFuture { return Match.query(on: req.db) .filter(\.$win == true) .count() } func totalLosses(req: Request) throws -> EventLoopFuture { return Match.query(on: req.db) .filter(\.$win == false) .count() } func getMarchStats(req:Request) throws -> EventLoopFuture { return getStatsByMonth(year: 2020, month: 03, req: req) } func getStatsByMonth(year:Int, month:Int, req: Request) -> EventLoopFuture{ let winCount = Match.query(on: req.db) .filter(\.$date >= getStartOfMonth(month: month, year: year)) .filter(\.$date <= getEndOfMonth(month: month, year: year)) .filter(\.$win == true ) .count() let lossCount = Match.query(on: req.db) .filter(\.$date >= getStartOfMonth(month: month, year: year)) .filter(\.$date <= getEndOfMonth(month: month, year: year)) .filter(\.$win == false ) .count() let combined = winCount.and(lossCount) return combined.map { (winCount, lossCount) -> (Stats) in let ratio:Double = (Double(winCount) / Double(lossCount)).truncate(places: 2) return Stats.init(winLoss: String(ratio), totalWins: winCount, totalLosses: lossCount) } } func statsForRecent(numberGames:Int, req:Request) -> EventLoopFuture { let winCount = Match.query(on: req.db) .sort(\.$date) .range(lower: 0, upper: numberGames) .filter(\.$win == true ) .count() let lossCount = Match.query(on: req.db) .sort(\.$date) .range(lower: 0, upper: numberGames) .filter(\.$win == false ) .count() let combined = winCount.and(lossCount) return combined.map { (winCount, lossCount) -> (Stats) in let ratio:Double = (Double(winCount) / Double(lossCount)).truncate(places: 2) return Stats.init(winLoss: String(ratio), totalWins: winCount, totalLosses: lossCount) } } private func getStartOfMonth(month:Int, year:Int) -> Date { let calendar = Calendar.current var components = DateComponents() components.day = 1 components.month = month components.year = year components.hour = 0 components.minute = 0 return calendar.date(from: components)! } private func getEndOfMonth(month:Int, year:Int) -> Date { let calendar = Calendar.current var components = DateComponents() components.day = -1 components.month = month + 1 components.year = year components.hour = 23 components.minute = 59 return calendar.date(from: components)! } // private func getAccumualtiveWLByDay(req:Request) { // // let winLossRatio:[String:Double] = [:] // // let matches = Match.query(on:req.db) // .sort(\.$date) // .all() // // var ratio = 0.0 // var cumulativeWLRatio = req.eventLoop.future(ratio) // // matches.map { (matches) -> [String:Double] in // // let winLossRatio2:[String:Double] = [:] // // matches.reduce(Dictionary()) { (partialRatio, match) -> [String:Double] in // // } // } // // } // // } func all(req: Request) throws -> EventLoopFuture { struct MonthYear { let month:Int let year:Int } let calendar = Calendar.current var components = DateComponents() components.day = 01 components.month = 03 components.year = 2020 components.hour = 0 components.minute = 0 var date = calendar.date(from: components)! var previousMonths:[MonthYear] = [] repeat { //let stats = getStatsByMonth(year: date.year, month: date.month, req: req) //returns eventloopfuture previousMonths.append(MonthYear(month: date.month, year: date.year)) date = Calendar.current.date(byAdding: .month, value: 1, to: date)! } while (date.month != (Date().month + 1) || date.year != Date().year) func getMonthStats (_ remaining: ArraySlice, allMonthlyStats: inout [MonthStats], eventLoop: EventLoop) -> EventLoopFuture<[MonthStats]> { var remaining = remaining if let first = remaining.popLast() { return getStatsByMonth(year: first.year, month: first.month, req: req).flatMap { [remaining, allMonthlyStats] (stats) -> EventLoopFuture<[MonthStats]> in print ("remaining \(remaining)") var allMonthlyStats = allMonthlyStats allMonthlyStats.append(MonthStats(month: first.month, year: first.year, stats:stats )) return getMonthStats(remaining, allMonthlyStats:&allMonthlyStats, eventLoop: eventLoop) } } else { print ("rett") return req.eventLoop.makeSucceededFuture(allMonthlyStats) } } var stats:[MonthStats] = [] let monthstats = getMonthStats(previousMonths[0.. AllStats in return AllStats.init(overall: overall, byMonth: monthlyStats) } // return getMonthStats(previousMonths, eventLoop: req.eventLoop) // var date = Date(year: 2020, month: 03, day: 01, hour: 0, minute: 0) // var monthlyStats = [String:Stats]() // repeat { // let stats = getStatsByMonth(year: date.year, month: date.month, req: req) //returns eventloopfuture // monthlyStats["\(date.month) \(date.year)"] = stats.map({ (newStats) -> (Stats) in // return Stats(winLoss: newStats.winLossRatio, totalWins: newStats.totalWins, totalLosses: newStats.totalLosses) // }) // date = Calendar.current.date(byAdding: .month, value: 1, to: date)!.date // } while (date.month != Date().month || date.year != Date().year) //// // // // // // // let combined = try overall(req: req).and(req.eventLoop.future(monthlyStats)) // return combined.map { (stats, dict) -> (AllStats) in // return AllStats(overall: stats, byMonth: monthlyStats ) // // } // let combined = try overall(req: req).and( // // // // // // ) } func overall(req: Request) throws -> EventLoopFuture { let lossCount = Match.query(on: req.db) .filter(\.$win == false) .count() let winCount = Match.query(on: req.db) .filter(\.$win == true ) .count() let combined = winCount.and(lossCount) return combined.map { (winCount, lossCount) -> (Stats) in let ratio:Double = (Double(winCount) / Double(lossCount)).truncate(places: 2) return Stats.init(winLoss: String(ratio), totalWins: winCount, totalLosses: lossCount) } } // // func create(req: Request) throws -> EventLoopFuture { // let newBeacon = try req.content.decode(Beacon.Create.self) // let beacon = Beacon(id: UUID(), ownerId: nil) // return beacon.save(on: req.db).map { beacon } // } // // func delete(req: Request) throws -> EventLoopFuture { // return Beacon.find(req.parameters.get("beaconID"), on: req.db) // .unwrap(or: Abort(.notFound)) // .flatMap { $0.delete(on: req.db) } // .transform(to: .ok) // } } extension Double { func truncate(places : Int)-> Double { return Double(floor(pow(10.0, Double(places)) * self)/pow(10.0, Double(places))) } } extension Date { var month:Int { let calanderDate = Calendar.current.dateComponents([.day, .year, .month], from: self) return calanderDate.month ?? 1 } var year:Int { let calanderDate = Calendar.current.dateComponents([.day, .month, .year], from: self) return calanderDate.year ?? 1 } }