11import json
2+ from collections import defaultdict
23from typing import Any , Iterable , Optional , override
34from urllib .parse import parse_qs , urlparse
45
1516 ConversationGroupVertical ,
1617 Vertical ,
1718)
19+ from pardner .verticals .sub_verticals import AssociatedMediaSubVertical
1820
1921
2022class GroupMeTransferService (BaseTransferService ):
@@ -135,32 +137,116 @@ def fetch_user_data(self, request_params: dict[str, Any] = {}) -> Any:
135137 self ._user_id = user_data ['id' ]
136138 return user_data
137139
138- def fetch_blocked_user_vertical (self , request_params : dict [str , Any ] = {}) -> Any :
140+ def parse_blocked_user_vertical (self , raw_data : Any ) -> BlockedUserVertical | None :
141+ """
142+ Given the response from the API request, creates a
143+ :class:`BlockedUserVertical` model object, if possible.
144+
145+ :param raw_data: the JSON representation of the data returned by the request.
146+
147+ :returns: :class:`BlockedUserVertical` or ``None``, depending on whether it
148+ was possible to extract data from the response
149+ """
150+ if not isinstance (raw_data , dict ):
151+ return None
152+ raw_data_dict = defaultdict (dict , raw_data )
153+ return BlockedUserVertical (
154+ service = self ._service_name ,
155+ creator_user_id = raw_data_dict .get ('user_id' ),
156+ data_owner_id = raw_data_dict .get ('user_id' , self ._user_id ),
157+ blocked_user_id = raw_data_dict .get ('blocked_user_id' ),
158+ created_at = raw_data_dict .get ('created_at' ),
159+ )
160+
161+ def fetch_blocked_user_vertical (
162+ self , request_params : dict [str , Any ] = {}
163+ ) -> tuple [list [BlockedUserVertical | None ], Any ]:
139164 """
140165 Sends a GET request to fetch the users blocked by the authenticated user.
141166
142- :returns: a JSON object with the result of the request.
167+ :returns: two elements: the first, a list of :class:`BlockedUserVertical`s
168+ or ``None``, if unable to parse; the second, the raw response from making the
169+ request.
143170 """
144171 blocked_users = self ._fetch_resource_common ('blocks' , request_params )
145-
146172 if 'blocks' not in blocked_users :
147173 raise ValueError (
148174 f'Unexpected response format: { json .dumps (blocked_users , indent = 2 )} '
149175 )
176+ return [
177+ self .parse_blocked_user_vertical (blocked_dict )
178+ for blocked_dict in blocked_users ['blocks' ]
179+ ], blocked_users
180+
181+ def parse_chat_bot_vertical (self , raw_data : Any ) -> ChatBotVertical | None :
182+ """
183+ Given the response from the API request, creates a
184+ :class:`ChatBotVertical` model object, if possible.
185+
186+ :param raw_data: the JSON representation of the data returned by the request.
150187
151- return blocked_users ['blocks' ]
188+ :returns: :class:`ChatBotVertical` or ``None``, depending on whether it
189+ was possible to extract data from the response
190+ """
191+ if not isinstance (raw_data , dict ):
192+ return None
193+ raw_data_dict = defaultdict (dict , raw_data )
194+ user_id = raw_data_dict .get ('user_id' , self ._user_id )
195+ return ChatBotVertical (
196+ service = self ._service_name ,
197+ service_object_id = raw_data_dict .get ('bot_id' ),
198+ creator_user_id = user_id ,
199+ data_owner_id = user_id ,
200+ name = raw_data_dict .get ('name' ),
201+ )
152202
153- def fetch_chat_bot_vertical (self , request_params : dict [str , Any ] = {}) -> Any :
203+ def fetch_chat_bot_vertical (
204+ self , request_params : dict [str , Any ] = {}
205+ ) -> tuple [list [ChatBotVertical | None ], Any ]:
154206 """
155207 Sends a GET request to fetch the chat bots created by the authenticated user.
156208
157- :returns: a JSON object with the result of the request.
209+ :returns: two elements: the first, a list of :class:`ChatBotVertical`s
210+ or ``None``, if unable to parse; the second, the raw response from making the
211+ request.
158212 """
159- return self ._fetch_resource_common ('bots' , request_params )
213+ bots_response = self ._fetch_resource_common ('bots' , request_params )
214+ if not isinstance (bots_response , list ):
215+ raise ValueError (
216+ f'Unexpected response format: { json .dumps (bots_response , indent = 2 )} '
217+ )
218+ return [
219+ self .parse_chat_bot_vertical (chat_bot_data )
220+ for chat_bot_data in bots_response
221+ ], bots_response
222+
223+ def parse_conversation_direct_vertical (
224+ self , raw_data : Any
225+ ) -> ConversationDirectVertical | None :
226+ """
227+ Given the response from the API request, creates a
228+ :class:`ConversationDirectVertical` model object, if possible.
229+
230+ :param raw_data: the JSON representation of the data returned by the request.
231+
232+ :returns: :class:`ConversationDirectVertical` or ``None``, depending on
233+ whether it was possible to extract data from the response
234+ """
235+ if not isinstance (raw_data , dict ):
236+ return None
237+ raw_data_dict = defaultdict (dict , raw_data )
238+ return ConversationDirectVertical (
239+ service = self ._service_name ,
240+ service_object_id = raw_data_dict .get ('id' ),
241+ data_owner_id = self ._user_id ,
242+ member_user_ids = [self ._user_id , raw_data_dict ['other_user' ].get ('id' )],
243+ messages_count = raw_data_dict .get ('messages_count' ),
244+ created_at = raw_data_dict .get ('created_at' ),
245+ )
160246
161247 def fetch_conversation_direct_vertical (
162248 self , request_params : dict [str , Any ] = {}, count : int = 10
163- ) -> Any :
249+ ) -> tuple [ list [ ConversationDirectVertical | None ], Any ] :
164250 """
165251 Sends a GET request to fetch the conversations the authenticated user is a part
166252 of with only one other member (i.e., a direct message). The response will
@@ -169,15 +255,72 @@ def fetch_conversation_direct_vertical(
169255
170256 :param count: the number of conversations to fetch. Defaults to 10.
171257
172- :returns: a JSON object with the result of the request.
258+ :returns: two elements: the first, a list of
259+ :class:`ConversationDirectVertical`s or ``None``, if unable to parse; the
260+ second, the raw response from making the request.
173261 """
174- if count <= 10 :
175- return self ._fetch_resource_common (
176- 'chats' , params = {** request_params , 'per_page' : count }
262+ if count > 10 :
263+ raise UnsupportedRequestException (
264+ self ._service_name ,
265+ 'can only make a request for at most 10 direct conversations at a time.' ,
177266 )
178- raise UnsupportedRequestException (
179- self ._service_name ,
180- 'can only make a request for at most 10 direct conversations at a time.' ,
267+ conversation_direct_raw_response = self ._fetch_resource_common (
268+ 'chats' , params = {** request_params , 'per_page' : count }
269+ )
270+ if not isinstance (conversation_direct_raw_response , list ):
271+ raise ValueError (
272+ 'Unexpected response format. Expected list, '
273+ f'got: { json .dumps (conversation_direct_raw_response , indent = 2 )} '
274+ )
275+ return [
276+ self .parse_conversation_direct_vertical (conversation_direct_data )
277+ for conversation_direct_data in conversation_direct_raw_response
278+ ], conversation_direct_raw_response
279+
280+ def parse_conversation_group_vertical (
281+ self , raw_data : Any
282+ ) -> ConversationGroupVertical | None :
283+ """
284+ Given the response from the API request, creates a
285+ :class:`ConversationGroupVertical` model object, if possible.
286+
287+ :param raw_data: the JSON representation of the data returned by the request.
288+
289+ :returns: :class:`ConversationGroupVertical` or ``None``, depending on
290+ whether it was possible to extract data from the response
291+ """
292+ if not isinstance (raw_data , dict ):
293+ return None
294+ raw_data_dict = defaultdict (dict , raw_data )
295+
296+ members_list = raw_data_dict .get ('members' , [])
297+ member_user_ids = []
298+ for member in members_list :
299+ if isinstance (member , dict ) and 'user_id' in member :
300+ member_user_ids .append (member ['user_id' ])
301+
302+ associated_media = []
303+ image_url = raw_data_dict .get ('image_url' , None )
304+ if image_url :
305+ associated_media = [AssociatedMediaSubVertical (image_url = image_url )]
306+
307+ is_private = None
308+ conversation_type = raw_data_dict .get ('type' )
309+ if isinstance (conversation_type , str ):
310+ is_private = conversation_type == 'private'
311+
312+ return ConversationGroupVertical (
313+ service = self ._service_name ,
314+ service_object_id = raw_data_dict .get ('id' ),
315+ data_owner_id = self ._user_id ,
316+ creator_user_id = raw_data_dict .get ('creator_user_id' ),
317+ title = raw_data_dict .get ('name' ),
318+ member_user_ids = member_user_ids ,
319+ members_count = len (members_list ),
320+ messages_count = raw_data_dict ['messages' ].get ('count' ),
321+ associated_media = associated_media ,
322+ created_at = raw_data_dict .get ('created_at' ),
323+ is_private = is_private ,
181324 )
182325
183326 def fetch_conversation_group_vertical (
@@ -190,13 +333,24 @@ def fetch_conversation_group_vertical(
190333
191334 :param count: the number of conversations to fetch. Defaults to 10.
192335
193- :returns: a JSON object with the result of the request.
336+ :returns: two elements: the first, a list of
337+ :class:`ConversationGroupVertical`s or ``None``, if unable to parse; the
338+ second, the raw response from making the request.
194339 """
195- if count <= 10 :
196- return self ._fetch_resource_common (
197- 'groups' , params = {** request_params , 'per_page' : count }
340+ if count > 10 :
341+ raise UnsupportedRequestException (
342+ self ._service_name ,
343+ 'can only make a request for at most 10 group conversations at a time.' ,
198344 )
199- raise UnsupportedRequestException (
200- self ._service_name ,
201- 'can only make a request for at most 10 group conversations at a time.' ,
345+ conversation_group_raw_response = self ._fetch_resource_common (
346+ 'groups' , params = {** request_params , 'per_page' : count }
202347 )
348+ if not isinstance (conversation_group_raw_response , list ):
349+ raise ValueError (
350+ 'Unexpected response format. Expected list, '
351+ f'got: { json .dumps (conversation_group_raw_response , indent = 2 )} '
352+ )
353+ return [
354+ self .parse_conversation_group_vertical (conversation_group_data )
355+ for conversation_group_data in conversation_group_raw_response
356+ ], conversation_group_raw_response
0 commit comments