Commit 4ec5722e by ajil.k

updated

parent a1c3fd63
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
[log_file_path]
file_name = temp/
\ No newline at end of file
import configparser
try:
config = configparser.ConfigParser()
config.read(r"conf\application.conf")
# logging file path
file_name = config.get("log_file_path", "file_name")
except configparser.NoOptionError as e:
print(f"could not find conf file {e}")
\ No newline at end of file
class EndPoints:
root = "/"
book_ticket = "/book ticket/"
delete_a_ticket = "/delete_ticket{ticket_id}"
cancel_all_tickets = "/cancel_all_tickets/"
seat_availability = "/seat_availability/"
get_booking_details = "/get_booking_details/"
from pydantic import BaseModel from pydantic import BaseModel, Field
# Model for fetching details from user # Model for fetching details from user
...@@ -8,3 +8,4 @@ class ticket_booking(BaseModel): ...@@ -8,3 +8,4 @@ class ticket_booking(BaseModel):
no_of_tickets: int no_of_tickets: int
seat_numbers: str seat_numbers: str
age: int age: int
import json
import pandas as pd
import paho.mqtt.client as mqtt
from fastapi import HTTPException
from scripts.core.handlers.avail_seats_redis import check_seat_avail
from scripts.database.RedisDB.db_connection import conn
from scripts.database.postgresql.db_connection import db_connect from scripts.database.postgresql.db_connection import db_connect
from scripts.database.postgresql.model import BookingDetails from scripts.database.postgresql.model import BookingDetails
from scripts.logging.logger import logger
class Tickets:
def __init__(self):
self.session = db_connect()
self.client = mqtt.Client()
self.client.connect("192.168.0.220", 1883, 60)
self.booked_list = []
def insert_data_into_db(details): def insert_data_into_db(self, details):
# add new booking details # add new booking details
try: try:
print(details) # Check if the data entered
new_booking = BookingDetails(mobile_no=details.mobile_no, if 5 >= details.no_of_tickets > 0:
preferred_class=details.preferred_class, raise HTTPException(status_code=400, detail="Can book only 5 tickets at a time.")
no_of_tickets=details.no_of_tickets, if details.preferred_class not in ["gold", "silver"]:
seat_numbers=details.seat_numbers, raise HTTPException(status_code=400, detail="Invalid class type")
age=details.age) seats = details.seat_numbers.split(",")
session = db_connect() integer_list = [int(item) for item in seats]
session.add(new_booking) if len(integer_list) != details.no_of_tickets:
session.commit() raise HTTPException(status_code=400, detail="Number of seat numbers must match the number of tickets")
except Exception as e:
print(e)
for seat_ in integer_list:
if seat_ not in self.booked_list:
if not check_seat_avail(conn, details.preferred_class, int(seat_)):
self.booked_list.append(seat_)
if self.booked_list:
raise HTTPException(status_code=400,
detail=f"Seat number that are already booked are : {self.booked_list} \n"
f"seat number you are going to book are {integer_list}")
payload = {details.preferred_class: integer_list}
self.client.publish("ticket2/", json.dumps(payload))
new_booking = BookingDetails(mobile_no=details.mobile_no,
preferred_class=details.preferred_class,
no_of_tickets=details.no_of_tickets,
seat_numbers=details.seat_numbers,
age=details.age)
self.session.add(new_booking)
self.session.commit()
return {"message": "Ticket booking successful"}
except Exception as e:
return e
def cancel_tickets(self):
try:
query = self.session.query(BookingDetails).update({BookingDetails.deleted: True})
# Commit the changes to the database
self.session.commit()
if query is not None:
# Publish the Message
topic = "ticket2/cancel_all"
message = "Show Cancelled"
self.client.publish(topic, message)
except Exception as e:
logger.error(e)
def delete_row(self, booking_id):
try:
# Soft delete a row in the ticket_details table
ticket = self.session.query(BookingDetails).filter(BookingDetails.booking_id == booking_id,
BookingDetails.deleted == False).first()
if ticket is not None:
ticket.deleted = True
self.session.commit()
no_seats = ticket.seat_numbers
data_of_list = no_seats.split(",")
integer_list = [int(item) for item in data_of_list]
data = {ticket.preferred_class: integer_list}
self.client.publish("ticket2/delete", json.dumps(data))
return data
else:
print(f"Ticket with id {booking_id} is not exist")
logger.error(f"Ticket with id {booking_id} is not exist")
return {"message": f"ticket with id {booking_id} not exist", "status": "Ticket not exist",
"data": booking_id}
except Exception as e:
logger.error(e)
def get_details(self):
try:
records = self.session.query(BookingDetails).all()
dict_records = [record.__dict__ for record in records]
# Remove any keys from the dictionaries that start with an underscore
dict_records_clean = [
{
key: values for key, values in record.items() if not key.startswith('_')
}
for record in dict_records
]
# Use pandas to convert the list of dictionaries to a DataFrame
df = pd.DataFrame(dict_records_clean)
print("-------------------------------Booking Details-------------------------------")
print(df)
# Use pandas to save the DataFrame to an Excel file
df.to_excel('temp/booking_details.xlsx', index=False)
except Exception as e:
logger.error(e)
import pickle
# check for the seat availability
def check_seat_avail(connection, ticket_class, seats_needed):
try:
class_lists = {
"gold": pickle.loads(connection.get("gold")),
"silver": pickle.loads(connection.get("silver"))
}
# get the availability of seat
if ticket_class not in class_lists:
return None
flag = 0
for seats in class_lists[ticket_class]:
if seats_needed in seats:
flag += 1
return True
if flag == 0:
return False
except Exception as e:
print(e)
# create redis db
import pickle
from scripts.database.RedisDB import db_connection
def redis_db_create(connection, ticket_class, seats, total_count):
try:
mapper_ticket_class = {
"gold": lambda count: connection.set("gold_available_seats", count),
"silver": lambda count: connection.set("silver_available_seats", count)
}
# if the class is not present
if ticket_class not in mapper_ticket_class:
return None
# getting the class from the mapper
mapper_ticket_class[ticket_class](total_count)
list_ = []
# appending to the list for creating the redis db
for row in range(1, total_count, seats):
list_.append([seat for seat in range(row, row + seats)])
return True if connection.set(ticket_class, pickle.dumps(list_)) else False
except Exception as e:
print(e)
redis_db_create(db_connection.conn, "gold", 30, 300)
redis_db_create(db_connection.conn, "silver", 25, 125)
# check if class seats are available
import pickle
def data_decode(val):
# decode the val to integers
if int(val.decode('UTF-8')):
return True
else:
return False
def create_json_view(connection, ticket_class):
mapper_ticket_class = {
"gold": pickle.loads(connection.get("gold")),
"silver": pickle.loads(connection.get("silver"))
}
class_list = mapper_ticket_class[ticket_class]
data = {"message": "Seat Availability"}
# create the json for the user to view
for i, row in enumerate(class_list):
data["Row {}".format(i + 1)] = ", ".join(map(str, row))
return data
# check if seats are available if then return seats else then return class that's available or return houseful
def seat_availability(connection, ticket_class):
try:
# counter for the checking if one class is full then get the other class
counter = None
class_avail = {
"gold": connection.get("gold_available_seats"),
"silver": connection.get("silver_available_seats")
}
# decode the data and the seat availability
for key, val in class_avail.items():
check_status = data_decode(val)
if key == ticket_class and check_status:
return create_json_view(connection, ticket_class)
elif key is not ticket_class and check_status:
counter = key
continue
if counter is not None:
return {"message": "Seat Availability", "Status": "Not Available", counter: "Available"}
else:
return {"HouseFull"}
except Exception as e:
print(e)
import redis
# gold seats db on redis
conn = redis.Redis('127.0.0.1', db=3)
from scripts.database.postgresql.model import Base from scripts.database.postgresql.model import Base
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from scripts.logging.logger import logger
def db_connect(): def db_connect():
...@@ -11,4 +12,4 @@ def db_connect(): ...@@ -11,4 +12,4 @@ def db_connect():
session = Session() session = Session()
return session return session
except Exception as e: except Exception as e:
print(e) logger.error(e)
from datetime import date from datetime import date
from sqlalchemy import Column, Integer, String, Date, Boolean from sqlalchemy import Column, Integer, String, Date, Boolean, BIGINT
from sqlalchemy.orm import declarative_base from sqlalchemy.orm import declarative_base
...@@ -10,10 +10,10 @@ Base = declarative_base() ...@@ -10,10 +10,10 @@ Base = declarative_base()
class BookingDetails(Base): class BookingDetails(Base):
__tablename__ = 'ticket_details' __tablename__ = 'ticket_details'
booking_id = Column(Integer, primary_key=True) booking_id = Column(Integer, primary_key=True)
mobile_no = Column(Integer) mobile_no = Column(BIGINT)
preferred_class = Column(String) preferred_class = Column(String)
no_of_tickets = Column(Integer) no_of_tickets = Column(Integer)
seat_numbers = Column(String) seat_numbers = Column(String)
date_of_purchase = Column(Date, default=date.today()) date_of_purchase = Column(Date, default=date.today())
age = Column(Integer) age = Column(Integer)
status = Column(Boolean, default=False) deleted = Column(Boolean, default=False)
import logging
import os
from logging.handlers import RotatingFileHandler
from scripts.config.application_config import file_name
def get_logger():
"""
Creates a rotating log
"""
__logger__ = logging.getLogger('')
__logger__.setLevel("ERROR")
log_formatter = '%(asctime)s - %(levelname)-6s - [%(threadName)5s:%(funcName)5s():%(lineno)s] - %(message)s'
time_format = "%Y-%m-%d %H:%M:%S"
formatter = logging.Formatter(log_formatter, time_format)
log_file = os.path.join(f"{file_name}_ERROR.log")
temp_handler = RotatingFileHandler(log_file,
maxBytes=100000000,
backupCount=5)
temp_handler.setFormatter(formatter)
__logger__.addHandler(temp_handler)
return __logger__
logger = get_logger()
# importing libraries # importing libraries
from scripts.constants.endpoints import EndPoints
from scripts.constants.schema import ticket_booking from scripts.constants.schema import ticket_booking
from scripts.core.handlers.api_functions import insert_data_into_db from scripts.core.handlers.api_functions import Tickets
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
import paho.mqtt.client as mqtt
from scripts.core.handlers.get_all_seats import seat_availability
from scripts.database.RedisDB.db_connection import conn
# Create FastAPI instance # Create FastAPI instance
app = FastAPI() app = FastAPI()
# Root # Root
@app.get("/") @app.get(EndPoints.root)
async def root(): async def root():
return {"Message": "It's Working!"} return {"Message": "It's Working!"}
# Upload and Insert data from csv to database @app.get(EndPoints.seat_availability)
@app.post("/read_data/") def check_seats(ticket_class: str):
def read_data(): message = seat_availability(conn, ticket_class)
insert_data_into_db() return message
return {"Message": "Data inserted from csv to database successfully!"}
#
# def on_connect(client, userdata, flags, rc):
# print("Connected with result code " + str(rc))
# client.subscribe("ticket_booking")
#
#
# def on_message(client, userdata, msg):
# print(msg.topic + " " + str(msg.payload))
#
#
# client = mqtt.Client()
# client.on_connect = on_connect
# client.on_message = on_message
#
# client.connect("192.168.0.220", 1883, 60)
#
#
# booked_seats = []
@app.post(EndPoints.delete_a_ticket, tags=["delete a ticket"])
def delete_tickets(tid: int):
res = Tickets().delete_row(tid)
return res
@app.post("/book_ticket/")
async def book_ticket(details: ticket_booking):
# if details.preferred_class not in ["gold", "silver"]: @app.get(EndPoints.cancel_all_tickets, tags=["cancel show"])
# raise HTTPException(status_code=400, detail="Invalid class type") async def cancel_all_tickets():
# Tickets().cancel_tickets()
# if len(details.seat_numbers) != details.no_of_tickets: return {"Message": "Cancelled all Tickets"}
# raise HTTPException(status_code=400, detail="Number of seat numbers must match the number of tickets")
# seats = ""
# for seat_number in details.seat_numbers: @app.post(EndPoints.book_ticket, tags=["Ticket Booking"])
# seats += str(seat_number) async def book_ticket(details: ticket_booking):
# if seat_number in booked_seats:
# raise HTTPException(status_code=400, detail=f"Seat number {seat_number} is already booked")
# booked_seats.append(seat_number)
#
# payload = f"{details.preferred_class} class ticket : booking: {details.no_of_tickets} tickets" \
# f"for seat numbers {details.seat_numbers} having telephone number {details.mobile_no} whose age is" \
# f" {details.age}",
# gold_payload = f"class_type :{details.preferred_class} ,seat_number :{details.seat_numbers} "
# silver_payload = f"class_type :{details.preferred_class} ,seat_number :{details.seat_numbers} "
# client.publish("ticket", str(payload))
# client.subscribe("ticket/#")
# print(seats)
try: try:
insert_data_into_db(details) return Tickets().insert_data_into_db(details)
except Exception as e: except Exception as e:
print("error ", e) print("error ", e)
return {"message": "Ticket booking successful"}
@app.get(EndPoints.get_booking_details, tags=["get booking details"])
def get_booking_details():
Tickets().get_details()
return {"data": "list all the data"}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment