Skip to content
This repository has been archived by the owner on Jan 22, 2021. It is now read-only.

Commit

Permalink
Merge pull request #77 from IBM/leaderboard.user
Browse files Browse the repository at this point in the history
Leaderboard.user
  • Loading branch information
sanjeevghimire authored Jun 1, 2018
2 parents ba52836 + b456f91 commit d8a9a06
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 26 deletions.
44 changes: 44 additions & 0 deletions Server/Sources/Application/Model/EntryPersistence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import CouchDB
import SwiftyJSON
import Dispatch

enum RainbowPersistenceError: Error {
case noAvatar
Expand Down Expand Up @@ -124,6 +125,49 @@ extension ScoreEntry {
}
}

static func getLeaderBoardDataForUser(id: String, from client: CouchDBClient, completion: @escaping (_ entries: [ScoreEntry]?, _ error: Error?) -> Void) {
getDatabase(from: client) { database, error in
guard let database = database else {
return completion(nil, error)
}
let dispatchGroup = DispatchGroup()
var entries = [ScoreEntry]()

dispatchGroup.enter()
database.retrieve(id, callback: { document, error in
if let document = document, let newEntry = ScoreEntry(document: document) {
if newEntry.finishDate != nil {
entries.append(newEntry)
}
}
dispatchGroup.leave()
})

dispatchGroup.enter()
database.queryByView("leader-board", ofDesign: "LeaderBoard", usingParameters: [Database.QueryParameters.limit(10) ,Database.QueryParameters.descending(false)], callback: { documents, error in
if let documents = documents {
for document in documents["rows"].arrayValue {
if let newEntry = ScoreEntry(document: document["value"]) {
entries.append(newEntry)
}
}
}
dispatchGroup.leave()
})
dispatchGroup.notify(queue: DispatchQueue.global(qos: .default), execute: {
let uniqueEntries = Array(Set(entries))
let sortedEntries = uniqueEntries.sorted {
guard let first = $0.totalTime, let second = $1.totalTime else {
return false
}
return first < second
}
completion(sortedEntries, nil)
})
}
}


