def _handle_patch_request(field: str):
    try:
        logging.info(f"User requested [{field}] change")

        if not _required_params(field):
            return make_response("Invalid parameter(s)", 406)

        if field=='votes':
            update_value='votes + 1'
        else:
            update_value = request.args.get('update')
        song_name = request.args.get('song_name')
        artist = request.args.get('artist')

        template = load_db_template(defaults.update_songs_column)
        query = template.render(field=field, update_value=update_value, song_name=song_name, artist=artist)

        connect_execute_query(query)

        logging.info(f"[{field}] successfully changed to {update_value}.")

        return make_response(f"Successfully changed [{field}] field.", 200)
    except Exception as e:
        logging.error(f"Unexpected error happened: {e}")
        return make_response("Unprocessable entity", 430)
def charts():
    if request.method =='GET':
        select_query="SELECT * from songs order by votes desc limit 10"
        songs=connect_execute_query(select_query)
        if not songs:
            logging.info("Couldn't get results")
            return render_template('charts.html')

        return render_template('charts.html',songs=songs)
        
    genre=request.form['genre']
    if 'all' in genre:
        select_query="SELECT * from songs order by votes desc limit 10"
        songs=connect_execute_query(select_query)
        if not songs:
            logging.info("Coudln't get results")
            return render_template('charts.html')

        return render_template('charts.html',songs=songs)

    select_query=f"SELECT * from songs where genre='{genre}' order by votes desc limit 10"
    songs=connect_execute_query(select_query)

    if not songs:
        logging.info("You have selected invalid genre, please try again")
        return render_template('charts.html')

    return render_template('charts.html',songs=songs) 
def _song_in_db(song_name: str, artist: str) -> bool:
    query = f"SELECT song_name from songs where song_name='{song_name}' and artist ='{artist}'"
    found = connect_execute_query(query)
    if not found:
        logging.info("Song is not in the database.")
        return False
    return True
    def decor(*args, **kwargs):
        secret = os.getenv('SECRET_KEY')

        if 'Authorization' not in request.headers:
            return make_response("Token auth is required for this endpoint.",
                                 403)

        auth_header = request.headers.get('Authorization')
        auth_token = auth_header.split(" ")[1] if auth_header else ""

        if not all(param in request.args for param in ['song_name', 'artist']):
            return make_response("Invalid parameter(s)", 406)

        song_name = request.args.get('song_name')
        artist = request.args.get('artist')

        try:
            token = jwt.decode(auth_token, secret,
                               algorithms=["HS256"])['token']
            token_query = f"SELECT token FROM songs WHERE song_name='{song_name}' AND artist='{artist}'"
            token_result = connect_execute_query(token_query)

            if not token_result:
                return make_response("Invalid token.", 405)

            if token_result[0][0] != token:
                return make_response("Invalid permissions for this song", 403)

            logging.info(f"User is authenticated to use this API Endpoint")
            return func(*args, **kwargs)
        except Exception as e:
            logging.error(f"Error happened during authentication: [{e}]")
            return make_response("Invalid token.", 405)
    def decor(*args, **kwargs):
        secret = os.getenv('SECRET_KEY')

        if 'Authorization' not in request.headers:
            return make_response("Token auth is required for this endpoint.",
                                 403)

        auth_header = request.headers.get('Authorization')
        auth_token = auth_header.split(" ")[1] if auth_header else ""

        try:
            token = jwt.decode(auth_token, secret,
                               algorithms=["HS256"])['token']
            token_query = f"SELECT * FROM users WHERE token='{token}'"
            result = connect_execute_query(token_query)

            if not result:
                return make_response("Invalid token.", 405)

            logging.info(
                f"User [{result[0][1]}] is authenticated to use this API Endpoint"
            )
            return func(*args, **kwargs)
        except Exception as e:
            logging.error(f"Error happened during authentication: [{e}]")
            return make_response("Invalid token.", 405)
def songs():
    if request.method =='GET':
        return render_template('songs.html')

    song_name = request.form.get('song')
    username = request.form.get('user')
    artist = request.form.get('artist')
    genre = request.form.get('genre')
    yt_link = request.form.get('yt_link')
    token = request.form.get('token')
       
    try:
        token = jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['token']
        token_query = f"SELECT * FROM users WHERE token='{token}'"
        result = connect_execute_query(token_query)

        if not result:
            flash("Token is not valid,please try again", category='error')
            return render_template('songs.html')

        logging.info(f"User [{result[0][1]}] is authenticated to use this API Endpoint")
    except Exception as e:
        logging.error(f"Error happened during authentication: [{e}]")
        flash(str(e), category='error')
        return render_template('songs.html')

    song = Song(artist,genre,song_name,yt_link,token)
    success = song.input_song()

    if not success:
        flash("Song already exists!", category='error')
        return render_template("songs.html")

    return render_template('added_song.html',name=song.song_name)
