Ejemplo n.º 1
0
class RecipeBox(database.Model):
    """
    Class that represents a user's recipe box (liked recipes, stored in the database).

    The following attributes of a user are stored in this table:
        is_liked (type: boolean) 
        user_id (type: int)
        recipe_id (type: int)

    All three values are required.
    """

    __tablename__ = 'recipe_boxes'

    id = database.Column(database.Integer, primary_key=True)

    is_liked = database.Column(database.Boolean, nullable=False, default=True)

    recipe_url = database.Column(database.String, nullable=False)

    recipe_title = database.Column(database.String, nullable=False)

    user_id = database.Column(
        database.Integer, database.ForeignKey('users.id', ondelete='cascade'))

    __table_args__ = (database.UniqueConstraint('user_id', 'recipe_url'), )

    def __init__(self, is_liked: bool, recipe_url: str, recipe_title: str,
                 user_id: int):
        self.is_liked = is_liked
        self.recipe_url = recipe_url
        self.recipe_title = recipe_title
        self.user_id = user_id
Ejemplo n.º 2
0
class Person(database.Model):
    person_id = database.Column(database.Integer,
                                primary_key=True,
                                unique=True)
    name = database.Column(database.String)
    address = database.Column(database.String)
    birth_day = database.Column(database.DateTime)
Ejemplo n.º 3
0
class Stock(database.Model):
    """
    Class that represents a purchased stock in a portfolio.

    The following attributes of a stock are stored in this table:
       * stock symbol (type: string)
       * number of shares (type: integer)
       * purchase price (type: integer)

    Note: Due to the limitation in the data types supported by SQLite, the
          purchase price is stored as an integer:
              $24.10 -> 2410
              $100.00 -> 10000
              $87.65 -> 8765
    """

    __tablename__ = 'stocks'

    id = database.Column(database.Integer, primary_key=True)
    stock_symbol = database.Column(database.String, nullable=False)
    number_of_shares = database.Column(database.Integer, nullable=False)
    purchase_price = database.Column(database.Integer, nullable=False)

    def __init__(self, stock_symbol: str, number_of_shares: str,
                 purchase_price: str):
        self.stock_symbol = stock_symbol
        self.number_of_shares = int(number_of_shares)
        self.purchase_price = int(float(purchase_price) * 100)

    def __repr__(self):
        return (
            f'{self.stock_symbol} - {self.number_of_shares} shares '
            f'purchased at ${self.purchase_price / 100}')
Ejemplo n.º 4
0
class User(database.Model):

    __tablename__ = "users"

    id = database.Column(database.Integer,
                         primary_key=True,
                         autoincrement=True)
    username = database.Column(database.String(256), nullable=False)
    email = database.Column(database.String(256), nullable=False, unique=True)
    name = database.Column(database.String(256), nullable=False)
    surname = database.Column(database.String(256), nullable=False)
    password = database.Column(database.String(512), nullable=False)
    created_at = database.Column(database.DateTime, default=func.now())

    def __init__(self, username, email, name, surname, password):
        self.username = username
        self.email = email
        self.name = name
        self.surname = surname
        self.password = generate_password_hash(password)

    def to_json(self):
        return {
            "id": self.id,
            "username": self.username,
            "email": self.email,
            "name": self.name,
            "surname": self.surname,
            "created_at": self.created_at
        }
Ejemplo n.º 5
0
class Stock(database.Model):
    "Class to represent purchased stock in portfolio"

    __tablename__ = 'stocks'

    id = database.Column(database.Integer, primary_key=True)
    stock_symbol = database.Column(database.String, nullable=False)
    number_of_shares = database.Column(database.Integer, nullable=False)
    purchase_price = database.Column(database.Integer, nullable=False)

    def __init__(self, stock_symbol: str, number_of_shares: str,
                 purchase_price: str):
        self.stock_symbol = stock_symbol
        self.number_of_shares = int(number_of_shares)
        self.purchase_price = int(float(purchase_price) * 100)

    def __repr__(self):
        return f'{self.stock_symbol} - {self.number_of_shares} shares purchased at ${self.purchase_price / 100}'
