def clash_disable(config, bot, update): send_typing_action(bot, update) username = update.message.from_user.username chat_id = update.message.chat_id message_id = update.message.message_id if not username: msg = "The unnamed ones are free from these silly humans vanity" else: with connector(config.engine()) as ses: all_excludes = ses.query(ClashExclude.username).filter(ClashExclude.chat_id == update.message.chat_id).all() all_excludes = [ x for x in all_excludes for x in x ] if username in all_excludes: msg = "You've already disabled notifications" else: exclude = ClashExclude( username=username, chat_id=chat_id) ses.add(exclude) msg = "Now you won't receive any notifications about Clash of Code games" bot.send_message(chat_id=update.message.chat_id, reply_to_message_id=message_id, text=msg) log_print("Disabled", chat_id=update.message.chat_id, username=username, level="INFO", command="clash_disable")
def clash_enable(config, bot, update): send_typing_action(bot, update) username = update.message.from_user.username chat_id = update.message.chat_id message_id = update.message.message_id if not username: msg = "The unnamed ones are free from these silly humans vanity" else: with connector(config.engine()) as ses: all_excludes = ses.query(ClashExclude.username).filter(ClashExclude.chat_id == update.message.chat_id).all() all_excludes = [ x for x in all_excludes for x in x ] if username in all_excludes: ses.query(ClashExclude).filter(and_( ClashExclude.chat_id == chat_id, ClashExclude.username == username)).delete() msg = "You will be notified when a new game is created!" else: msg = "You've already subscribed" bot.send_message(chat_id=update.message.chat_id, reply_to_message_id=message_id, text=msg, parse_mode="markdown") log_print("Enabled", chat_id=update.message.chat_id, username=username, level="INFO", command="clash_disable")
def drop(self, bot, update, args): if update.message.from_user.username not in self.config.admins(): message = "This command is only allowed for admins." bot.send_message(chat_id=update.message.chat_id, text=message) return usernames = [name[1:] for name in args if name[0] == "@"] if not usernames: usage_text = "Usage: `/ping_drop [@username]`\n" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=usage_text) return answer = "" with connector(self.config.engine()) as ses: for username in usernames: result = ses.query(Pingers).filter( and_(Pingers.chat_id == update.message.chat_id, Pingers.username == username)) if not result.all(): answer += "User `@{0}` not found\n".format(username) else: result.delete() answer += "User `@{0}` deleted\n".format(username) bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=answer)
def show(self, bot, update, args, me=0): usernames = " ".join(args).split() username = usernames[0] if usernames else "" if not username: username = update.message.from_user.username elif username[0] == "@": username = username[1:] else: usage_text = "Usage:\n`/ping_show[_me] @username`\n`/ping_show me`\n`/ping_show`\n" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=usage_text) return with connector(self.config.engine()) as ses: user_matches = ses.query(Pingers).filter( Pingers.chat_id == update.message.chat_id, Pingers.username == username, Pingers.me == me).all() out_text = "" for match in user_matches: out_text += "\n{}".format(match.match) if out_text == "": out_text = "No such user" bot.send_message(chat_id=update.message.chat_id, text=out_text) log_print('Show pings of "@{0}", by {1}'.format( username, update.message.from_user.username))
def me(config, bot, update, args): import telegram send_typing_action(bot, update) username = update.message.from_user.username with connector(config.engine()) as ses: user_matches = ses.query(Pingers).filter(Pingers.chat_id == update.message.chat_id, Pingers.username == username).all() out_text = "" if [x.match for x in user_matches if x.me == 1]: match = random.choice([x.match for x in user_matches if x.me == 1]) else: match = username out_text=italize("{match} {message}".format( match=match.capitalize(), message=escape(' '.join(args)))) bot.send_message(chat_id=update.message.chat_id, text=out_text, parse_mode=telegram.ParseMode.HTML) bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) log_print("Me", chat_id=update.message.chat_id, match=match, username=username, level="INFO", command="me")
def add(self, bot, update, args): usernames = [name[1:] for name in args if name[0] == "@"] matches = [match for match in args if match[0] != "@"] user = update.message.from_user.username if not usernames: usernames = [user] if not matches: usage_text = "Usage:\n`/ping_add [@username] [match]`\n`/ping_add [match]`" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=usage_text) return if user not in self.config.admins() and (len(usernames) > 1 or len( list(filter(lambda x: x != user, usernames))) != 0): message = "Adding pings for another users is only allowed for admins." bot.send_message(chat_id=update.message.chat_id, text=message) return if user not in self.config.admins(): with connector(self.config.engine()) as ses: count = ses.query(Pingers).filter( and_(Pingers.chat_id == update.message.chat_id, Pingers.username == user)).count() if count + len(matches) > 10: bot.send_message(chat_id=update.message.chat_id, text="You can add only 10 matches") log_print('Pinger limit is exhausted', user) return answer = "" with connector(self.config.engine()) as ses: for username in usernames: for match in matches: ping = Pingers(username=username, match=match, chat_id=update.message.chat_id) ses.add(ping) answer += "Match `{0}` for user `@{1}` has been added\n".format( match, username) bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=answer)
async def answer_parser(config, bot, update): in_text = prepare_message(update) with connector(config.engine()) as ses: out_text = ses.query(Answers.answer).filter( literal(in_text).contains(Answers.match)) for message in ["".join(i) for i in out_text]: bot.send_message(chat_id=update.message.chat_id, text=message) log_print("Answer", update.message.from_user.username)
async def ping_parser(config, bot, update): in_text = prepare_message(update) with connector(config.engine()) as ses: in_text_list = in_text.split() username = update.message.from_user.username chat_id = update.message.chat_id try: ses.query(PingPhrases.phrase).filter( PingPhrases.phrase.in_(in_text_list)).limit(1).one() usernames = ses.query(Pingers.username).filter( and_(Pingers.match.in_(in_text_list), or_(Pingers.chat_id == chat_id, Pingers.chat_id == "all"))).distinct().all() usernames = [i for i in usernames for i in i] if 'EVERYONE GET IN HERE' in usernames: try: ses.query(PingExcludes.match).filter( PingExcludes.match.in_(in_text_list)).one() usernames = ses.query(Pingers.username).filter( and_( Pingers.username.notin_(usernames), Pingers.username != username, or_(Pingers.chat_id == chat_id, Pingers.chat_id == "all"))).distinct().all() usernames = [i for i in usernames for i in i] except NoResultFound: if ['EVERYONE GET IN HERE'] == usernames: usernames = ses.query(Pingers.username).filter( and_( Pingers.username != 'EVERYONE GET IN HERE', Pingers.username != username, or_(Pingers.chat_id == chat_id, Pingers.chat_id == "all"))).distinct().all() usernames = [i for i in usernames for i in i] if usernames: send_typing_action(bot, update) if 'EVERYONE GET IN HERE' in usernames: usernames.remove('EVERYONE GET IN HERE') out_text = " ".join(["@" + i for i in usernames]) bot.send_message(chat_id=update.message.chat_id, reply_to_message_id=update.message.message_id, text=out_text) log_print("Ping", chat_id=update.message.chat_id, username=username, pinged=out_text.split(), level="INFO", command="ping") except NoResultFound: pass
def show_all(self, bot, update): if update.message.from_user.username not in self.config.admins(): message = "This command is only allowed for admins." bot.send_message(chat_id=update.message.chat_id, text=message) return with connector(self.config.engine()) as ses: all_matches = ses.query(Pingers).filter( Pingers.chat_id == update.message.chat_id).all() out_text = "" for match in all_matches: out_text += "\n{0} | {1}".format(match.username, match.match) bot.send_message(chat_id=update.message.chat_id, text=out_text)
def delete(self, bot, update, args): usernames = [name[1:] for name in args if name[0] == "@"] matches = [match.lower() for match in args if match[0] != "@"] sender_username = update.message.from_user.username if not usernames: usernames = [sender_username] if not matches: if sender_username not in self.config.admins(): usage_text = "Usage:\n`/ping_delete [match]`" else: usage_text = "Usage:\n`/ping_delete [@username] [match]`\n`/ping_delete [match]`" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=usage_text) return if sender_username not in self.config.admins() and ( len(usernames) > 1 or len(list(filter(lambda x: x != sender_username, usernames))) != 0): message = "Deleting pings of another users is only allowed for admins." bot.send_message(chat_id=update.message.chat_id, text=message) return answer = "" with connector(self.config.engine()) as ses: for username in usernames: for match in matches: result = ses.query(Pingers).filter( and_(Pingers.chat_id == update.message.chat_id, Pingers.username == username, Pingers.match == match)) if not result.all(): answer += "Match `{0}` for user `@{1}` not found\n".format( match, username) else: result.delete() answer += "Match `{0}` for user `@{1}` deleted\n".format( match, username) log_print("Match deleted", chat_id=update.message.chat_id, ping_username=username, match=match, username=update.message.from_user.username, level="INFO", command="ping_delete") bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=answer)
async def answer_parser(config, bot, update): in_text = prepare_message(update) with connector(config.engine()) as ses: out_text = ses.query(Answers.answer).filter( literal(in_text).contains(Answers.match)) for message in ["".join(i) for i in out_text]: send_typing_action(bot, update) bot.send_message(chat_id=update.message.chat_id, text=message) log_print("Answer", chat_id=update.message.chat_id, username=username, level="INFO", command="answer")
async def weather_parser(config, bot, update): in_text = prepare_message(update) with connector(config.engine()) as ses: try: phrase = "".join( ses.query(WeatherPhrases.match).filter( literal(in_text.lower()).contains( WeatherPhrases.match)).one()) weather( config, bot, update, in_text.lower()[in_text.lower().find(phrase) + len(phrase):].split()) return except NoResultFound: pass
def welcome(config, bot, update): send_typing_action(bot, update) with connector(config.engine()) as ses: try: input_message = ses.query(Welcome.welcome).all() except NoResultFound: return welcome_message = "Welcome @{}!".format(update.message.new_chat_members[0].username) for line in input_message: welcome_message += "\n{}".format("".join(line)) log_print('Welcome "@{0}", added by @{1}'.format(update.message.new_chat_members[0].username, update.message.from_user.username)) bot.send_message(chat_id=update.message.chat_id, text=welcome_message)
def me(config, bot, update, *args, **kwargs): username = update.message.from_user.username with connector(config.engine()) as ses: user_matches = ses.query(Pingers).filter( Pingers.chat_id == update.message.chat_id, Pingers.username == username).all() out_text = "" if [x.match for x in user_matches if x.me == 1]: match = random.choice([x.match for x in user_matches if x.me == 1]) else: match = username out_text = "{match} {message}".format( match=match, message=update.message.text.split(' ', 1)[1]) bot.send_message(chat_id=update.message.chat_id, text=out_text) bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id, *args, **kwargs) log_print('Me by {1}'.format(username, update.message.from_user.username))
def wset(config, bot, update, args): city = " ".join(args) username = update.message.from_user.username with connector(config.engine()) as ses: try: ses.query(Locations.username).filter( Locations.username == username).one() if not city: w_city = "".join( ses.query(Locations.city).filter( Locations.username == username).one()) out_text = "@{0} city is {1}".format(username, w_city) city = 'deleted' elif city == "delete": ses.query(Locations.username).filter( Locations.username == username).delete() out_text = "Deleted information about @{0}".format(username) city = 'deleted' else: ses.query(Locations).filter( Locations.username == username).update({'city': city}) out_text = "New city for @{0}: {1}".format(username, city) except NoResultFound: if not city or city == "delete": out_text = "Usage:\n/wset <city> - Set default city for /w\n/wset delete - Delete your default city".format( username) city = 'none' else: new_location = Locations(username=username, city=city) ses.add(new_location) out_text = "Added @{0}: {1}".format(username, city) bot.send_message(chat_id=update.message.chat_id, text=out_text) log_print('Wset "{0}"'.format(out_text))
def test_db(self, config): with connector(config.engine()) as ses: phrase = ses.query(PingPhrases).one() assert phrase.phrase == "пни"
def add(self, bot, update, args, me=0): usernames = [name[1:] for name in args if name[0] == "@"] matches = [ match.lower().replace('ё', 'е') for match in args if match[0] != "@" ] sender_username = update.message.from_user.username if not usernames: usernames = [sender_username] if not matches: if sender_username not in self.config.admins(): usage_text = "Usage:\n`/ping_add[_me] [match]`" else: usage_text = "Usage:\n`/ping_add[_me] [@username] [match]`\n`/ping_add [match]`" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=usage_text) return if sender_username not in self.config.admins() and ( len(usernames) > 1 or len(list(filter(lambda x: x != sender_username, usernames))) != 0): message = "Adding pings for another users is only allowed for admins." bot.send_message(chat_id=update.message.chat_id, text=message) return if sender_username not in self.config.admins(): with connector(self.config.engine()) as ses: count = ses.query(Pingers).filter( and_(Pingers.chat_id == update.message.chat_id, Pingers.username == sender_username)).count() if count + len(matches) > 10: bot.send_message(chat_id=update.message.chat_id, text="You can add only 10 matches") log_print("Pinger limit exhausted", chat_id=update.message.chat_id, username=sender_username, level="INFO", command="ping_add") return answer = "" with connector(self.config.engine()) as ses: for username in usernames: for match in matches: match_exists = ses.query(Pingers).filter( and_(Pingers.chat_id == update.message.chat_id, Pingers.username == username, Pingers.match == match)).all() if not match_exists: ping = Pingers(username=username, match=match, chat_id=update.message.chat_id, me=me) ses.add(ping) answer += "Match `{0}` for user `@{1}` has been added\n".format( match, username) log_print("Match added", chat_id=update.message.chat_id, ping_username=username, match=match, username=sender_username, level="INFO", command="ping_add") else: answer += "Match `{0}` for user `@{1}` already exists!\n".format( match, username) bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=answer)
def weather(config, bot, update, args): city = " ".join(args) username = update.message.from_user.username if not city: with connector(config.engine()) as ses: try: city = ses.query(Locations.city).filter( Locations.username == username).one() city = "".join([i for i in city]) except NoResultFound: try: city = ses.query(Locations.city).filter( Locations.username == "default_city").one() city = "".join([i for i in city]) except NoResultFound: if username in config.admins(): error_message = ''' You didn't set the default city You can add default city by this command: `/db insert into locations(username,city) \ values(\"default_city\",\"YOUR CITY HERE\")`''' error_message = "\n".join( [i.strip() for i in error_message.split('\n')]) else: error_message = "Administrator didn't set the default city\nTry /w City" bot.send_message(chat_id=update.message.chat_id, parse_mode='markdown', text=error_message) return try: token = config.weather_token() owm = pyowm.OWM(token, language='en') observation = owm.weather_at_place(city) except (UnauthorizedError, NotFoundError, NotImplementedError) as e: bot.send_message(chat_id=update.message.chat_id, text=str(e)) log_print('Weather "{0}"'.format(str(e)), username) return forecast = owm.three_hours_forecast(city) now_weather = observation.get_weather() city = observation.get_location().get_name() weathers = {} # Today today = pyowm.timeutils.next_three_hours() weather = forecast.get_weather_at(today) temp = str(round(weather.get_temperature(unit='celsius')["temp"])) if temp[0] != '-' and temp != "0": weathers["today", "temp", 0] = '+' + temp else: weathers["today", "temp", 0] = temp weathers["today", "emoji", 0] = get_emoji(weather.get_status()) status = weather.get_detailed_status() weathers["today", "status", 0] = status[0].upper() + status[1:] # Tomorrow for i in [6, 12, 18]: weather = forecast.get_weather_at(pyowm.timeutils.tomorrow(i, 0)) temp = str(round(weather.get_temperature('celsius')["temp"])) if temp[0] != '-' and temp != "0": weathers["tomorrow", "temp", i] = '+' + temp else: weathers["tomorrow", "temp", i] = temp weathers["tomorrow", "emoji", i] = get_emoji(weather.get_status()) status = weather.get_detailed_status() weathers["tomorrow", "status", i] = status[0].upper() + status[1:] now_temp = str(round(now_weather.get_temperature(unit='celsius')["temp"])) if now_temp[0] != '-' and now_temp[0] != "0": now_temp = '+' + now_temp now_status = now_weather.get_detailed_status() now_status = now_status[0].upper() + now_status[1:] now_emoji = get_emoji(now_weather.get_status()) try: message = ''.join(""" *Now:* *{0}:* {1} {2} {3} *In near future:* {4} {5} {6} *Tomorrow:* *Morning:* {7} {8} {9} *Noon:* {10} {11} {12} *Evening:* {13} {14} {15} """.format(city, now_temp, now_emoji, now_status, *[weathers[i] for i in weathers])) except IndexError: error_message = "Something wrong with API:\n\n{}".format(weathers) bot.send_message(chat_id=update.message.chat_id, text=error_message) log_print('"{0}"'.format(error_message), username) return message = "\n".join([k.strip() for k in message.split('\n')]) bot.send_message(chat_id=update.message.chat_id, parse_mode="markdown", text=message) log_print('Weather "{0}"'.format(city), username)
def clash(config, bot, update): send_typing_action(bot, update) last_game={} username = update.message.from_user.username last_game = get_last_game(config, username, update.message.chat_id) clash_id = "" users = "" cookies = clash_get_cookies(config) if last_game["clash_id"]: r = requests.post('https://www.codingame.com/services/ClashOfCodeRemoteService/findClashReportInfoByHandle', headers={"content-type":"application/json;charset=UTF-8"}, data='[{}]'.format(last_game["clash_id"])) if r.status_code == 200: results = json.loads(r.text) if results["success"]["started"] or results["success"]["finished"]: r = requests.post('https://www.codingame.com/services/ClashOfCodeRemoteService/createPrivateClash', headers={"content-type":"application/json;charset=UTF-8", "cookie":"rememberMe={remember_me};cgSession={cg_session}".format( remember_me=cookies["rememberMe"], cg_session=cookies["cgSession"])}, data='[{user_id}, {{"SHORT":true}}]'.format(user_id=cookies["user_id"])) if r.status_code == 200: clash_id = json.loads(r.text)["success"]["publicHandle"] else: try: bot.delete_message(chat_id=update.message.chat_id, message_id=last_game["message_id"]) except telegram.error.BadRequest: pass clash_id = last_game["clash_id"] else: r = requests.post('https://www.codingame.com/services/ClashOfCodeRemoteService/createPrivateClash', headers={"content-type":"application/json;charset=UTF-8", "cookie":"rememberMe={remember_me};cgSession={cg_session}".format( remember_me=cookies["rememberMe"], cg_session=cookies["cgSession"])}, data='[{user_id}, {{"SHORT":true}}]'.format(user_id=cookies["user_id"])) if r.status_code == 200: clash_id = json.loads(r.text)["success"]["publicHandle"] if clash_id: with connector(config.engine()) as ses: all_matches = ses.query(Pingers.username).filter(Pingers.chat_id == update.message.chat_id).order_by(Pingers.username).distinct().all() exclude = ses.query(ClashExclude.username).filter(ClashExclude.chat_id == update.message.chat_id).all() users = [ x for x in all_matches if x not in exclude ] users = [ x for x in users for x in x ] out_text = "" users=" ".join(["@{}".format(user) for user in users]) message = """ Clash of Code! https://www.codingame.com/clashofcode/clash/{clash_id} {users} Please send /clash_disable if you don't want to receive these notifications """.format(clash_id=clash_id, users=users) if "clash_id" in last_game and last_game["clash_id"] != clash_id: last_game["username"] = username last_game["clash_id"] = clash_id log_print("Created", chat_id=update.message.chat_id, username=username, clash_id=clash_id, level="INFO", command="clash") else: log_print("Failed on creating", chat_id=update.message.chat_id, username=username, clash_id=clash_id, level="ERROR", command="clash") message = "Something went wrong..." sent = bot.send_message(chat_id=update.message.chat_id, text=message) last_game["users"] = users last_game["message_id"] = sent.message_id save_last_game(config, last_game, update.message.chat_id)