def _handle_do_rm_choice_cmd(self, text): # /do-rm-choice-{choice_id} try: choice_id = int(text[14:]) except Exception: Log.e(f"Failed while parsing choice id: {text}") raise with model.open_session(self._Session) as s: poll_ms = _query_active_polls(s, self._chat_id) if not poll_ms: raise _ResponseException(self.RESPONSE_ERROR_POLL_NOT_EXIST) poll_m = poll_ms[0] if poll_m.creator_user_id != self._user["id"]: raise _ResponseException(self.RESPONSE_ERROR_NOT_CREATOR) if len(poll_m.choices) == 1: raise _ResponseException(self.RESPONSE_ERROR_RM_LAST_CHOICE) choice_m = next( filter(lambda c_m: c_m.poll_choice_id == choice_id, poll_m.choices)) choice = choice_m.text s.delete(choice_m) self._edit_message_text(self.RESPONSE_RM_CHOICE_PERSISTED_F % choice, parse_mode="Markdown")
def _handle_do_unvote_cmd(self, text): # /do-unvote-{choice_id} try: vote = int(text[11:]) except Exception: Log.e(f"Failed while parsing choice id: {text}") raise with model.open_session(self._Session) as s: poll_ms = _query_active_user_votes(s, self._chat_id, self._user["id"]) if not poll_ms: raise _ResponseException( self.RESPONSE_ERROR_NOT_VOTED % f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) poll_m = poll_ms[0] for c_m in poll_m.choices: if c_m.poll_choice_id == vote: for v_m in c_m.votes: if v_m.user_id == self._user["id"]: vote_m = v_m break try: choice_text = vote_m.choice.text s.delete(vote_m) except NameError: # User hasn't voted this option? raise _ResponseException( self.RESPONSE_ERROR_NOT_VOTED % f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) text = self.RESPONSE_UNVOTED % ( f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) announce_text = self.RESPONSE_UNVOTE_ANNOUNCE % ( f"[{self._user['first_name']}](tg://user?id={self._user['id']})", choice_text) self._edit_message_text(text, parse_mode="Markdown") self._send_message(announce_text, parse_mode="Markdown") # Start a new session to make the delete effective with model.open_session(self._Session) as s: poll_ms = _query_active_polls(s, self._chat_id) if not poll_ms: # ??? raise _ResponseException(self.RESPONSE_ERROR_POLL_NOT_EXIST) poll_m = poll_ms[0] poll_text = _repr_poll(poll_m) poll_keyboard = _make_poll_inline_keyboard( poll_m.creator_user_id == self._user["id"]) self._send_message( poll_text, parse_mode="Markdown", reply_markup=InlineKeyboardMarkup(inline_keyboard=poll_keyboard))
def _handle_do_vote_cmd(self, text): # /do-vote-{choice_id} try: vote = int(text[9:]) except Exception: Log.e(f"Failed while parsing choice id: {text}") raise with model.open_session(self._Session) as s: poll_ms = _query_active_polls(s, self._chat_id) if not poll_ms: raise _ResponseException(self.RESPONSE_ERROR_POLL_NOT_EXIST) poll_m = poll_ms[0] user_id = self._user["id"] for c_m in poll_m.choices: if c_m.poll_choice_id == vote: choice_m = c_m break # We don't need a fallback val for choice_m -- it'll raise when we # access it anyway if not poll_m.is_multiple_vote: # Make sure user hasn't voted yet for c_m in poll_m.choices: if any(user_id == v_m.user_id for v_m in c_m.votes): raise _ResponseException( self.RESPONSE_ERROR_MULTIPLE_VOTE % f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) else: # Make sure user hasn't voted for this choice yet if any(user_id == v_m.user_id for v_m in choice_m.votes): raise _ResponseException( self.RESPONSE_ERROR_IDENTICAL_VOTE % f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) vote_m = model.PollVote(user_id=user_id, user_name=self._user["first_name"], choice=choice_m) s.add(vote_m) text = self.RESPONSE_VOTED % ( f"[{self._user['first_name']}](tg://user?id={self._user['id']})" ) announce_text = self.RESPONSE_VOTE_ANNOUNCE % ( f"[{self._user['first_name']}](tg://user?id={self._user['id']})", choice_m.text) poll_text = _repr_poll(poll_m) poll_keyboard = _make_poll_inline_keyboard( poll_m.creator_user_id == self._user["id"]) self._edit_message_text(text, parse_mode="Markdown") self._send_message(announce_text, parse_mode="Markdown") self._send_message( poll_text, parse_mode="Markdown", reply_markup=InlineKeyboardMarkup(inline_keyboard=poll_keyboard))
def handle(self): try: self._do_handle() except _ResponseException as e: Log.e("Failed while handle", e) self._bot.sendMessage(self._glance["chat_id"], e.response) except Exception as e: Log.e("Failed while handle", e) self._bot.sendMessage(self._glance["chat_id"], self.RESPONSE_EXCEPTION)
def _callback(): try: self._ensure_allowed_users() return self._do_handle() except _WhitelistException as e: Log.i("Disallowed user (%s) is chating with us" % self._msg["from"]["first_name"]) return self.RESPONSE_DISALLOWED_USER except Exception as e: Log.e("Failed while _do_handle", e) return self.RESPONSE_EXCEPTION
def handle(self): try: self._do_handle() except _ResponseException as e: Log.e("Failed while handle", e) self._send_message(e.response, parse_mode="Markdown") except Exception as e: Log.e("Failed while handle", e) self._send_message(self.RESPONSE_EXCEPTION) finally: # After the user presses a callback button, Telegram clients will # display a progress bar until you call answerCallbackQuery. It is, # therefore, necessary to react by calling answerCallbackQuery even # if no notification to the user is needed self._bot.answerCallbackQuery(self._glance["query_id"])
def handle(self): try: self._ensure_supported_chat() self._ensure_allowed_users() self._do_handle() except _ChanelException as e: pass except _WhitelistException as e: Log.i("Disallowed user (%s) is chating with us" % self._msg["from"]["first_name"]) self._bot.sendMessage(self._glance["chat_id"], self.RESPONSE_MD_DISALLOWED_USER, parse_mode = "Markdown") except Exception as e: Log.e("Failed while _do_handle", e) self._bot.sendMessage(self._glance["chat_id"], self.RESPONSE_EXCEPTION)
def _build_response(self, text): query = _QueryHandler(text) if query.is_empty: return self._TextResponse(self.RESPONSE_NO_RESULTS) try: response = CustomSearchApi().list(**query.request_args) except CustomSearchApi.NetworkError as e: Log.e("Failed while list %d: %s" % (e.status_code, e.message)) if e.status_code == 404: return self._TextResponse(self.RESPONSE_NO_MORE_QUOTA) else: raise e if not response or "items" not in response: return self._TextResponse(self.RESPONSE_NO_RESULTS) if query.is_image: return self._build_image_response(response) else: return self._build_text_response(response)
def _do_handle(self): Log.v(self._msg) query = _QueryHandler(self._glance["query_string"]) if query.is_empty: return [] try: response = CustomSearchApi().list(**query.request_args) except CustomSearchApi.NetworkError as e: Log.e("Failed while list %d: %s" % (e.status_code, e.message)) if e.status_code == 403: return self.RESPONSE_NO_MORE_QUOTA else: raise e if not response or "items" not in response: return self.RESPONSE_NO_RESULTS if query.is_image: return self._build_image_response(response) else: return self._build_text_response(response)
def handle(self): try: self._ensure_allowed_users() response = self._do_handle() except _WhitelistException as e: Log.i("Disallowed user (%s) is chating with us" % self._msg["from"]["first_name"]) response = self.RESPONSE_DISALLOWED_USER except Exception as e: Log.e("Failed while _do_handle", e) response = self.RESPONSE_EXCEPTION if isinstance(response, list): self._bot.answerInlineQuery(self._glance["query_id"], response) elif isinstance(response, tuple): self._bot.answerInlineQuery(self._glance["query_id"], *response) elif isinstance(response, dict): self._bot.answerInlineQuery(self._glance["query_id"], **response) else: raise ValueError("Invalid response format")
def list(self, q, **kwargs): Log.d("Searching: %s" % q) if not q: return {} args = dict(kwargs) args.update({ "key": self.API_KEY, "cx": self.SEARCH_ENGINE_ID, "safe": "medium", "q": q, }) with http_request("GET", self.URL, params=args) as response: if response.status_code != 200: Log.e("Failed while list: %d" % response.status_code) if response.text: raise self.NetworkError(url=self.URL, status_code=response.status_code, message=response.text) else: raise self.NetworkError(url=self.URL, status_code=response.status_code) else: return response.json()