Ejemplo n.º 6
0
class ProviderObject(database.Model):

    __tablename__ = "data_store"

    id = database.Column(database.Integer,
                         primary_key=True,
                         autoincrement=True)
    model_id = database.Column(database.Integer, nullable=False)
    data_path = database.Column(database.String(512), nullable=False)

    def __init__(self, model_id, data_path):
        self.model_id = model_id
        self.data_path = data_path

    def to_json(self):
        return {
            "id": self.id,
            "model_id": self.model_id,
            "data_path": self.data_path,
            "filename": os.path.basename(self.data_path)
        }
Ejemplo n.º 7
0
class User(database.Model):
    "Class to represent users on the site"

    __tablename__ = 'users'

    id = database.Column(database.Integer, primary_key=True)
    email = database.Column(database.String, unique=True)
    password_hashed = database.Column(database.String(60))

    def __init__(self, email: str, password_plaintext: str):
        self.email = email
        self.password_hashed = bcrypt.generate_password_hash(
            password_plaintext,
            current_app.config.get('BCRYPT_LOG_ROUNDS')).decode('utf-8')

    def is_password_correct(self, password_plaintext: str):
        return bcrypt.check_password_hash(self.password_hashed,
                                          password_plaintext)

    def __repr__(self):
        return f'<User: {self.email}>'
Ejemplo n.º 8
0
class ModelState(database.Model):

    __tablename__ = "model_state"

    id = database.Column(database.Integer,
                         primary_key=True,
                         autoincrement=True)
    model_id = database.Column(database.Integer, nullable=False)
    test_accuracy = database.Column(database.Float, nullable=False)
    test_loss = database.Column(database.Float, nullable=False)
    last_test_time = database.Column(database.DateTime, nullable=False)
    test_duration = database.Column(database.DateTime, nullable=False)

    def __init__(self, model_id, test_accuracy, test_loss, last_test_time,
                 test_duration):
        self.model_id = model_id
        self.test_accuracy = test_accuracy
        self.test_loss = test_loss
        self.last_test_time = last_test_time
        self.test_duration = test_duration

    def to_json(self):
        return {
            "id": self.id,
            "model_id": self.model_id,
            "test_acc": self.test_accuracy,
            "test_loss": self.test_loss,
            "last_test_time": self.last_test_time,
            "test_duration": self.test_duration
        }
Ejemplo n.º 9
0
class User(database.Model):

        __tablename__ = "users"

        id = database.Column(database.Integer, primary_key=True, autoincrement=True)
        username = database.Column(database.String(256), nullable=False)
        email = database.Column(database.String(256), nullable=False, unique=True)
        name = database.Column(database.String(256), nullable=False)
        surname = database.Column(database.String(256), nullable=False)
        password = database.Column(database.String(512), nullable=False)
        created_at = database.Column(database.DateTime, default=func.now())

        def __init__(self, username, email, name, surname):
            self.username = username
            self.email = email
            self.name = name
            self.surname = surname

        def to_json(self):
            return {
                "id": self.id,
                "username": self.username,
                "email": self.email,
                "name": self.name,
                "surname": self.surname,
                "created_at": self.created_at
            }

        def encode_auth_token(self, user_id):
            try:
                current_app.logger.debug(f"TOKEN_EXP_DAYS: {current_app.config.get('TOKEN_EXP_DAYS')}")
                payload = {
                    "exp": datetime.datetime.utcnow() + datetime.timedelta(days=current_app.config.get("TOKEN_EXP_DAYS")),
                    # "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=current_app.config.get("TOKEN_EXP_DAYS")),
                    "iat": datetime.datetime.utcnow(),
                    "sub": user_id
                }
                token = jwt.encode(payload, current_app.config.get("SECRET_KEY"))

                current_app.logger.debug(f"TOKEN: {token}")

                return token

            except Exception as e:
                current_app.logger.error(e)
                return e

        def decode_auth_token(self, token):
            try:
                payload = jwt.decode(token, current_app.config.get("SECRET"))
                return payload["sub"]
            except jwt.ExpiredSignatureError:
                return "Signature expired."
            except jwt.InvalidSignatureError:
                return "Invalid token."
