From c7fc35fb0f51552b3a0353a0aab7bd683fa23332 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Sat, 3 Oct 2020 17:08:07 +0000 Subject: [PATCH] Add support for fetching room list FossilOrigin-Name: 092c122c690b6e64c67120c6c153e82fceb484078dd3d713d56e01ce13c3902d --- src/MTXClient.h | 18 +++++- src/MTXClient.m | 27 ++++++++ src/ObjMatrix.h | 1 + src/exceptions/MTXClientException.h | 44 +++++++++++++ src/exceptions/MTXClientException.m | 62 +++++++++++++++++++ .../MTXFetchRoomListFailedException.h | 32 ++++++++++ .../MTXFetchRoomListFailedException.m | 34 ++++++++++ src/exceptions/MTXLogoutFailedException.h | 16 +---- src/exceptions/MTXLogoutFailedException.m | 38 +----------- src/exceptions/Makefile | 4 +- tests/tests.m | 43 ++++++++++--- 11 files changed, 258 insertions(+), 61 deletions(-) create mode 100644 src/exceptions/MTXClientException.h create mode 100644 src/exceptions/MTXClientException.m create mode 100644 src/exceptions/MTXFetchRoomListFailedException.h create mode 100644 src/exceptions/MTXFetchRoomListFailedException.m diff --git a/src/MTXClient.h b/src/MTXClient.h index 0ecda2b..e52170e 100644 --- a/src/MTXClient.h +++ b/src/MTXClient.h @@ -42,6 +42,15 @@ typedef void (^mtx_client_login_block_t)(MTXClient *_Nullable client, */ typedef void (^mtx_client_logout_block_t)(id _Nullable exception); +/** + * @brief A block called when the room list was fetched. + * + * @param rooms An array of joined rooms, or nil on error + * @param exception An exception if fetching the room list failed + */ +typedef void (^mtx_client_room_list_block_t)( + OFArray *_Nullable rooms, id _Nullable exception); + /** * @brief A class that represents a client. */ @@ -105,9 +114,16 @@ typedef void (^mtx_client_logout_block_t)(id _Nullable exception); * * @warning The client can no longer be used after this succeeded! * - * @param block The block to call when logging out succeeded or failed + * @param block A block to call when logging out succeeded or failed */ - (void)asyncLogOutWithBlock: (mtx_client_logout_block_t)block; + +/** + * @brief Fetches the list of joined rooms. + * + * @param block A block to call with the list of joined room + */ +- (void)asyncFetchRoomList: (mtx_client_room_list_block_t)block; @end OF_ASSUME_NONNULL_END diff --git a/src/MTXClient.m b/src/MTXClient.m index 88278ba..608574d 100644 --- a/src/MTXClient.m +++ b/src/MTXClient.m @@ -23,6 +23,7 @@ #import "MTXClient.h" #import "MTXRequest.h" +#import "MTXFetchRoomListFailedException.h" #import "MTXLoginFailedException.h" #import "MTXLogoutFailedException.h" @@ -204,4 +205,30 @@ validateHomeserver(OFURL *homeserver) objc_autoreleasePoolPop(pool); } + +- (void)asyncFetchRoomList: (mtx_client_room_list_block_t)block +{ + void *pool = objc_autoreleasePoolPush(); + MTXRequest *request = + [self requestWithPath: @"/_matrix/client/r0/joined_rooms"]; + [request asyncPerformWithBlock: ^ (mtx_response_t response, + int statusCode, id exception) { + if (exception != nil) { + block(nil, exception); + return; + } + + if (statusCode != 200 || response[@"joined_rooms"] == nil) { + block(nil, [MTXFetchRoomListFailedException + exceptionWithClient: self + statusCode: statusCode + response: response]); + return; + } + + block(response[@"joined_rooms"], nil); + }]; + + objc_autoreleasePoolPop(pool); +} @end diff --git a/src/ObjMatrix.h b/src/ObjMatrix.h index a7cdadd..a0b09e4 100644 --- a/src/ObjMatrix.h +++ b/src/ObjMatrix.h @@ -23,5 +23,6 @@ #import "MTXClient.h" #import "MTXRequest.h" +#import "MTXFetchRoomListFailedException.h" #import "MTXLoginFailedException.h" #import "MTXLogoutFailedException.h" diff --git a/src/exceptions/MTXClientException.h b/src/exceptions/MTXClientException.h new file mode 100644 index 0000000..4dad4ad --- /dev/null +++ b/src/exceptions/MTXClientException.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "MTXRequest.h" + +OF_ASSUME_NONNULL_BEGIN + +@class MTXClient; + +@interface MTXClientException: OFException +@property (readonly, nonatomic) MTXClient *client; +@property (readonly, nonatomic) int statusCode; +@property (readonly, nonatomic) mtx_response_t response; + ++ (instancetype)exceptionWithClient: (MTXClient *)client + statusCode: (int)statusCode + response: (mtx_response_t)response; +- (instancetype)initWithClient: (OFString *)user + statusCode: (int)statusCode + response: (mtx_response_t)response; +@end + +OF_ASSUME_NONNULL_END diff --git a/src/exceptions/MTXClientException.m b/src/exceptions/MTXClientException.m new file mode 100644 index 0000000..b6bae8d --- /dev/null +++ b/src/exceptions/MTXClientException.m @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "MTXLogoutFailedException.h" + +#import "MTXClient.h" + +@implementation MTXClientException ++ (instancetype)exceptionWithClient: (MTXClient *)client + statusCode: (int)statusCode + response: (mtx_response_t)response +{ + return [[[self alloc] initWithClient: client + statusCode: statusCode + response: response] autorelease]; +} + +- (instancetype)initWithClient: (MTXClient *)client + statusCode: (int)statusCode + response: (mtx_response_t)response +{ + self = [super init]; + + @try { + _client = [client retain]; + _statusCode = statusCode; + _response = [response copy]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_client release]; + [_response release]; + + [super dealloc]; +} +@end diff --git a/src/exceptions/MTXFetchRoomListFailedException.h b/src/exceptions/MTXFetchRoomListFailedException.h new file mode 100644 index 0000000..fcee811 --- /dev/null +++ b/src/exceptions/MTXFetchRoomListFailedException.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "MTXClientException.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface MTXFetchRoomListFailedException: MTXClientException +@end + +OF_ASSUME_NONNULL_END diff --git a/src/exceptions/MTXFetchRoomListFailedException.m b/src/exceptions/MTXFetchRoomListFailedException.m new file mode 100644 index 0000000..4f0c158 --- /dev/null +++ b/src/exceptions/MTXFetchRoomListFailedException.m @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "MTXFetchRoomListFailedException.h" + +#import "MTXClient.h" + +@implementation MTXFetchRoomListFailedException +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to fetch room list for %@: %@", + self.client.userID, self.response]; +} +@end diff --git a/src/exceptions/MTXLogoutFailedException.h b/src/exceptions/MTXLogoutFailedException.h index 4bd586c..4075d17 100644 --- a/src/exceptions/MTXLogoutFailedException.h +++ b/src/exceptions/MTXLogoutFailedException.h @@ -22,23 +22,11 @@ #import -#import "MTXRequest.h" +#import "MTXClientException.h" OF_ASSUME_NONNULL_BEGIN -@class MTXClient; - -@interface MTXLogoutFailedException: OFException -@property (readonly, nonatomic) MTXClient *client; -@property (readonly, nonatomic) int statusCode; -@property (readonly, nonatomic) mtx_response_t response; - -+ (instancetype)exceptionWithClient: (MTXClient *)client - statusCode: (int)statusCode - response: (mtx_response_t)response; -- (instancetype)initWithClient: (OFString *)user - statusCode: (int)statusCode - response: (mtx_response_t)response; +@interface MTXLogoutFailedException: MTXClientException @end OF_ASSUME_NONNULL_END diff --git a/src/exceptions/MTXLogoutFailedException.m b/src/exceptions/MTXLogoutFailedException.m index e6be63c..f87c9fa 100644 --- a/src/exceptions/MTXLogoutFailedException.m +++ b/src/exceptions/MTXLogoutFailedException.m @@ -25,44 +25,10 @@ #import "MTXClient.h" @implementation MTXLogoutFailedException -+ (instancetype)exceptionWithClient: (MTXClient *)client - statusCode: (int)statusCode - response: (mtx_response_t)response -{ - return [[[self alloc] initWithClient: client - statusCode: statusCode - response: response] autorelease]; -} - -- (instancetype)initWithClient: (MTXClient *)client - statusCode: (int)statusCode - response: (mtx_response_t)response -{ - self = [super init]; - - @try { - _client = [client retain]; - _statusCode = statusCode; - _response = [response copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - [_client release]; - [_response release]; - - [super dealloc]; -} - - (OFString *)description { return [OFString stringWithFormat: - @"Failed to log out user %@: %@", _client.userID, _response]; + @"Failed to log out user %@: %@", + self.client.userID, self.response]; } @end diff --git a/src/exceptions/Makefile b/src/exceptions/Makefile index efb0d0b..5b569b6 100644 --- a/src/exceptions/Makefile +++ b/src/exceptions/Makefile @@ -3,7 +3,9 @@ include ../../extra.mk STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A} STATIC_LIB_NOINST = ${EXCEPTIONS_A} -SRCS = MTXLoginFailedException.m \ +SRCS = MTXClientException.m \ + MTXFetchRoomListFailedException.m \ + MTXLoginFailedException.m \ MTXLogoutFailedException.m INCLUDES = ${SRCS:.m=.h} diff --git a/tests/tests.m b/tests/tests.m index abfd53f..87f0081 100644 --- a/tests/tests.m +++ b/tests/tests.m @@ -30,6 +30,10 @@ OF_APPLICATION_DELEGATE(Tests) @implementation Tests +{ + MTXClient *_client; +} + - (void)applicationDidFinishLaunching { __auto_type environment = OFApplication.environment; @@ -52,18 +56,39 @@ OF_APPLICATION_DELEGATE(Tests) [OFApplication terminateWithStatus: 1]; } - of_log(@"Logged in client: %@", client); + _client = [client retain]; + of_log(@"Logged in client: %@", _client); - [client asyncLogOutWithBlock: ^ (id exception) { - if (exception != nil) { - of_log(@"Failed to log out: %@\n", exception); - [OFApplication terminateWithStatus: 1]; - } + [self fetchRoomList]; + }]; +} - of_log(@"Logged out client"); +- (void)fetchRoomList +{ + [_client asyncFetchRoomList: ^ (OFArray *rooms, + id exception) { + if (exception != nil) { + of_log(@"Failed to fetch room list: %@", exception); + [OFApplication terminateWithStatus: 1]; + } - [OFApplication terminate]; - }]; + of_log(@"Fetched room list: %@", rooms); + + [self logOut]; + }]; +} + +- (void)logOut +{ + [_client asyncLogOutWithBlock: ^ (id exception) { + if (exception != nil) { + of_log(@"Failed to log out: %@\n", exception); + [OFApplication terminateWithStatus: 1]; + } + + of_log(@"Logged out client"); + + [OFApplication terminate]; }]; } @end