Exemple #7
0
    def input_song(self) -> bool:
        if self.check_if_song_exists():
            logging.info(
                f"Adding [{self.artist.upper()}:{self.song_name}] song into db."
            )

            template = load_db_template(defaults.song_insert)
            insert_query = template.render(song_name=self.song_name,
                                           artist=self.artist,
                                           genre=self.genre,
                                           yt_link=self.yt_link,
                                           token=self.token)

            connect_execute_query(insert_query)

            return True

        return False
Exemple #8
0
 def validate_user(self) -> bool:
     query = f"SELECT user FROM users WHERE user=\'{self.name}\'"
     result = connect_execute_query(query)
     if result:
         logging.warning(f"User by the name {result[0][0]} already exists.")
         return False
     else:
         logging.info(f"User with name {self.name} is valid.")
         return True
Exemple #9
0
 def check_if_song_exists(self) -> bool:
     query = f"SELECT * FROM songs WHERE UPPER(artist)=\'{self.artist.upper()}\' AND UPPER(song_name)=\'{self.song_name.upper()}\'"
     result = connect_execute_query(query)
     if result:
         logging.warning(
             f"Song [{self.artist}:{self.song_name}] you wanted to add already exists."
         )
         return False
     else:
         return True
def _handle_request(wanted_params: list, endpoint: str, top_count: int = 0):
    logging.info(f"User requested list of {endpoint}.")
    try:
        if invalid_parameters(wanted_params):
            logging.info("Bad parameter added to request.")
            return make_response(f"Bad parameter", 420)

        if invalid_param_value():
            logging.info("Bad parameter values added to request.")
            return make_response("Bad parameter value", 421)

        where_query = ''
        for param in wanted_params:
            if param == 'sort':
                continue

            if param in request.args:
                logging.info(
                    f"User requested {param} to be {request.args.get(param)}.")
                where_query += f"{' AND' if where_query else ''} {param}='{request.args.get(param)}'"

        where_query = f" WHERE{where_query}" if where_query else ''

        values = [param for param in wanted_params if param != 'sort']
        values_str = ','.join(values)

        query = f"SELECT {values_str} FROM songs{where_query}"
        songs = connect_execute_query(query)

        response = [dict(zip(values, song)) for song in songs]

        sort_desc = 'sort' in request.args and request.args.get(
            'sort') == 'desc'

        if 'votes' in endpoint:
            logging.info(
                f"Results will be sorted in {'descending' if sort_desc else 'ascending'} order"
            )
            response = sorted(response,
                              key=lambda k: k['votes'],
                              reverse=sort_desc)

        if top_count != 0:
            logging.info(f"User requested first {top_count} results.")
            response = response[:top_count] if sort_desc else response[
                -top_count:]

        return jsonify(response)
    except Exception as e:
        logging.error(
            f"Error happened while using /api/{endpoint} endpoint: {e}")
        return make_response('Could not get the results. Please try later.',
                             430)
def _handle_delete_request(song_name: str, artist: str):
    try:
        logging.info(f"User requested delete of {song_name}.")

        if not _song_in_db(song_name, artist):
            return make_response("Bad song_name value", 405)

        query = f"DELETE FROM songs where song_name='{song_name}' and artist='{artist}'"
        songs = connect_execute_query(query)
        return make_response("Song is successfully deleted from database.")

    except Exception as e:
        logging.error(f"Error happened while using /api/songs endpoint: {e}")
        return make_response('Could not get the results. Please try later.',
                             430)
Exemple #12
0
    def get_encoded_token(self) -> str:
        try:
            query = f"SELECT token FROM users WHERE user='******'"
            result = connect_execute_query(query)

            if result:
                token = result[0][0]
                return str(
                    jwt.encode({'token': token},
                               os.getenv('SECRET_KEY'),
                               algorithm="HS256"))
            else:
                logging.warning(
                    f"User [{self.name}] is missing from DB. Trying to add him."
                )
                user_added = self.input_user()

                if not user_added:
                    logging.critical(
                        f"User [{self.name}] failed to be added to the DB.")
                    return None

                logging.info(
                    "User successfully added to the DB, acquiring token.")
                result = connect_execute_query(query)

                if not result:
                    return None

                return str(
                    jwt.encode({'token': result[0][0]},
                               os.getenv('SECRET_KEY'),
                               algorithm="HS256"))
        except Exception as e:
            logging.error(f"Error happened while acquiring token: {e}")
            return None
Exemple #13
0
    def input_user(self) -> bool:
        if len(self.name) <= 3:
            logging.info("Username must have more than 3 characters.")
            return False

        if len(self.password) <= 4:
            logging.info("Password must have more than 4 characters.")
            return False

        if self.validate_user():
            logging.info(f"Adding {self.name} user into db.")
            token = str(uuid.uuid4())

            template = load_db_template(defaults.user_insert)
            insert_query = template.render(user=self.name,
                                           password=generate_hash(
                                               self.password),
                                           token=token)

            connect_execute_query(insert_query)

            return True

        return False