Ejemplo n.º 10
0
class ModelDefinition(database.Model):

    __tablename__ = "models"

    id = database.Column(database.Integer, primary_key=True, autoincrement=True)
    model_title = database.Column(database.String(256), nullable=False)
    path_to_model = database.Column(database.String(512))  # Contains the path to uploaded model config file
    path_to_custom_objects = database.Column(database.String(512))
    deployed_by = database.Column(database.Integer, nullable=False)
    model_framework = database.Column(database.String(128), nullable=False)

    def __init__(self, model_title, path_to_model, path_to_custom_objects, deployed_by, model_framework):
        self.model_title = model_title
        self.path_to_model = path_to_model
        self.path_to_custom_objects = path_to_custom_objects
        self.deployed_by = deployed_by
        self.model_framework = model_framework

    def to_json(self):
        return {
            "id": self.id,
            "model_title": self.model_title,
            "path": self.path_to_model,
            "custom_objects_path": self.path_to_custom_objects,
            "filename": os.path.basename(self.path_to_model),
            "custom_objects_filename": os.path.basename(self.path_to_custom_objects),
            "deployed_by": self.deployed_by,
            "model_framework": self.model_framework
        }
Ejemplo n.º 11
0
class Meal(database.Model):
    """
    Class that handles a user's meal planning.

    Users can add items from their saved recipe box to create meals.

    The following attributes of a meal are stored in this table:
        * meal_date: The date a user plans to have a meal (required)
        * meal_title: The (optional) title of the meal, assigned by the user (not required).
        * meal_notes: The (optional) notes about the meal, provided by the user (not required).
        * recipe_id: The Spoonacular recipe_id (Required).
        * recipe_title: The Spoonacular recipe_title (Required).
        * recipe_url: The source URL of the recipe (Required).
        * user_id: The user_id (Foreign key from User table; required).
    """

    __tablename__ = 'meals'

    id = database.Column(database.Integer, primary_key=True)

    meal_date = database.Column(database.DateTime,
                                nullable=False,
                                default=datetime.now())

    meal_title = database.Column(database.String(100), nullable=True)

    meal_notes = database.Column(database.String(1000), nullable=True)

    recipe_id = database.Column(database.Integer, nullable=False)

    recipe_title = database.Column(database.String, nullable=False)

    recipe_url = database.Column(database.String, nullable=False)

    user_id = database.Column(database.Integer,
                              database.ForeignKey('users.id'))

    def __init__(self, meal_date: datetime, meal_title: str, meal_notes: str,
                 recipe_id: int, recipe_title: str, recipe_url: str,
                 user_id: int):
        self.meal_date = meal_date
        self.meal_title = meal_title
        self.meal_notes = meal_notes

        self.recipe_id = recipe_id
        self.recipe_title = recipe_title
        self.recipe_url = recipe_url
        self.user_id = user_id
Ejemplo n.º 12
0
class UserProfile(database.Model):
    """
    Class that represents a user's profile information.

    The following attributes of a user are stored in this table:
        username (type: string) 
        first_name (type: string) 
        last_name (type: string)

    The username attribute is required; first_name and last_name are optional.
    """

    __tablename__ = 'user_profiles'

    id = database.Column(database.Integer, primary_key=True)

    username = database.Column(database.String, nullable=False)

    first_name = database.Column(database.String, nullable=True)

    last_name = database.Column(database.String, nullable=True)

    user_id = database.Column(database.Integer,
                              database.ForeignKey('users.id'))

    def __init__(self, username: str, first_name: str, last_name: str,
                 user_id: int):
        self.username = username
        self.first_name = first_name
        self.last_name = last_name
        self.user_id = user_id

    def __repr__(self):
        """ Show info about user_profile. """

        u = self
        return f"<UserProfile {u.username} {u.first_name} {u.last_name}"
