diff --git a/Sources/App/Controllers/StatsAPIController.swift b/Sources/App/Controllers/StatsAPIController.swift deleted file mode 100644 index 8d7430f..0000000 --- a/Sources/App/Controllers/StatsAPIController.swift +++ /dev/null @@ -1,117 +0,0 @@ -//// -//// StatsAPIController.swift -//// App -//// -//// Created by Michael Simard on 5/29/20. -//// -// -//import Fluent -//import Vapor -// -// -// -// -// -//protocol ContentController { -// associatedtype Model: Fluent.Model -//} -// -//protocol StatsContentRepresentable { -// associatedtype StatsItem: Content -// var statsContent : StatsItem { get } -//} -// -// -//protocol StatsContentController: ContentController where Model: StatsContentRepresentable { -// -// func stats (_:Request) throws -> EventLoopFuture> -// func setupStatsRoute( routes: RoutesBuilder) -//} -// -//extension StatsContentController { -// -// -// func stats (req:Request) throws -> EventLoopFuture> { -// return Model.query(on: req.db).paginate(for: req).map { $0.map(\.statsContent)} -// -// } -// -// func setupStatsRoute( routes: RoutesBuilder) -// { -// routes.get(use: self.stats) -// } -// -//} -// -// -// -////*********** -// -//final class StatsModel: Model, Content { -// typealias IDValue = <#type#> -// -// static var schema: String -// -// init() { -// <#code#> -// } -// -// var winLoss:String -// var totalWins:Int -// var totalLosses:Int -// init( winLoss:String, totalWins:Int, totalLosses:Int) { -// -// self.winLoss = winLoss -// self.totalWins = totalWins -// self.totalLosses = totalLosses -// } -//} -// -//extension StatsModel: StatsContentRepresentable { -// -// struct StatsItem: Content { -// -// var winLoss:String -// var totalWins:Int -// var totalLosses:Int -// -// init(model:StatsModel) { -// -// self.winLoss = model.winLoss -// self.totalWins = model.totalWins -// self.totalLosses = model.totalLosses -// } -// } -// -// var statsContent: StatsItem { .init(model:self) } -//} -// -// -////*********** -// -// -//struct StatsAPIController: StatsContentController { -// -// typealias Model = StatsModel -// -// -//} -// -//struct StatsRouter: RouteCollection { -// -// func boot(routes: RoutesBuilder) throws { -// let statsRoute = routes.grouped("api", "stats") -// -// StatsAPIController().setupStatsRoute(routes: statsRoute) -// -//// statsRoute.get("allMatches", use: index) -//// statsRoute.get("totalWins", use: totalWins) -//// statsRoute.get("totalLosses", use: totalLosses) -// //statsRoute.get("overall", use: totalLosses) -// -// //beaconsRoute.get("overallStats", use: index) -// //beaconsRoute.post("", use: create) -// // beaconsRoute.delete(":beaconID", use: delete) -// -// } -//} diff --git a/Sources/App/Controllers/StatsController.swift b/Sources/App/Controllers/StatsController.swift index 520202a..041615f 100644 --- a/Sources/App/Controllers/StatsController.swift +++ b/Sources/App/Controllers/StatsController.swift @@ -3,6 +3,11 @@ import Vapor + struct CODDate { + let month:Int + let year:Int + let day: Int + } struct StatsController: RouteCollection { @@ -13,17 +18,13 @@ struct StatsController: RouteCollection { 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) - + statsRoute.get("allDaily", use: allDaily) + } func index(req: Request) throws -> EventLoopFuture<[Match]> { - return Match.query(on: req.db).all() + return Match.query(on: req.db).sort(\.$date).all() } @@ -40,10 +41,10 @@ struct StatsController: RouteCollection { } func getMarchStats(req:Request) throws -> EventLoopFuture { - return getStatsByMonth(year: 2020, month: 03, req: req) + return getstatsForMonth(year: 2020, month: 03, req: req) } - func getStatsByMonth(year:Int, month:Int, req: Request) -> EventLoopFuture{ + func getstatsForMonth(year:Int, month:Int, req: Request) -> EventLoopFuture{ let winCount = Match.query(on: req.db) .filter(\.$date >= getStartOfMonth(month: month, year: year)) @@ -66,6 +67,34 @@ struct StatsController: RouteCollection { } } + func getStatsForDay(year:Int, month:Int, day:Int, req: Request) -> EventLoopFuture{ + + + let winCount = Match.query(on: req.db) + .filter(\.$date >= getStartOfDay(day:day, month: month, year: year)) + .filter(\.$date <= getEndOfDay(day: day, month: month, year: year)) + .filter(\.$win == true ) + .count() + + + let lossCount = Match.query(on: req.db) + .filter(\.$date >= getStartOfDay(day:day, month: month, year: year)) + .filter(\.$date <= getEndOfDay(day: day, 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) @@ -93,113 +122,82 @@ struct StatsController: RouteCollection { 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 getStartOfDay(day:Int, month:Int, year:Int) -> Date { + let calendar = Calendar.current + var components = DateComponents() + components.day = day - 1 + components.month = month + components.year = year + components.hour = 0 + components.minute = 0 + 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 - // - // } - // } - // - // } - // - // } + private func getEndOfDay(day:Int, month:Int, year:Int) -> Date { + let calendar = Calendar.current + var components = DateComponents() + components.day = day - 1 + components.month = month + components.year = year + components.hour = 23 + components.minute = 59 + return calendar.date(from: components)! + } 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] = [] + var date = getStartDate() + var previousMonths:[CODDate] = [] repeat { //let stats = getStatsByMonth(year: date.year, month: date.month, req: req) //returns eventloopfuture - previousMonths.append(MonthYear(month: date.month, year: date.year)) + previousMonths.append(CODDate(month: date.month, year: date.year, day: 15)) 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]> { + 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)") + return getstatsForMonth(year: first.year, month: first.month, req: req).flatMap { [remaining, allMonthlyStats] (stats) -> EventLoopFuture<[MonthStats]> in 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) } } @@ -211,37 +209,6 @@ struct StatsController: RouteCollection { return try overall(req: req).and(monthstats).map { (overall, monthlyStats) -> 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( - // - // - // - // - // - // ) } @@ -269,20 +236,74 @@ struct StatsController: RouteCollection { } } - // - // 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) - // } + func allDaily(req:Request) -> EventLoopFuture{ + + var date = getStartDate() + var previousDays:[CODDate] = [] + + + repeat { + previousDays.append(CODDate(month: date.month, year: date.year, day: date.day)) + date = Calendar.current.date(byAdding: .day, value: 1, to: date)! + + } while (date < Date()) + + + func getDailyStats (_ remaining: ArraySlice, allDailyStats: inout [DailyStats], eventLoop: EventLoop) -> EventLoopFuture<[DailyStats]> { + var remaining = remaining + if let first = remaining.popLast() { + + + + return getStatsForDay(year: first.year, month: first.month, day:first.day, req: req).flatMap { [remaining, allDailyStats] (stats) -> EventLoopFuture<[DailyStats]> in + var allDailyStats = allDailyStats + allDailyStats.append(DailyStats(day: first.day, month: first.month, year: first.year, stats: stats)) + return getDailyStats(remaining, allDailyStats:&allDailyStats, eventLoop: eventLoop) + } + + } else { + return req.eventLoop.makeSucceededFuture(allDailyStats) + } + } + + + var stats:[DailyStats] = [] + let dailyStats = getDailyStats(previousDays[0.. AllDailyStats in + return AllDailyStats(dailyStats: dailyStats.filter({ (dailyStats) -> Bool in + if dailyStats.stats.totalWins == 0 && dailyStats.stats.totalLosses == 0 { + return false + } + return true + })) + } + + } + + +// func allCumulativeStats(req:Request) -> EventLoopFuture { +// +// +// } + + + private func getStartDate() -> Date { + + let calendar = Calendar.current + + var components = DateComponents() + components.day = 20 + components.month = 03 + components.year = 2020 + components.hour = 0 + components.minute = 0 + + return calendar.date(from: components)! + } + + } @@ -305,4 +326,9 @@ extension Date { let calanderDate = Calendar.current.dateComponents([.day, .month, .year], from: self) return calanderDate.year ?? 1 } + + var day:Int { + let calanderDate = Calendar.current.dateComponents([.day, .month, .year], from: self) + return calanderDate.day ?? 1 + } } diff --git a/Sources/App/Models/AllStats.swift b/Sources/App/Models/AllStats.swift index c699154..69a814c 100644 --- a/Sources/App/Models/AllStats.swift +++ b/Sources/App/Models/AllStats.swift @@ -49,6 +49,36 @@ final class Stats: Content { } } +final class AllDailyStats: Content { + var dailyStats : [DailyStats] + + init(dailyStats:[DailyStats]) { + self.dailyStats = dailyStats + } +} + + +final class AllRollingStats: Content { + var cumulativeStats:[DailyStats] +} + + + +final class DailyStats: Content { + + var day: String + var month:String + var year: String + var stats:Stats + + init(day:Int, month:Int, year:Int, stats:Stats) { + self.day = String(day) + self.month = Utilities.monthToString(month: month) + self.year = String(year) + self.stats = stats + } +} + class Utilities { class func monthToString(month:Int) -> String { switch month {