From 2149245c954bb24477ae1451bbfa87c8868818c4 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 7 Jun 2017 18:00:50 +0200 Subject: [PATCH 01/24] initial logic --- Sources/Core/CoffeeManager.swift | 20 +++++++++++++++++++ .../CoffeeManagerInputProtocol.swift | 10 ++++++++++ Sources/Core/Models/Person.swift | 10 ++++++++++ Sources/Core/SpellChecker/SpellChecker.swift | 0 4 files changed, 40 insertions(+) create mode 100644 Sources/Core/CoffeeManager.swift create mode 100644 Sources/Core/Interface/CoffeeManagerInputProtocol.swift create mode 100644 Sources/Core/Models/Person.swift create mode 100644 Sources/Core/SpellChecker/SpellChecker.swift diff --git a/Sources/Core/CoffeeManager.swift b/Sources/Core/CoffeeManager.swift new file mode 100644 index 0000000..89a443b --- /dev/null +++ b/Sources/Core/CoffeeManager.swift @@ -0,0 +1,20 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation + +class CoffeeManager : NSObject { + open let persons : [Person] + + init(with persons: [Person]) { + self.persons = persons + } +} + +extension CoffeeManager : CoffeeManagerInputProtocol { + func process(text: String) { + + } +} diff --git a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift new file mode 100644 index 0000000..a8adda9 --- /dev/null +++ b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift @@ -0,0 +1,10 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation + +protocol CoffeeManagerInputProtocol { + func process(text:String) +} diff --git a/Sources/Core/Models/Person.swift b/Sources/Core/Models/Person.swift new file mode 100644 index 0000000..57b861c --- /dev/null +++ b/Sources/Core/Models/Person.swift @@ -0,0 +1,10 @@ +// +// Person.swift +// SwiftBot +// + +import Foundation + +struct Person { + let name : String +} diff --git a/Sources/Core/SpellChecker/SpellChecker.swift b/Sources/Core/SpellChecker/SpellChecker.swift new file mode 100644 index 0000000..e69de29 From 2b5c3b2d4a53778f0fdadc3262f7f6df2181fba1 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Fri, 23 Jun 2017 16:53:51 +0200 Subject: [PATCH 02/24] remove inheritance from NSObject --- Sources/Core/CoffeeManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Core/CoffeeManager.swift b/Sources/Core/CoffeeManager.swift index 89a443b..ba11a57 100644 --- a/Sources/Core/CoffeeManager.swift +++ b/Sources/Core/CoffeeManager.swift @@ -5,7 +5,7 @@ import Foundation -class CoffeeManager : NSObject { +class CoffeeManager { open let persons : [Person] init(with persons: [Person]) { From dab2370da30325c83034876801cb11c71b00ee72 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Tue, 27 Jun 2017 17:59:13 +0200 Subject: [PATCH 03/24] add dependencies to Package.swift for CoffeeBot --- Package.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index ef2cd5c..1644250 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,10 @@ let package = Package( dependencies:["BotsKit"]), Target( name:"SwiftBot", - dependencies:["ChatProviders","Storage","EchoBot"]) + dependencies:["ChatProviders","Storage","EchoBot"]), + Target( + name:"CoffeeBot", + dependencies:["BotsKit"]) ], dependencies: [ .Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2), From 1b3db3a94638bb0c90b3596f12a72849336550b5 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Tue, 27 Jun 2017 18:01:15 +0200 Subject: [PATCH 04/24] delete unnecessary files --- Sources/Core/CoffeeManager.swift | 20 ------------------- .../CoffeeManagerInputProtocol.swift | 10 ---------- Sources/Core/Models/Person.swift | 10 ---------- Sources/Core/SpellChecker/SpellChecker.swift | 0 4 files changed, 40 deletions(-) delete mode 100644 Sources/Core/CoffeeManager.swift delete mode 100644 Sources/Core/Interface/CoffeeManagerInputProtocol.swift delete mode 100644 Sources/Core/Models/Person.swift delete mode 100644 Sources/Core/SpellChecker/SpellChecker.swift diff --git a/Sources/Core/CoffeeManager.swift b/Sources/Core/CoffeeManager.swift deleted file mode 100644 index ba11a57..0000000 --- a/Sources/Core/CoffeeManager.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// CoffeeManager.swift -// SwiftBot -// - -import Foundation - -class CoffeeManager { - open let persons : [Person] - - init(with persons: [Person]) { - self.persons = persons - } -} - -extension CoffeeManager : CoffeeManagerInputProtocol { - func process(text: String) { - - } -} diff --git a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift deleted file mode 100644 index a8adda9..0000000 --- a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// CoffeeManager.swift -// SwiftBot -// - -import Foundation - -protocol CoffeeManagerInputProtocol { - func process(text:String) -} diff --git a/Sources/Core/Models/Person.swift b/Sources/Core/Models/Person.swift deleted file mode 100644 index 57b861c..0000000 --- a/Sources/Core/Models/Person.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// Person.swift -// SwiftBot -// - -import Foundation - -struct Person { - let name : String -} diff --git a/Sources/Core/SpellChecker/SpellChecker.swift b/Sources/Core/SpellChecker/SpellChecker.swift deleted file mode 100644 index e69de29..0000000 From 69c27c18a6f7d8ddc0bc0460eb065d8632bea634 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Tue, 27 Jun 2017 18:01:42 +0200 Subject: [PATCH 05/24] add models needed for CoffeeBot --- Sources/CoffeeBot/Models/Coffee.swift | 17 +++++++++++ Sources/CoffeeBot/Models/CoffeeAddition.swift | 9 ++++++ Sources/CoffeeBot/Models/CoffeeRequest.swift | 12 ++++++++ Sources/CoffeeBot/Models/CoffeeType.swift | 10 +++++++ Sources/CoffeeBot/Models/Session.swift | 28 +++++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 Sources/CoffeeBot/Models/Coffee.swift create mode 100644 Sources/CoffeeBot/Models/CoffeeAddition.swift create mode 100644 Sources/CoffeeBot/Models/CoffeeRequest.swift create mode 100644 Sources/CoffeeBot/Models/CoffeeType.swift create mode 100644 Sources/CoffeeBot/Models/Session.swift diff --git a/Sources/CoffeeBot/Models/Coffee.swift b/Sources/CoffeeBot/Models/Coffee.swift new file mode 100644 index 0000000..e44bdf6 --- /dev/null +++ b/Sources/CoffeeBot/Models/Coffee.swift @@ -0,0 +1,17 @@ +// +// Coffee.swift +// Coffee +// + +internal struct Coffee { + let type : CoffeeType + let additions : [CoffeeAddition] + var description : String { + get { + let additionsDescription = self.additions.map { (addition) -> String in + return addition.rawValue + } + return "\(self.type.rawValue) with \(additionsDescription)" + } + } +} diff --git a/Sources/CoffeeBot/Models/CoffeeAddition.swift b/Sources/CoffeeBot/Models/CoffeeAddition.swift new file mode 100644 index 0000000..f337be4 --- /dev/null +++ b/Sources/CoffeeBot/Models/CoffeeAddition.swift @@ -0,0 +1,9 @@ +// +// CoffeeAddition.swift +// CoffeeAddition +// + +public enum CoffeeAddition : String { + case milk + case sugar +} diff --git a/Sources/CoffeeBot/Models/CoffeeRequest.swift b/Sources/CoffeeBot/Models/CoffeeRequest.swift new file mode 100644 index 0000000..bf7debd --- /dev/null +++ b/Sources/CoffeeBot/Models/CoffeeRequest.swift @@ -0,0 +1,12 @@ +// +// CoffeeRequest.swift +// CoffeeRequest +// + +import Foundation +import BotsKit + +internal struct CoffeeRequest { + let person : Account + let coffee : Coffee +} diff --git a/Sources/CoffeeBot/Models/CoffeeType.swift b/Sources/CoffeeBot/Models/CoffeeType.swift new file mode 100644 index 0000000..248945f --- /dev/null +++ b/Sources/CoffeeBot/Models/CoffeeType.swift @@ -0,0 +1,10 @@ +// +// CoffeeType.swift +// CoffeeType +// + +internal enum CoffeeType : String { + case latte + case capuccino + case filterCoffee +} diff --git a/Sources/CoffeeBot/Models/Session.swift b/Sources/CoffeeBot/Models/Session.swift new file mode 100644 index 0000000..39801f3 --- /dev/null +++ b/Sources/CoffeeBot/Models/Session.swift @@ -0,0 +1,28 @@ +// +// Session.swift +// Session +// + +import Foundation +import BotsKit + +internal struct Session { + + let coffeesRequested : [CoffeeRequest] = [] + var membersReplied : [Account] { + get { + return self.coffeesRequested.map({ (request) -> Account in + return request.person + }) + } + } + + var description : String { + get { + let descriptions : [String] = self.coffeesRequested.map { (request) -> String in + return request.coffee.description + } + return descriptions.joined(separator: "\n") + } + } +} From 1cdea8fef7f30cf5073d62b14356a40fb837323d Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Tue, 27 Jun 2017 18:03:18 +0200 Subject: [PATCH 06/24] add initial impl. of CoffeeBot and CoffeeManager --- Sources/CoffeeBot/CoffeeBot.swift | 33 +++++++++++++ .../CoffeeBot/CoffeeBotInputProtocol.swift | 9 ++++ .../CoffeeManager/CoffeeManager.swift | 46 +++++++++++++++++++ .../CoffeeManagerInputProtocol.swift | 11 +++++ 4 files changed, 99 insertions(+) create mode 100644 Sources/CoffeeBot/CoffeeBot.swift create mode 100644 Sources/CoffeeBot/CoffeeBotInputProtocol.swift create mode 100644 Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift create mode 100644 Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift diff --git a/Sources/CoffeeBot/CoffeeBot.swift b/Sources/CoffeeBot/CoffeeBot.swift new file mode 100644 index 0000000..1729d9b --- /dev/null +++ b/Sources/CoffeeBot/CoffeeBot.swift @@ -0,0 +1,33 @@ +// +// CoffeeBot.swift +// CoffeeBot +// + +import LoggerAPI +import BotsKit + +public final class CoffeeBot : Bot { + + //MARK: Properties + public let name = "CoffeeBot" + public var sendActivity: Signal = Signal() + private let coffeeManager : CoffeeManager + + //MARK: Bot Protocol + public func dispatch(activity: Activity) -> DispatchResult { + self.coffeeManager.process(activity: activity) + return .ok + } + + //MARK: Lifecycle + public init() { + self.coffeeManager = CoffeeManager() + self.coffeeManager.botDelegate = self + } +} + +extension CoffeeBot : CoffeeBotInputProtocol { + func send(activity: Activity) { + self.sendActivity.update(activity) + } +} diff --git a/Sources/CoffeeBot/CoffeeBotInputProtocol.swift b/Sources/CoffeeBot/CoffeeBotInputProtocol.swift new file mode 100644 index 0000000..e5aa762 --- /dev/null +++ b/Sources/CoffeeBot/CoffeeBotInputProtocol.swift @@ -0,0 +1,9 @@ +// +// CoffeeBotInputProtocol.swift +// CoffeeBotInputProtocol +// +import BotsKit + +protocol CoffeeBotInputProtocol { + func send(activity:Activity) +} diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift new file mode 100644 index 0000000..91d9470 --- /dev/null +++ b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift @@ -0,0 +1,46 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation +import BotsKit + +class CoffeeManager { + + //MARK: Properties + fileprivate let session : Session + weak var botDelegate : CoffeeBot? + + //MARK: Lifecycle + init() { + self.session = Session() + } + + //MARK: Private + fileprivate func refreshSession() { + //read the current message session from db or disk + } + + fileprivate func hasEveryoneReplied(for activity:Activity) -> Bool { + return self.session.membersReplied.count == activity.conversation.members.count + } + + fileprivate func acknowledgeInputs(with activity:Activity) { + let updatedActivity = activity.replay(text: self.session.description) + self.botDelegate?.send(activity: updatedActivity) + } +} + +extension CoffeeManager : CoffeeManagerInputProtocol { + func process(activity: Activity) { + self.refreshSession() + + if hasEveryoneReplied(for: activity) { + self.acknowledgeInputs(with: activity) + //proceed to next steps + } else { + //process message and save to session + } + } +} diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift new file mode 100644 index 0000000..74e7bb9 --- /dev/null +++ b/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift @@ -0,0 +1,11 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation +import BotsKit + +protocol CoffeeManagerInputProtocol { + func process(activity:Activity) +} From d6b39710a3cd918353b5f2cedeb981cc9ea62da6 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 7 Jun 2017 18:00:50 +0200 Subject: [PATCH 07/24] initial logic --- Sources/Core/CoffeeManager.swift | 20 +++++++++++++++++++ .../CoffeeManagerInputProtocol.swift | 10 ++++++++++ Sources/Core/Models/Person.swift | 10 ++++++++++ Sources/Core/SpellChecker/SpellChecker.swift | 0 4 files changed, 40 insertions(+) create mode 100644 Sources/Core/CoffeeManager.swift create mode 100644 Sources/Core/Interface/CoffeeManagerInputProtocol.swift create mode 100644 Sources/Core/Models/Person.swift create mode 100644 Sources/Core/SpellChecker/SpellChecker.swift diff --git a/Sources/Core/CoffeeManager.swift b/Sources/Core/CoffeeManager.swift new file mode 100644 index 0000000..89a443b --- /dev/null +++ b/Sources/Core/CoffeeManager.swift @@ -0,0 +1,20 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation + +class CoffeeManager : NSObject { + open let persons : [Person] + + init(with persons: [Person]) { + self.persons = persons + } +} + +extension CoffeeManager : CoffeeManagerInputProtocol { + func process(text: String) { + + } +} diff --git a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift new file mode 100644 index 0000000..a8adda9 --- /dev/null +++ b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift @@ -0,0 +1,10 @@ +// +// CoffeeManager.swift +// SwiftBot +// + +import Foundation + +protocol CoffeeManagerInputProtocol { + func process(text:String) +} diff --git a/Sources/Core/Models/Person.swift b/Sources/Core/Models/Person.swift new file mode 100644 index 0000000..57b861c --- /dev/null +++ b/Sources/Core/Models/Person.swift @@ -0,0 +1,10 @@ +// +// Person.swift +// SwiftBot +// + +import Foundation + +struct Person { + let name : String +} diff --git a/Sources/Core/SpellChecker/SpellChecker.swift b/Sources/Core/SpellChecker/SpellChecker.swift new file mode 100644 index 0000000..e69de29 From 955b33f1132e2cc53474b459d24f05a3113b73ae Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:00:45 +0200 Subject: [PATCH 08/24] add AppointingService This commit adds the initial stub for AppointingService which chooses a person to prepare the coffees from given session --- .../Services/AppointingService.swift | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Sources/CoffeeBot/Services/AppointingService.swift diff --git a/Sources/CoffeeBot/Services/AppointingService.swift b/Sources/CoffeeBot/Services/AppointingService.swift new file mode 100644 index 0000000..9b52561 --- /dev/null +++ b/Sources/CoffeeBot/Services/AppointingService.swift @@ -0,0 +1,35 @@ +// +// AppointingService.swift +// AppointingService +// +// Created by Said Ozcan on 28/06/2017. +// + +import BotsKit + +internal protocol AppointingServiceProtocol { + func appointJobToAPerson(with session:Session) -> Account +} + +internal class AppointingService { + + //MARK: Private + fileprivate func chooseAPerson(from persons:[Account]) -> Account { + let randomPersonIndex = generateRandomNumber(in: 0..) -> Int { + //TODO: Generate random number here + return 0 + } +} + +extension AppointingService : AppointingServiceProtocol { + + func appointJobToAPerson(with session: Session) -> Account { + //TODO: There could be some logic to not to choose previously chosen members maybe. + //Or choose the person who asks for a lot of things + return self.chooseAPerson(from: session.membersReplied) + } +} From f730f35c02e0c090ebab4a6311927a23104fc6dd Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:01:14 +0200 Subject: [PATCH 09/24] add EntityRecognitionService This commit adds initial stub for EntityRecognitionService which parses given string to entities such as Coffee --- .../Services/EntityRecognitionService.swift | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Sources/CoffeeBot/Services/EntityRecognitionService.swift diff --git a/Sources/CoffeeBot/Services/EntityRecognitionService.swift b/Sources/CoffeeBot/Services/EntityRecognitionService.swift new file mode 100644 index 0000000..12481ed --- /dev/null +++ b/Sources/CoffeeBot/Services/EntityRecognitionService.swift @@ -0,0 +1,22 @@ +// +// EntityRecognitionService.swift +// PerfectLib +// +// Created by Said Ozcan on 28/06/2017. +// + +import Foundation + +internal protocol EntityRecognitionServiceProtocol { + func parse(_ text:String) -> [Coffee] +} + +internal class EntityRecognitionService {} + +extension EntityRecognitionService : EntityRecognitionServiceProtocol { + + func parse(_ text: String) -> [Coffee] { + //TODO: Parse entities in the given text and return relevant models + return [] + } +} From cb3c88c7225743525956aa8fd8b8abedc38e43df Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:01:48 +0200 Subject: [PATCH 10/24] add SessionService This commit adds initial stub for SessionService which has functionalities to store and restore the session --- .../CoffeeBot/Services/SessionService.swift | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Sources/CoffeeBot/Services/SessionService.swift diff --git a/Sources/CoffeeBot/Services/SessionService.swift b/Sources/CoffeeBot/Services/SessionService.swift new file mode 100644 index 0000000..b1738f8 --- /dev/null +++ b/Sources/CoffeeBot/Services/SessionService.swift @@ -0,0 +1,22 @@ +// +// SessionService.swift +// SessionService +// + +internal protocol SessionServiceProtocol { + func restoreSession() -> Session + func save(session:Session) +} + +internal class SessionService {} + +extension SessionService : SessionServiceProtocol { + + func restoreSession() -> Session { + return Session() + } + + func save(session: Session) { + + } +} From 6623c4f42786f29db59a2374992071042ae13037 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:02:20 +0200 Subject: [PATCH 11/24] add SpellCheckingService This commit adds initial stub for SpellCheckingService which normalizes a given text --- .../Services/SpellCheckingService.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Sources/CoffeeBot/Services/SpellCheckingService.swift diff --git a/Sources/CoffeeBot/Services/SpellCheckingService.swift b/Sources/CoffeeBot/Services/SpellCheckingService.swift new file mode 100644 index 0000000..8a5aace --- /dev/null +++ b/Sources/CoffeeBot/Services/SpellCheckingService.swift @@ -0,0 +1,18 @@ +// +// SpellCheckingService.swift +// SpellCheckingService +// + +internal protocol SpellCheckerServiceProtocol { + func normalize(_ text:String) -> String +} + +internal class SpellCheckingService {} + +extension SpellCheckingService : SpellCheckerServiceProtocol { + func normalize(_ text: String) -> String { + //TODO: Normalize the text via removing the symbols, numbers, irrelevant features, + //checking disambiguations and returning the normalized text + return text + } +} From f10ff07fd01d60e636270d712e50ab6fa970986d Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:03:06 +0200 Subject: [PATCH 12/24] add TextProcessingService Add inital stub for TextProcessingService which processes the given text and return a result --- .../Services/TextProcessingService.swift | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Sources/CoffeeBot/Services/TextProcessingService.swift diff --git a/Sources/CoffeeBot/Services/TextProcessingService.swift b/Sources/CoffeeBot/Services/TextProcessingService.swift new file mode 100644 index 0000000..ebeda71 --- /dev/null +++ b/Sources/CoffeeBot/Services/TextProcessingService.swift @@ -0,0 +1,35 @@ +// +// TextProcessingService.swift +// TextProcessingService +// + +internal enum TextProcessingServiceResult { + case success([T]) + case error(Error) +} + +internal protocol TextProcessingServiceProtocol { + func process(_ text:String) -> TextProcessingServiceResult +} + +internal class TextProcessingService { + + //MARK: Properties + fileprivate let spellCheckerService : SpellCheckingService + fileprivate let entityRecognitionService : EntityRecognitionService + + //MARK: Lifecycle + init(spellCheckerService:SpellCheckingService, entityRecognitionService:EntityRecognitionService) { + self.spellCheckerService = spellCheckerService + self.entityRecognitionService = entityRecognitionService + } +} + +extension TextProcessingService : TextProcessingServiceProtocol { + + func process(_ text:String) -> TextProcessingServiceResult { + let normalizedString = self.spellCheckerService.normalize(text) + let coffeesRequested = self.entityRecognitionService.parse(normalizedString) + return TextProcessingServiceResult.success(coffeesRequested) + } +} From dadd20b9052dbfa4990e34f3323cf70379fe6ca7 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:04:33 +0200 Subject: [PATCH 13/24] add amount property to Coffee --- Sources/CoffeeBot/Models/Coffee.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/CoffeeBot/Models/Coffee.swift b/Sources/CoffeeBot/Models/Coffee.swift index e44bdf6..75f7a61 100644 --- a/Sources/CoffeeBot/Models/Coffee.swift +++ b/Sources/CoffeeBot/Models/Coffee.swift @@ -4,6 +4,7 @@ // internal struct Coffee { + let amount : Int let type : CoffeeType let additions : [CoffeeAddition] var description : String { From 83d96bc5685427335c8c58d22d4b651d9ca0d45f Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:05:20 +0200 Subject: [PATCH 14/24] update description of Cofee model This commit updates the description of Coffee model where now it returns all descriptions of additions as string --- Sources/CoffeeBot/Models/Coffee.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CoffeeBot/Models/Coffee.swift b/Sources/CoffeeBot/Models/Coffee.swift index 75f7a61..f92911c 100644 --- a/Sources/CoffeeBot/Models/Coffee.swift +++ b/Sources/CoffeeBot/Models/Coffee.swift @@ -12,7 +12,7 @@ internal struct Coffee { let additionsDescription = self.additions.map { (addition) -> String in return addition.rawValue } - return "\(self.type.rawValue) with \(additionsDescription)" + return "\(self.type.rawValue) with \(additionsDescription.joined(separator:" "))" } } } From 7313101b0f5bc23abb4ea26a285fba7ff8db359a Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:05:53 +0200 Subject: [PATCH 15/24] move CoffeeManagerInputProtocol to CoffeeManager --- Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift | 6 +++++- .../CoffeeManager/CoffeeManagerInputProtocol.swift | 11 ----------- 2 files changed, 5 insertions(+), 12 deletions(-) delete mode 100644 Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift index 91d9470..d8ed1ef 100644 --- a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift +++ b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift @@ -5,6 +5,9 @@ import Foundation import BotsKit +internal protocol CoffeeManagerProtocol { + func process(activity:Activity) +} class CoffeeManager { @@ -32,7 +35,8 @@ class CoffeeManager { } } -extension CoffeeManager : CoffeeManagerInputProtocol { +extension CoffeeManager : CoffeeManagerProtocol { + func process(activity: Activity) { self.refreshSession() diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift deleted file mode 100644 index 74e7bb9..0000000 --- a/Sources/CoffeeBot/CoffeeManager/CoffeeManagerInputProtocol.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// CoffeeManager.swift -// SwiftBot -// - -import Foundation -import BotsKit - -protocol CoffeeManagerInputProtocol { - func process(activity:Activity) -} From c9ca73f69526cbf44bbe693b821e735de735c071 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:06:23 +0200 Subject: [PATCH 16/24] move CoffeeBotInputProtocol to CoffeeBot --- Sources/CoffeeBot/CoffeeBot.swift | 4 ++++ Sources/CoffeeBot/CoffeeBotInputProtocol.swift | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 Sources/CoffeeBot/CoffeeBotInputProtocol.swift diff --git a/Sources/CoffeeBot/CoffeeBot.swift b/Sources/CoffeeBot/CoffeeBot.swift index 1729d9b..407c360 100644 --- a/Sources/CoffeeBot/CoffeeBot.swift +++ b/Sources/CoffeeBot/CoffeeBot.swift @@ -6,6 +6,10 @@ import LoggerAPI import BotsKit +internal protocol CoffeeBotInputProtocol { + func send(activity:Activity) +} + public final class CoffeeBot : Bot { //MARK: Properties diff --git a/Sources/CoffeeBot/CoffeeBotInputProtocol.swift b/Sources/CoffeeBot/CoffeeBotInputProtocol.swift deleted file mode 100644 index e5aa762..0000000 --- a/Sources/CoffeeBot/CoffeeBotInputProtocol.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// CoffeeBotInputProtocol.swift -// CoffeeBotInputProtocol -// -import BotsKit - -protocol CoffeeBotInputProtocol { - func send(activity:Activity) -} From dc748263bce62d8fc0c0c636937084763724bcfe Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:07:29 +0200 Subject: [PATCH 17/24] update CoffeeRequest:cofee property This commit updates coffee property to become an array instead of one Coffee since a person may request multiple coffees --- Sources/CoffeeBot/Models/CoffeeRequest.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CoffeeBot/Models/CoffeeRequest.swift b/Sources/CoffeeBot/Models/CoffeeRequest.swift index bf7debd..f333b68 100644 --- a/Sources/CoffeeBot/Models/CoffeeRequest.swift +++ b/Sources/CoffeeBot/Models/CoffeeRequest.swift @@ -8,5 +8,5 @@ import BotsKit internal struct CoffeeRequest { let person : Account - let coffee : Coffee + let coffees : [Coffee] } From bbb022120204b57af115c240b40ede862c4fcaa8 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:07:59 +0200 Subject: [PATCH 18/24] add description to CoffeeRequest model --- Sources/CoffeeBot/Models/CoffeeRequest.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/CoffeeBot/Models/CoffeeRequest.swift b/Sources/CoffeeBot/Models/CoffeeRequest.swift index f333b68..923bf31 100644 --- a/Sources/CoffeeBot/Models/CoffeeRequest.swift +++ b/Sources/CoffeeBot/Models/CoffeeRequest.swift @@ -9,4 +9,11 @@ import BotsKit internal struct CoffeeRequest { let person : Account let coffees : [Coffee] + + var description : String { + let coffeeDescriptions = coffees.map { (coffee) -> String in + return coffee.description + } + return "\(person.name) would like to have: \n \(coffeeDescriptions.joined(separator:" "))" + } } From a8bc4088b20f0c1bf5976eca8669b3c7b91b09d0 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:08:41 +0200 Subject: [PATCH 19/24] make coffeesRequested property mutable in Session --- Sources/CoffeeBot/Models/Session.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CoffeeBot/Models/Session.swift b/Sources/CoffeeBot/Models/Session.swift index 39801f3..5979330 100644 --- a/Sources/CoffeeBot/Models/Session.swift +++ b/Sources/CoffeeBot/Models/Session.swift @@ -8,7 +8,7 @@ import BotsKit internal struct Session { - let coffeesRequested : [CoffeeRequest] = [] + var coffeesRequested : [CoffeeRequest] = [] var membersReplied : [Account] { get { return self.coffeesRequested.map({ (request) -> Account in From 4661e5aae957c3a113b34bbc9f120a93adfe8dc5 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:09:03 +0200 Subject: [PATCH 20/24] update description property in Session --- Sources/CoffeeBot/Models/Session.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CoffeeBot/Models/Session.swift b/Sources/CoffeeBot/Models/Session.swift index 5979330..07f2c1c 100644 --- a/Sources/CoffeeBot/Models/Session.swift +++ b/Sources/CoffeeBot/Models/Session.swift @@ -20,7 +20,7 @@ internal struct Session { var description : String { get { let descriptions : [String] = self.coffeesRequested.map { (request) -> String in - return request.coffee.description + return request.description } return descriptions.joined(separator: "\n") } From 777e527ebdd0a08f930c0131a9fd35d72676a431 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:11:58 +0200 Subject: [PATCH 21/24] delete old files again --- Sources/Core/CoffeeManager.swift | 20 ------------------- .../CoffeeManagerInputProtocol.swift | 10 ---------- Sources/Core/Models/Person.swift | 10 ---------- Sources/Core/SpellChecker/SpellChecker.swift | 0 4 files changed, 40 deletions(-) delete mode 100644 Sources/Core/CoffeeManager.swift delete mode 100644 Sources/Core/Interface/CoffeeManagerInputProtocol.swift delete mode 100644 Sources/Core/Models/Person.swift delete mode 100644 Sources/Core/SpellChecker/SpellChecker.swift diff --git a/Sources/Core/CoffeeManager.swift b/Sources/Core/CoffeeManager.swift deleted file mode 100644 index 89a443b..0000000 --- a/Sources/Core/CoffeeManager.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// CoffeeManager.swift -// SwiftBot -// - -import Foundation - -class CoffeeManager : NSObject { - open let persons : [Person] - - init(with persons: [Person]) { - self.persons = persons - } -} - -extension CoffeeManager : CoffeeManagerInputProtocol { - func process(text: String) { - - } -} diff --git a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift b/Sources/Core/Interface/CoffeeManagerInputProtocol.swift deleted file mode 100644 index a8adda9..0000000 --- a/Sources/Core/Interface/CoffeeManagerInputProtocol.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// CoffeeManager.swift -// SwiftBot -// - -import Foundation - -protocol CoffeeManagerInputProtocol { - func process(text:String) -} diff --git a/Sources/Core/Models/Person.swift b/Sources/Core/Models/Person.swift deleted file mode 100644 index 57b861c..0000000 --- a/Sources/Core/Models/Person.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// Person.swift -// SwiftBot -// - -import Foundation - -struct Person { - let name : String -} diff --git a/Sources/Core/SpellChecker/SpellChecker.swift b/Sources/Core/SpellChecker/SpellChecker.swift deleted file mode 100644 index e69de29..0000000 From 79da0f4e4c7269e2c0f365cc3ad781e79ca0e75a Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:13:26 +0200 Subject: [PATCH 22/24] initializing CoffeeManager with all services --- Sources/CoffeeBot/CoffeeBot.swift | 17 ++++++++++++++--- .../CoffeeBot/CoffeeManager/CoffeeManager.swift | 9 +++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Sources/CoffeeBot/CoffeeBot.swift b/Sources/CoffeeBot/CoffeeBot.swift index 407c360..6061985 100644 --- a/Sources/CoffeeBot/CoffeeBot.swift +++ b/Sources/CoffeeBot/CoffeeBot.swift @@ -12,12 +12,14 @@ internal protocol CoffeeBotInputProtocol { public final class CoffeeBot : Bot { - //MARK: Properties + //MARK: Bot Protocol Properties public let name = "CoffeeBot" public var sendActivity: Signal = Signal() + + //MARK: Other Properties private let coffeeManager : CoffeeManager - //MARK: Bot Protocol + //MARK: Bot Protocol Methods public func dispatch(activity: Activity) -> DispatchResult { self.coffeeManager.process(activity: activity) return .ok @@ -25,7 +27,16 @@ public final class CoffeeBot : Bot { //MARK: Lifecycle public init() { - self.coffeeManager = CoffeeManager() + let sessionService = SessionService() + let appointingService = AppointingService() + let spellCheckerService = SpellCheckingService() + let entityRecognitionService = EntityRecognitionService() + let textProcessingService = TextProcessingService(spellCheckerService: spellCheckerService, + entityRecognitionService: entityRecognitionService) + + self.coffeeManager = CoffeeManager(textProcessingService: textProcessingService, + appointingService:appointingService, + sessionService:sessionService) self.coffeeManager.botDelegate = self } } diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift index d8ed1ef..83e478e 100644 --- a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift +++ b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift @@ -13,11 +13,16 @@ class CoffeeManager { //MARK: Properties fileprivate let session : Session + fileprivate let textProcessingService : TextProcessingService + fileprivate let appointingService : AppointingService + fileprivate let sessionService : SessionService weak var botDelegate : CoffeeBot? //MARK: Lifecycle - init() { - self.session = Session() + init(textProcessingService:TextProcessingService, appointingService:AppointingService, sessionService:SessionService) { + self.textProcessingService = textProcessingService + self.appointingService = appointingService + self.sessionService = sessionService } //MARK: Private From 20f5f5e3802dbd0c2e9c2defe9f29dac37282b34 Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:15:27 +0200 Subject: [PATCH 23/24] implement initial flow for processing a message --- .../CoffeeManager/CoffeeManager.swift | 63 +++++++++++++++---- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift index 83e478e..a344465 100644 --- a/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift +++ b/Sources/CoffeeBot/CoffeeManager/CoffeeManager.swift @@ -5,6 +5,8 @@ import Foundation import BotsKit +import LoggerAPI + internal protocol CoffeeManagerProtocol { func process(activity:Activity) } @@ -12,7 +14,7 @@ internal protocol CoffeeManagerProtocol { class CoffeeManager { //MARK: Properties - fileprivate let session : Session + fileprivate var session : Session? = nil fileprivate let textProcessingService : TextProcessingService fileprivate let appointingService : AppointingService fileprivate let sessionService : SessionService @@ -26,16 +28,27 @@ class CoffeeManager { } //MARK: Private - fileprivate func refreshSession() { - //read the current message session from db or disk + fileprivate func hasEveryoneReplied(in conversation:Conversation, with currentSession:Session) -> Bool { + return currentSession.membersReplied.count == conversation.members.count + } + + fileprivate func isTimeoutPeriodFinished() -> Bool { + //TODO: Set a timeout for messages + //E.g. all coffee requests should be made within 2 minutes. + return false + } + + fileprivate func acknowledgeInputs(with activity:Activity, for session:Session) { + self.post(update: session.description, on: activity) } - fileprivate func hasEveryoneReplied(for activity:Activity) -> Bool { - return self.session.membersReplied.count == activity.conversation.members.count + fileprivate func postProcessingResult(chosenPerson:Account, session:Session, activity:Activity) { + let update = "\(chosenPerson.name) was selected to retrieve \(session.description). Congrats! ☕️" + self.post(update: update, on: activity) } - fileprivate func acknowledgeInputs(with activity:Activity) { - let updatedActivity = activity.replay(text: self.session.description) + fileprivate func post(update text:String, on activity:Activity) { + let updatedActivity = activity.replay(text: text) self.botDelegate?.send(activity: updatedActivity) } } @@ -43,13 +56,39 @@ class CoffeeManager { extension CoffeeManager : CoffeeManagerProtocol { func process(activity: Activity) { - self.refreshSession() - if hasEveryoneReplied(for: activity) { - self.acknowledgeInputs(with: activity) + //Restoring current context + self.session = self.sessionService.restoreSession() + guard var session = self.session else { return } + + //Processing the current message + let processingResult = self.textProcessingService.process(activity.text) + + //Saving the coffee to session + switch processingResult { + case .success(let coffees): + let coffeesRequested = CoffeeRequest(person: activity.from, coffees: coffees) + session.coffeesRequested.append(coffeesRequested) + self.sessionService.save(session: session) + + case .error(let error): + Log.error("An error occured during processing message:\(error.localizedDescription)") + return + } + + //Dispatching further events + if + hasEveryoneReplied(in: activity.conversation, with: session) || + isTimeoutPeriodFinished() + { + //Printing acknowledgement of current requests + self.acknowledgeInputs(with: activity, for: session) + + self.post(update: "Finding the lucky one...", on: activity) + //proceed to next steps - } else { - //process message and save to session + let luckyPerson = self.appointingService.appointJobToAPerson(with: session) + self.postProcessingResult(chosenPerson: luckyPerson, session: session, activity: activity) } } } From 4686a88ed18ecf5713f3c353fda01c151e88c27c Mon Sep 17 00:00:00 2001 From: Said Ozcan Date: Wed, 28 Jun 2017 03:21:30 +0200 Subject: [PATCH 24/24] delete old spellchecker file This commit deletes old spell checker file since we can always restore it from .git history to use in new SpellChecker class. --- Sources/CoffeeBot/spellchecker.swift | 44 ---------------------------- 1 file changed, 44 deletions(-) delete mode 100644 Sources/CoffeeBot/spellchecker.swift diff --git a/Sources/CoffeeBot/spellchecker.swift b/Sources/CoffeeBot/spellchecker.swift deleted file mode 100644 index e3bd97a..0000000 --- a/Sources/CoffeeBot/spellchecker.swift +++ /dev/null @@ -1,44 +0,0 @@ - -import Foundation -import PerfectCURL - -func testFunc() -> String { - return "HueHue" -} - -class SpellCheker { - - internal func sendRequest(text: String, completion: @escaping (String?) -> (Void)) - { - do { - let body = self.textInBodyFormat(text: text) - let json = try CURLRequest("https://montanaflynn-spellcheck.p.mashape.com/check?text=" + body, .failOnError, - .httpMethod(CURLRequest.HTTPMethod.get), - .addHeader(.fromStandard(name: "X-Mashape-Key"), "OA5qHL58kvmshkz5xa4FQowNtD3tp1cD0n2jsnPY9TFf28l8Ka"), - .addHeader(.fromStandard(name: "Accept"), "application/json") - ).perform().bodyJSON - - let suggestion = self.suggestionFromJSON(json: json) - completion(suggestion) - } - catch let error { - fatalError("\(error)") - } - } - - private func textInBodyFormat(text: String) -> String - { - let result = text.replacingOccurrences(of: " ", with: "+") - return result - } - - private func suggestionFromJSON(json: [String:Any]) -> String? - { -// print("json: \(json)") - guard let result = json["suggestion"] as? String else { - return nil - } - return result - } -} -