Ejemplo n.º 13
0
class ModelState(database.Model):

    __tablename__ = "model_state"

    id = database.Column(database.Integer,
                         primary_key=True,
                         autoincrement=True)
    model_id = database.Column(database.Integer, nullable=False)
    test_accuracy = database.Column(database.Float, nullable=False)
    test_loss = database.Column(database.Float, nullable=False)
    last_test_time = database.Column(database.DateTime, nullable=False)
    test_duration = database.Column(database.Float, nullable=False)
    test_status = database.Column(database.String, nullable=False)
    test_device = database.Column(database.String, nullable=False)

    def __init__(self, model_id, test_accuracy, test_loss, last_test_time,
                 test_duration, test_status, test_device):
        self.model_id = model_id
        self.test_accuracy = test_accuracy
        self.test_loss = test_loss
        self.last_test_time = last_test_time
        self.test_duration = test_duration
        self.test_status = test_status
        self.test_device = test_device

    def to_json(self):
        return {
            "id": self.id,
            "model_id": self.model_id,
            "test_acc": round(self.test_accuracy, 2),
            "test_loss": round(self.test_loss, 2),
            "last_test_time": self.last_test_time.strftime("%d/%m/%Y %H:%M"),
            "test_duration": round(self.test_duration, 2),
            "test_status": self.test_status,
            "test_device": self.test_device
        }
Ejemplo n.º 14
0
class User(database.Model):
    """
    Class that handles user logins and authentication.

    The following attributes of a login are stored in this table:
        * user_id (as a foreign key. When a user successfully registers, the user_id is inserted into the logins table.)
        * email - the user's email
        * hashed password - hashed password (using Flask-Bcrypt)
        * A foreign key relationship with UserProfile, which joins data from the Users and UserProfiles tables
        * A foreign key relationship with Follow, which manages a self-referential follower/following relatitionship.
    """
    __tablename__ = 'users'

    id = database.Column(database.Integer, primary_key=True)

    email = database.Column(database.String, unique=True, nullable=False)

    password_hashed = database.Column(database.String(264), nullable=False)

    registered_on = database.Column(database.DateTime, nullable=True)

    email_confirmation_sent_on = database.Column(database.DateTime,
                                                 nullable=True)

    email_confirmed = database.Column(database.Boolean, default=False)

    email_confirmed_on = database.Column(database.DateTime, nullable=True)

    def __init__(self, email: str, password_plaintext: str):
        self.email = email
        self.password_hashed = self._generate_password_hash(password_plaintext)
        self.registered_on = datetime.now()
        self.email_confirmation_sent_on = datetime.now()
        self.email_confirmed = False
        self.email_confirmed_on = None

    user_profiles = database.relationship('UserProfile',
                                          backref='user',
                                          lazy='dynamic')

    user_recipes = database.relationship('RecipeBox',
                                         backref='user',
                                         lazy='dynamic')

    followed = database.relationship(
        'User',
        secondary=followers,
        primaryjoin=(followers.c.follower_id == id),
        secondaryjoin=(followers.c.followed_id == id),
        backref=database.backref('followers', lazy='dynamic'),
        lazy='dynamic')

    user_meals = database.relationship("Meal", backref='user', lazy='dynamic')

    def is_password_correct(self, password_plaintext: str):
        return bcrypt.check_password_hash(self.password_hashed,
                                          password_plaintext)

    def set_password(self, password_plaintext: str):
        self.password_hashed = self._generate_password_hash(password_plaintext)

    def follow(self, user):
        if not self.is_following(user):
            self.followed.append(user)

    def unfollow(self, user):
        if self.is_following(user):
            self.followed.remove(user)

    def is_following(self, user):
        return self.followed.filter(
            followers.c.followed_id == user.id).count() > 0

    @staticmethod
    def _generate_password_hash(password_plaintext):
        return bcrypt.generate_password_hash(
            password_plaintext,
            current_app.config.get('BCRYPT_LOG_ROUNDS')).decode('utf-8')

    def __repr__(self):
        return f'<User: {self.email} {self.password_hashed}>'

    @property
    def is_authenticated(self):
        """Return True if the user has been successfully registered."""
        return True

    @property
    def is_active(self):
        """Always True, as all users are active."""
        return True

    @property
    def is_anonymous(self):
        """Always False, as anonymous users aren't supported."""
        return False

    def get_id(self):
        """Return the user ID as a unicode string (`str`)."""
        return str(self.id)
