ObjMatrix  Check-in [cce4e8d73a]

Overview
Comment:Add support for sending messages
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: cce4e8d73aefdb9a721a42b68b1c769c886d4fdb9a0a45d5bea30f41fe52d237
User & Date: js on 2020-10-03 18:09:38
Other Links: manifest | tags
Context
2020-10-03
19:47
Add support for storage check-in: 3c84d235e5 user: js tags: trunk
18:09
Add support for sending messages check-in: cce4e8d73a user: js tags: trunk
17:50
Add support for leaving rooms check-in: 193ebad6ad user: js tags: trunk
Changes

Modified src/MTXClient.h from [0bab750caa] to [b94a3d1693].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 * @param client If the login succeeded, the newly created client
 * @param exception If the login failed, an exception
 */
typedef void (^mtx_client_login_block_t)(MTXClient *_Nullable client,
    id _Nullable exception);

/**
 * @brief A block called when the device was logged out.
 *
 * @param exception `nil` on success, otherwise an exception
 */
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<OFString *> *_Nullable rooms, id _Nullable exception);

/**
 * @brief A block called when a room was joined.
 *
 * @param roomID The room ID that was joined, or nil on error. This can be used
 *		 to get the room ID if a room alias was joined.
 * @param exception An exception if joining the room failed
 */
typedef void (^mtx_client_room_join_block_t)(OFString *_Nullable roomID,
    id _Nullable exception);

/**
 * @brief A block called when a room was left.
 *
 * @param exception An exception if leaving the room failed
 */
typedef void (^mtx_client_room_leave_block_t)(id _Nullable exception);

/**
 * @brief A class that represents a client.
 */
@interface MTXClient: OFObject
/**
 * @brief The user ID used by the client.
 */







|



|




















<
<
<
<
<
<
<







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







64
65
66
67
68
69
70
 * @param client If the login succeeded, the newly created client
 * @param exception If the login failed, an exception
 */
typedef void (^mtx_client_login_block_t)(MTXClient *_Nullable client,
    id _Nullable exception);

/**
 * @brief A block called when the response for an operation was received.
 *
 * @param exception `nil` on success, otherwise an exception
 */
typedef void (^mtx_client_response_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<OFString *> *_Nullable rooms, id _Nullable exception);

/**
 * @brief A block called when a room was joined.
 *
 * @param roomID The room ID that was joined, or nil on error. This can be used
 *		 to get the room ID if a room alias was joined.
 * @param exception An exception if joining the room failed
 */
typedef void (^mtx_client_room_join_block_t)(OFString *_Nullable roomID,
    id _Nullable exception);








/**
 * @brief A class that represents a client.
 */
@interface MTXClient: OFObject
/**
 * @brief The user ID used by the client.
 */
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
 * @brief Logs out the device and invalidates the access token.
 *
 * @warning The client can no longer be used after this succeeded!
 *
 * @param block A block to call when logging out succeeded or failed
 */
- (void)logOutWithBlock: (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)fetchRoomListWithBlock: (mtx_client_room_list_block_t)block;







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
 * @brief Logs out the device and invalidates the access token.
 *
 * @warning The client can no longer be used after this succeeded!
 *
 * @param block A block to call when logging out succeeded or failed
 */
- (void)logOutWithBlock: (mtx_client_response_block_t)block;

/**
 * @brief Fetches the list of joined rooms.
 *
 * @param block A block to call with the list of joined room
 */
- (void)fetchRoomListWithBlock: (mtx_client_room_list_block_t)block;
154
155
156
157
158
159
160
161











162
163
164
/**
 * @brief Leaves the specified room.
 *
 * @param roomID The room ID to leave
 * @param block A block to call when the room was left
 */
- (void)leaveRoom: (OFString *)roomID
	    block: (mtx_client_room_leave_block_t)block;











@end

OF_ASSUME_NONNULL_END







|
>
>
>
>
>
>
>
>
>
>
>



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
 * @brief Leaves the specified room.
 *
 * @param roomID The room ID to leave
 * @param block A block to call when the room was left
 */
- (void)leaveRoom: (OFString *)roomID
	    block: (mtx_client_response_block_t)block;

/**
 * @brief Sends the specified message to the specified room ID.
 *
 * @param message The message to send
 * @param roomID The room ID to which to send the message
 * @param block A block to call when the message was sent
 */
- (void)sendMessage: (OFString *)message
	     roomID: (OFString *)roomID
	      block: (mtx_client_response_block_t)block;
@end

OF_ASSUME_NONNULL_END

