Supports polling for updates
This commit is contained in:
@@ -8,7 +8,9 @@
|
||||
|
||||
#import "MBIMBridge.h"
|
||||
#import "MBIMBridgeOperation.h"
|
||||
#import "MBIMConcurrentHTTPServer.h"
|
||||
#import "MBIMHTTPConnection.h"
|
||||
#import "MBIMUpdateQueue.h"
|
||||
#import "hooking.h"
|
||||
|
||||
#import <CocoaHTTPServer/HTTPServer.h>
|
||||
@@ -22,7 +24,7 @@
|
||||
static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
|
||||
@interface MBIMBridge (/* INTERNAL */)
|
||||
@property (nonatomic, strong) HTTPServer *httpServer;
|
||||
@property (nonatomic, strong) MBIMConcurrentHTTPServer *httpServer;
|
||||
@property (nonatomic, strong) NSOperationQueue *operationQueue;
|
||||
|
||||
- (instancetype)_init;
|
||||
@@ -52,6 +54,7 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
[sDaemonListener addHandler:self];
|
||||
|
||||
_operationQueue = [[NSOperationQueue alloc] init];
|
||||
_operationQueue.maxConcurrentOperationCount = 5;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -115,7 +118,19 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
{
|
||||
NSLog(@"Received message from chat with GUID: %@", [[notification object] guid]);
|
||||
|
||||
// TODO: Notify observers or something
|
||||
IMChat *chat = [notification object];
|
||||
IMMessage *message = [[notification userInfo] objectForKey:IMChatValueKey];
|
||||
if (chat && message) {
|
||||
if (![message isFromMe]) {
|
||||
MBIMUpdateItem *updateItem = [[MBIMUpdateItem alloc] init];
|
||||
updateItem.changedChat = chat;
|
||||
updateItem.message = message;
|
||||
|
||||
[[MBIMUpdateQueue sharedInstance] enqueueUpdateItem:updateItem];
|
||||
} else {
|
||||
// TODO: care about messages from me?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_chatRegistryDidLoad:(NSNotification *)notification
|
||||
@@ -133,7 +148,7 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
|
||||
- (void)startWebServer
|
||||
{
|
||||
self.httpServer = [[HTTPServer alloc] init];
|
||||
self.httpServer = [[MBIMConcurrentHTTPServer alloc] init];
|
||||
[self.httpServer setConnectionClass:[MBIMHTTPConnection class]];
|
||||
[self.httpServer setPort:8080];
|
||||
|
||||
|
||||
17
kordophone/Bridge/MBIMConcurrentHTTPServer.h
Normal file
17
kordophone/Bridge/MBIMConcurrentHTTPServer.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MBIMConcurrentHTTPServer.h
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import <CocoaHTTPServer/HTTPServer.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MBIMConcurrentHTTPServer : HTTPServer
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
23
kordophone/Bridge/MBIMConcurrentHTTPServer.m
Normal file
23
kordophone/Bridge/MBIMConcurrentHTTPServer.m
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// MBIMConcurrentHTTPServer.m
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MBIMConcurrentHTTPServer.h"
|
||||
|
||||
@implementation MBIMConcurrentHTTPServer
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
connectionQueue = dispatch_queue_create("net.buzzert.MBIMConcurrentHTTPConnectionQueue", DISPATCH_QUEUE_CONCURRENT);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
@implementation MBIMHTTPConnection {
|
||||
NSMutableData *_bodyData;
|
||||
MBIMBridgeOperation *_currentOperation;
|
||||
}
|
||||
|
||||
- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path
|
||||
@@ -37,11 +38,11 @@
|
||||
NSString *endpointName = [url lastPathComponent];
|
||||
Class operationClass = [MBIMBridgeOperation operationClassForEndpointName:endpointName];
|
||||
if (operationClass != nil) {
|
||||
MBIMBridgeOperation *operation = [[operationClass alloc] initWithRequestURL:url completion:completion];
|
||||
operation.requestBodyData = _bodyData;
|
||||
_currentOperation = [[operationClass alloc] initWithRequestURL:url completion:completion];
|
||||
_currentOperation.requestBodyData = _bodyData;
|
||||
|
||||
[[[MBIMBridge sharedInstance] operationQueue] addOperation:operation];
|
||||
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)));
|
||||
[[[MBIMBridge sharedInstance] operationQueue] addOperation:_currentOperation];
|
||||
dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60.0 * NSEC_PER_SEC)));
|
||||
} else {
|
||||
response = [[HTTPErrorResponse alloc] initWithErrorCode:404];
|
||||
}
|
||||
@@ -68,4 +69,10 @@
|
||||
[_bodyData appendData:postDataChunk];
|
||||
}
|
||||
|
||||
- (void)die
|
||||
{
|
||||
[_currentOperation cancel];
|
||||
[super die];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
30
kordophone/Bridge/MBIMUpdateQueue.h
Normal file
30
kordophone/Bridge/MBIMUpdateQueue.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// MBIMUpdateQueue.h
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IMCore/IMCore.h>
|
||||
#import <IMFoundation/IMFoundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MBIMUpdateItem : NSObject
|
||||
@property (nonatomic, strong) IMChat *changedChat;
|
||||
@property (nonatomic, strong) IMMessage *message;
|
||||
@end
|
||||
|
||||
typedef void (^MBIMUpdateConsumer)(MBIMUpdateItem *item);
|
||||
|
||||
@interface MBIMUpdateQueue : NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
- (void)addConsumer:(MBIMUpdateConsumer)consumer;
|
||||
- (void)enqueueUpdateItem:(MBIMUpdateItem *)item;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
61
kordophone/Bridge/MBIMUpdateQueue.m
Normal file
61
kordophone/Bridge/MBIMUpdateQueue.m
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// MBIMUpdateQueue.m
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MBIMUpdateQueue.h"
|
||||
|
||||
@implementation MBIMUpdateQueue {
|
||||
dispatch_queue_t _accessQueue;
|
||||
NSMutableArray *_consumers;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static MBIMUpdateQueue *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_accessQueue = dispatch_queue_create("net.buzzert.MBIMUpdateQueue", DISPATCH_QUEUE_SERIAL);
|
||||
_consumers = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addConsumer:(MBIMUpdateConsumer)consumer
|
||||
{
|
||||
__weak NSMutableArray *consumers = _consumers;
|
||||
dispatch_async(_accessQueue, ^{
|
||||
[consumers addObject:consumer];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)enqueueUpdateItem:(MBIMUpdateItem *)item
|
||||
{
|
||||
__weak NSMutableArray *consumers = _consumers;
|
||||
dispatch_async(_accessQueue, ^{
|
||||
for (MBIMUpdateConsumer consumer in consumers) {
|
||||
consumer(item);
|
||||
}
|
||||
|
||||
[consumers removeAllObjects];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MBIMUpdateItem
|
||||
@end
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "MBIMMessagesListOperation.h"
|
||||
#import "MBIMHTTPUtilities.h"
|
||||
#import "IMMessageItem+Encoded.h"
|
||||
|
||||
#import <IMCore/IMCore.h>
|
||||
|
||||
@@ -52,10 +53,7 @@
|
||||
|
||||
NSMutableArray *messages = [NSMutableArray array];
|
||||
for (IMMessageItem *imMessage in [[chat chatItems] messages]) {
|
||||
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
|
||||
messageDict[@"text"] = [[imMessage body] string];
|
||||
messageDict[@"date"] = MBIMWebServerFormatRFC822([imMessage time]);
|
||||
messageDict[@"sender"] = [imMessage sender];
|
||||
NSDictionary *messageDict = [imMessage mbim_dictionaryRepresentation];
|
||||
[messages addObject:messageDict];
|
||||
}
|
||||
|
||||
|
||||
17
kordophone/Bridge/Operations/MBIMUpdatePollOperation.h
Normal file
17
kordophone/Bridge/Operations/MBIMUpdatePollOperation.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MBIMUpdatePollOperation.h
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MBIMBridgeOperation.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MBIMUpdatePollOperation : MBIMBridgeOperation
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
39
kordophone/Bridge/Operations/MBIMUpdatePollOperation.m
Normal file
39
kordophone/Bridge/Operations/MBIMUpdatePollOperation.m
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// MBIMUpdatePollOperation.m
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MBIMUpdatePollOperation.h"
|
||||
#import "MBIMUpdateQueue.h"
|
||||
#import "IMMessageItem+Encoded.h"
|
||||
|
||||
@implementation MBIMUpdatePollOperation
|
||||
|
||||
+ (void)load { [super load]; }
|
||||
|
||||
+ (NSString *)endpointName
|
||||
{
|
||||
return @"pollUpdates";
|
||||
}
|
||||
|
||||
- (void)main
|
||||
{
|
||||
MBIMUpdateConsumer consumer = ^(MBIMUpdateItem *nextUpdateItem) {
|
||||
NSDictionary *updateDict = @{
|
||||
@"guid" : [[nextUpdateItem changedChat] guid],
|
||||
@"message" : [[nextUpdateItem message] mbim_dictionaryRepresentation]
|
||||
};
|
||||
|
||||
MBIMJSONDataResponse *response = [MBIMJSONDataResponse responseWithJSONObject:updateDict];
|
||||
self.serverCompletionBlock(response);
|
||||
};
|
||||
|
||||
[[MBIMUpdateQueue sharedInstance] addConsumer:consumer];
|
||||
}
|
||||
|
||||
// TODO: cancel needs to remove the consumer from the update queue
|
||||
|
||||
@end
|
||||
24
kordophone/Categories/IMMessageItem+Encoded.h
Normal file
24
kordophone/Categories/IMMessageItem+Encoded.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// IMMessageItem+Encoded.h
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import <IMCore/IMCore.h>
|
||||
#import <IMSharedUtilities/IMSharedUtilities.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface IMMessage (Encoded)
|
||||
- (NSDictionary *)mbim_dictionaryRepresentation;
|
||||
|
||||
@end
|
||||
|
||||
@interface IMMessageItem (Encoded)
|
||||
- (NSDictionary *)mbim_dictionaryRepresentation;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
38
kordophone/Categories/IMMessageItem+Encoded.m
Normal file
38
kordophone/Categories/IMMessageItem+Encoded.m
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// IMMessageItem+Encoded.m
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/16/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import "IMMessageItem+Encoded.h"
|
||||
#import "MBIMHTTPUtilities.h"
|
||||
|
||||
@implementation IMMessage (Encoded)
|
||||
|
||||
- (NSDictionary *)mbim_dictionaryRepresentation
|
||||
{
|
||||
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
|
||||
messageDict[@"text"] = [[self text] string];
|
||||
messageDict[@"date"] = MBIMWebServerFormatRFC822([self time]);
|
||||
messageDict[@"sender"] = [[self sender] displayID];
|
||||
|
||||
return messageDict;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation IMMessageItem (Encoded)
|
||||
|
||||
- (NSDictionary *)mbim_dictionaryRepresentation
|
||||
{
|
||||
NSMutableDictionary *messageDict = [NSMutableDictionary dictionary];
|
||||
messageDict[@"text"] = [[self body] string];
|
||||
messageDict[@"date"] = MBIMWebServerFormatRFC822([self time]);
|
||||
messageDict[@"sender"] = [self sender];
|
||||
|
||||
return messageDict;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user