Organize everything into operations
This commit is contained in:
@@ -7,6 +7,10 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
CD602056219B5DFD0024D9C5 /* MBIMBridgeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CD602055219B5DFD0024D9C5 /* MBIMBridgeOperation.m */; };
|
||||||
|
CD60205C219B623F0024D9C5 /* MBIMMessagesListOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CD60205B219B623F0024D9C5 /* MBIMMessagesListOperation.m */; };
|
||||||
|
CD60205F219B674B0024D9C5 /* MBIMConversationListOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CD60205E219B674B0024D9C5 /* MBIMConversationListOperation.m */; };
|
||||||
|
CD602062219B68950024D9C5 /* MBIMSendMessageOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CD602061219B68950024D9C5 /* MBIMSendMessageOperation.m */; };
|
||||||
CDF62335219A895D00690038 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF62334219A895D00690038 /* main.m */; };
|
CDF62335219A895D00690038 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF62334219A895D00690038 /* main.m */; };
|
||||||
CDF62339219A8A5600690038 /* MBIMBridge.h in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4469219A4BC300F2AC00 /* MBIMBridge.h */; };
|
CDF62339219A8A5600690038 /* MBIMBridge.h in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4469219A4BC300F2AC00 /* MBIMBridge.h */; };
|
||||||
CDF6233A219A8A5600690038 /* MBIMBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C446A219A4BC300F2AC00 /* MBIMBridge.m */; };
|
CDF6233A219A8A5600690038 /* MBIMBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C446A219A4BC300F2AC00 /* MBIMBridge.m */; };
|
||||||
@@ -102,6 +106,14 @@
|
|||||||
1A33B43C219A5ACD0034485A /* OSXDebugDefaults.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OSXDebugDefaults.xcconfig; sourceTree = "<group>"; };
|
1A33B43C219A5ACD0034485A /* OSXDebugDefaults.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OSXDebugDefaults.xcconfig; sourceTree = "<group>"; };
|
||||||
1A33B43D219A5ACD0034485A /* ReleaseDefaults.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ReleaseDefaults.xcconfig; sourceTree = "<group>"; };
|
1A33B43D219A5ACD0034485A /* ReleaseDefaults.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ReleaseDefaults.xcconfig; sourceTree = "<group>"; };
|
||||||
1A33B43E219A5BD80034485A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
1A33B43E219A5BD80034485A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||||
|
CD602054219B5DFD0024D9C5 /* MBIMBridgeOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBIMBridgeOperation.h; sourceTree = "<group>"; };
|
||||||
|
CD602055219B5DFD0024D9C5 /* MBIMBridgeOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBIMBridgeOperation.m; sourceTree = "<group>"; };
|
||||||
|
CD60205A219B623F0024D9C5 /* MBIMMessagesListOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBIMMessagesListOperation.h; sourceTree = "<group>"; };
|
||||||
|
CD60205B219B623F0024D9C5 /* MBIMMessagesListOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBIMMessagesListOperation.m; sourceTree = "<group>"; };
|
||||||
|
CD60205D219B674B0024D9C5 /* MBIMConversationListOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBIMConversationListOperation.h; sourceTree = "<group>"; };
|
||||||
|
CD60205E219B674B0024D9C5 /* MBIMConversationListOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBIMConversationListOperation.m; sourceTree = "<group>"; };
|
||||||
|
CD602060219B68950024D9C5 /* MBIMSendMessageOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBIMSendMessageOperation.h; sourceTree = "<group>"; };
|
||||||
|
CD602061219B68950024D9C5 /* MBIMSendMessageOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBIMSendMessageOperation.m; sourceTree = "<group>"; };
|
||||||
CDF62312219A869000690038 /* GCDWebServer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GCDWebServer.xcodeproj; path = GCDWebServer/GCDWebServer.xcodeproj; sourceTree = "<group>"; };
|
CDF62312219A869000690038 /* GCDWebServer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GCDWebServer.xcodeproj; path = GCDWebServer/GCDWebServer.xcodeproj; sourceTree = "<group>"; };
|
||||||
CDF62332219A895D00690038 /* kordophoned */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kordophoned; sourceTree = BUILT_PRODUCTS_DIR; };
|
CDF62332219A895D00690038 /* kordophoned */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kordophoned; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
CDF62334219A895D00690038 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
CDF62334219A895D00690038 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
@@ -170,6 +182,7 @@
|
|||||||
1A0C446D219A4BCD00F2AC00 /* Bridge */ = {
|
1A0C446D219A4BCD00F2AC00 /* Bridge */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CD60204C219B5D710024D9C5 /* Operations */,
|
||||||
1A0C4469219A4BC300F2AC00 /* MBIMBridge.h */,
|
1A0C4469219A4BC300F2AC00 /* MBIMBridge.h */,
|
||||||
1A0C446A219A4BC300F2AC00 /* MBIMBridge.m */,
|
1A0C446A219A4BC300F2AC00 /* MBIMBridge.m */,
|
||||||
);
|
);
|
||||||
@@ -187,6 +200,21 @@
|
|||||||
path = "Config Files";
|
path = "Config Files";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CD60204C219B5D710024D9C5 /* Operations */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CD602054219B5DFD0024D9C5 /* MBIMBridgeOperation.h */,
|
||||||
|
CD602055219B5DFD0024D9C5 /* MBIMBridgeOperation.m */,
|
||||||
|
CD60205A219B623F0024D9C5 /* MBIMMessagesListOperation.h */,
|
||||||
|
CD60205B219B623F0024D9C5 /* MBIMMessagesListOperation.m */,
|
||||||
|
CD60205D219B674B0024D9C5 /* MBIMConversationListOperation.h */,
|
||||||
|
CD60205E219B674B0024D9C5 /* MBIMConversationListOperation.m */,
|
||||||
|
CD602060219B68950024D9C5 /* MBIMSendMessageOperation.h */,
|
||||||
|
CD602061219B68950024D9C5 /* MBIMSendMessageOperation.m */,
|
||||||
|
);
|
||||||
|
path = Operations;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
CDF62313219A869000690038 /* Products */ = {
|
CDF62313219A869000690038 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -330,6 +358,10 @@
|
|||||||
CDF62339219A8A5600690038 /* MBIMBridge.h in Sources */,
|
CDF62339219A8A5600690038 /* MBIMBridge.h in Sources */,
|
||||||
CDF6233A219A8A5600690038 /* MBIMBridge.m in Sources */,
|
CDF6233A219A8A5600690038 /* MBIMBridge.m in Sources */,
|
||||||
CDF62335219A895D00690038 /* main.m in Sources */,
|
CDF62335219A895D00690038 /* main.m in Sources */,
|
||||||
|
CD60205C219B623F0024D9C5 /* MBIMMessagesListOperation.m in Sources */,
|
||||||
|
CD602062219B68950024D9C5 /* MBIMSendMessageOperation.m in Sources */,
|
||||||
|
CD602056219B5DFD0024D9C5 /* MBIMBridgeOperation.m in Sources */,
|
||||||
|
CD60205F219B674B0024D9C5 /* MBIMConversationListOperation.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "MBIMBridge.h"
|
#import "MBIMBridge.h"
|
||||||
|
#import "MBIMBridgeOperation.h"
|
||||||
|
|
||||||
#import <GCDWebServers/GCDWebServers.h>
|
#import <GCDWebServers/GCDWebServers.h>
|
||||||
|
|
||||||
@@ -18,12 +19,9 @@
|
|||||||
|
|
||||||
static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||||
|
|
||||||
static NSString *const kAPIEndpointConversationList = @"conversations";
|
|
||||||
static NSString *const kAPIEndpointConversationContents = @"messages";
|
|
||||||
static NSString *const kAPIEndpointSendMessage = @"sendMessage";
|
|
||||||
|
|
||||||
@interface MBIMBridge (/* INTERNAL */)
|
@interface MBIMBridge (/* INTERNAL */)
|
||||||
@property (nonatomic, strong) GCDWebServer *webServer;
|
@property (nonatomic, strong) GCDWebServer *webServer;
|
||||||
|
@property (nonatomic, strong) NSOperationQueue *operationQueue;
|
||||||
|
|
||||||
- (instancetype)_init;
|
- (instancetype)_init;
|
||||||
@end
|
@end
|
||||||
@@ -50,6 +48,8 @@ static NSString *const kAPIEndpointSendMessage = @"sendMessage";
|
|||||||
|
|
||||||
[sDaemonController setDelegate:self];
|
[sDaemonController setDelegate:self];
|
||||||
[sDaemonListener addHandler:self];
|
[sDaemonListener addHandler:self];
|
||||||
|
|
||||||
|
_operationQueue = [[NSOperationQueue alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -108,28 +108,21 @@ static NSString *const kAPIEndpointSendMessage = @"sendMessage";
|
|||||||
NSLog(@"chat items changed: %@", notification);
|
NSLog(@"chat items changed: %@", notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_sendMessage:(NSString *)messageBody toChatWithGUID:(NSString *)chatGUID
|
|
||||||
{
|
|
||||||
IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
|
|
||||||
IMHandle *handle = [[iMessageAccount arrayOfAllIMHandles] firstObject];
|
|
||||||
|
|
||||||
NSAttributedString *replyAttrString = [[NSAttributedString alloc] initWithString:messageBody];
|
|
||||||
IMMessage *reply = [IMMessage fromMeIMHandle:handle withText:replyAttrString fileTransferGUIDs:@[] flags:kIMMessageFinished];
|
|
||||||
|
|
||||||
IMChat *chat = [sChatRegistry existingChatWithGUID:chatGUID];
|
|
||||||
if (!chat) {
|
|
||||||
NSLog(@"Chat does not exist: %@", chatGUID);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
[chat sendMessage:reply];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Web Server initialization
|
#pragma mark Web Server initialization
|
||||||
|
|
||||||
|
- (void)_handleAsyncServerRequest:(GCDWebServerRequest *)request completion:(GCDWebServerCompletionBlock)completion
|
||||||
|
{
|
||||||
|
NSString *endpointName = [[request URL] lastPathComponent];
|
||||||
|
Class operationClass = [MBIMBridgeOperation operationClassForEndpointName:endpointName];
|
||||||
|
if (operationClass != nil) {
|
||||||
|
MBIMBridgeOperation *operation = [[operationClass alloc] initWithRequest:request completion:completion];
|
||||||
|
[[self operationQueue] addOperation:operation];
|
||||||
|
} else {
|
||||||
|
completion([GCDWebServerDataResponse responseWithStatusCode:404]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)startWebServer
|
- (void)startWebServer
|
||||||
{
|
{
|
||||||
[GCDWebServer setLogLevel:3];
|
[GCDWebServer setLogLevel:3];
|
||||||
@@ -138,96 +131,15 @@ static NSString *const kAPIEndpointSendMessage = @"sendMessage";
|
|||||||
self.webServer = [[GCDWebServer alloc] init];
|
self.webServer = [[GCDWebServer alloc] init];
|
||||||
[self.webServer addDefaultHandlerForMethod:@"GET"
|
[self.webServer addDefaultHandlerForMethod:@"GET"
|
||||||
requestClass:[GCDWebServerRequest class]
|
requestClass:[GCDWebServerRequest class]
|
||||||
processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) { return [weakSelf _handleWebServerRequest:request]; }];
|
asyncProcessBlock:^(__kindof GCDWebServerRequest * _Nonnull request, GCDWebServerCompletionBlock _Nonnull completionBlock) { [weakSelf _handleAsyncServerRequest:request completion:completionBlock]; }];
|
||||||
|
|
||||||
[self.webServer addDefaultHandlerForMethod:@"POST"
|
[self.webServer addDefaultHandlerForMethod:@"POST"
|
||||||
requestClass:[GCDWebServerURLEncodedFormRequest class]
|
requestClass:[GCDWebServerURLEncodedFormRequest class]
|
||||||
processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) { return [weakSelf _handleWebServerPOST:(GCDWebServerURLEncodedFormRequest *)request]; }];
|
asyncProcessBlock:^(__kindof GCDWebServerRequest * _Nonnull request, GCDWebServerCompletionBlock _Nonnull completionBlock) { [weakSelf _handleAsyncServerRequest:request completion:completionBlock]; }];
|
||||||
|
|
||||||
[self.webServer startWithPort:8080 bonjourName:nil];
|
[self.webServer startWithPort:8080 bonjourName:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GCDWebServerResponse *)_handleWebServerPOST:(__kindof GCDWebServerURLEncodedFormRequest * _Nonnull)request
|
|
||||||
{
|
|
||||||
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[request URL] resolvingAgainstBaseURL:NO];
|
|
||||||
NSString *endpoint = [[urlComponents path] lastPathComponent];
|
|
||||||
|
|
||||||
if ([endpoint isEqualToString:kAPIEndpointSendMessage]) {
|
|
||||||
NSDictionary *args = [request arguments];
|
|
||||||
|
|
||||||
NSString *guid = [args objectForKey:@"guid"];
|
|
||||||
NSString *messageBody = [args objectForKey:@"body"];
|
|
||||||
BOOL result = [self _sendMessage:messageBody toChatWithGUID:guid];
|
|
||||||
if (result) {
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:200];
|
|
||||||
} else {
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:500];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:404];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (GCDWebServerResponse *)_handleWebServerRequest:(__kindof GCDWebServerRequest * _Nonnull)request
|
|
||||||
{
|
|
||||||
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[request URL] resolvingAgainstBaseURL:NO];
|
|
||||||
NSString *endpoint = [[urlComponents path] lastPathComponent];
|
|
||||||
|
|
||||||
if ([endpoint isEqualToString:kAPIEndpointConversationList]) {
|
|
||||||
NSArray<IMChat *> *chats = [sChatRegistry allExistingChats];
|
|
||||||
|
|
||||||
NSMutableArray *conversations = [NSMutableArray array];
|
|
||||||
for (IMChat *chat in chats) {
|
|
||||||
NSMutableDictionary *chatDict = [NSMutableDictionary dictionary];
|
|
||||||
chatDict[@"guid"] = [chat guid];
|
|
||||||
chatDict[@"displayName"] = [chat displayName];
|
|
||||||
chatDict[@"date"] = GCDWebServerFormatRFC822([chat lastFinishedMessageDate]);
|
|
||||||
|
|
||||||
[conversations addObject:chatDict];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [GCDWebServerDataResponse responseWithJSONObject:conversations];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([endpoint isEqualToString:kAPIEndpointConversationContents]) {
|
|
||||||
NSString *guid = nil;
|
|
||||||
for (NSURLQueryItem *queryItem in [urlComponents queryItems]) {
|
|
||||||
if ([[queryItem name] isEqualToString:@"guid"]) {
|
|
||||||
guid = [queryItem value];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!guid) {
|
|
||||||
NSLog(@"No query item provided");
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:500];
|
|
||||||
}
|
|
||||||
|
|
||||||
IMChat *chat = [sChatRegistry existingChatWithGUID:guid];
|
|
||||||
if (!chat) {
|
|
||||||
NSLog(@"Chat with guid: %@ not found", guid);
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:500];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load messages
|
|
||||||
[chat loadMessagesBeforeDate:[NSDate date] limit:50 loadImmediately:YES];
|
|
||||||
|
|
||||||
NSMutableArray *messages = [NSMutableArray array];
|
|
||||||
for (IMMessageItem *imMessage in [[chat chatItems] messages]) {
|
|
||||||
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
|
|
||||||
messageDict[@"text"] = [[imMessage body] string];
|
|
||||||
messageDict[@"date"] = GCDWebServerFormatRFC822([imMessage time]);
|
|
||||||
messageDict[@"sender"] = [imMessage sender];
|
|
||||||
[messages addObject:messageDict];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [GCDWebServerDataResponse responseWithJSONObject:messages];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return [GCDWebServerDataResponse responseWithStatusCode:404];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Daemon lifecycle
|
#pragma mark Daemon lifecycle
|
||||||
|
|
||||||
|
|||||||
25
kordophone/Bridge/Operations/MBIMBridgeOperation.h
Normal file
25
kordophone/Bridge/Operations/MBIMBridgeOperation.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// MBIMBridgeOperation.h
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <GCDWebServers/GCDWebServers.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MBIMBridgeOperation : NSOperation
|
||||||
|
@property (class, nonatomic, readonly) NSString *endpointName;
|
||||||
|
|
||||||
|
@property (nonatomic, readonly) GCDWebServerRequest *request;
|
||||||
|
@property (nonatomic, readonly) GCDWebServerCompletionBlock serverCompletionBlock;
|
||||||
|
|
||||||
|
+ (nullable Class)operationClassForEndpointName:(NSString *)endpointName;
|
||||||
|
- (instancetype)initWithRequest:(GCDWebServerRequest *)request completion:(GCDWebServerCompletionBlock)completionBlock;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
58
kordophone/Bridge/Operations/MBIMBridgeOperation.m
Normal file
58
kordophone/Bridge/Operations/MBIMBridgeOperation.m
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// MBIMBridgeOperation.m
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMBridgeOperation.h"
|
||||||
|
|
||||||
|
@interface MBIMBridgeOperation (/*INTERNAL*/)
|
||||||
|
@property (nonatomic, copy) GCDWebServerCompletionBlock serverCompletionBlock;
|
||||||
|
@property (nonatomic, strong) GCDWebServerRequest *request;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MBIMBridgeOperation
|
||||||
|
|
||||||
|
+ (NSString *)endpointName
|
||||||
|
{
|
||||||
|
// To be inplemented by subclasses
|
||||||
|
return @"__unimplemented__";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSMutableDictionary *)_operationClassMapping
|
||||||
|
{
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
static NSMutableDictionary *operationClassMapping = nil;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
operationClassMapping = [[NSMutableDictionary alloc] init];
|
||||||
|
});
|
||||||
|
|
||||||
|
return operationClassMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)load
|
||||||
|
{
|
||||||
|
if ([self class] != [MBIMBridgeOperation class]) {
|
||||||
|
[[self _operationClassMapping] setObject:[self class] forKey:[self endpointName]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (nullable Class)operationClassForEndpointName:(NSString *)endpointName
|
||||||
|
{
|
||||||
|
return [[self _operationClassMapping] objectForKey:endpointName];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithRequest:(GCDWebServerRequest *)request completion:(GCDWebServerCompletionBlock)completionBlock
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self.request = request;
|
||||||
|
self.serverCompletionBlock = completionBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
kordophone/Bridge/Operations/MBIMConversationListOperation.h
Normal file
17
kordophone/Bridge/Operations/MBIMConversationListOperation.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// MBIMConversationListOperation.h
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMBridgeOperation.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MBIMConversationListOperation : MBIMBridgeOperation
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
40
kordophone/Bridge/Operations/MBIMConversationListOperation.m
Normal file
40
kordophone/Bridge/Operations/MBIMConversationListOperation.m
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// MBIMConversationListOperation.m
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMConversationListOperation.h"
|
||||||
|
|
||||||
|
#import <IMCore/IMCore.h>
|
||||||
|
|
||||||
|
@implementation MBIMConversationListOperation
|
||||||
|
|
||||||
|
+ (void)load { [super load]; }
|
||||||
|
|
||||||
|
+ (NSString *)endpointName
|
||||||
|
{
|
||||||
|
return @"conversations";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)main
|
||||||
|
{
|
||||||
|
NSArray<IMChat *> *chats = [sChatRegistry allExistingChats];
|
||||||
|
|
||||||
|
NSMutableArray *conversations = [NSMutableArray array];
|
||||||
|
for (IMChat *chat in chats) {
|
||||||
|
NSMutableDictionary *chatDict = [NSMutableDictionary dictionary];
|
||||||
|
chatDict[@"guid"] = [chat guid];
|
||||||
|
chatDict[@"displayName"] = [chat displayName];
|
||||||
|
chatDict[@"date"] = GCDWebServerFormatRFC822([chat lastFinishedMessageDate]);
|
||||||
|
|
||||||
|
[conversations addObject:chatDict];
|
||||||
|
}
|
||||||
|
|
||||||
|
GCDWebServerResponse *response = [GCDWebServerDataResponse responseWithJSONObject:conversations];
|
||||||
|
self.serverCompletionBlock(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
kordophone/Bridge/Operations/MBIMMessagesListOperation.h
Normal file
17
kordophone/Bridge/Operations/MBIMMessagesListOperation.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// MBIMMessagesListOperation.h
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMBridgeOperation.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MBIMMessagesListOperation : MBIMBridgeOperation
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
67
kordophone/Bridge/Operations/MBIMMessagesListOperation.m
Normal file
67
kordophone/Bridge/Operations/MBIMMessagesListOperation.m
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// MBIMMessagesListOperation.m
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMMessagesListOperation.h"
|
||||||
|
|
||||||
|
#import <IMCore/IMCore.h>
|
||||||
|
|
||||||
|
@implementation MBIMMessagesListOperation
|
||||||
|
|
||||||
|
+ (void)load { [super load]; }
|
||||||
|
|
||||||
|
+ (NSString *)endpointName
|
||||||
|
{
|
||||||
|
return @"messages";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)main
|
||||||
|
{
|
||||||
|
GCDWebServerResponse *response = nil;
|
||||||
|
do {
|
||||||
|
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[self.request URL] resolvingAgainstBaseURL:NO];
|
||||||
|
|
||||||
|
NSString *guid = nil;
|
||||||
|
for (NSURLQueryItem *queryItem in [urlComponents queryItems]) {
|
||||||
|
if ([[queryItem name] isEqualToString:@"guid"]) {
|
||||||
|
guid = [queryItem value];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!guid) {
|
||||||
|
NSLog(@"No query item provided");
|
||||||
|
response = [GCDWebServerDataResponse responseWithStatusCode:500];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMChat *chat = [sChatRegistry existingChatWithGUID:guid];
|
||||||
|
if (!chat) {
|
||||||
|
NSLog(@"Chat with guid: %@ not found", guid);
|
||||||
|
response = [GCDWebServerDataResponse responseWithStatusCode:500];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load messages
|
||||||
|
[chat loadMessagesBeforeDate:[NSDate date] limit:50 loadImmediately:YES];
|
||||||
|
|
||||||
|
NSMutableArray *messages = [NSMutableArray array];
|
||||||
|
for (IMMessageItem *imMessage in [[chat chatItems] messages]) {
|
||||||
|
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
|
||||||
|
messageDict[@"text"] = [[imMessage body] string];
|
||||||
|
messageDict[@"date"] = GCDWebServerFormatRFC822([imMessage time]);
|
||||||
|
messageDict[@"sender"] = [imMessage sender];
|
||||||
|
[messages addObject:messageDict];
|
||||||
|
}
|
||||||
|
|
||||||
|
response = [GCDWebServerDataResponse responseWithJSONObject:messages];
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
self.serverCompletionBlock(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
kordophone/Bridge/Operations/MBIMSendMessageOperation.h
Normal file
17
kordophone/Bridge/Operations/MBIMSendMessageOperation.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// MBIMSendMessageOperation.h
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMBridgeOperation.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface MBIMSendMessageOperation : MBIMBridgeOperation
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
63
kordophone/Bridge/Operations/MBIMSendMessageOperation.m
Normal file
63
kordophone/Bridge/Operations/MBIMSendMessageOperation.m
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// MBIMSendMessageOperation.m
|
||||||
|
// kordophoned
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 11/13/18.
|
||||||
|
// Copyright © 2018 James Magahern. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MBIMSendMessageOperation.h"
|
||||||
|
|
||||||
|
#import <IMCore/IMCore.h>
|
||||||
|
#import <IMCore/IMCore_Private.h>
|
||||||
|
|
||||||
|
@implementation MBIMSendMessageOperation
|
||||||
|
|
||||||
|
+ (void)load { [super load]; }
|
||||||
|
|
||||||
|
+ (NSString *)endpointName
|
||||||
|
{
|
||||||
|
return @"sendMessage";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_sendMessage:(NSString *)messageBody toChatWithGUID:(NSString *)chatGUID
|
||||||
|
{
|
||||||
|
IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
|
||||||
|
IMHandle *handle = [[iMessageAccount arrayOfAllIMHandles] firstObject];
|
||||||
|
|
||||||
|
NSAttributedString *replyAttrString = [[NSAttributedString alloc] initWithString:messageBody];
|
||||||
|
IMMessage *reply = [IMMessage fromMeIMHandle:handle withText:replyAttrString fileTransferGUIDs:@[] flags:kIMMessageFinished];
|
||||||
|
|
||||||
|
IMChat *chat = [sChatRegistry existingChatWithGUID:chatGUID];
|
||||||
|
if (!chat) {
|
||||||
|
NSLog(@"Chat does not exist: %@", chatGUID);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
[chat sendMessage:reply];
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)main
|
||||||
|
{
|
||||||
|
assert([self.request isKindOfClass:[GCDWebServerURLEncodedFormRequest class]]);
|
||||||
|
|
||||||
|
GCDWebServerURLEncodedFormRequest *formRequest = (GCDWebServerURLEncodedFormRequest *)self.request;
|
||||||
|
NSDictionary *args = [formRequest arguments];
|
||||||
|
|
||||||
|
NSString *guid = [args objectForKey:@"guid"];
|
||||||
|
NSString *messageBody = [args objectForKey:@"body"];
|
||||||
|
BOOL result = [self _sendMessage:messageBody toChatWithGUID:guid];
|
||||||
|
|
||||||
|
GCDWebServerResponse *response = nil;
|
||||||
|
if (result) {
|
||||||
|
response = [GCDWebServerDataResponse responseWithStatusCode:200];
|
||||||
|
} else {
|
||||||
|
response = [GCDWebServerDataResponse responseWithStatusCode:500];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serverCompletionBlock(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user