Modified src/MTXClient.m from [046c876603] to [654eca2334].

24
25
26
27
28
29
30

31
32
33
34
35
36
37
#import "MTXRequest.h"

#import "MTXFetchRoomListFailedException.h"
#import "MTXJoinRoomFailedException.h"
#import "MTXLeaveRoomFailedException.h"
#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"


static void
validateHomeserver(OFURL *homeserver)
{
	if (![homeserver.scheme isEqual: @"http"] &&
	    ![homeserver.scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException







>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#import "MTXRequest.h"

#import "MTXFetchRoomListFailedException.h"
#import "MTXJoinRoomFailedException.h"
#import "MTXLeaveRoomFailedException.h"
#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"
#import "MTXSendMessageFailedException.h"

static void
validateHomeserver(OFURL *homeserver)
{
	if (![homeserver.scheme isEqual: @"http"] &&
	    ![homeserver.scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
- (MTXRequest *)requestWithPath: (OFString *)path
{
	return [MTXRequest requestWithPath: path
			       accessToken: _accessToken
				homeserver: _homeserver];
}

- (void)logOutWithBlock: (mtx_client_logout_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	MTXRequest *request =
	    [self requestWithPath: @"/_matrix/client/r0/logout"];
	request.method = OF_HTTP_REQUEST_METHOD_POST;
	[request performWithBlock: ^ (mtx_response_t response, int statusCode,
				       id exception) {







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
- (MTXRequest *)requestWithPath: (OFString *)path
{
	return [MTXRequest requestWithPath: path
			       accessToken: _accessToken
				homeserver: _homeserver];
}

- (void)logOutWithBlock: (mtx_client_response_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	MTXRequest *request =
	    [self requestWithPath: @"/_matrix/client/r0/logout"];
	request.method = OF_HTTP_REQUEST_METHOD_POST;
	[request performWithBlock: ^ (mtx_response_t response, int statusCode,
				       id exception) {
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313




































314
315
316
317
318
319
320
		block(roomID, nil);
	}];

	objc_autoreleasePoolPop(pool);
}

- (void)leaveRoom: (OFString *)roomID
	    block: (mtx_client_room_leave_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	MTXRequest *request = [self requestWithPath: [OFString
	    stringWithFormat: @"/_matrix/client/r0/rooms/%@/leave", roomID]];
	request.method = OF_HTTP_REQUEST_METHOD_POST;
	[request performWithBlock: ^ (mtx_response_t response, int statusCode,
				       id exception) {
		if (exception != nil) {
			block(exception);
			return;
		}

		if (statusCode != 200) {
			block([MTXLeaveRoomFailedException
			    exceptionWithRoomID: roomID
				     statusCode: statusCode
				       response: response
					 client: self]);
			return;
		}





































		block(nil);
	}];

	objc_autoreleasePoolPop(pool);
}
@end







|




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
		block(roomID, nil);
	}];

	objc_autoreleasePoolPop(pool);
}

- (void)leaveRoom: (OFString *)roomID
	    block: (mtx_client_response_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	MTXRequest *request = [self requestWithPath: [OFString
	    stringWithFormat: @"/_matrix/client/r0/rooms/%@/leave", roomID]];
	request.method = OF_HTTP_REQUEST_METHOD_POST;
	[request performWithBlock: ^ (mtx_response_t response, int statusCode,
				       id exception) {
		if (exception != nil) {
			block(exception);
			return;
		}

		if (statusCode != 200) {
			block([MTXLeaveRoomFailedException
			    exceptionWithRoomID: roomID
				     statusCode: statusCode
				       response: response
					 client: self]);
			return;
		}

		block(nil);
	}];

	objc_autoreleasePoolPop(pool);
}

- (void)sendMessage: (OFString *)message
	     roomID: (OFString *)roomID
	      block: (mtx_client_response_block_t)block;
{
	void *pool = objc_autoreleasePoolPush();
	OFString *path = [OFString stringWithFormat:
	    @"/_matrix/client/r0/rooms/%@/send/m.room.message", roomID];
	MTXRequest *request = [self requestWithPath: path];
	request.method = OF_HTTP_REQUEST_METHOD_POST;
	request.body = @{
		@"msgtype": @"m.text",
		@"body": message
	};
	[request performWithBlock: ^ (mtx_response_t response, int statusCode,
				       id exception) {
		if (exception != nil) {
			block(exception);
			return;
		}

		if (statusCode != 200) {
			block([MTXSendMessageFailedException
			    exceptionWithMessage: message
					  roomID: roomID
				      statusCode: statusCode
					response: response
					  client: self]);
			return;
		}

		block(nil);
	}];

	objc_autoreleasePoolPop(pool);
}
@end

Added src/exceptions/MTXSendMessageFailedException.h version [d7a7a80695].







































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * 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 <ObjFW/ObjFW.h>

#import "MTXClientException.h"

OF_ASSUME_NONNULL_BEGIN

@interface MTXSendMessageFailedException: MTXClientException
@property (readonly, nonatomic) OFString *message;
@property (readonly, nonatomic) OFString *roomID;

+ (instancetype)exceptionWithStatusCode: (int)statusCode
			       response: (mtx_response_t)response
				 client: (MTXClient *)client OF_UNAVAILABLE;
+ (instancetype)exceptionWithMessage: (OFString *)message
			      roomID: (OFString *)roomID
			  statusCode: (int)statusCode
			    response: (mtx_response_t)response
			      client: (MTXClient *)client;
- (instancetype)initWithStatusCode: (int)statusCode
			  response: (mtx_response_t)response
			    client: (MTXClient *)client OF_UNAVAILABLE;
- (instancetype)initWithMessage: (OFString *)message
			 roomID: (OFString *)roomID
		     statusCode: (int)statusCode
		       response: (mtx_response_t)response
			 client: (MTXClient *)client OF_DESIGNATED_INITIALIZER;
@end

OF_ASSUME_NONNULL_END

Added src/exceptions/MTXSendMessageFailedException.m version [2c6af4070c].

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * 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 "MTXSendMessageFailedException.h"

#import "MTXClient.h"

@implementation MTXSendMessageFailedException
+ (instancetype)exceptionWithMessage: (OFString *)message
			      roomID: (OFString *)roomID
			  statusCode: (int)statusCode
			    response: (mtx_response_t)response
			      client: (MTXClient *)client
{
	return [[[self alloc] initWithMessage: message
				       roomID: roomID
				   statusCode: statusCode
				     response: response
				       client: client] autorelease];
}

- (instancetype)initWithMessage: (OFString *)message
			 roomID: (OFString *)roomID
		     statusCode: (int)statusCode
		       response: (mtx_response_t)response
			 client: (MTXClient *)client
{
	self = [super initWithStatusCode: statusCode
				response: response
				  client: client];

	@try {
		_message = [message copy];
		_roomID = [roomID copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_message release];
	[_roomID release];

	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to send message to room %@ for %@: %@",
	    _roomID, self.client.userID, self.response];
}
@end

Modified src/exceptions/Makefile from [71eab3e5a4] to [21b2ee299e].

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}

SRCS = MTXClientException.m			\
       MTXFetchRoomListFailedException.m	\
       MTXJoinRoomFailedException.m		\
       MTXLeaveRoomFailedException.m		\
       MTXLoginFailedException.m		\
       MTXLogoutFailedException.m

INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I..











|
>






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}

SRCS = MTXClientException.m			\
       MTXFetchRoomListFailedException.m	\
       MTXJoinRoomFailedException.m		\
       MTXLeaveRoomFailedException.m		\
       MTXLoginFailedException.m		\
       MTXLogoutFailedException.m		\
       MTXSendMessageFailedException.m
INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I..

Modified tests/tests.m from [c338030dd8] to [fa8fe451a7].

86
87
88
89
90
91
92

















93
94
95
96
97
98
99
		if (exception != nil) {
			of_log(@"Failed to join room %@: %@", room, exception);
			[OFApplication terminateWithStatus: 1];
		}

		of_log(@"Joined room %@", roomID);


















		[self leaveRoom: roomID];
	}];
}

- (void)leaveRoom: (OFString *)roomID
{
	[_client leaveRoom: roomID







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
		if (exception != nil) {
			of_log(@"Failed to join room %@: %@", room, exception);
			[OFApplication terminateWithStatus: 1];
		}

		of_log(@"Joined room %@", roomID);

		[self sendMessage: roomID];
	}];
}

- (void)sendMessage: (OFString *)roomID
{
	[_client sendMessage: @"ObjMatrix test successful!"
		      roomID: roomID
		       block: ^ (id exception) {
		if (exception != nil) {
			of_log(@"Failed to send message to room %@: %@",
			    roomID, exception);
			[OFApplication terminateWithStatus: 1];
		}

		of_log(@"Message sent to %@", roomID);

		[self leaveRoom: roomID];
	}];
}

- (void)leaveRoom: (OFString *)roomID
{
	[_client leaveRoom: roomID