Parts Implemented by Alperen Kantarcı

User creation, update and deleting functions implemented.Flask login and session management used with this user class. Message creation, and deletion operations implemented. News creation and deletion implemented. Functions that users could use also implemented by me. Any input form handling and code cleanup made by me.

Users Table, Class & Functions

There are 3 types of users admin,restaurant owner and customer. Restaurant owner and customer is generated by registration form but admin user create itself by init db.

Attributes of Users Table

  • ID SERIAL PRIMARY KEY
    Primary key of user
  • FIRSTNAME VARCHAR(80) NOT NULL
    Name of the user
  • LASTNAME VARCHAR(80) NOT NULL
    Surname of the user
  • MAIL VARCHAR(80) NOT NULL
    Email for sign in
  • PASSWORD VARCHAR(500) NOT NULL
    Hashed password
  • BIRTHDATE DATE NOT NULL
    Birthdate of th user
  • CITY VARCHAR(80) NOT NULL
    City that user’s live
  • GENDER VARCHAR(20)
    Gender of the user man,woman and other
  • USERTYPE INTEGER NOT NULL
    0 for admin 1 for restaurant owner 2 for customer
  • AVATAR VARCHAR(255)
    Avatar link
  • BIO VARCHAR(500)
    If user gives bio

Operations

To operate create, select, update and delete operations a class implemented.Also this class inherits UserMixin so for current_user in flask i added some properties to the user class. .. code-block:: python

@property
def get_gender(self):
return self.Gender

@property def get_birthdate(self):

return self.Birthdate

@property def get_bio(self):

return self.Bio

@property def get_city(self):

return self.City

@property def get_avatar(self):

return self.Avatar

@property def get_mail(self):

return self.Mail

@property def get_name(self):

return self.FirstName

@property def get_lastname(self):

return self.LastName

@property def get_type(self):

return self.UserType

@property def is_active(self):

return True

@property def is_authenticated(self):

return True

@property def is_anonymous(self):

return False
def get_id(self):
return self.Mail

@property def get_Id(self):

return self.Id

Create

To add new users constructor of Users class used. This constructor takes input parameters of the user. I inherited UserMixin class in order to handle flask_login operations

  class Users(UserMixin):
