optimzations for dashbaord
This commit is contained in:
@@ -18,9 +18,7 @@ struct StatsController: RouteCollection {
|
||||
statsRoute.get("totalWins", use: totalWins)
|
||||
statsRoute.get("totalLosses", use: totalLosses)
|
||||
statsRoute.get("overall", use: overall)
|
||||
statsRoute.get("all", use: test)
|
||||
statsRoute.get("allDaily", use: allDaily)
|
||||
statsRoute.get("test", use: test)
|
||||
statsRoute.post("logMatch", use: logMatch)
|
||||
statsRoute.get("history","page",":page", use: history)
|
||||
statsRoute.get("history", use: history)
|
||||
@@ -85,10 +83,17 @@ struct StatsController: RouteCollection {
|
||||
return Stats( totalWins: Int(winCount), totalLosses: Int(lossCount))
|
||||
}
|
||||
|
||||
func getStatsWithMostRecentDailyRecord(matches:[Match], game:String? = nil) -> StatsWithMostRecentDailyRecord {
|
||||
func getStatsWithMostRecentDailyRecord(sortedMatches:[Match], game:String? = nil) -> StatsWithMostRecentDailyRecord {
|
||||
|
||||
let stats = getStats(matches: matches)
|
||||
let mostRecentDailyStats = self.mostRecentDailyStats(matches: matches, game: game)
|
||||
|
||||
let startTime = Date()
|
||||
//print ("MRR START \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
let stats = getStats(matches: sortedMatches)
|
||||
//print ("MRR STATS \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
let mostRecentDailyStats = self.mostRecentDailyStats(matches: sortedMatches, game: game)
|
||||
//print ("MRR DAILY \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
let ret = StatsWithMostRecentDailyRecord(winLoss: stats.winLossRatio, totalWins: stats.totalWins, totalLosses: stats.totalLosses, mostRecentRecord:"\(mostRecentDailyStats.totalWins)-\(mostRecentDailyStats.totalLosses)")
|
||||
|
||||
@@ -97,9 +102,15 @@ struct StatsController: RouteCollection {
|
||||
|
||||
func mostRecentDailyStats (matches:[Match], game:String? = nil) -> Stats{
|
||||
|
||||
let daysPlayed = getDaysPlayed(matches: matches)
|
||||
|
||||
let startTime = Date()
|
||||
|
||||
let daysPlayed = getDaysPlayed(sortedMatches: matches)
|
||||
let lastDayPlayed = daysPlayed.last
|
||||
|
||||
|
||||
//print ("MDD days played \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
return getStats(matches: matches.filter({ (match) -> Bool in
|
||||
var shouldInclude =
|
||||
match.date.day == lastDayPlayed?.day &&
|
||||
@@ -108,20 +119,8 @@ struct StatsController: RouteCollection {
|
||||
self.shouldCountMatch(match: match)
|
||||
|
||||
if let game = game {
|
||||
// if game == "mw" {
|
||||
// shouldInclude = shouldInclude && match.codGame == "mw"
|
||||
// }
|
||||
// else if game == "bocw" {
|
||||
// shouldInclude = shouldInclude && match.codGame == "bocw"
|
||||
//
|
||||
// }else {
|
||||
//
|
||||
// }
|
||||
|
||||
shouldInclude = shouldInclude && match.codGame == game
|
||||
}
|
||||
|
||||
|
||||
return shouldInclude
|
||||
}))
|
||||
}
|
||||
@@ -141,16 +140,20 @@ struct StatsController: RouteCollection {
|
||||
return match.players?.components(separatedBy: ",").count ?? 0
|
||||
}
|
||||
|
||||
private func getDaysPlayed(matches:[Match]) -> [CODDate] {
|
||||
private func getDaysPlayed(sortedMatches:[Match]) -> [CODDate] {
|
||||
|
||||
var sortedMatches = matches
|
||||
sortedMatches.sort { (match1, match2) -> Bool in
|
||||
return match1.date < match2.date
|
||||
let startTime = Date()
|
||||
|
||||
//print ("MDP Sort \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
let dates = sortedMatches.suffix(30).map { (match) -> CODDate in
|
||||
return CODDate(month: match.date.month, year: match.date.year, day: match.date.day, hour: match.date.hour, minute: match.date.minute)
|
||||
}
|
||||
|
||||
return sortedMatches.map { (match) -> CODDate in
|
||||
return CODDate(month: match.date.month, year: match.date.year, day: match.date.day, hour: match.date.hour, minute: match.date.minute)
|
||||
}.reduce([CODDate]()) { (datesPlayed, codDate) -> [CODDate] in
|
||||
//print ("MDP to dates \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
|
||||
return dates.reduce([CODDate]()) { (datesPlayed, codDate) -> [CODDate] in
|
||||
|
||||
if datesPlayed.contains(where: { (existingDate) -> Bool in
|
||||
if codDate.month == existingDate.month && codDate.year == existingDate.year && existingDate.day == codDate.day{
|
||||
@@ -170,7 +173,7 @@ struct StatsController: RouteCollection {
|
||||
|
||||
func getCumulativeWinLossRatios(matches:[Match]) -> [DataPoint] {
|
||||
|
||||
let daysPlayed = getDaysPlayed(matches: matches)
|
||||
let daysPlayed = getDaysPlayed(sortedMatches: matches)
|
||||
|
||||
var cumulativeRatios : [DataPoint] = []
|
||||
var cumulativeWins:Int = 0
|
||||
@@ -215,106 +218,6 @@ struct StatsController: RouteCollection {
|
||||
return cumulativeRatios
|
||||
}
|
||||
|
||||
|
||||
func test(req: Request) throws -> EventLoopFuture<AllStats> {
|
||||
|
||||
let startTime = Date()
|
||||
|
||||
var date = getStartDate()
|
||||
var previousMonths:[CODDate] = []
|
||||
|
||||
repeat {
|
||||
//let stats = getStatsByMonth(year: date.year, month: date.month, req: req) //returns eventloopfuture<Stats>
|
||||
previousMonths.append(CODDate(month: date.month, year: date.year, day: 15, hour:6, minute: 0))
|
||||
date = Calendar.current.date(byAdding: .month, value: 1, to: date)!
|
||||
} while ( date < Calendar.current.date(byAdding: .month, value: 1, to: Date())!)
|
||||
|
||||
// print (date - Date().timeIntervalSince(startTime))
|
||||
|
||||
return Match.query(on: req.db).all().map { (matches) -> AllStats in
|
||||
let overallStats = self.getStatsWithMostRecentDailyRecord(matches: matches)
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
let mwStats = self.getStatsWithMostRecentDailyRecord(matches: matches.filter({ (match) -> Bool in
|
||||
return match.codGame == "mw"
|
||||
}))
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
let bocwStats = self.getStatsWithMostRecentDailyRecord(matches: matches.filter({ (match) -> Bool in
|
||||
return match.codGame == "bocw"
|
||||
}))
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
|
||||
|
||||
let mostRecentDailyStats = self.mostRecentDailyStats(matches: matches)
|
||||
|
||||
|
||||
let monthlyStats = previousMonths.reversed().map { (codDate) -> MonthStats in
|
||||
let relevantMatches = matches.filter { (match) -> Bool in
|
||||
return match.date.month == codDate.month
|
||||
}
|
||||
return MonthStats(month: codDate.month, year: codDate.year, stats: self.getStats(matches: relevantMatches ))
|
||||
}
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
|
||||
// let cumulativeWinLossRatios = self.getCumulativeWinLossRatios(matches: matches)
|
||||
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
// let highestWinLossRatio = cumulativeWinLossRatios.reduce("0") { (highestRatio, dataPoint) -> String in
|
||||
// if dataPoint.y > Double(highestRatio)!{
|
||||
// return String(dataPoint.y)
|
||||
// }
|
||||
// return highestRatio
|
||||
// }
|
||||
// print ( Date().timeIntervalSince(startTime))
|
||||
|
||||
|
||||
return AllStats.init(overall: overallStats,mwStats: mwStats, bocwStats: bocwStats, byMonth: monthlyStats, mostRecentRecord: "\(mostRecentDailyStats.totalWins) - \(mostRecentDailyStats.totalLosses)")
|
||||
|
||||
}
|
||||
|
||||
|
||||
// func getMonthStats (_ remaining: ArraySlice<CODDate>, allMonthlyStats: inout [MonthStats], eventLoop: EventLoop) -> EventLoopFuture<[MonthStats]> {
|
||||
// var remaining = remaining
|
||||
// if let first = remaining.popLast() {
|
||||
//
|
||||
// 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 {
|
||||
// return req.eventLoop.makeSucceededFuture(allMonthlyStats)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var stats:[MonthStats] = []
|
||||
// let monthstats = getMonthStats(previousMonths[0..<previousMonths.count], allMonthlyStats:&stats, eventLoop: req.eventLoop)
|
||||
// let cumulativeRatios = getCumulativeWinLossRatios(req: req)
|
||||
// let mostRecentDayStats = mostRecentDailyStats(req: req)
|
||||
//
|
||||
// return try overall(req: req).and(monthstats).and(cumulativeRatios).and(mostRecentDayStats).map { arg -> AllStats in
|
||||
//
|
||||
// let (((overall, monthlyStats), cumulativeRatios), mostRecentDayStats) = arg
|
||||
// let highestWinLossRatio = cumulativeRatios.reduce("0") { (highestRatio, dataPoint) -> String in
|
||||
// if dataPoint.y > Double(highestRatio)!{
|
||||
// return String(dataPoint.y)
|
||||
// }
|
||||
// return highestRatio
|
||||
// }
|
||||
//
|
||||
// return AllStats.init(overall: overall,mwStats: overall, bocwStats: overall, byMonth: monthlyStats, highestWinLossRatio: highestWinLossRatio, dataPoints: cumulativeRatios, mostRecentRecord: "\(mostRecentDayStats.totalWins) - \(mostRecentDayStats.totalLosses)")
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func index(req: Request) throws -> EventLoopFuture<[Match]> {
|
||||
return Match.query(on: req.db).sort(\.$date).all()
|
||||
}
|
||||
@@ -490,62 +393,12 @@ struct StatsController: RouteCollection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// func all(req: Request) throws -> EventLoopFuture<AllStats> {
|
||||
//
|
||||
// var date = getStartDate()
|
||||
// var previousMonths:[CODDate] = []
|
||||
//
|
||||
// repeat {
|
||||
// //let stats = getStatsByMonth(year: date.year, month: date.month, req: req) //returns eventloopfuture<Stats>
|
||||
// previousMonths.append(CODDate(month: date.month, year: date.year, day: 15, hour:6, minute: 0))
|
||||
// date = Calendar.current.date(byAdding: .month, value: 1, to: date)!
|
||||
// }while ( date < Calendar.current.date(byAdding: .month, value: 1, to: Date())!)
|
||||
//
|
||||
//
|
||||
// func getMonthStats (_ remaining: ArraySlice<CODDate>, allMonthlyStats: inout [MonthStats], eventLoop: EventLoop) -> EventLoopFuture<[MonthStats]> {
|
||||
// var remaining = remaining
|
||||
// if let first = remaining.popLast() {
|
||||
//
|
||||
// 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 {
|
||||
// return req.eventLoop.makeSucceededFuture(allMonthlyStats)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var stats:[MonthStats] = []
|
||||
// let monthstats = getMonthStats(previousMonths[0..<previousMonths.count], allMonthlyStats:&stats, eventLoop: req.eventLoop)
|
||||
// let cumulativeRatios = getCumulativeWinLossRatios(req: req)
|
||||
// let mostRecentDayStats = mostRecentDailyStats(req: req)
|
||||
//
|
||||
// return try overall(req: req).and(monthstats).and(cumulativeRatios).and(mostRecentDayStats).map { arg -> AllStats in
|
||||
//
|
||||
// let (((overall, monthlyStats), cumulativeRatios), mostRecentDayStats) = arg
|
||||
// let highestWinLossRatio = cumulativeRatios.reduce("0") { (highestRatio, dataPoint) -> String in
|
||||
// if dataPoint.y > Double(highestRatio)!{
|
||||
// return String(dataPoint.y)
|
||||
// }
|
||||
// return highestRatio
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return AllStats.init(overall: overall,mwStats: overall, bocwStats: overall, byMonth: monthlyStats, highestWinLossRatio: highestWinLossRatio, dataPoints: cumulativeRatios, mostRecentRecord: "\(mostRecentDayStats.totalWins) - \(mostRecentDayStats.totalLosses)")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
func overall(req: Request) throws -> EventLoopFuture<OverallStats> {
|
||||
|
||||
|
||||
|
||||
let startTime = Date()
|
||||
|
||||
let statsWithHyder = statsWithPlayer(req: req, playerId: 5)
|
||||
|
||||
let statsWithoutHyder = statsWithoutPlayer(req: req, playerId: 5)
|
||||
@@ -554,13 +407,17 @@ struct StatsController: RouteCollection {
|
||||
|
||||
let hyderStats = hyderFuture.map { (withHyder, withoutHyder) -> [Stats] in
|
||||
return [withHyder, withoutHyder]
|
||||
|
||||
//print ("Hyder done \(Date().timeIntervalSince(startTime))")
|
||||
}
|
||||
|
||||
|
||||
let matches = Match.query(on: req.db).all()
|
||||
let matches = Match.query(on: req.db).sort( \.$date).all()
|
||||
|
||||
return matches.and(hyderStats).map { (matches, hyderStats) -> (OverallStats) in
|
||||
|
||||
//print ("got matches \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
let queue = DispatchQueue(label: "com.sledsoft.cod-tracker.queue", attributes: .concurrent)
|
||||
let group = DispatchGroup()
|
||||
|
||||
@@ -568,18 +425,25 @@ struct StatsController: RouteCollection {
|
||||
var mwStats:StatsWithMostRecentDailyRecord?
|
||||
var bocwStats:StatsWithMostRecentDailyRecord?
|
||||
var mostRecentStats:Stats?
|
||||
var mapStats:[Int:Stats]?
|
||||
var worstMap:Int?
|
||||
var bestMap:Int?
|
||||
|
||||
group.enter()
|
||||
queue.async {
|
||||
overallStats = self.getStatsWithMostRecentDailyRecord(matches: matches)
|
||||
overallStats = self.getStatsWithMostRecentDailyRecord(sortedMatches: matches)
|
||||
group.leave()
|
||||
//print ("all stats done \(Date().timeIntervalSince(startTime))")
|
||||
}
|
||||
|
||||
group.enter()
|
||||
queue.async {
|
||||
mwStats = self.getStatsWithMostRecentDailyRecord(matches: matches.filter({ (match) -> Bool in
|
||||
mwStats = self.getStatsWithMostRecentDailyRecord(sortedMatches: matches.filter({ (match) -> Bool in
|
||||
return match.codGame == "mw" && self.shouldCountMatch(match: match )
|
||||
}))
|
||||
|
||||
//print ("mw stats done \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
group.leave()
|
||||
|
||||
}
|
||||
@@ -587,25 +451,47 @@ struct StatsController: RouteCollection {
|
||||
|
||||
group.enter()
|
||||
queue.async {
|
||||
bocwStats = self.getStatsWithMostRecentDailyRecord(matches: matches.filter({ (match) -> Bool in
|
||||
|
||||
bocwStats = self.getStatsWithMostRecentDailyRecord(sortedMatches: matches.filter({ (match) -> Bool in
|
||||
return match.codGame == "bocw" && self.shouldCountMatch(match: match )
|
||||
}))
|
||||
|
||||
//print ("cw done \(Date().timeIntervalSince(startTime))")
|
||||
|
||||
group.leave()
|
||||
|
||||
}
|
||||
|
||||
// group.enter()
|
||||
// queue.async {
|
||||
// mostRecentStats = self.mostRecentDailyStats(matches: matches)
|
||||
// group.leave()
|
||||
// }
|
||||
group.enter()
|
||||
queue.async {
|
||||
mapStats = self.getMapStats(matches: matches)
|
||||
//print ("maps done \(Date().timeIntervalSince(startTime))")
|
||||
group.leave()
|
||||
|
||||
}
|
||||
//
|
||||
group.enter()
|
||||
queue.async {
|
||||
let mapStats = self.getMapStats(matches: matches)
|
||||
|
||||
bestMap = self.getBestMap(records: mapStats)
|
||||
//print ("best done \(Date().timeIntervalSince(startTime))")
|
||||
group.leave()
|
||||
|
||||
}
|
||||
|
||||
group.enter()
|
||||
queue.async {
|
||||
let mapStats = self.getMapStats(matches: matches)
|
||||
|
||||
worstMap = self.getWorstMap(records: mapStats)
|
||||
//print ("worst done \(Date().timeIntervalSince(startTime))")
|
||||
group.leave()
|
||||
|
||||
}
|
||||
|
||||
group.wait()
|
||||
|
||||
let mapStats = self.getMapStats(matches: matches)
|
||||
let bestMap = self.getBestMap(records: mapStats)
|
||||
let worstMap = self.getWorstMap(records: mapStats)
|
||||
|
||||
let dashboardItems = [
|
||||
DashboardItem(title: "Overall", content: overallStats!.record, title2: "Ratio", content2: overallStats!.winLossRatio),
|
||||
DashboardItem(title: "Total MW Games", content: "\(mwStats!.totalWins + mwStats!.totalLosses)" , title2:"", content2:""),
|
||||
@@ -613,21 +499,12 @@ struct StatsController: RouteCollection {
|
||||
DashboardItem(title: "Cold War Overall", content: bocwStats!.record, title2: "Ratio", content2: bocwStats!.winLossRatio),
|
||||
DashboardItem(title: "With Hyder", content: hyderStats[0].record, title2: "Ratio", content2: hyderStats[0].winLossRatio),
|
||||
DashboardItem(title: "No Hyder", content: hyderStats[1].record, title2: "Ratio", content2: hyderStats[1].winLossRatio),
|
||||
DashboardItem(title: "Best Map", content: MapData.allMaps[bestMap]?.name ?? "error", title2: "Ratio", content2: "\(mapStats[bestMap]!.winLossRatio) \(mapStats[bestMap]!.record)"),
|
||||
DashboardItem(title: "Worst Map", content: MapData.allMaps[worstMap]?.name ?? "error", title2: "Ratio", content2: "\(mapStats[worstMap]!.winLossRatio) \(mapStats[worstMap]!.record)"),
|
||||
DashboardItem(title: "Best Map", content: MapData.allMaps[bestMap!]?.name ?? "error", title2: "Ratio", content2: "\(mapStats![bestMap!]!.winLossRatio) \(mapStats![bestMap!]!.record)"),
|
||||
DashboardItem(title: "Worst Map", content: MapData.allMaps[worstMap!]?.name ?? "error", title2: "Ratio", content2: "\(mapStats![worstMap!]!.winLossRatio) \(mapStats![worstMap!]!.record)"),
|
||||
DashboardItem(title: "Final Kills Ruined by Adam", content: "\(matches.filter{$0.finalKillRuinedPlayerId == 6}.count + 7)", title2: "", content2: ""),
|
||||
]
|
||||
|
||||
|
||||
return OverallStats(overall: overallStats!, mwStats: mwStats!, bocwStats: bocwStats!, mostRecentRecord: "Temporarily Unavailable", statsWithHyder:hyderStats[0], statsWithoutHyder: hyderStats[1], dashboardItems:dashboardItems)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return Match.query(on: req.db).all().map { (matches) -> OverallStats in
|
||||
//
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -647,7 +524,7 @@ struct StatsController: RouteCollection {
|
||||
var loss:Double = 0
|
||||
|
||||
for record in records {
|
||||
print("\(record.map.name) \(record.stats.record) \(record.ratio)")
|
||||
//print("\(record.map.name) \(record.stats.record) \(record.ratio)")
|
||||
wins = wins + Double(record.stats.totalWins)
|
||||
loss = loss + Double(record.stats.totalLosses)
|
||||
|
||||
@@ -818,13 +695,8 @@ struct StatsController: RouteCollection {
|
||||
|
||||
func getCumulativeWinLossRatios(req:Request) -> EventLoopFuture<[DataPoint]> {
|
||||
|
||||
// let previousDays = getDaysPlayed().reversed()
|
||||
|
||||
|
||||
return getDaysPlayed(req: req).flatMap { (previousDays) -> (EventLoopFuture<[DataPoint]>) in
|
||||
|
||||
|
||||
|
||||
func getRatios (_ remaining: ArraySlice<CODDate>, allDailyStats: inout [DailyStats], cumulativeWinLossRatios: inout [DataPoint], eventLoop: EventLoop) -> EventLoopFuture<[DataPoint]> {
|
||||
var remaining = remaining
|
||||
if let first = remaining.popLast() {
|
||||
@@ -843,7 +715,7 @@ struct StatsController: RouteCollection {
|
||||
if !(stats.totalWins == 0 && stats.totalLosses == 0) {
|
||||
|
||||
let date = self.createDate(day: first.day, month: first.month, year: first.year, hour: first.hour + 6, minute:first.minute) // 6 hours to make sure we pick a time that isnt on borders of us time zones
|
||||
// print ("p \(date.timeIntervalSince1970)")
|
||||
// //print ("p \(date.timeIntervalSince1970)")
|
||||
let x = Double(cumulativeWinLossRatios.count)
|
||||
|
||||
let d = Date(timeIntervalSince1970: date.timeIntervalSince1970)
|
||||
@@ -868,56 +740,3 @@ struct StatsController: RouteCollection {
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.month ?? 1
|
||||
}
|
||||
|
||||
var year:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.year ?? 1
|
||||
}
|
||||
|
||||
var day:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.day ?? 1
|
||||
}
|
||||
|
||||
var hour:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.hour ?? 1
|
||||
}
|
||||
|
||||
|
||||
var minute:Int {
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.minute ?? 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
55
Sources/App/Data/Extensions/Date+components.swift
Normal file
55
Sources/App/Data/Extensions/Date+components.swift
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Date+components.swift
|
||||
// App
|
||||
//
|
||||
// Created by Michael Simard on 1/15/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
extension Date {
|
||||
|
||||
var month:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.month ?? 1
|
||||
}
|
||||
|
||||
var year:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.year ?? 1
|
||||
}
|
||||
|
||||
var day:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.day ?? 1
|
||||
}
|
||||
|
||||
var hour:Int {
|
||||
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.hour ?? 1
|
||||
}
|
||||
|
||||
|
||||
var minute:Int {
|
||||
var calendar = Calendar.current
|
||||
calendar.timeZone = TimeZone(identifier: "GMT")!
|
||||
let calanderDate = calendar.dateComponents([.minute, .month, .year, .hour, .day], from: self)
|
||||
return calanderDate.minute ?? 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
16
Sources/App/Data/Extensions/Double+Truncate.swift
Normal file
16
Sources/App/Data/Extensions/Double+Truncate.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Double+Truncate.swift
|
||||
// App
|
||||
//
|
||||
// Created by Michael Simard on 1/15/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Double
|
||||
{
|
||||
func truncate(places : Int)-> Double
|
||||
{
|
||||
return Double(floor(pow(10.0, Double(places)) * self)/pow(10.0, Double(places)))
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,39 @@ x-shared_environment: &shared_environment
|
||||
DATABASE_NAME: cod_db
|
||||
DATABASE_USERNAME: cod
|
||||
DATABASE_PASSWORD: pw4cod
|
||||
VIRTUAL_HOST: app.local
|
||||
|
||||
services:
|
||||
nginx-proxy:
|
||||
image: jwilder/nginx-proxy:alpine
|
||||
restart: "always" # Always restart container
|
||||
ports:
|
||||
- "80:80" # Port mappings in format host:container
|
||||
- "443:443" # Port mappings in format host:container
|
||||
networks:
|
||||
- nginx-proxy # Name of the etwork these two containers will share
|
||||
labels:
|
||||
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" # Label needed for Let's Encrypt companion container
|
||||
volumes: # Volumes needed for container to configure proixes and access certificates genereated by Let's Encrypt companion container
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- "nginx-conf:/etc/nginx/conf.d"
|
||||
- "nginx-vhost:/etc/nginx/vhost.d"
|
||||
- "html:/usr/share/nginx/html"
|
||||
- "certs:/etc/nginx/certs:ro"
|
||||
|
||||
letsencrypt-nginx-proxy-companion:
|
||||
image: jrcs/letsencrypt-nginx-proxy-companion
|
||||
restart: always
|
||||
container_name: letsencrypt-nginx-proxy-companion
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
- "nginx-conf:/etc/nginx/conf.d"
|
||||
- "nginx-vhost:/etc/nginx/vhost.d"
|
||||
- "html:/usr/share/nginx/html"
|
||||
- "certs:/etc/nginx/certs:rw"
|
||||
depends_on: # Make sure we start nginx proxy container first
|
||||
- app
|
||||
- nginx-proxy
|
||||
app:
|
||||
image: cod-backend:latest
|
||||
build:
|
||||
@@ -72,3 +103,11 @@ services:
|
||||
POSTGRES_DB: cod_db
|
||||
ports:
|
||||
- '5432:5432'
|
||||
networks:
|
||||
nginx-proxy: # Name of our shared network that containers will use
|
||||
volumes: # Names of volumes that out containers will share. Those will persist on docker's host machine.
|
||||
nginx-conf:
|
||||
nginx-vhost:
|
||||
html:
|
||||
certs:
|
||||
db_data:
|
||||
Reference in New Issue
Block a user