def start(self): filters_list = ["USD", "EUR", "NOK", "JPY", "GBP", "KZT", "UAH"] cbr_api = CBRAPI(filters_list) ex_rates = cbr_api.do() if self.event.args: self.check_args(1) if len(self.event.args) == 1: value = 1 currency = self.event.args[0].lower() else: self.float_args = [0] self.parse_float() value = self.event.args[0] currency = self.event.args[1].lower() if any(ext in currency for ext in ['rub', "руб"]): msg = "Перевод в другие валюты:\n" for ex_rate in ex_rates: total_value = self.to_fixed(value / ex_rates[ex_rate]['value'], 2) msg += f"{total_value} {ex_rate}\n" return msg else: for code in ex_rates: if currency[:5] in ex_rates[code]['name'] or currency in code.lower(): total_value = self.to_fixed(value * ex_rates[code]['value'], 2) msg = "Перевод в рубли:\n" msg += f"{total_value} руб." return msg raise PWarning("Пока не знаю как переводить из этой валюты") else: msg = "Курс валют:\n" for ex_rate in ex_rates: ex_rates[ex_rate]['value'] = self.to_fixed(ex_rates[ex_rate]['value'], 2) msg += f"{ex_rate} - {ex_rates[ex_rate]['value']} руб.\n" return msg
def start(self): msgs = self.event.fwd if not msgs: if not self.event.original_args: raise PWarning( "Требуется аргументы или пересылаемые сообщения") msgs = [{ 'text': self.event.original_args, 'from_id': int(self.event.sender.user_id) }] issue_text = "" for msg in msgs: text = msg['text'] if msg['from_id'] > 0: fwd_user_id = int(msg['from_id']) fwd_user = self.bot.get_user_by_id(fwd_user_id) username = str(fwd_user) else: fwd_user_id = int(msg['from_id']) username = str(self.bot.get_bot_by_id(fwd_user_id)) issue_text += f"{username}:\n{text}\n\n" github_api = GithubAPI() title = f"Ишю от пользователя {self.event.sender}" body = f"{issue_text}\n\n" \ f"Данное ишю сгенерировано автоматически" response = github_api.create_issue(title, body) result = { 'msg': f"Сохранено\n" f"Отслеживать созданное ишю можно по этой ссылке:\n" f"{response['html_url']}", 'attachments': [response['html_url']] } return result
def get_urls(self, query): r = requests.get( self.url, params={ 'count': 10, 'q': query, 't': 'images', 'safesearch': 1, 'locale': 'ru_RU', 'uiv': 4 }, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' }) if r.status_code == 429: raise PWarning("Сегодняшний лимит исчерпан") r_json = r.json() if r_json['status'] == 'error': raise PError("Ошибка API") response = r.json().get('data').get('result').get('items') urls = [r.get('media') for r in response] return urls
def check_sender(self, role: Role): """ Проверка на роль отправителя :param role: требуемая роль :return: bool """ if self.event.sender.check_role(role): if role == Role.ADMIN: if self.event.platform == Platform.VK: if self.event.sender.user_id == env.str("VK_ADMIN_ID"): return True elif self.event.platform == Platform.TG: if self.event.sender.user_id == env.str("TG_ADMIN_ID"): return True else: print("Попытка доступа под админом не с моего id O_o") raise PError("Э ты чё, ты не админ. Где мой админ???") else: return True if role == Role.CONFERENCE_ADMIN: if self.event.chat.admin == self.event.sender: return True error = f"Команда доступна только для пользователей с уровнем прав {role.value}" raise PWarning(error)
def start(self): with lock: min_gamers = int( len(self.bot.user_model.filter(chats=self.event.chat)) / 2) if min_gamers < 2: min_gamers = 2 gamers = RateModel.objects.filter( chat=self.event.chat).order_by("date") if self.event.args and self.event.args[0] == 'f': self.check_sender(Role.CONFERENCE_ADMIN) if len(gamers) <= 1: raise PWarning( "Ну ты ваще обалдел? Хотя бы один игрок-то пусть будет" ) else: if len(gamers) < min_gamers: raise PWarning( f"Минимальное количество игроков - {min_gamers}") messages = ["Ставки сделаны, ставок больше нет."] rnd = get_random_int(1, 100) winner_rates = ([abs(rnd - gamer.rate) for gamer in gamers]) min_val = min(winner_rates) winners = [] for i, winner_rate in enumerate(winner_rates): if winner_rate == min_val: winners.append(gamers[i]) winners_str = "" for winner in winners: gamer = winner.gamer winners_str += f"{gamer}\n" if winner.rate != rnd: gamer.points += 1 else: gamer.points += 5 winners_str += "\nБонус x5 за точное попадание\n" gamer.save() if self.event.command == "казино": attachments = [] photo = self.bot.get_attachment_by_id('photo', None, 457241180) attachments.append(photo) if len(winners) == 1: msg = { 'msg': f"Выпавшее число - {rnd}\nПобедитель этого казино:\n{winners_str}", 'attachments': attachments } else: msg = { 'msg': f"Выпавшее число - {rnd}\nПобедители этого казино:\n{winners_str}", 'attachments': attachments } else: if len(winners) == 1: msg = f"Выпавшее число - {rnd}\nПобедитель:\n{winners_str}" else: msg = f"Выпавшее число - {rnd}\nПобедители:\n{winners_str}" gamers.delete() messages.append(msg) return messages
def start(self): from apps.bot.initial import HELP_TEXTS help_texts = HELP_TEXTS[self.event.platform] ordered_roles = [ { "role": Role.USER, "text": "общие команды" }, { "role": Role.ADMIN, "text": "команды для администраторов" }, { "role": Role.MODERATOR, "text": "команды для модераторов" }, { "role": Role.MINECRAFT, "text": "команды для игроков майнкрафта" }, { "role": Role.TRUSTED, "text": "команды для доверенных пользователей" }, { "role": Role.STUDENT, "text": "команды для студентов" }, { "role": Role.MINECRAFT_NOTIFY, "text": "команды для уведомлённых майнкрафтеров" }, { "role": Role.TERRARIA, "text": "команды для игроков террарии" }, { "role": Role.HOME, "text": "команды для домашних пользователей" }, ] if self.event.args: role = get_role_by_str(self.event.original_args.lower()) if not role: raise PWarning("Не знаю такой роли") for ordered_role in ordered_roles: if ordered_role['role'] == role: result = self.get_str_for_role(help_texts, ordered_role) if not result: return "У вас нет прав для просмотра команд данной роли" return result return "У данной роли нет списка команд" output = "" for role in ordered_roles: output += self.get_str_for_role(help_texts, role) if 'games' in help_texts: output += "\n\n— игры —\n" output += help_texts['games'] output = output.rstrip() return output
def weather_changes(self, city): entity_yesterday = Service.objects.filter( name=f'weatherchange_yesterday_{city.name}') if not entity_yesterday.exists(): raise PWarning("Не нашёл вчерашней погоды для этого города.") yandexweather_api = YandexWeatherAPI(city) weather_yesterday = json.loads(entity_yesterday.first().value) weather_today = yandexweather_api.get_weather() parts_yesterday = self.get_parts(weather_yesterday) parts_today = self.get_parts(weather_today) difference_total = [] for part in parts_today: yesterday_part = self.get_part_for_type(weather_yesterday, part) today_part = self.get_part_for_type(weather_today, part) difference_for_part = "" # Если погода не ясная или не облачная clear_weather_statuses = [ 'clear', 'partly-cloudy', 'cloudy', 'overcast' ] if today_part['condition'] not in clear_weather_statuses: weather_today_str = WEATHER_TRANSLATOR[ today_part['condition']].lower() difference_for_part += f"Ожидается {weather_today_str}\n" if part in parts_yesterday: avg_temp_yesterday = self.get_avg_temp(yesterday_part) avg_temp_today = self.get_avg_temp(today_part) # Изменение температуры на 5 градусов delta_temp = avg_temp_today - avg_temp_yesterday if delta_temp >= 5: difference_for_part += f"Температура на {round(delta_temp)} градусов больше, чем вчера\n" elif delta_temp <= -5: difference_for_part += f"Температура на {round(-delta_temp)} градусов меньше, чем вчера\n" # Разница ощущаемой и по факту температур delta_feels_temp = today_part[ 'temp_feels_like'] - avg_temp_today if delta_feels_temp >= 5: difference_for_part += f"Ощущаемая температура на {round(delta_feels_temp)} градусов больше, чем реальная\n" elif delta_feels_temp <= -5: difference_for_part += f"Ощущаемая температура на {round(-delta_feels_temp)} градусов меньше, чем реальная\n" # Скорость ветра if today_part['wind_speed'] > 10: difference_for_part += f"Скорость ветра {today_part['wind_speed']}м/с\n" if today_part['wind_gust'] > 20: difference_for_part += f"Порывы скорости ветра до {today_part['wind_gust']}м/с\n" if difference_for_part: difference_total.append( f"Изменения на {DAY_TRANSLATOR[part]}:\n" f"{difference_for_part}") if not difference_total: return f"Нет изменений погоды в г. {city}" else: difference_str = '\n\n'.join(difference_total) return f"Изменения погоды в г. {city}:\n\n" \ f"{difference_str}"
def get_on_or_off(arg): if arg in ON_OFF_TRANSLATOR: return ON_OFF_TRANSLATOR[arg] else: raise PWarning("Не понял, включить или выключить?")
def set_activity(self, peer_id, activity='typing'): if activity not in ['typing', 'audiomessage']: raise PWarning("Не знаю такого типа активности") self.vk.messages.setActivity(type=activity, peer_id=peer_id, group_id=self.group_id)
def check_player_captain(player): if player.role == 'captain': return True raise PWarning("Загадывать может только капитан")
def prepare_game(self): def get_random_words(): words_shuffled = sorted( WORDS, key=lambda x: random.random())[:DIMENSION * DIMENSION] team_words_shuffled = [] for i, word in enumerate(words_shuffled): team_words_shuffled.append({'state': 'close', 'name': word}) if i < 9: team_words_shuffled[-1]['type'] = 'blue' elif i == 9: team_words_shuffled[-1]['type'] = 'death' elif i < 18: team_words_shuffled[-1]['type'] = 'red' else: team_words_shuffled[-1]['type'] = 'neutral' team_words_shuffled = sorted(team_words_shuffled, key=lambda x: random.random()) for i, word in enumerate(team_words_shuffled): team_words_shuffled[i]['row'] = int(i / DIMENSION) team_words_shuffled[i]['col'] = i % DIMENSION words_table = [] for i in range(DIMENSION): words_table.append(team_words_shuffled[i * DIMENSION:(i + 1) * DIMENSION]) return words_table preference_captain = self.players.filter(role_preference='captain') if len(preference_captain) < 2: preference_none = self.players.filter( role_preference=None).order_by('?')[:(2 - len(preference_captain))] captains = preference_captain | preference_none else: captains = preference_captain.order_by('?')[:2] if len(captains) < 2: raise PWarning("Недостаточно игроков на роль капитана") for captain in captains: captain.role = 'captain' players = self.players.exclude( id__in=[captain.id for captain in captains]) for player in players: player.role = 'player' players = sorted(players, key=lambda x: random.random()) self.players = CodenamesUser.objects.filter(chat=self.event.chat) half_users = int(len(players) / 2) if len(players) % 2 == 1: half_users += 1 commands = {'blue': [], 'red': []} commands['blue'].append(captains[0]) commands['red'].append(captains[1]) commands['blue'] += players[:half_users] commands['red'] += players[half_users:] for command in commands: for user in commands[command]: user.command = command user.save() board = get_random_words() session = CodenamesSession() session.chat = self.event.chat session.board = board session.save() self.session = session self.bot.send_message(self.event.peer_id, msg=self.get_info(), keyboard=self.get_keyboard(board)) for captain in captains: self.send_captain_keyboard( board, captain, msg=f"Вы капитан {translator_commands[captain.command]} команды" )
def check_not_session(session): if not session: return True raise PWarning("Игра уже началась")
def check_session(session): if session: return True raise PWarning("Игра ещё не началась")
def start(self): self.bot.set_activity(self.event.peer_id) detail = False if self.event.args: country = self.event.args[0] if len(self.event.args) >= 2: _type = self.event.args[1].lower() if _type == "график" or _type.endswith('фик'): detail = 'Graphic' # )) if _type in [ "гист", "гистограмма" ] or _type.endswith('ста') or _type.endswith('са'): detail = 'Gist' else: country = "Мир" if country != "Мир": if has_cyrillic(country): amazon_translate_api = AmazonTranslateAPI() country_transliterate = amazon_translate_api.get_translate( country, 'en').replace(' ', '-') else: country_transliterate = country else: country_transliterate = None if country.lower() in ["сша", "usa"]: country_transliterate = "united-states" covid19_api = Covid19API(country_transliterate) result = covid19_api.get_by_country() if not result: raise PWarning("Не нашёл такой страны") msg = f"{country.capitalize()}\n\n{result}" if detail in ["Gist", "Graphic"]: self.platforms = [Platform.VK, Platform.TG] self.check_platforms() if detail == "Gist": datas = covid19_api.get_detail_by_country() _, a = plt.subplots() x = datas['Dates'] y1 = datas['Active'] y2 = datas['Deaths'] y3 = datas['Recovered'] y2_bottom = y1 y3_bottom = [x + y for x, y in zip(y1, y2)] a.bar(x, y1, label="Болеют", color="#46aada", width=1) a.bar(x, y2, bottom=y2_bottom, label="Умершие", color="red", width=1) a.bar(x, y3, bottom=y3_bottom, label="Выздоровевшие", color="green", width=1) a.xaxis.set_visible(False) elif detail == "Graphic": datas = covid19_api.get_detail_by_country() plt.plot(datas['Recovered'], "bo-", label="Выздоровевшие", color="green") plt.plot(datas['Active'], "bo-", label="Больные", color="#46aada") plt.plot(datas['Deaths'], "bo-", label="Умершие", color="red") plt.title(country.capitalize()) plt.xlabel('День') plt.ylabel('Количество людей') plt.legend() with lock: graphic = BytesIO() plt.savefig(graphic) plt.cla() attachments = self.bot.upload_photos(graphic) return {'msg': msg, 'attachments': attachments} else: return msg
def get_zodiac_sign_by_sign_or_name(self, text): for zodiac_sign in self.signs: if zodiac_sign.is_contains_name_or_sign(text): return zodiac_sign raise PWarning("Не знаю такого знака зодиака")
def get_conference_users(self, peer_id): try: return self.vk.messages.getConversationMembers(peer_id=peer_id, group_id=self.group_id, lang='ru')[ 'profiles'] except: raise PWarning("У бота нет админских прав для получения списка пользователей в конференции")
def check_next_step(session, step_name): if session.next_step == step_name: return True raise PWarning("Сейчас не ваш ход")
def check_player(player): if player: return True raise PWarning("Вы не игрок")
def start(self): self.bot.set_activity(self.event.peer_id, 'audiomessage') url = self.event.args[0] ydl_params = {'outtmpl': '%(id)s%(ext)s', 'logger': NothingLogger()} ydl = youtube_dl.YoutubeDL(ydl_params) ydl.add_default_info_extractors() try: video_info = ydl.extract_info(url, download=False) except youtube_dl.utils.DownloadError: raise PWarning("Не смог найти видео по этой ссылке") audio_urls = [] if video_info['duration'] > 600: raise PWarning("Нельзя грузить музяку > 10 минут") if 'formats' in video_info: for _format in video_info['formats']: if _format['ext'] == 'm4a': audio_urls.append(_format) if len(audio_urls) == 0: raise PWarning( "Чёт проблемки, напишите разрабу и пришлите ссылку на видео") max_asr_i = 0 max_asr = audio_urls[0]['asr'] for i, audio_url in enumerate(audio_urls): if audio_url['asr'] > max_asr: max_asr = audio_url['asr'] max_asr_i = i if 'fragment_base_url' in audio_urls[max_asr_i]: audio_link = audio_urls[max_asr_i]['fragment_base_url'] else: audio_link = audio_urls[max_asr_i]['url'] artist = video_info['uploader'] title = video_info['title'] dashs = ['-', '—', '–', '−'] for dash in dashs: first_dash = video_info['title'].find(dash) if first_dash != -1: artist = video_info['title'][0:first_dash].strip() title = video_info['title'][first_dash + 1:].strip() break response = requests.get(audio_link) if response.status_code == 403: raise PWarning( "Нет доступа к ссылке, не могу скачать((\n" "Пока сам не понял как решить эту проблему, думаю над этим") i = io.BytesIO(response.content) i.seek(0) o = io.BytesIO() o.name = "audio.mp3" AudioSegment.from_file(i, 'm4a').export(o, format='mp3') try: audio_attachment = self.bot.upload_audio(o, artist, title) except Exception as e: msg = f"{str(e)}\n\nСсылка на скачивание: {audio_link}" return msg return {'attachments': [audio_attachment]}