def __init__(self,Id,FirstName,LastName,Mail,Password,Birthdate,City,Gender,UserType,Avatar,Bio):
    self.Id = Id
    self.FirstName = FirstName
    self.LastName = LastName
    self.Mail = Mail
    self.Password = Password
    self.Birthdate = Birthdate
    self.Bio = Bio
    self.City = City
    self.Gender = Gender
    self.UserType = UserType
    self.Avatar = Avatar
    self.active = True
    if UserType == 0:
        self.is_admin = True
    else:
        self.is_admin = False

    with dbapi2.connect(current_app.config['dsn']) as connection:
        cursor = connection.cursor()
        query = """
        INSERT INTO USERS (FIRSTNAME, LASTNAME, MAIL, PASSWORD, BIRTHDATE, CITY, GENDER, USERTYPE, AVATAR, BIO)
        VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""

        cursor.execute(query, (firstName, lastName, email, hashed_password, birthDate,city, gender, userType, avatar,bio))

Select

There are 3 select methods for users. First one, get_user which flask login use it takes username as input and return user. Second one returns user by taking userid as input. Last one returns whole user list in the database.

    def get_user(db_mail):
if type(db_mail) is int:
    return None

if db_mail in current_app.config['ADMIN_USERS']:
    user = Users(1,'admin','admin','admin@restoranlandin.com',current_app.config['PASSWORD'], '2012-10-10', '', '',0, '','')
    return user

with dbapi2.connect(current_app.config['dsn']) as connection:
    cursor = connection.cursor()
    statement = """SELECT * FROM USERS WHERE MAIL = %s"""
    cursor.execute(statement, [db_mail])
    db_user = cursor.fetchone()
    user = Users(db_user[0],db_user[1], db_user[2], db_user[3],db_user[4], db_user[5], db_user[6], db_user[7], db_user[8], db_user[9], db_user[10])


if user is not None:
    user.is_admin = user.Mail in current_app.config['ADMIN_USERS']

return user

Update

An User can be updated from User Edit form.

with dbapi2.connect(current_app.config['dsn']) as connection:
            cursor = connection.cursor()
            query = """
                UPDATE USERS
                    SET FIRSTNAME = %s,
                        LASTNAME = %s,
                        MAIL = %s,
                        BIRTHDATE = %s,
                        CITY = %s,
                        GENDER = %s,
                        AVATAR = %s,
                        BIO = %s
                    WHERE (ID = %s)"""

            cursor.execute(query, (firstName, lastName, email, birthDate, city, gender, avatar, bio, current_user.get_Id))

Delete

Users can be deleted by admin from admin panel.

def delete_user_by_id(userID):
with dbapi2.connect(current_app.config['dsn']) as connection:
    cursor = connection.cursor()
    query = """
        DELETE FROM USERS WHERE ID = %s"""
    cursor.execute(query, [userID] )
    connection.commit()

Users deleted by their id.

Many of other tables referencing users table so other members implemented different functions for different usages.

News Table, Class & Functions

Admin can publish news from admin panel which includes topic and content and also can give external links or direction to the restaurant pages.

Attributes of News Table

  • ID SERIAL PRIMARY KEY
    Primary key of news id
  • TOPIC VARCHAR(80) NOT NULL
    Header of the news
  • CONTENT VARCHAR(800) NOT NULL
    Message content of the news
  • LINK VARCHAR(200)
    External link
  • RESTAURANT INTEGER REFERENCES RESTAURANTS(ID) ON DELETE CASCADE
    Restaurant link for restaurant that will be linked

Operations

To operate create, select and update and delete a class implemented.

Create

Whenever admin creates news this function is used.

Select

There are 2 select methods for news. First one, return only one new . Second one returns whole news as list in the database.

def get_news_by_id(id):
with dbapi2.connect(current_app.config['dsn']) as connection:
        cursor = connection.cursor()
        query = """
        SELECT * FROM NEWS WHERE ID = %s"""
        cursor.execute(query,[id])
        db_news = cursor.fetchone()
        news_class = News(db_news[1],db_news[2],db_news[3],db_news[4])
        news_class.find_news_id()
        return news_class



def get_all_news():
with dbapi2.connect(current_app.config['dsn']) as connection:
        cursor = connection.cursor()
        query = """SELECT * FROM NEWS"""
        cursor.execute(query)
        db_news = cursor.fetchall()

        if db_news is None:
        db_news = {}
        return db_news

Update

A News can be updated from News Edit form.

def update_news(self):
    with dbapi2.connect(current_app.config['dsn']) as connection:
        cursor = connection.cursor()
        if self.Restaurant == "":
            query = """UPDATE NEWS SET TOPIC = %s, CONTENT = %s, LINK = %s WHERE ID = %s"""
            cursor.execute(query,(self.Topic,self.Content,self.Link,self.Id))
        else:
            query = """UPDATE NEWS SET TOPIC = %s, CONTENT = %s, LINK = %s, RESTAURANT = %s WHERE ID = %s"""
            cursor.execute(query,(self.Topic,self.Content,self.Link,self.Restaurant,self.Id))
        connection.commit()

Delete

A News can be deleted from News Edit form.

def delete_news(Id):
if Id != '':
    with dbapi2.connect(current_app.config['dsn']) as connection:
        cursor = connection.cursor()
        statement = """DELETE FROM NEWS WHERE ID = %s"""
        cursor.execute(statement, [Id])
        connection.commit()

Messages Table, Class & Functions

Every user can send private messages to each other.Yet, admin user has access to see all user emails to send message to the users. So get_all_users function only can be used in admin page.

Attributes of Messages Table

  • ID SERIAL PRIMARY KEY
    Id used for primary key
  • SENDER INTEGER REFERENCES USERS(ID) ON DELETE CASCADE
    Sender id used for identification of sender, if user deleted messages will be deleted as well
  • RECEIVER INTEGER REFERENCES USERS(ID) ON DELETE CASCADE
    Receiver id used for identification of sender, if user deleted messages will be deleted as well
  • TOPIC VARCHAR(80) NOT NULL
    Topic of message
  • CONTENT VARCHAR(800) NOT NULL
    Content of the message
  • SENDDATE TIMESTAMP NOT NULL
    Send time for message

Operations

To operate create, select a class implemented.

Create

Whenever any user sends message this function will be used.

Select

Selecting all user messages from database.


def select_all_messages(user_id):

with dbapi2.connect(current_app.config[‘dsn’]) as connection:
cursor = connection.cursor() statement = “”“SELECT * FROM MESSAGES WHERE SENDER = %s OR RECEIVER = %s”“” cursor.execute(statement,(user_id,user_id)) messages = cursor.fetchall()
if len(messages) == 0:
return messages
for i in range(len(messages)):
with dbapi2.connect(current_app.config[‘dsn’]) as connection:
cursor = connection.cursor() statement = “”“SELECT FIRSTNAME FROM USERS WHERE ID = (SELECT SENDER FROM MESSAGES WHERE ID = %s)”“” cursor.execute(statement,[ messages[i][0]]) sender_name = (cursor.fetchone())[0]
with dbapi2.connect(current_app.config[‘dsn’]) as connection:
cursor = connection.cursor() statement = “”“SELECT LASTNAME FROM USERS WHERE ID = (SELECT SENDER FROM MESSAGES WHERE ID = %s)”“” cursor.execute(statement,[messages[i][0]]) sender_name += ” ” + (cursor.fetchone())[0]

messages[i] = list(messages[i]) messages[i].append(messages[i][1]) messages[i].append(messages[i][2]) messages[i][1] = sender_name messages[i] = tuple(messages[i])

with dbapi2.connect(current_app.config[‘dsn’]) as connection:
cursor = connection.cursor() statement = “”“SELECT FIRSTNAME FROM USERS WHERE ID = (SELECT RECEIVER FROM MESSAGES WHERE ID = %s)”“” cursor.execute(statement,[messages[i][0]]) receiver_name = (cursor.fetchone())[0]
with dbapi2.connect(current_app.config[‘dsn’]) as connection:
cursor = connection.cursor() statement = “”“SELECT LASTNAME FROM USERS WHERE ID = (SELECT RECEIVER FROM MESSAGES WHERE ID = %s)”“” cursor.execute(statement,[messages[i][0]]) receiver_name += ” ” + (cursor.fetchone())[0]

messages[i] = list(messages[i]) messages[i][2] = receiver_name messages[i] = tuple(messages[i])

return messages