Ejemplo n.º 15
0
class Stock(database.Model):
    """
    Class that represents a purchased stock in a portfolio

    The following attributes of a stock are stored in this table:
        stock symbol (type: string)
        number of shares (type: integer)
        purchase price (type: integer)
        purchase date (type: datetime)
        current price (type: integer)
        date when current price was retrieved from the Alpha Vantage API (type: datetime)
        position value = current price * number of shares (type: integer)

    Note: Due to a limitation in the data types supported by SQLite, the
          purchase price is stored as an integer:
              $24.10 -> 2410
              $100.00 -> 10000
              $87.65 -> 8765
    """
    __tablename__ = 'stocks'

    id = database.Column(database.Integer, primary_key=True)
    stock_symbol = database.Column(database.String, nullable=False)
    number_of_shares = database.Column(database.Integer, nullable=False)
    purchase_price = database.Column(database.Integer, nullable=False)
    user_id = database.Column(database.Integer,
                              database.ForeignKey('users.id'))
    purchase_date = database.Column(database.DateTime)
    current_price = database.Column(database.Integer)
    current_price_date = database.Column(database.DateTime)
    position_value = database.Column(database.Integer)

    def __init__(self,
                 stock_symbol: str,
                 number_of_shares: str,
                 purchase_price: str,
                 user_id: int,
                 purchase_date=None):
        self.stock_symbol = stock_symbol
        self.number_of_shares = int(number_of_shares)
        self.purchase_price = int(float(purchase_price) * 100)
        self.user_id = user_id
        self.purchase_date = purchase_date
        self.current_price = 0
        self.current_price_date = None
        self.position_value = 0

    def __repr__(self):
        return f'{self.stock_symbol} - {self.number_of_shares} shares purchased at ${self.purchase_price / 100}'

    def create_alpha_vantage_get_url_daily_compact(self):
        return 'https://www.alphavantage.co/query?function={}&symbol={}&outputsize={}&apikey={}'.format(
            'TIME_SERIES_DAILY_ADJUSTED', self.stock_symbol, 'compact',
            current_app.config['ALPHA_VANTAGE_API_KEY'])

    def get_stock_data(self):
        if self.current_price_date is None or self.current_price_date.date(
        ) != datetime.now().date():
            url = self.create_alpha_vantage_get_url_daily_compact()

        try:
            r = requests.get(url)
        except requests.exceptions.ConnectionError:
            current_app.logger.error(
                f'Error! Network problem preventing retrieving the stock data ({ self.stock_symbol })!'
            )

        # Status code returned from Alpha Vantage needs to be 200 (OK) to process stock data
        if r.status_code != 200:
            current_app.logger.warning(
                f'Error! Received unexpected status code ({ r.status_code }) '
                f'when retrieving stock data ({ self.stock_symbol })!')
            return

        daily_data = r.json()

        # The key of 'Time Series (Daily)' needs to be present in order to process the stock data
        # Typically, this key will not be present if the API rate limit has been exceeded.
        if 'Time Series (Daily)' not in daily_data:
            current_app.logger.warning(
                f'Could not find Time Series (Daily) key when retrieving '
                f'the stock data ({ self.stock_symbol })!')
            return

        for element in daily_data['Time Series (Daily)']:
            current_price = float(
                daily_data['Time Series (Daily)'][element]['4. close'])
            self.current_price = int(float(current_price) * 100)
            self.current_price_date = datetime.now()
            self.position_value = self.current_price * self.number_of_shares
            break
        current_app.logger.debug(
            f'Retrieved current price {self.current_price / 100} '
            f'for the stock data ({ self.stock_symbol })!')

    def get_stock_position_value(self) -> float:
        return float(self.position_value / 100)

    def create_alpha_vantage_get_url_weekly(self):
        return 'https://www.alphavantage.co/query?function={}&symbol={}&apikey={}'.format(
            'TIME_SERIES_WEEKLY_ADJUSTED', self.stock_symbol,
            current_app.config['ALPHA_VANTAGE_API_KEY'])

    def get_weekly_stock_data(self):
        title = ''
        labels = []
        values = []
        url = self.create_alpha_vantage_get_url_weekly()

        try:
            r = requests.get(url)
        except requests.exceptions.ConnectionError:
            current_app.logger.info(
                f"Error! Network problem preventing retrieving the weekly stock data ({ self.stock_symbol })!"
            )

        if r.status_code == 200:
            weekly_data = r.json()
            title = f'Weekly Prices ({self.stock_symbol})'

            # Determine the start date as either:
            #   - If the start date is less than 12 weeks ago, then use the date from 12 weeks ago
            #   - Otherwise, use the purchase date
            start_date = self.purchase_date
            if (datetime.now() - self.purchase_date) < timedelta(weeks=12):
                start_date = datetime.now() - timedelta(weeks=12)

            for element in weekly_data['Weekly Adjusted Time Series']:
                date = datetime.fromisoformat(element)
                if date.date() > start_date.date():
                    labels.append(date)
                    values.append(weekly_data['Weekly Adjusted Time Series']
                                  [element]['4. close'])

            # Reverse the elements as the data from Alpha Vantage is read in latest to oldest
            labels.reverse()
            values.reverse()
        else:
            current_app.logger.info(
                f"Error! Received unexpected status code ({ r.status_code }) when retrieving weekly stock data ({ self.stock_symbol })!"
            )

        return title, labels, values
