@@ -77,6 +77,24 @@ def _get_call_args(self, reply_to, extra, attach, notify):
7777
7878 return args
7979
80+ @staticmethod
81+ def _get_file_args (path , file_id , url ):
82+ args = None
83+ if path is not None and file_id is None and url is None :
84+ file = open (path , "rb" )
85+ elif file_id is not None and path is None and url is None :
86+ args = file_id
87+ file = None
88+ elif url is not None and file_id is None and path is None :
89+ args = url
90+ file = None
91+ elif path is None and file_id is None and url is None :
92+ raise TypeError ("path or file_id or URL is missing" )
93+ else :
94+ raise TypeError ("Only one among path, file_id and URL must be" +
95+ "passed" )
96+ return args , file
97+
8098 @_require_api
8199 def send (self , message , preview = True , reply_to = None , syntax = None ,
82100 extra = None , attach = None , notify = True ):
@@ -102,26 +120,19 @@ def send_photo(self, path=None, file_id=None, url=None, caption=None,
102120 if syntax is not None :
103121 syntax = syntaxes .guess_syntax (caption , syntax )
104122 args ["parse_mode" ] = syntax
105- if path is not None and file_id is None and url is None :
106- files = {"photo" : open (path , "rb" )}
107- elif file_id is not None and path is None and url is None :
108- args ["photo" ] = file_id
109- files = None
110- elif url is not None and file_id is None and path is None :
111- args ["photo" ] = url
112- files = None
113- elif path is None and file_id is None and url is None :
114- raise TypeError ("path or file_id or URL is missing" )
115- else :
116- raise TypeError ("Only one among path, file_id and URL must be" +
117- "passed" )
123+ files = dict ()
124+ args ["photo" ], files ["photo" ] = self ._get_file_args (path ,
125+ file_id ,
126+ url )
127+ if files ["photo" ] is None :
128+ del files ["photo" ]
118129
119130 return self ._api .call ("sendPhoto" , args , files ,
120131 expect = _objects ().Message )
121132
122133 @_require_api
123134 def send_audio (self , path = None , file_id = None , url = None , duration = None ,
124- performer = None , title = None , reply_to = None ,
135+ thumb = None , performer = None , title = None , reply_to = None ,
125136 extra = None , attach = None , notify = True , caption = None , * ,
126137 syntax = None ):
127138 """Send an audio track"""
@@ -138,19 +149,14 @@ def send_audio(self, path=None, file_id=None, url=None, duration=None,
138149 if title is not None :
139150 args ["title" ] = title
140151
141- if path is not None and file_id is None and url is None :
142- files = {"audio" : open (path , "rb" )}
143- elif file_id is not None and path is None and url is None :
144- files = None
145- args ["audio" ] = file_id
146- elif url is not None and file_id is None and path is None :
147- args ["audio" ] = url
148- files = None
149- elif path is None and file_id is None and url is None :
150- raise TypeError ("path or file_id or URL is missing" )
151- else :
152- raise TypeError ("Only one among path, file_id and URL must be" +
153- "passed" )
152+ files = dict ()
153+ args ["audio" ], files ["audio" ] = self ._get_file_args (path ,
154+ file_id ,
155+ url )
156+ if files ["audio" ] is None :
157+ del files ["audio" ]
158+ if thumb is not None :
159+ files ["thumb" ] = thumb
154160
155161 return self ._api .call ("sendAudio" , args , files ,
156162 expect = _objects ().Message )
@@ -168,30 +174,25 @@ def send_voice(self, path=None, file_id=None, url=None, duration=None,
168174 args ["parse_mode" ] = syntax
169175 if duration is not None :
170176 args ["duration" ] = duration
177+ if title is not None :
178+ args ["title" ] = title
171179 syntax = syntaxes .guess_syntax (caption , syntax )
172180 if syntax is not None :
173181 args ["parse_mode" ] = syntax
174182
175- if path is not None and file_id is None and url is None :
176- files = {"voice" : open (path , "rb" )}
177- elif file_id is not None and path is None and url is None :
178- files = None
179- args ["voice" ] = file_id
180- elif url is not None and file_id is None and path is None :
181- args ["voice" ] = url
182- files = None
183- elif path is None and file_id is None and url is None :
184- raise TypeError ("path or file_id or URL is missing" )
185- else :
186- raise TypeError ("Only one among path, file_id and URL must be" +
187- "passed" )
183+ files = dict ()
184+ args ["voice" ], files ["voice" ] = self ._get_file_args (path ,
185+ file_id ,
186+ url )
187+ if files ["voice" ] is None :
188+ del files ["voice" ]
188189
189190 return self ._api .call ("sendVoice" , args , files ,
190191 expect = _objects ().Message )
191192
192193 @_require_api
193194 def send_video (self , path = None , file_id = None , url = None ,
194- duration = None , caption = None , streaming = True ,
195+ duration = None , caption = None , streaming = True , thumb = None ,
195196 reply_to = None , extra = None , attach = None ,
196197 notify = True , * , syntax = None ):
197198 """Send a video"""
@@ -204,83 +205,81 @@ def send_video(self, path=None, file_id=None, url=None,
204205 if syntax is not None :
205206 syntax = syntaxes .guess_syntax (caption , syntax )
206207 args ["parse_mode" ] = syntax
207- if path is not None and file_id is None and url is None :
208- files = {"video" : open (path , "rb" )}
209- elif file_id is not None and path is None and url is None :
210- files = None
211- args ["video" ] = file_id
212- elif url is not None and file_id is None and path is None :
213- args ["video" ] = url
214- files = None
215- elif path is None and file_id is None and url is None :
216- raise TypeError ("path or file_id or URL is missing" )
217- else :
218- raise TypeError ("Only one among path, file_id and URL must be" +
219- "passed" )
208+
209+ files = dict ()
210+ args ["video" ], files ["video" ] = self ._get_file_args (path ,
211+ file_id ,
212+ url )
213+ if files ["video" ] is None :
214+ del files ["video" ]
215+ if thumb is not None :
216+ files ["thumb" ] = thumb
220217
221218 return self ._api .call ("sendVideo" , args , files ,
222219 expect = _objects ().Message )
223220
224221 @_require_api
225222 def send_video_note (self , path = None , file_id = None , duration = None ,
226- diameter = None , reply_to = None , extra = None ,
223+ diameter = None , thumb = None , reply_to = None , extra = None ,
227224 attach = None , notify = True ):
228225 """Send a video note"""
229226 args = self ._get_call_args (reply_to , extra , attach , notify )
230227 if duration is not None :
231228 args ["duration" ] = duration
232229 if diameter is not None :
233230 args ["length" ] = diameter
234- if path is not None and file_id is None :
235- files = {"video_note" : open (path , "rb" )}
236- elif file_id is not None and path is None :
237- files = None
238- args ["video_note" ] = file_id
239- elif path is None and file_id is None :
240- raise TypeError ("Path or file_id or URL is missing" )
241- else :
242- raise TypeError ("Only one among path and file_id must be" +
243- "passed" )
231+
232+ files = dict ()
233+ args ["video_note" ], files ["video_note" ] = self ._get_file_args (path ,
234+ file_id ,
235+ None )
236+ if files ["video_note" ] is None :
237+ del files ["video_note" ]
238+ if thumb is not None :
239+ files ["thumb" ] = thumb
244240
245241 return self ._api .call ("sendVideoNote" , args , files ,
246242 expect = _objects ().Message )
247243
248244 @_require_api
249- def send_file (self , path = None , file_id = None , url = None , reply_to = None ,
250- extra = None , attach = None , notify = True , caption = None , * ,
251- syntax = None ):
245+ def send_file (self , path = None , file_id = None , url = None , thumb = None ,
246+ reply_to = None , extra = None , attach = None ,
247+ notify = True , caption = None , * , syntax = None ):
252248 """Send a generic file"""
253249 args = self ._get_call_args (reply_to , extra , attach , notify )
254250 if caption is not None :
255251 args ["caption" ] = caption
256252 if syntax is not None :
257253 syntax = syntaxes .guess_syntax (caption , syntax )
258254 args ["parse_mode" ] = syntax
259- if path is not None and file_id is None and url is None :
260- files = {"document" : open (path , "rb" )}
261- elif file_id is not None and path is None and url is None :
262- files = None
263- args ["document" ] = file_id
264- elif url is not None and file_id is None and path is None :
265- args ["document" ] = url
266- files = None
267- elif path is None and file_id is None and url is None :
268- raise TypeError ("path or file_id or URL is missing" )
269- else :
270- raise TypeError ("Only one among path, file_id and URL must be" +
271- "passed" )
255+
256+ files = dict ()
257+ args ["document" ], files ["document" ] = self ._get_file_args (path ,
258+ file_id ,
259+ url )
260+ if files ["document" ] is None :
261+ del files ["document" ]
262+ if thumb is not None :
263+ files ["thumb" ] = thumb
272264
273265 return self ._api .call ("sendDocument" , args , files ,
274266 expect = _objects ().Message )
275267
276268 @_require_api
277- def send_location (self , latitude , longitude , reply_to = None , extra = None ,
278- attach = None , notify = True ):
279- """Send a geographic location"""
269+ def send_location (self , latitude , longitude , live_period = None ,
270+ reply_to = None , extra = None , attach = None , notify = True ):
271+ """Send a geographic location, set live_period to a number between 60
272+ and 86400 if it's a live location"""
280273 args = self ._get_call_args (reply_to , extra , attach , notify )
281274 args ["latitude" ] = latitude
282275 args ["longitude" ] = longitude
283276
277+ if live_period :
278+ if live_period < 60 or live_period > 86400 :
279+ raise ValueError (
280+ "live_period must be a number between 60 and 86400" )
281+ args ["live_period" ] = live_period
282+
284283 return self ._api .call ("sendLocation" , args ,
285284 expect = _objects ().Message )
286285
@@ -313,19 +312,13 @@ def send_sticker(self, sticker=None, reply_to=None, extra=None,
313312 )
314313
315314 args = self ._get_call_args (reply_to , extra , attach , notify )
316- if path is not None and file_id is None and url is None :
317- files = {"sticker" : open (path , "rb" )}
318- elif file_id is not None and path is None and url is None :
319- files = None
320- args ["sticker" ] = file_id
321- elif url is not None and file_id is None and path is None :
322- args ["sticker" ] = url
323- files = None
324- elif path is None and file_id is None and url is None :
325- raise TypeError ("path or file_id or URL is missing" )
326- else :
327- raise TypeError ("Only one among path, file_id and URL must be " +
328- "passed" )
315+
316+ files = dict ()
317+ args ["sticker" ], files ["sticker" ] = self ._get_file_args (path ,
318+ file_id ,
319+ url )
320+ if files ["sticker" ] is None :
321+ del files ["sticker" ]
329322
330323 return self ._api .call ("sendSticker" , args , files ,
331324 expect = _objects ().Message )
@@ -451,10 +444,55 @@ def edit_caption(self, caption, extra=None, attach=None, *, syntax=None):
451444 def edit_attach (self , attach ):
452445 """Edit this message's attachment"""
453446 args = {"message_id" : self .id , "chat_id" : self .chat .id }
454- args ["reply_markup" ] = attach
447+ if not hasattr (attach , "_serialize_attachment" ):
448+ raise ValueError ("%s is not an attachment" % attach )
449+ args ["reply_markup" ] = json .dumps (attach ._serialize_attachment (
450+ self .chat
451+ ))
455452
456453 self ._api .call ("editMessageReplyMarkup" , args )
457454
455+ @_require_api
456+ def edit_live_location (self , latitude , longitude , extra = None , attach = None ):
457+ """Edit this message's live location position"""
458+ args = {"message_id" : self .id , "chat_id" : self .chat .id }
459+ args ["latitude" ] = latitude
460+ args ["longitude" ] = longitude
461+
462+ if extra is not None :
463+ _deprecated_message (
464+ "The extra parameter" , "1.0" , "use the attach parameter" , - 3
465+ )
466+ args ["reply_markup" ] = json .dumps (extra .serialize ())
467+
468+ if attach is not None :
469+ if not hasattr (attach , "_serialize_attachment" ):
470+ raise ValueError ("%s is not an attachment" % attach )
471+ args ["reply_markup" ] = json .dumps (attach ._serialize_attachment (
472+ self .chat
473+ ))
474+
475+ self ._api .call ("editMessageLiveLocation" , args )
476+
477+ @_require_api
478+ def stop_live_location (self , extra = None , attach = None ):
479+ """Stop this message's live location"""
480+ args = {"message_id" : self .id , "chat_id" : self .chat .id }
481+
482+ if extra is not None :
483+ _deprecated_message (
484+ "The extra parameter" , "1.0" , "use the attach parameter" , - 3
485+ )
486+ args ["reply_markup" ] = json .dumps (extra .serialize ())
487+
488+ if attach is not None :
489+ if not hasattr (attach , "_serialize_attachment" ):
490+ raise ValueError ("%s is not an attachment" % attach )
491+ args ["reply_markup" ] = json .dumps (attach ._serialize_attachment (
492+ self .chat
493+ ))
494+ self ._api .call ("stopMessageLiveLocation" , args )
495+
458496 @_require_api
459497 def reply (self , * args , ** kwargs ):
460498 """Reply to the current message"""
0 commit comments