def _tidal_track_to_track(self, tidal_track: dict, album: Optional[Album] = None) -> Track: # we can be pretty sure that an album ID is valid if it comes from TIDAL album = album or cast(Album, self.get_album_by_id(tidal_track["album"]["id"])) artists = [ self._tidal_artist_to_artist(tidal_artist) for tidal_artist in tidal_track["artists"] ] chosen_quality, best_available_quality = self._get_quality(tidal_track) file_extension = { "master": "flac", "lossless": "flac", "high": "mp4", "low": "mp4", }[chosen_quality] return Track( id=tidal_track["id"], name=tidal_track["title"], artists=artists, album=album, explicit=tidal_track.get("explicit", False), track_number=tidal_track["trackNumber"], disc_number=tidal_track["volumeNumber"], chosen_quality=chosen_quality, best_available_quality=best_available_quality, file_extension=file_extension, )
def createPost(): session = getSession() name = request.form.get('name') location = request.form.get('location') size = request.form.get('size') try: """ connection.execute( "INSERT INTO tracks(name,location,size) VALUES(%s, %s,%s)", name, location, size ) """ track = Track() track.name = name track.location = location track.size = size session.add(track) session.commit() files = request.files.getlist("images") imagesPaths = uploadfiles(files, folderTracks) for imagesPath in imagesPaths: trackImage = TrackImage() trackImage.src = imagesPath trackImage.track_id = track.id session.add(trackImage) session.commit() return redirect(url_for('track.tracks')) except Exception as error: session.rollback() raise error return render_template('createTracks.html')
def run(self): session = getSession() for item in data: track = self.db.session.query(Track).filter( Track.name == item.get("name") ).first() exist = bool(track) if not exist: track = Track() track.name = item.get("name") track.location = item.get("location") track.size = item.get("size") or 5000 if not exist: self.db.session.add(track) self.db.session.commit() images = item.get("images") if images: for image in images: haveImage = self.db.session.query(TrackImage).filter( TrackImage.track_id == track.id ).first() if not haveImage: ext = Path(image).suffix namefile = uuid.uuid4().hex + ext file = open(path + image, 'rb') s3.put_object(Bucket=bucket, Key=to + namefile, Body=file) trackImage = TrackImage() trackImage.src = namefile trackImage.track_id = track.id self.db.session.add(trackImage)
def create_track(payload): try: name = request.get_json()['name'] artist_id = request.get_json()['artist_id'] release_id = request.get_json()['release_id'] price = request.get_json()['price'] new_track = Track( name=name, artist_id=artist_id, release_id=release_id, price=price ) new_track.insert() return jsonify({ 'success': True, 'name': new_track.name, 'artist_id': new_track.artist_id, 'release_id': new_track.release_id, 'price': new_track.price }) except: abort(422)
def set_tracks_to_db(tracks, session): # добавляем трек for track in tracks: artist = track[0] title = track[1] set_id = tracks.get(track, -1) session.add(Track(artist, title, set_id)) # комитим session.commit()
def filter_library(): print("REACHED BEGINNING OF FUNCTION") dummy_list = [{ 'name': 'Just My Luck', 'album_name': 'PMD', 'artists': 'Marc E. Bassy, blackbear', 'popularity': 60, 'id': '2QsBAfiNmngcrZsOTznqBG', 'audio_features': { 'danceability': 0.616, 'energy': 0.62, 'valence': 0.367, 'tempo': 156.986, 'loudness': -6.398, 'acousticness': 0.231, 'instrumentalness': 7.83e-06, 'liveness': 0.181, 'speechiness': 0.0358 } }, { 'name': 'Rushing Back', 'album_name': 'Rushing Back', 'artists': 'Flume, Vera Blue', 'popularity': 70, 'id': '2zoNNEAyPK2OGDfajardlY', 'audio_features': { 'danceability': 0.574, 'energy': 0.612, 'valence': 0.368, 'tempo': 136.046, 'loudness': -4.741, 'acousticness': 0.357, 'instrumentalness': 0, 'liveness': 0.158, 'speechiness': 0.0781 } }] #import json; print(json.dumps(request.args, indent=2)) #import code; code.interact(local=dict(globals(), **locals())) library = TrackCollection( current_user.get_access_token(), list( map(lambda x: Track(current_user.get_access_token(), x), dummy_list))) return render_template('library.html', saved_tracks=library.filter_by_query( request.args.get('query_str'))) # # Launch App # if __name__ == "__main__": # try: # app.run(host='0.0.0.0', port=8080, debug=True) # except: # print("Server Crashed :(")
def read_track(file: str) -> Track: track = Track() with open(file) as f: for i, row in enumerate(csv.DictReader(f)): point = Point(i, float(row['radius']), prev=track.points[-1] if i > 0 else None) track.points.append(point) if point.prev: point.prev.next = point return track
def test_db_create_track(self): track = Track('track_name', 'genre_name', 'release_date', 1, 0, 'url', True, 'uri') db.session.add(track) db.session.commit() track_result = Track.query.filter(Track.name == 'track_name').first() assert (track_result is track) db.session.delete(track) db.session.commit() assert Track.query.filter_by(name='track_name').first() is None
def track_decoder(t, album): # explicit = True if t['explicit'] == 'true' else False # need to get genre and release date from album # need to get url from external URL object spotify_track = requests.get(t['href']) t = json.loads(spotify_track.text) track = Track(t['name'], album.genre, album.release_date, t['duration_ms'], t['popularity'], t['preview_url'], t['explicit'], t['uri']) return track
def start(request): request.first_request = True track = Track() track.save() print track request.session["is_reporting"] = track.id logging.debug = patch_function(logging.debug, TypeSubRequest.LOG) logging.info = patch_function(logging.info, TypeSubRequest.LOG) logging.critical = patch_function(logging.critical, TypeSubRequest.LOG) logging.error = patch_function(logging.error, TypeSubRequest.LOG) logging.exception = patch_function(logging.exception, TypeSubRequest.LOG)
def _save_spot(self, cursor): cursor = [round(x, 6) for x in cursor] lat = cursor[0] lon = cursor[1] track = self.session.query(Track).filter_by(lat=lat, lon=lon).first() if not track: track = Track(lat=lat, lon=lon, rad=self.rad, found=0, saved=0) try: self.session.add(track) self.session.commit() except exc.SQLAlchemyError as err: session.rollback() logger.error(err)
def add_to_playlist(track, user, track_info): matchingTrack = Track.query.filter_by(spotify_id=track['id']).first() if matchingTrack is None: matchingTrack = Track(track['name'], get_artists_string(track), track['id'], 0 , "") db.session.add(matchingTrack) db.session.commit() playedTrack = PlayedTracks(matchingTrack.id, user.id) db.session.add(playedTrack) db.session.commit() return matchingTrack.id
def edit_track(): track = db.get_track(request.json['id']) edited_track = Track(id=track['id'], date=track['date'], time=track['time'], kind=track['kind'], camera_id=track['camera']['id'], person_id=request.json['person']['id'], encoding_id=request.json['encoding_id'], image=track['image']) db.edit_track(edited_track) return jsonify({'track': 'true'})
def _parse_track(self, json_obj): track = Track(**json_obj) if 'artist' in json_obj: track.artist = self._parse_artist(json_obj['artist']) elif 'artists' in json_obj: track.artist = self._parse_artist(json_obj['artists'][0]) if 'artists' in json_obj: track.artists, track._ftArtists = self._parse_all_artists( track.artist.id, json_obj['artists']) else: track.artists = [track.artist] track._ftArtists = [] track.album = self._parse_album(json_obj['album'], artist=track.artist) if self.is_logged_in and self.user.favorites: track._isFavorite = self.user.favorites.isFavoriteTrack(track.id) return track
def dict_to_db(data_dict, title, index_to_id): """Enters the data into the MongoDB. Args: * data_dict: dict containing annotations for 1 video. { 'url': <url>, 'tracks': [ {'faces':[ {'time': 0.0, 'box': [1, 2, 3, 4]}, {'time': 1.0, 'box': [2, 3, 4, 5]}, ... ], 'annotation': 'Georges Clooney' } ] } * title : string, title of the movie * index_to_id: dict maps from index in the timecode.txt to entity ID """ tracks = [] for track in data_dict['tracks']: ent_id = index_to_id[int(track['annotation'])] boxes = [] for box in sorted(track['faces'], key=lambda x: x['time']): boxes.append( Box(timestamp=box['time'], x=box['box'][0], y=box['box'][1], w=box['box'][2], h=box['box'][3])) tracks.append( Track(start=boxes[0].timestamp, end=boxes[-1].timestamp, boxes=boxes, entity=ent_id)) # Create the video vid = Video(title=title, tracks=tracks) vid.save() # Get the hash of the URL (minus the protocol) url = data_dict['url'].split('https://www.')[1] hasher = hashlib.md5() hasher.update(url) hash_md5 = hasher.hexdigest() SourceVideo(source_url=url, hash=hash_md5, reminiz_video=vid.id).save()
def generate_data(): faker = Faker() for i in range(0, 24): name = faker.name() u = User(name=name) u.put() full = faker.lorem() firstbio, secounddis = full[:len(full) / 2], full[len(full) / 2:] a = Artist(name=name, owner=u._key, is_active=True, location=faker.full_address(), bio=firstbio) a.put() cover_art = "http://lorempixel.com/1024/1024/{}".format( random.choice(image_sets)) track_list = [] for i in range(0, 12): t = Track(title=faker.name(), artist_id=a._key, artist_name=a.name, source_file=random.choice(song_set), explicit=False, is_active=True, price=CurrencyValue(amount=0, currency="USD")) t.put() track_list.append(t._key) alb = Album(title=faker.name(), artist_name=a.name, artist_id=a._key, tracks=track_list, cover_art=cover_art, description=secounddis, release_date=datetime.utcnow(), genre_id=random.choice(genres), price=CurrencyValue(amount=0, currency="USD"), is_active=True) alb.put()
def webhook_lidarr(): try: if request.json['eventType'] == 'Test': aprint('Received TEST webhook', 'WEBHOOK.MAIN') return HTTPResponse(status=200) if not request.json: error = { 'error': 'Request JSON not correct', 'code': 10, } return HTTPResponse(status=500, body=error) # pprint.pprint(request.json) webhook_request = request.json artist = webhook_request['artist']['name'] tracks = webhook_request['tracks'] except Exception as e: error = { 'error': 'Request JSON not correct', 'code': 10, 'stack_trace': str(e) } return HTTPResponse(status=500, body=error) for track in tracks: track_data = { 'ARTIST': artist, 'TITLE': track['title'], 'TRACK_NUMBER': track['trackNumber'], 'QUALITY': track['quality'] } msg = '{ARTIST} - {TITLE} ({TRACK_NUMBER}) | {QUALITY}'.format( ARTIST=track_data['ARTIST'], TITLE=track_data['TITLE'], TRACK_NUMBER=track_data['TRACK_NUMBER'], QUALITY=track_data['QUALITY']) new_track = Track(artist=track_data['ARTIST'], title=track_data['TITLE'], tracknumber=track_data['TRACK_NUMBER'], quality=track_data['QUALITY'], timestamp=datetime.datetime.now(current_tz)) new_track.save() aprint(msg, 'WEBHOOK.MUSIC') return HTTPResponse(status=200)
def hodl(ticker: str, start_date: date, end_date: date, user_config: dict = None): user_config = user_config or {} config = deepcopy( DEFAULT_CONFIG.get( ticker, { 'x_scale': settings.DEFAULT_X_SCALE, 'y_scale': settings.DEFAULT_Y_SCALE })) for k, v in user_config.items(): if v is not None: config[k] = v start_date_string = start_date.isoformat() if start_date else "" end_date_string = end_date.isoformat() if end_date else "" data = tiingo_client.get(start_date_string, end_date_string, ticker) start = data[0] start_date = parser.parse(start["date"]).date() end_date = parser.parse(data[-1]["date"]).date() x_scale = config["x_scale"] y_scale = config["y_scale"] track = Track( start_date, end_date, ticker, [ Point( x=idx + settings.STARTING_AREA_X * x_scale, y=day["close"] - start["close"] + settings.STARTING_AREA_Y * y_scale, date_recorded=day["date"].split('T')[0], price=day["close"], ) for idx, day in enumerate(data) ], config, ) return track_to_json(track)
def test_db_track_artist_relationship(self): track = Track('track_name', 'genre_name', 'release_date', 1, 0, 'url', True, 'uri') artist = Artist('artist_name', 'url', 'country', 'decade', 'genre') artist.tracks.append(track) db.session.add(track) db.session.add(artist) db.session.commit() track_result = Track.query.filter_by(name='track_name').first() artist_result = Artist.query.filter_by(name='artist_name').first() assert (track_result is track) assert (artist_result is artist) assert (artist.tracks[0] is track_result) assert (track.artist is artist_result) db.session.delete(track_result) db.session.delete(artist_result) db.session.commit() assert Track.query.filter_by(name='track_name').first() is None assert Artist.query.filter_by(name='artist_name').first() is None
def addTrack_post(): name = request.form.get('name') slug = request.form.get('slug') gen_id = request.form.get('gen_id') description = request.form.get('description') track = Genre.query.filter_by(name=name).first() if track: flash('Track already exists') return redirect(url_for('main.addTrack')) new_track = Track(name=name, slug=slug, description=description, gen_id=gen_id) db.session.add(new_track) db.session.commit() flash('Genre deleted!', 'success') return redirect(url_for('main.home'))
def make_objects(self): """ Create iteration objects :return: void """ self.vehicles = [] for vehicle_index in range(self.vehicle_count): vehicle = Vehicle( vehicle_index + 1, self.vehicle_lengths[vehicle_index], self.vehicle_types[vehicle_index], self.departure_times[vehicle_index], self.schedule_types[vehicle_index], self.track_specifics[vehicle_index] ) self.vehicles.append(vehicle) track_counter = 1 self.tracks = [] for track_index in range(self.track_count): allowed_vehicles = [] for vehicle_index in range(self.vehicle_count): if self.track_specifics[vehicle_index][track_index] == 1: allowed_vehicles.append(vehicle_index + 1) track_id = str(track_counter) tracks_blocked_by = self.tracks_blocked_by[track_id] if track_id in self.tracks_blocked_by else None blocking_tracks = self.blocking_tracks[track_id] if track_id in self.blocking_tracks else None track = Track( track_id, self.track_lengths[track_index], allowed_vehicles, tracks_blocked_by, blocking_tracks ) self.tracks.append(track) track_counter += 1
def test_db_relationship(self): track = Track('track_name', 'genre_name', 'release_date', 1, 0, 'url', True, 'uri') album = Album('album_name', 'genre', 'release', 'url', 'label', 1, 'uri') album.tracks.append(track) db.session.add(track) db.session.add(album) db.session.commit() track_result = Track.query.filter_by(name='track_name').first() album_result = Album.query.filter_by(name='album_name').first() assert (track_result is track) assert (album_result is album) assert (album.tracks[0] is track_result) assert (track.album is album_result) db.session.delete(track_result) db.session.delete(album_result) db.session.commit() assert Track.query.filter_by(name='track_name').first() is None assert Album.query.filter_by(name='album_name').first() is None
def get_track(self, track_id): track = self.db.session.query(Track).get(track_id) if track: return track else: response = self.client.track(track_id) track = Track() track.track_id = track_id track.track_data = response # Album track.album = self.get_album(response['album']['id']) # Artists for artist_response in response['artists']: track.artists.append(self.get_artist(artist_response['id'])) # Audio feature audio_feature_response = self.client.audio_features(track_id)[0] if audio_feature_response: # Some tracks do not have audio features track.audio_feature_data = audio_feature_response print("> Track {} was not in database.".format( track.track_data['name'])) self.db.save_instance(track) return self.db.session.query(Track).get(track_id)
def add_track(self, name: str, artist: int, release_date: str = None, duration: int = None, language: str = None, text: str = None): track = Track(name=name, artist=artist, release_date=release_date, duration=duration, language=language, text=text) self.session.add(track) try: self.session.commit() except IntegrityError: self.session.rollback() raise ArtistNotFoundException(f"Artist {artist} not found") return track.id
def seed_tracks(): with open(TRACK_DATA_PATH, 'rb') as csv_file: reader = csv.DictReader(csv_file, delimiter=';') tracks = [] meta_data = [] for data in reader: attrs = normalize_attrs(data) track_attrs = slice_attrs(attrs, TRACK_ATTRIBUTES) meta_attrs = slice_attrs(attrs, META_ATTRIBUTES) meta_attrs['artist_hotness'] = meta_attrs.pop('artist_hotttnesss') meta_attrs['song_hotness'] = meta_attrs.pop('song_hotttnesss') tracks.append(Track(**track_attrs)) meta_data.append(MetaData(**meta_attrs)) db.session.add_all(tracks) db.session.commit() for i, track in enumerate(tracks): meta_data[i].track_id = track.id db.session.add_all(meta_data) db.session.commit()
def add_track(self, track_id=None, track_data=None, track_features=None): if track_id is None and (track_data is None or track_features is None): raise Exception if track_data is None: track_data = self.sp.track(track_id) if track_features is None: track_features = self.sp.audio_features(track_id)[0] if track_id is None: track_id = track_data['id'] track = Track(spotify_id=track_id, lead_artist_id=track_data['artists'][0]['id'], album_id=track_data['album']['id'], name=track_data['name'], length_ms=track_data.get('duration_ms'), explicit=track_data.get('explicit'), popularity=track_data.get('popularity'), track_number=track_data.get('track_number'), acousticness=track_features.get('acousticness'), danceability=track_features.get('danceability'), energy=track_features.get('energy'), instrumentalness=track_features.get('instrumentalness'), key=track_features.get('key'), liveness=track_features.get('liveness'), mode=track_features.get('mode'), speechiness=track_features.get('speechiness'), tempo=track_features.get('tempo'), valence=track_features.get('valence'), time_signature=track_features.get('time_signature')) self.db.add(track) return
from models import Track, Line, Point from dateutil import parser example_track = Track( start_date=parser.parse("2010-01-01"), end_date=parser.parse("2020-01-01") ) example_track.lines.append(Line(point_a=Point(x=-10, y=20), point_b=Point(x=50, y=25)))
def populate_music_entity_tables(): """ * Loads playlist ids from `playlists` table * For each playlist id, queries tracks * Saves link between track id and playlist id * saves track info to `tracks` table * saves track to artist link in `track_to_artist` table """ session = get_session() client = SpotifyAuthAPI() playlists = get_playlists_to_process(session) playlist_count = playlists.count() for i, playlist in enumerate(playlists): print "populating playlist {} of {}".format(i + 1, playlist_count) playlist_id = playlist.playlist_id owner_id = playlist.owner_id try: s_playlist = client.get('users/{}/playlists/{}/tracks'.format(owner_id, playlist_id)) except SpotifyException: continue except UnicodeEncodeError: print owner_id.encode('utf-8'), playlist_id.encode('utf-8') continue if len(s_playlist) > TOO_MANY_SONGS_TO_STORE: print "skipping playlist {} because it has {} songs".format(playlist.name.encode('utf-8'), len(s_playlist)) playlist.too_big = True session.add(playlist) session.commit() continue s_playlist = filter(None, [t['track'] for t in s_playlist]) for k, s_track in enumerate(s_playlist): if k % 25 == 0: print 'creating track {} of {}'.format(k + 1, len(s_playlist)) if not s_track.get('id'): print 'skipping track name: {} because no track id'.format(s_track.get('name').encode('utf-8')) continue track = session.query(Track).get(s_track['id']) if track is None: track = Track( track_id=s_track['id'], name=s_track['name'], album_id=s_track['album']['id'], album_name=s_track['album']['name'], ) s_artists = s_track['artists'] for s_artist in s_artists: if not s_artist.get('id'): print 'skipping artist name: {} because no artist id'.format(s_artist.get('name')) continue artist = session.query(Artist).get(s_artist['id']) if artist is None: artist = Artist( artist_id=s_artist['id'], name=s_artist['name'], ) track.artists.append(artist) playlist.tracks.append(track) session.add(playlist) session.commit()
import random from config import count_tracks from config import count_users from random_words import RandomWords from random_words import RandomNicknames from models import User from models import Track rw = RandomWords() # класс отвечающий за случайные слова rn = RandomNicknames() # класс отвечающий за случайный ник tracks = [ Track( ' '.join(rw.random_words( count=random.randint(1, 5))), # название из слов от 1 до 5 random.randint(1, 8), # размер в мб random.randint(50, 300) # продолжительнос в с ) for t in range(count_tracks) ] users = [ User( rn.random_nick(gender='u'), # какой - то никнейм random.randint(12, 50), # возраст [random.choice(tracks) for _ in range(random.randint(5, 20)) ] # какие-то случайные песни от 5 до 20 ) for _ in range(count_users) ]
def webhook(): from models import User, Track update = telegram.update.Update.de_json(request.get_json(force=True), bot) if update.effective_user is None: # TODO: I want exit automatically from channel return 'OK' command = update.message.text chat_id = update.message.chat_id chat_username = update.message.from_user.username standard_keyboard = ReplyKeyboardMarkup(keyboard=[[ KeyboardButton(text='track'), KeyboardButton(text='list') ], [KeyboardButton(text='delete'), KeyboardButton(text='info')]], resize_keyboard=True) new_message = 'Non ho capito, usa info per avere informazioni.' # keyboard = ReplyKeyboardRemove() keyboard = None disable_web_page_preview = False user = User.query.filter_by(chat_id=chat_id).first() if not user: user = User(chat_id=chat_id, state='creation', chat_username=chat_username) user.save() if not command: new_message = 'tipo di messaggio non supportato' elif command == 'cancel': if user.state == 'delete': new_message = 'eliminazione annullata' elif user.state == 'track': new_message = 'track annullata' elif user.state == 'track_name': track = Track.query.filter_by(user=user, name='temp').first() track.delete() new_message = 'track annullata' keyboard = standard_keyboard user.state = 'cancel' elif user.state == 'track': if command[:20] == 'https://www.g2a.com/': if command.find('?') != -1: command = command[:command.find('?')] url = command game_id = url[-14:] response = requests.get(url=G2A_URL + game_id, cookies=COOKIES) data = response.json() if len(data): new_price = float(data['lowest_price']) track = Track(name='temp', game_id=game_id, game_link=url + '?mkey=' + G2A_KEY, game_price=new_price, game_median_price=new_price, user=user) track.save() user.state = 'track_name' new_message = 'Con che nome lo vuoi salvare?' else: new_message = 'Link non valido' else: new_message = 'Link non valido' elif user.state == 'track_name': track = Track.query.filter_by(name=command, user=user).first() if track: new_message = 'Nome non valido' else: track = Track.query.filter_by(name='temp', user=user).first() # TODO: if track is None? track.name = command user.state = 'track_finish' track.save() new_message = 'Track salvato' keyboard = standard_keyboard elif user.state == 'delete': track = Track.query.filter_by(user=user, name=command).first() if track: track.delete() user.state = 'delete_finish' new_message = 'Track Eliminato' keyboard = standard_keyboard else: new_message = 'Nome non valido' elif command == 'track': user.state = 'track' new_message = 'Inserisci il link di g2a' keyboard = ReplyKeyboardMarkup( keyboard=[[KeyboardButton(text='cancel')]], resize_keyboard=True) elif command == 'delete': tracks = Track.query.filter_by(user=user).all() if len(tracks): command_list = [] for track in tracks: command_list.append([KeyboardButton(text=track.name)]) command_list.append([KeyboardButton(text='cancel')]) user.state = 'delete' new_message = 'Cosa vuoi eliminare?' keyboard = ReplyKeyboardMarkup(keyboard=command_list, resize_keyboard=True) else: new_message = 'Nessun gioco in lista' user.state = 'delete_empty' elif command == 'list': tracks = Track.query.filter_by(user=user).all() if len(tracks): new_message = 'Lista dei Track: \n\n' for track in tracks: new_message += 'Name: <a href="' + track.game_link + '">' + track.name + '</a>\n' new_message += 'Price: ' + str(track.game_price) + '\n' new_message += '\n' user.state = 'list' disable_web_page_preview = True else: new_message = 'Nessun gioco in lista' user.state = 'list_empty' elif command == 'info' or command == '/start': user.state = 'info' new_message = 'Benvenuto nel bot \n\n' new_message += 'Comandi: \n' new_message += 'track - aggiunge il link del gioco alla tua lista \n' new_message += 'list - mostra i giochi della tua lista \n' new_message += 'delete - cancella elementi dalla tua lista \n\n' new_message += 'Se hai problemi o vuoi segnalarmi bug scrivimi a @matteo_baldelli \n' new_message += '<a href="https://www.paypal.me/MatteoBaldelli">Donate</a> \n' new_message += '<a href="https://telegram.me/storebot?start=g2apricebot">Rate me</a>' keyboard = standard_keyboard disable_web_page_preview = True else: user.state = 'error' keyboard = standard_keyboard user.save() try: bot.send_message( chat_id, new_message, parse_mode='HTML', disable_web_page_preview=disable_web_page_preview, reply_markup=keyboard, ) except Unauthorized: user.delete() return 'OK'