Ejemplo n.º 16
0
class User(database.Model):
    """
    Class that represents a user of the application

    The following attributes of a user are stored in this table:
        * email - email address of the user
        * hashed password - hashed password (using Flask-Bcrypt)
        * registered_on - date & time that the user registered
        * email_confirmation_sent_on - date & time that the confirmation email
        *                              was sent
        * email_confirmed - flag indicating if the user's email address has
        *                   been confirmed
        * email_confirmed_on - date & time that the user's email address was
        *                      confirmed

    REMEMBER: Never store the plaintext password in a database!
    """
    __tablename__ = 'users'

    id = database.Column(database.Integer, primary_key=True)
    email = database.Column(database.String, unique=True)
    password_hashed = database.Column(database.String(60))
    registered_on = database.Column(database.DateTime)
    email_confirmation_sent_on = database.Column(database.DateTime)
    email_confirmed = database.Column(database.Boolean, default=False)
    email_confirmed_on = database.Column(database.DateTime)

    def __init__(self, email: str, password_plaintext: str):
        """Create a new User object

        This constructor assumes that an email is sent to the new user to
        confirm their email address at the same time that the user is
        registered.
        """
        self.email = email
        self.password_hashed = self._generate_password_hash(password_plaintext)
        self.registered_on = datetime.now()
        self.email_confirmation_sent_on = datetime.now()
        self.email_confirmed = False
        self.email_confirmed_on = None

    def is_password_correct(self, password_plaintext: str):
        return bcrypt.check_password_hash(self.password_hashed,
                                          password_plaintext)

    def __repr__(self):
        return f'<User: {self.email}'

    @property
    def is_authenticated(self):
        """Return True if the user has been successfully registered."""
        return True

    @property
    def is_active(self):
        """Always True, as all users are active."""
        return True

    @property
    def is_anonymous(self):
        """Always False, as anonymous users aren't supported."""
        return False

    def get_id(self):
        """Return the user ID as a unicode string (`str`)."""
        return str(self.id)

    def set_password(self, password_plaintext: str):
        self.password_hashed = self._generate_password_hash(password_plaintext)

    @staticmethod
    def _generate_password_hash(password_plaintext: str):
        return bcrypt.generate_password_hash(
            password_plaintext,
            current_app.config.get('BCRYPT_LOG_ROUNDS')
        ).decode('utf-8')
Ejemplo n.º 17
0
from project import database, bcrypt
from flask import current_app
from datetime import datetime

followers = database.Table(
    'followers',
    database.Column('follower_id', database.Integer,
                    database.ForeignKey('users.id')),
    database.Column('followed_id', database.Integer,
                    database.ForeignKey('users.id')))


class User(database.Model):
    """
    Class that handles user logins and authentication.

    The following attributes of a login are stored in this table:
        * user_id (as a foreign key. When a user successfully registers, the user_id is inserted into the logins table.)
        * email - the user's email
        * hashed password - hashed password (using Flask-Bcrypt)
        * A foreign key relationship with UserProfile, which joins data from the Users and UserProfiles tables
        * A foreign key relationship with Follow, which manages a self-referential follower/following relatitionship.
    """
    __tablename__ = 'users'

    id = database.Column(database.Integer, primary_key=True)

    email = database.Column(database.String, unique=True, nullable=False)

    password_hashed = database.Column(database.String(264), nullable=False)