static func getScores(from client: CouchDBClient, completion: @escaping (_ entries: [ScoreEntry]?, _ error: Error?) -> Void) {
getDatabase(from: client) { database, error in
guard let database = database else {
Expand Down
4 changes: 4 additions & 0 deletions Server/Sources/Application/Model/ScoreEntry+SwiftyJSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ extension ScoreEntry {
startDate = potentialStartDate
finishDate = document["finishDate"].dateTime
objects = nil

totalTime = nil
if document["finishDate"] != nil {
totalTime = document["finishDate"].doubleValue - document["startDate"].doubleValue
}
}

mutating func toJSONDocument() -> JSON? {
Expand Down
10 changes: 10 additions & 0 deletions Server/Sources/Application/Model/ScoreEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ struct ScoreEntry: Codable {
var objects: [ObjectEntry]?
var totalTime: Double?
}

extension ScoreEntry: Hashable {
var hashValue: Int {
return id?.hashValue ?? Int(INT_MAX)
}

static func == (lhs: ScoreEntry, rhs: ScoreEntry) -> Bool {
return lhs.id == rhs.id
}
}
11 changes: 11 additions & 0 deletions Server/Sources/Application/Routes/ScoreRoutes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func initializeScoreRoutes(app: App) {
app.router.post("watsonml/entries", handler: addNewEntry)
app.router.put("/watsonml/entries", handler: updateEntry)
app.router.get("/watsonml/leaderboard", handler: getLeaderBoard)
app.router.get("/watsonml/leaderboard", handler: getLeaderBoardForUser)
app.router.get("/avatar/leaderboardAvatar/:id", handler: getLeaderboardAvatar)
}

Expand Down Expand Up @@ -87,6 +88,16 @@ func getLeaderBoard(completion: @escaping ([ScoreEntry]?, RequestError?) -> Void
}
}

func getLeaderBoardForUser(id: String, completion: @escaping ([ScoreEntry]?, RequestError?) -> Void) {
Log.info("Getting leaderboard data")
guard let client = client else {
return completion(nil, .failedDependency)
}
ScoreEntry.Persistence.getLeaderBoardDataForUser(id: id, from: client) { entries, error in
return completion(entries, error as? RequestError)
}
}

func getLeaderboardAvatar(request: RouterRequest, response: RouterResponse, next: @escaping () -> Void) {
guard let requestID = request.parameters["id"] else {
response.status(.badRequest).send(json: [])
Expand Down
20 changes: 3 additions & 17 deletions iOS/rainbow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@
531AAF8920A4B0690056B24B /* Booklet.json in Resources */ = {isa = PBXBuildFile; fileRef = 531AAF8620A4B0690056B24B /* Booklet.json */; };
531AAF9620A4B98F0056B24B /* Lumina.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9420A4B98F0056B24B /* Lumina.framework */; };
531AAF9720A4B98F0056B24B /* VisualRecognitionV3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9520A4B98F0056B24B /* VisualRecognitionV3.framework */; };
531AAF9820A4B9C80056B24B /* Lumina.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9420A4B98F0056B24B /* Lumina.framework */; };
531AAF9920A4B9C80056B24B /* Lumina.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9420A4B98F0056B24B /* Lumina.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
531AAF9A20A4B9C80056B24B /* VisualRecognitionV3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9520A4B98F0056B24B /* VisualRecognitionV3.framework */; };
531AAF9B20A4B9C80056B24B /* VisualRecognitionV3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 531AAF9520A4B98F0056B24B /* VisualRecognitionV3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
531AAF9D20A4BA280056B24B /* StyleGuides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 531AAF9C20A4BA280056B24B /* StyleGuides.swift */; };
53381902209757B900DE66CB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53381901209757B900DE66CB /* AppDelegate.swift */; };
Expand All @@ -61,7 +59,6 @@
5341F4CF209BEAD600AD37EF /* ChecklistTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5341F4CE209BEAD600AD37EF /* ChecklistTableViewController.swift */; };
5365924020AB8B3500F76E37 /* Date+WatsonML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5365923F20AB8B3500F76E37 /* Date+WatsonML.swift */; };
5365924220AB8F0900F76E37 /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5365924120AB8F0900F76E37 /* SVProgressHUD.framework */; };
5365924320AB8F1000F76E37 /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5365924120AB8F0900F76E37 /* SVProgressHUD.framework */; };
5365924420AB8F1000F76E37 /* SVProgressHUD.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5365924120AB8F0900F76E37 /* SVProgressHUD.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
53864AD32098DD5D006B8264 /* ScoreEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53864AD22098DD5D006B8264 /* ScoreEntry.swift */; };
538D191420ACB03100742E17 /* Fireworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538D191320ACB03100742E17 /* Fireworks.swift */; };
Expand All @@ -74,20 +71,16 @@
53AC588920A9382B0031EDC9 /* GameStartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53AC588820A9382B0031EDC9 /* GameStartView.swift */; };
53AC588B20A9E9160031EDC9 /* GameObjects.json in Resources */ = {isa = PBXBuildFile; fileRef = 53AC588A20A9E9160031EDC9 /* GameObjects.json */; };
53AC588D20AA17130031EDC9 /* ObjectConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53AC588C20AA17130031EDC9 /* ObjectConfig.swift */; };
53AC589120AA2FF50031EDC9 /* BMSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588E20AA2FF50031EDC9 /* BMSCore.framework */; };
53AC589220AA2FF50031EDC9 /* BMSAnalyticsAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588F20AA2FF50031EDC9 /* BMSAnalyticsAPI.framework */; };
53AC589320AA2FF50031EDC9 /* BMSPush.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC589020AA2FF50031EDC9 /* BMSPush.framework */; };
53AC589420AA30030031EDC9 /* BMSAnalyticsAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588F20AA2FF50031EDC9 /* BMSAnalyticsAPI.framework */; };
53AC589520AA30030031EDC9 /* BMSAnalyticsAPI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588F20AA2FF50031EDC9 /* BMSAnalyticsAPI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
53AC589620AA30030031EDC9 /* BMSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588E20AA2FF50031EDC9 /* BMSCore.framework */; };
53AC589720AA30030031EDC9 /* BMSCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC588E20AA2FF50031EDC9 /* BMSCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
53AC589820AA30030031EDC9 /* BMSPush.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC589020AA2FF50031EDC9 /* BMSPush.framework */; };
53AC589920AA30030031EDC9 /* BMSPush.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53AC589020AA2FF50031EDC9 /* BMSPush.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
53BAF34820AB3BB200583BE6 /* AvatarClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53BAF34720AB3BB200583BE6 /* AvatarClient.swift */; };
53BAF34C20AB3E4A00583BE6 /* DefaultAvatar.json in Resources */ = {isa = PBXBuildFile; fileRef = 53BAF34B20AB3E4A00583BE6 /* DefaultAvatar.json */; };
53BAF35020AB52DF00583BE6 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53BAF34F20AB52DF00583BE6 /* MainTabBarController.swift */; };
53C06E3320BEF3C700C03BA6 /* Kingfisher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53C06E3220BEF3C700C03BA6 /* Kingfisher.framework */; };
53C06E3420BEF3CD00C03BA6 /* Kingfisher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53C06E3220BEF3C700C03BA6 /* Kingfisher.framework */; };
53C06E3520BEF3CD00C03BA6 /* Kingfisher.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53C06E3220BEF3C700C03BA6 /* Kingfisher.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
53C6D18B20ADBB10008DF112 /* ProjectRainbowModel_1753554316.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 53C6D18A20ADBB10008DF112 /* ProjectRainbowModel_1753554316.mlmodel */; };
53C953A220ABA1E40059F593 /* KituraServerCredentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C953A120ABA1E40059F593 /* KituraServerCredentials.swift */; };
Expand Down Expand Up @@ -232,16 +225,9 @@
531AAF9620A4B98F0056B24B /* Lumina.framework in Frameworks */,
53AC589420AA30030031EDC9 /* BMSAnalyticsAPI.framework in Frameworks */,
531AAF9720A4B98F0056B24B /* VisualRecognitionV3.framework in Frameworks */,
531AAF9820A4B9C80056B24B /* Lumina.framework in Frameworks */,
53AC589320AA2FF50031EDC9 /* BMSPush.framework in Frameworks */,
5365924320AB8F1000F76E37 /* SVProgressHUD.framework in Frameworks */,
53C06E3320BEF3C700C03BA6 /* Kingfisher.framework in Frameworks */,
53AC589620AA30030031EDC9 /* BMSCore.framework in Frameworks */,
53C06E3420BEF3CD00C03BA6 /* Kingfisher.framework in Frameworks */,
53AC589220AA2FF50031EDC9 /* BMSAnalyticsAPI.framework in Frameworks */,
53AC589120AA2FF50031EDC9 /* BMSCore.framework in Frameworks */,
531AAF9A20A4B9C80056B24B /* VisualRecognitionV3.framework in Frameworks */,
53AC589820AA30030031EDC9 /* BMSPush.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -553,7 +539,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0930;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = IBM;
TargetAttributes = {
533818FD209757B900DE66CB = {
Expand Down Expand Up @@ -825,7 +811,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.3;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -879,7 +865,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.3;
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ class LeaderboardTableViewCell: UITableViewCell {

class LeaderboardTableViewController: UITableViewController {
var leaderboard: [ScoreEntry]?
var yourUser: ScoreEntry?

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
SVProgressHUD.show(withStatus: "Loading Leaderboard...")
getLeaderboard()
do {
yourUser = try ScoreEntry.ClientPersistence.get()
getLeaderboard()
} catch {
print("Could not load your user")
}
}

override func viewDidLoad() {
Expand All @@ -46,7 +52,7 @@ class LeaderboardTableViewController: UITableViewController {
}

private func getLeaderboard() {
ScoreEntry.ServerCalls.getAll { entries, error in
ScoreEntry.ServerCalls.getAll(for: yourUser?.id) { entries, error in
DispatchQueue.main.async {
if error != nil {
SVProgressHUD.showError(withStatus: "Could not load leaderboard")
Expand Down Expand Up @@ -98,6 +104,9 @@ class LeaderboardTableViewController: UITableViewController {
cell.avatarImageView?.kf.indicatorType = .activity
cell.avatarImageView?.kf.setImage(with: url)
}
if yourUser?.username == currentEntry.username {
cell.backgroundColor = UIColor.RainbowColors.neutral
}
return cell
}

Expand Down
24 changes: 17 additions & 7 deletions iOS/rainbow/Model/ScoreEntry+Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension UIApplication {

var rainbowServerBaseURL: String {
var baseURL = UIApplication.shared.isDebugMode ? "http://localhost:8080" : "https://rainbow-scavenger-viz-rec.mybluemix.net" // need to update when we deploy
baseURL = "https://watsonml-vivatech.mybluemix.net/"
baseURL = "https://watsonml-vivatech.mybluemix.net/"
return baseURL
}
}
Expand Down Expand Up @@ -73,15 +73,25 @@ extension ScoreEntry {
}
}

static func getAll(completion: @escaping (_ entries: [ScoreEntry]?, _ error: RainbowClientError?) -> Void) {
static func getAll(for identifier: String?, completion: @escaping (_ entries: [ScoreEntry]?, _ error: RainbowClientError?) -> Void) {
guard let client = KituraKit(baseURL: UIApplication.shared.rainbowServerBaseURL) else {
return completion(nil, RainbowClientError.couldNotCreateClient)
}
client.get("/watsonml/leaderboard") { (entries: [ScoreEntry]?, error: RequestError?) in
if error != nil {
return completion(nil, RainbowClientError.couldNotGetEntries)
} else {
return completion(entries, nil)
if let identifier = identifier {
client.get("/watsonml/leaderboard", identifier: identifier) { (entries: [ScoreEntry]?, error: RequestError?) in
if error != nil {
return completion(nil, RainbowClientError.couldNotGetEntries)
} else {
return completion(entries, nil)
}
}
} else {
client.get("/watsonml/leaderboard") { (entries: [ScoreEntry]?, error: RequestError?) in
if error != nil {
return completion(nil, RainbowClientError.couldNotGetEntries)
} else {
return completion(entries, nil)
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions iOS/rainbow/Model/ScoreEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ struct ScoreEntry: Codable {
var objects: [ObjectEntry]?
var totalTime: Double?
}

extension ScoreEntry: Hashable {
var hashValue: Int {
return id?.hashValue ?? Int(INT_MAX)
}

static func == (lhs: ScoreEntry, rhs: ScoreEntry) -> Bool {
return lhs.id == rhs.id
}
}

0 comments on commit d8a9a06

Please sign in to comment.