"E-Commerece Web Application": Master of Computer Applications

Download as pdf or txt
Download as pdf or txt
You are on page 1of 388

A

Project Report
On

“E-COMMERECE WEB APPLICATION”

Submitted in partial fulfilment of


the requirements for the 4 th Semester Sessional Examination of

MASTER OF COMPUTER APPLICATIONS

By

BIKASH PRADHAN(22PG030331)
BIPIN KUMAR BHADRA(22PG0303332)
BIBHULI KUMAR BHOLA SAHOO(22PG030346)

Under the Supervision of

Mrs Sucheta Krupalini moharana Designation Of Guide

SCHOOL OF SCIENCES

DEPARTMENT OF COMPUTER SCIENCE AND APPLICATIONS


GANDHI INSTITUTE OF ENGINEERING AND TECHNOLOGY UNIVERSITY, GUNUPUR-
765022
2023-2024
E-COMMERECE WEB APPLICATION

A Project submitted
in partial fulfilment of the requirements
for the Degree of

MASTER OF COMPUTER APPLICATIONS

By

BIKASH PRADHAN

BIPIN KUAMAR BHADRA

BIBHULI KUMAR BHOLA

REGISTRATION NO

22PG030331
22PG0303332
22PG030

Under the Supervision of

MRS .SUCHETA KRUPALINI MOHARANA

DEPARTMENT OF COMPUTER SCIENCE & APPLICATIONS


GIET UNIVERSITY, GUNUPUR-765022, ODISHA

2023-2024
GIET UNIVERSITY,GUNUPUR
Department of Computer Science & Applications
Dist. - Rayagada, Odisha-765022

CERTIFICATE

This is to certify that the project work entitled “E-COMMERECE


WEB APPLICATION” is done by Bikash Pradhan(22PG030331),
Bipin Kumar Bhadra(22PG030332),Bibhuli kumar
Bholo(22PG030346) in partially fulfils the requirements for the 4th
Semester Examination of Master of Computer Applications during the
academic year 2023-24. This work is submitted to the department as
part of the 4th Semester Major Project evaluation.

Project Supervisor Project Coordinator

External Examiner HOD


Computer Science and Applications
ACKNOWLEDGEMENT

We express our sincere gratitude to Prof. Satya Narayan Das, Head of The Department of
Computer Science and Applications for allowing me to accomplish the project. With his
active support and guidance, this project report has been completed.

We also thank Mr. Ashutosh Mallik our Project Coordinator for guidance and help.

We also thank Mrs. Sucheta Krupalini Moharana our Project Supervisor for guidance and help.

Signature of the Students


Contents

Page Number

Abstract 1

1. Introduction 2-4
1.1 Purpose 2
1.2 Project Scope 2
1.3 Project Features 3-4
2. Literature Review 5-7
3. Problem Statement 8-10
4. System Analysis 11-33
4.1 Identification of Need 11
4.2 Preliminary Investigation 12-13
4.3 Feasibility Study 13 -14
4.4 Project Planning 15-17
4.5 Software Requirement Specifications (SRS) 17-31
4.6 Software Engineering Paradigm Applied 31-33
5. System Design &Specifications 34-47
5.1 Data models (like DFD) 41-43
5.2 Entity Relationship Model 44
5.3 Use-case Diagrams 44-45
5.4 Class Diagrams 45-46
5.5 State Diagrams/Sequence Diagrams 47
6. Source Code 48-88
7. Screenshots 89-92
8. Testing 93-100
8.1 Testing Techniques and Testing Strategies Used Testing Plan used 94-96
8.2 Test Reports for Unit Test Cases and System Test Cases 96-100
9. Conclusion 101-102
10. Future Enhancement 103-105
11. References / Bibliography 106
ABSTRACT

Title: Development of an E-STORE Using Python, D jango, HTML, CSS, and Bootstrap

Abstract:
In today's digital age, online shopping has become increasingly popular, especially for
essential items like groceries. This project aims to develop a comprehensive online
grocery shop using Python, Django, HTML, CSS, and Bootstrap.

The system will provide users with a convenient platform to browse through a wide
range of grocery products, add them to their cart, and securely complete their purchases.
The backend will be powered by Django, a high-level Python web framework, which
will handle user authentication, product management, order processing, and database
interactions.

The frontend will be developed using HTML, CSS, and Bootstrap to create a visually
appealing and responsive user interface. Bootstrap's grid system and components will
ensure that the website is accessible across various devices and screen sizes, providing a
seamless shopping experience for users on desktops, laptops, tablets, and smartphones.

Key features of the online grocery shop will include user registration and login, product
categorization and search functionality, product details and images, shopping cart
management, secure payment processing integration, order tracking, and email
notifications.

Overall, this project aims to leverage modern web development technologies to create
an efficient and user-friendly online grocery shopping platform, catering to the needs of
today's digitally savvy consumers.

1
INTRODUCTION
 PURPOSE :

The purpose of developing an online grocery shop using Python, Django,


HTML, CSS, and Bootstrap is multi-faceted:

1. Convenience: The primary aim is to provide consumers with a convenient


way to purchase groceries from the comfort of their homes. By offering an
online platform, customers can browse, select, and order groceries at any
time, eliminating the need to physically visit a store.
2. Accessibility: An online grocery shop enhances accessibility for
individuals who may have mobility issues or live in remote areas with
limited access to physical stores. They can access a wide range of grocery
products with just an internet connection.
3. Time-saving: By streamlining the shopping process, customers can save
time that would have been spent commuting to and from a store, searching
for items, and waiting in checkout lines. The online platform allows for
quick browsing, searching, and purchasing of products.
4. Product variety: Online grocery shops can offer a broader range of
products compared to traditional brick-and-mortar stores. Customers can
explore a diverse selection of brands, flavors, and specialty items without the
constraints of physical shelf space.
5. Personalization: Through user accounts and preferences tracking, online
grocery shops can offer personalized recommendations and promotions
tailored to individual shopping habits and preferences. This enhances the
shopping experience and encourages customer loyalty.
6. Scalability: By leveraging Python and Django for backend development
and HTML, CSS, and Bootstrap for frontend design, the online grocery shop
can be built to scale. It can accommodate a growing customer base and
expand its offerings and features as needed.

In essence, the purpose of developing an online grocery shop using these


technologies is to create a modern, user-friendly, and efficient platform that
meets the evolving needs of consumers in today's digital landscape.

2
 PROJECT FEATURES :

Here's a breakdown of the project features for the online grocery shop developed using Python,
Django, HTML, CSS, and Bootstrap:
1. User Registration and Authentication:
- Allow users to register with the platform by providing necessary details.
- Implement authentication mechanisms to ensure secure access to user accounts.
- Enable users to log in and log out of their accounts securely.
2. Product Management:
- Provide functionality for administrators to add, edit, and delete grocery products.
- Include fields such as product name, description, price, quantity, and images.
- Implement product categorization and tagging for easy navigation.
3. Browsing and Searching:
- Enable users to browse through the available grocery products conveniently.
- Implement search functionality to allow users to find specific products quickly.
- Provide filtering options based on categories, prices, and other attributes.
4. Shopping Cart Management:
- Allow users to add products to their shopping carts while browsing.
- Provide options to update the quantity or remove items from the cart.
- Display the total cost and summary of items in the shopping cart.
5. Checkout Process:
- Implement a streamlined checkout process for users to complete their purchases.
- Include forms for users to provide shipping and billing information.
- Integrate secure payment gateways for processing transactions (e.g., PayPal, Stripe).

6. Order Tracking and History:

3
1.1.1 Error Handling and Security: Robust error handling mechanisms and security
measures are implemented to ensure data integrity, user privacy, and protection against
unauthorized access.

4
1. LITERATURE REVIEW
Collaborative music playback systems have emerged as a novel way for users to engage with
music in shared listening experiences. These systems enable multiple users to synchronize
their music playback across devices, allowing for collaborative playlist creation, voting on
tracks, and real-time interaction. This literature review aims to provide a comprehensive
overview of existing research and developments in collaborative music playback systems,
focusing on design principles, technical implementations, user experiences, and the social
impact of these systems.

2.1 DESIGN PRINCIPLES AND TECHINCAL IMPLEMENTATION


Research in collaborative music playback systems has explored various design principles and
technical implementations to facilitate seamless synchronization and interaction among users.
One key aspect is the architecture of the system, which may be centralized, decentralized, or
hybrid. Centralized architectures typically rely on a server to manage playback
synchronization and user interactions, while decentralized architectures leverage peer-to-peer
or mesh networking to distribute control among connected devices. Hybrid approaches
combine elements of both centralized and decentralized architectures to optimize
performance and scalability.

In terms of synchronization techniques, real-time algorithms play a crucial role in ensuring


accurate timing alignment between audio streams across devices. These algorithms must
account for factors such as network latency, device processing capabilities, and audio
buffering to deliver a consistent listening experience. Additionally, researchers have
investigated protocols for communication and data exchange between devices, considering
factors like reliability, efficiency, and compatibility with existing standards.

2.2 USER EXPERIENCE AND IINTERFACE DESIGN


User experience (UX) plays a crucial role in the success of collaborative music playback
systems. Studies have investigated various UX factors, such as interface design, interaction
patterns, and social features, to enhance user engagement and satisfaction. Intuitive interfaces
with intuitive controls enable users to navigate, search, and manage playlists effortlessly.
Social features like chat, voting, and collaborative playlist creation foster a sense of
5
community and encourage active participation among users. Furthermore, personalized
recommendations and adaptive interfaces tailor the music listening experience to individual
preferences, enhancing user satisfaction and retention. Adaptive interfaces that adapt to user
behavior, context, and feedback can enhance user satisfaction and retention. Additionally,
accessibility features ensure that the system is inclusive and usable for users with diverse
needs and abilities.

2.3 SOCIAL IMPACT AND USER ENGAGEMENT


Collaborative music playback systems have a significant impact on music consumption habits
and social interactions. Research has shown that shared listening experiences strengthen
social bonds and promote collaborative behaviors among users. Users engage in activities
like co-curating playlists, discovering new music together, and engaging in real-time
interactions like voting on tracks or controlling playback. Moreover, collaborative music
playback systems encourage exploration and serendipitous discovery, exposing users to a
diverse range of musical genres and artists they might not encounter otherwise. This
collaborative discovery process fosters a deeper appreciation for music and cultivates a sense
of belonging within online communities.

2.4 CHALLENGES AND FUTURE DIRECTIONS


Despite the benefits, collaborative music playback systems face several challenges, including
technical constraints, privacy concerns, and scalability issues. Synchronizing playback across
devices while minimizing latency remains a significant challenge, particularly in
heterogeneous network environments with varying bandwidth and latency characteristics.
Moreover, ensuring data privacy and security is crucial, as collaborative music playback
systems often involve sharing personal music preferences and listening habits. Additionally,
scalability becomes a concern as the number of users and concurrent sessions grows,
necessitating robust infrastructure and optimization techniques to handle increasing load and
maintain performance.

Looking ahead, future research directions in collaborative music playback systems may
include exploring novel interaction paradigms, integrating emerging technologies like virtual
reality and spatial audio, and investigating the social and cultural implications of shared

6
listening experiences. Moreover, interdisciplinary collaborations between researchers,
designers, musicians, and industry stakeholders can lead to innovative solutions that redefine
how people discover, share, and enjoy music together in the digital age.

In conclusion, collaborative music playback systems offer exciting opportunities to enhance


social interaction, foster musical discovery, and transform the way people engage with music.
By addressing design challenges, improving user experiences, and exploring new avenues for
innovation, researchers and practitioners can continue to advance the field of collaborative
music playback systems and create meaningful experiences for music enthusiasts worldwide.

7
2. PROBLEM STATEMENT
The problem statement for the project revolves around the need for a collaborative music
playback system that allows multiple users to join a virtual room, synchronize playback, and
control music playback together. Existing music streaming platforms lack real-time
collaboration features, limiting the ability for users to enjoy music together simultaneously.
Therefore, there is a need to develop a platform that enables users to create and join rooms,
interact with other users in real-time, and collectively control music playback. This project
aims to address these limitations by implementing features such as room creation, user
authentication through Spotify, real-time synchronization of playback, and control of
playback features by both hosts and guests.

3.1 KEY CHALLENGES


The key challenges of this project include:

3.1.1 Real-Time Synchronization: Ensuring that all users in a room experience


synchronized music playback without significant latency or delays is crucial. Achieving this
requires efficient data handling and synchronization techniques.

3.1.2 User Authentication and Integration with Spotify API: Integrating user
authentication via Spotify and leveraging the Spotify API to retrieve and control music
playback requires handling OAuth flows securely and managing access tokens effectively.

3.1.3 Room Management and Data Consistency: Managing rooms dynamically, including
creation, joining, and leaving, while maintaining data consistency and integrity across
connected users presents challenges in database design and synchronization.

3.1.4 Playback Control Permissions: Implementing logic to allow hosts to control playback
permissions for guests, such as play, pause, and skip, requires robust authorization
mechanisms.

3.1.5 Real-Time Updates and Notifications: Enabling real-time updates for playback
control and room settings poses challenges in handling WebSocket communications and
ensuring efficient event propagation.

8
3.1.6 Error Handling and Resilience: Implementing robust error handling mechanisms to
address potential failures in API calls, user authentication, or real-time synchronization is
essential for maintaining a seamless user experience.

3.2 SOLUTION REQUIREMENTS


The solution requirements to address the challenges of the project include:

3.2.1 Real-Time Synchronization

• Implement WebSocket communication to enable real-time synchronization of


playback events and updates across all connected users.

• Utilize efficient data structures and algorithms for managing playback state and
ensuring synchronized playback experiences.

3.2.2 User Authentication and Integration with Spotify API

• Implement OAuth 2.0 authentication flow securely to authenticate users with their
Spotify accounts.

• Utilize Spotify API endpoints to retrieve user-specific music data, control playback,
and manage user permissions.

3.2.3 Room Management and Data Consistency

• Design a robust database schema to manage rooms, users, and playback state
efficiently.

• Implement transactional operations and data synchronization mechanisms to ensure


data consistency across connected users.

3.2.4 Playback Control Permissions

• Implement role-based access control (RBAC) mechanisms to manage user roles (host
vs. guest) and permissions for controlling playback.

• Design intuitive user interfaces to allow hosts to manage playback permissions


effectively.

9
3.2.5 Real-Time Updates and Notifications

• Implement WebSocket-based pub-sub systems to propagate real-time updates and


notifications to all connected users.

• Design event-driven architectures to handle and process events related to playback


control, room management, and user interactions.

3.2.6 Error Handling and Resilience

• Implement robust error handling mechanisms to gracefully handle errors and failures
in API calls, authentication flows, and real-time communication.

• Utilize logging and monitoring tools to track and diagnose errors in real-time,
ensuring quick resolution and minimal disruption to the user experience.

10
3. SYSTEM ANALYSIS

4.1 IDENTIFICATION OF NEED


The identification of the need for this project stems from several factors:

4.1.1 Rising Popularity of Music Streaming Platforms

• With the increasing popularity of music streaming services like Spotify, there's a
growing demand for collaborative music playback systems that allow users to listen
to music together in real-time.

4.1.2 Desire for Social Music Listening Experiences

• Many users enjoy listening to music with friends or family members, whether they're
in the same location or miles apart. A collaborative music playback system fulfills
the need for shared music listening experiences.

4.1.3 Enhanced Engagement and Interaction

• Collaborative music playback systems provide an interactive platform where users


can engage with each other while listening to music. It creates opportunities for
social interaction, discussion, and shared enjoyment of music.

4.1.4 Virtual Events and Gatherings

• With the rise of virtual events and gatherings, there's a need for platforms that enable
participants to listen to music together during online parties, virtual hangouts, or
remote celebrations.

4.1.5 Support for Remote Work and Learning

• In remote work and learning environments, collaborative music playback systems can
serve as icebreakers, team-building tools, or background entertainment during
virtual meetings and study sessions.

4.1.6 Customization and Personalization

• Users often have diverse musical preferences and tastes. A collaborative music
playback system allows users to share and discover music based on their individual
preferences, creating personalized listening experiences.

11
4.2 PRELIMINARY INVESTIGATION:
The preliminary investigation of this project involves cconducting initial research and
analysis to gather information and assess the feasibility of the project. It includes the
following steps:

4.2.1 Identifying Stakeholders

• Determine the primary stakeholders involved in the project, including users,


developers, music streaming platforms, and potential collaborators.

4.2.2 Defining Objectives

• Clarify the project's goals and objectives, such as developing a collaborative music
playback system, integrating with the Spotify API, enabling real-time
synchronization of playback, and providing user-friendly interfaces.

4.2.3 Gathering Requirements

• Collect requirements from stakeholders regarding functionality, user experience,


platform compatibility, security, scalability, and other relevant aspects.

4.2.4 Market Analysis

• Conduct a market analysis to understand the current landscape of music streaming


platforms, collaborative music playback systems, and related technologies. Identify
existing solutions, their features, strengths, and weaknesses.

4.2.5 Technical Feasibility

• Assess the technical feasibility of implementing the project, considering factors such
as available resources (e.g., technology stack, development tools), integration with
third-party APIs (e.g., Spotify), and scalability requirements.

4.2.6 Resource Allocation

• Determine the resources needed for the project, including personnel, time, budget,
hardware, and software. Allocate resources effectively to ensure successful project
execution.

12
4.2.7 Risk Assessment

• Identify potential risks and challenges associated with the project, such as technical
complexities, data security concerns, regulatory compliance, and dependencies on
external factors (e.g., API changes).

4.2.8 Cost-Benefit Analysis

• Evaluate the costs and benefits of implementing the project, considering factors such
as development costs, potential revenue streams, market demand, competitive
advantage, and long-term sustainability.

4.3 FEASIBILITY STUDY


A feasibility study for this project would involve evaluating various aspects to determine if
the project is viable and achievable. Here's how it can be approached:

4.3.1 Technical Feasibility

• Assess the technical requirements of integrating with the Spotify API and
implementing real-time synchronization of playback across multiple users.

• Evaluate the compatibility of chosen technologies (Python, Django, React) with the
project requirements.

• Determine if the project can be implemented within the constraints of available


technology stack and development resources.

4.3.2 Financial Feasibility

• Estimate the costs associated with development, including personnel, infrastructure,


software licenses, and any third-party services (such as hosting or Spotify API
access).

• Compare the projected costs with the budget allocated for the project to ensure
financial viability.

• Consider potential revenue streams, such as subscription fees, in-app purchases, or


advertising, to offset development costs.

13
4.3.3 Operational Feasibility

• Evaluate the operational aspects of the project, including how it will be managed,
maintained, and supported post-launch.

• Assess the availability of skilled personnel to develop, deploy, and maintain the
application.

• Consider scalability requirements and whether the project can accommodate growth
in user base and usage over time.

4.3.4 Legal and Regulatory Feasibility

• Identify any legal or regulatory requirements related to music streaming, user data
privacy, copyright, and licensing.

• Ensure compliance with relevant laws and regulations to avoid legal issues and
penalties.

4.3.5 Market Feasibility

• Analyze the market demand for collaborative music playback systems and the
potential user base for the application.

• Identify competitors and assess their offerings, strengths, and weaknesses.

• Determine if the project fills a gap in the market and offers unique features or
advantages compared to existing solutions.

4.3.6 Schedule Feasibility:

• Develop a realistic timeline for project development, testing, and deployment.

• Consider any dependencies, constraints, or risks that may impact the project schedule.

• Ensure that the proposed timeline aligns with stakeholders' expectations and business
objectives.

14
4.4 PROJECT PLANNING
Project planning for this collaborative music playback system involves organizing tasks,
allocating resources, and establishing timelines to ensure successful development and
deployment. Here's an outline of the project planning process:

4.4.1 Define Project Scope and Objectives

• Clearly articulate the goals and objectives of the project, including the features and
functionality of the collaborative music playback system.

• Define the target audience and user requirements to guide development.

4.4.2 Create Work Breakdown Structure (WBS)

• Break down the project into smaller, manageable tasks and subtasks.

• Organize tasks into a hierarchical structure to facilitate planning and resource


allocation.

4.4.3 Estimate Time and Resources

• Estimate the time required to complete each task based on factors such as complexity,
dependencies, and available resources.

• Determine the resources needed for development, including personnel, equipment,


and software tools.

4.4.4 Develop Project Schedule

• Create a project timeline or Gantt chart that outlines the sequence of tasks, milestones,
and deadlines.

• Allocate resources and establish dependencies between tasks to ensure smooth


progress.

4.4.5 Identify Risks and Mitigation Strategies

• Identify potential risks and uncertainties that may impact the project schedule, budget,
or quality.

• Develop strategies to mitigate risks and minimize their impact on the project.

15
• Establish contingency plans to address unforeseen challenges that may arise during
development.

4.4.6 Allocate Responsibilities

• Assign roles and responsibilities to team members based on their skills, expertise, and
availability.

• Clearly communicate expectations and deliverables to ensure accountability and


collaboration.

4.4.7 Monitor and Control Progress

• Regularly monitor project progress against the established schedule and milestones.

• Track resource utilization, budget expenditures, and any deviations from the plan.

• Implement corrective actions as needed to keep the project on track and address any
issues or delays.

4.4.8 Communicate with Stakeholders

• Maintain open communication channels with stakeholders, including clients, team


members, and project sponsors.

• Provide regular updates on project status, accomplishments, and challenges.

• Solicit feedback and address any concerns to ensure stakeholder satisfaction and
alignment with project goals.

4.4.9 Project closure

• Prepare comprehensive documentation that captures all aspects of the project,


including requirements, design decisions, implementation details, and testing results.

• Conduct a post-project review to assess the overall success of the collaborative music
playback system. Evaluate the project against its original objectives, budget, and
schedule.

• Ensure a smooth transition of the collaborative music playback system to the


appropriate stakeholders, such as end-users or operations teams.

16
• Prepare a formal project closure report summarizing the project's outcomes,
achievements, and recommendations for future improvements.

4.5 SOFTWARE REQUIREMENT SPECIFICATIONS (SRS)


The Software Requirements Specification (SRS) for the collaborative music playback system
outlines the functional and non-functional requirements of the software. Here's an overview
of the SRS:

4.5.1 Introduction

 Provide an overview of the collaborative music playback system.

 Describe the purpose, scope, and objectives of the software.

 Identify stakeholders and their roles in the project.

4.5.2 Functional Requirements

• User Management

• Users can register and log in using their Spotify accounts.

• Hosts can create rooms and manage room settings.

• Guests can join rooms using unique codes generated by hosts.

• Music Playback

• Users can play, pause, skip, and control playback of music tracks.

• Hosts can control playback permissions for guests.

• Real-time Synchronization

• Music playback is synchronized across all connected users in the same room.

• Voting System

• Users can vote to skip tracks, with the option for hosts to set the minimum
number of votes required.

17
• Room Management

• Hosts can set room parameters such as maximum number of participants,


playback control options, and voting system settings.

• Hosts can close the room, preventing new participants from joining.

• User Interaction

• Users can chat with other participants in the same room, enhancing social
interaction.

• Hosts can broadcast messages to all participants in the room, such as


announcements or song dedications.

• Playback History

• The system maintains a playback history for each room, allowing users to
view previously played tracks and their associated metadata.

• Guest Permissions

• Hosts can grant specific permissions to individual guests, such as allowing


certain users to control playback or skip tracks.

• Playlist Management

• Users can create and manage playlists within the application, adding or
removing tracks from their personal collection.

• Hosts can create shared playlists for the entire room to collaborate on.

4.5.3 Non-Functional Requirements

• Performance

• The system should have low latency for real-time synchronization.

• It should support a large number of concurrent users without degradation in


performance.

• Security

• User authentication and authorization should be implemented securely


using OAuth 2.0.
18
• Data transmission should be encrypted to protect user privacy.

• Reliability

• The system should be highly available and resilient to failures.

• It should gracefully handle errors and recover from faults.

• Usability

• The user interface should be intuitive and user-friendly.

• It should provide feedback and guidance to users as they interact with the
system.

• Accessibility

• The user interface should be accessible to users with disabilities, complying


with accessibility standards such as WCAG (Web Content Accessibility
Guidelines).

• Support for screen readers and keyboard navigation should be provided.

• Scalability

• The system should be designed to scale both vertically and horizontally to


handle increases in user traffic and data volume.

• Load balancing and caching mechanisms should be implemented to distribute


workload efficiently.

• Internationalization and Localization

• The application should support multiple languages and locales to


accommodate users from different regions.

• Text and user interface elements should be easily translatable and


customizable.

• Data Privacy and GDPR Compliance

• The system should adhere to data privacy regulations such as GDPR (General
Data Protection Regulation).

19
• User consent mechanisms should be implemented for data collection and
processing activities.

• Error Handling and Logging

• Comprehensive error handling should be in place to gracefully manage


exceptions and errors.

• Logs should be generated for system events, user actions, and error conditions,
aiding in troubleshooting and auditing.

4.5.4 External Interfaces

 Spotify API

• Integration with the Spotify API for music playback and user authentication.

 Frontend Interface

• Interaction with the frontend application developed using React.js.

 Database Interface

• Interaction with the database to store user information, room settings, and playback
data.

4.5.5 Constraints

 Technology Stack

➢ Front-End Development

❖ HTML(Hypertext Markup Language)

HTML, or Hypertext Markup Language, is the standard language used to create and
design web pages. It provides the structure for web content by using various tags and
attributes to define elements on a page. HTML is the backbone of web development,
providing the foundation for creating visually appealing and interactive web pages. It
works hand in hand with CSS (Cascading Style Sheets) for styling and JavaScript for
interactivity, forming the core technologies of the World Wide Web.

20
Overview of HTML

▪ Tags: HTML is built on tags, which are enclosed in angle brackets `< >`. Tags
are used to define different types of content on a webpage, such as headings,
paragraphs, images, links, and more.

▪ Elements: HTML elements are made up of tags and the content they surround.
For example, a paragraph element `<p>` starts with an opening tag and ends with
a closing tag `</p>`, enclosing the paragraph text.

▪ Attributes: Tags can have attributes that provide additional information about an
element. Attributes are placed within the opening tag and typically come inname-
value pairs, such as `href` in an anchor tag `<a href="https://example.com">`.

▪ Document Structure: HTML documents have a specific structure consisting of an


opening `<html>` tag followed by `<head>` and `<body>` tags. The `<head>`
section typically contains metadata like the page title, links to stylesheets, and
scripts. The `<body>` section contains the visible content of the webpage.

▪ Semantic Markup: HTML5 introduced semantic elements that provide more


meaning to the content, making it easier for search engines and assistive
technologies to understand. Examples include `<header>`, `<footer>`, `<nav>`,
`<article>`, `<section>`, `<aside>`, etc.

HTML Tags Used

▪ HTML: The HTML element (`<html>`) is the root element of an HTML page. It
wraps all the content on the page.

▪ Head: The head element (`<head>`) contains metadata and links to external
resources used by the HTML document. It doesn't display any content directly to
the user.

▪ Meta: The meta element (`<meta>`) is used to provide metadata about the HTML
document. Common uses include specifying the character encoding (`charset`
attribute) and setting the viewport for responsive design (`viewport` attribute).

21
▪ Title: The title element (`<title>`) sets the title of the HTML document, which is
displayed in the browser's title bar or tab. It's also used by search engines for page
indexing and in bookmarks.

▪ Script:The script element (`<script>`) is used to embed or reference executable


code, typically JavaScript, within an HTML document. It can be used to add
interactivity, handle events, manipulate the DOM, and more.

▪ Div: The div element (`<div>`) is a generic container used to group and style
HTML elements. It's often used to create sections or divisions within a webpage
and is styled using CSS.

▪ Body: The body element (`<body>`) contains the content of the HTML document
that's displayed to the user. It includes text, images, links, forms, and other
elements that make up the visible part of the webpage.

❖ CSS(Cascading Style Sheets)

CSS (Cascading Style Sheets) is a language used for describing the presentation
of a document written in HTML (HyperText Markup Language). Here's an overview
of CSS:

▪ Selectors: CSS selectors are patterns used to select the elements you want to
style. They can select elements based on their tag name, class, ID, attributes, and
more. They are a fundamental part of CSS syntax and play a crucial role in
styling web pages.

▪ Properties and Values: CSS properties are the styling attributes you can apply to
selected elements. Each property has a specific value associated with it that
defines how the property should be applied. Examples of properties include
`color`, `font-size`, `background-color`, `margin`, `padding`, and `border`.

▪ Cascading: CSS stands for "Cascading" Style Sheets, which refers to the way
styles are applied to elements. Styles can be inherited from parent elements,
overridden by more specific selectors, or overwritten by inline styles.

▪ Units: CSS supports different units of measurement for specifying sizes and
distances, such as pixels (`px`), percentages (`%`), ems (`em`), rems (`rem`), and
viewport units (`vw`, `vh`, `vmin`, `vmax`).

22
❖ JavaScript

JavaScript (JS) serves as the primary language for adding interactivity and
dynamic behavior to web pages. Here's an overview of JavaScript within the
project context:

▪ Client-Side Scripting: JavaScript is primarily used for client-side scripting,


meaning it runs in the user's web browser rather than on the server. This
allows for dynamic content manipulation without needing to reload the entire
page.

▪ DOM Manipulation: One of the core features of JavaScript is its ability to


manipulate the Document Object Model (DOM). The DOM represents the
structure of HTML elements on a web page, and JavaScript can be used to
access, modify, or delete these elements dynamically.

▪ Event Handling: JavaScript enables event-driven programming, where


functions (event handlers) are executed in response to user actions or system
events. Common events include clicks, mouse movements, keyboard inputs,
form submissions, and page loads.

▪ AJAX (Asynchronous JavaScript and XML): AJAX allows for asynchronous


communication between the web browser and the server, enabling data to be
exchanged with the server in the background without interfering with the
current page. This is commonly used to update parts of a web page without
requiring a full reload.

▪ API Integration: JavaScript can interact with various APIs (Application


Programming Interfaces) to access external services and data. This includes
fetching data from servers, integrating with third-party services (e.g., social
media platforms, mapping services), and performing operations like
authentication and authorization.

▪ Form Validation: JavaScript can be used to validate form inputs in real-time,


providing instant feedback to users and preventing invalid data submission.
This helps improve the user experience and ensures data integrity.

23
▪ Animation and Effects: JavaScript can create animations and visual effects on
web pages using techniques like CSS animations, transitions, and
libraries/frameworks such as jQuery or GSAP (GreenSock Animation
Platform).

▪ Error Handling and Debugging: JavaScript provides mechanisms for error


handling and debugging, including try-catch blocks, console logging, and
browser developer tools. Proper error handling ensures graceful degradation
in case of errors and helps developers identify and fix issues.

▪ Modularization and Libraries: JavaScript supports modular programming


through the use of modules, allowing code to be organized into reusable
components. Additionally, developers often leverage third-party libraries and
frameworks (e.g., React.js, Vue.js, AngularJS) to streamline development and
add advanced features.

▪ Security Considerations: When working with JavaScript, security is a critical


consideration. Developers must be mindful of potential security
vulnerabilities such as cross-site scripting (XSS) attacks and implement best
practices to protect against them.

❖ React

React is a JavaScript library used for building user interfaces, particularly for
single-page applications (SPAs) where content is dynamically updated without
requiring full page reloads. Here's an overview of React within this project:

▪ Component-Based Architecture: React follows a component-based


architecture, where UIs are composed of reusable components. Each
component encapsulates its own logic, state, and markup, making it easier
to manage and maintain complex user interfaces.

▪ Virtual DOM: React uses a virtual DOM (Document Object Model) to


efficiently update the UI. Instead of directly manipulating the browser's
DOM, React creates a lightweight in-memory representation of the DOM
and updates it as needed. This approach minimizes unnecessary DOM
manipulation and leads to better performance.

24
▪ JSX (JavaScript XML): React utilizes JSX, a syntax extension that allows
developers to write HTML-like code within JavaScript. JSX makes it
easier to describe UI components and their structure, combining HTML
markup with JavaScript logic seamlessly.

▪ State Management: React components can have state, which represents


data that can change over time. By using the `useState` hook (or `setState`
method in class components), developers can manage and update
component state, triggering re-renders as necessary to reflect state changes
in the UI.

▪ Props (Properties): React components can receive data via props, which
are essentially read-only inputs passed from parent to child components.
Props allow for communication between components and enable
component customization and reusability.

▪ Lifecycle Methods (Class Components): Class components in React have


lifecycle methods that are invoked at different stages of a component's
lifecycle, such as mounting, updating, and unmounting. These methods
can be used to perform initialization, data fetching, and cleanup tasks.

▪ Hooks (Functional Components): Functional components in React can use


hooks to add state and other features previously exclusive to class
components. Hooks like `useEffect`, `useContext`, and `useReducer`
enable functional components to manage state, perform side effects, and
access context without needing to use class syntax.

▪ Routing: React applications often use a router library (such as React


Router) to handle client-side routing and navigation. This allows for the
creation of multi-page experiences within a single-page application, with
different components rendered based on the URL.

▪ Server-Side Rendering (SSR): While not necessarily applicable to all


React projects, SSR is a technique used to render React components on
the server side and send HTML to the client. This can improve
performance and SEO by providing faster initial page loads and ensuring
content is indexable by search engines.

25
▪ Component Libraries and Ecosystem: React has a rich ecosystem of third-
party libraries and tools that extend its capabilities. This includes state
management libraries like Redux, UI component libraries like Material-UI
or Ant Design, and development tools like React DevTools and Create
React App.

➢ Back-End Development

❖ Python

Python serves as the backend language, responsible for handling server-side logic,
database interactions, and API endpoints. Python serves as the backend language,
responsible for handling server-side logic, database interactions, and API
endpoints.

▪ Django Framework: The project likely uses the Django web framework, which
is a high-level Python web framework that encourages rapid development and
clean, pragmatic design. Django provides a set of built-in tools and
conventions for handling common web development tasks, such as URL
routing, database modeling, and user authentication.

▪ API Endpoints: Python code defines API endpoints using Django's `django-
rest-framework` or similar libraries. These endpoints handle incoming HTTP
requests from the frontend, perform necessary data processing or database
operations, and return appropriate HTTP responses (usually in JSON format)
containing the requested data or indicating the outcome of the request.

▪ Model-View-Controller (MVC) Architecture: Django follows the MVC


architectural pattern, although in Django's terminology it's referred to as
Model-View-Template (MVT). Models define the structure and behavior of the
application's data, views handle the presentation logic and interact with
models, and templates render HTML pages to be served to the client.

▪ ORM (Object-Relational Mapping): Django provides an ORM layer that


abstracts away the details of database interaction, allowing developers to work
with database tables and records using Python classes and methods. Models in
Django represent database tables, and queries are performed using Python
syntax rather than raw SQL.
26
▪ Middleware: Django middleware allows for processing of requests and
responses before and after they reach the view layer. Middleware can perform
tasks such as authentication, request/response logging, error handling, and
more.

▪ Session Management and Authentication: Django provides built-in support for


user authentication and session management. Developers can easily integrate
features like user registration, login, logout, password management, and access
control using Django's authentication system.

▪ URL Routing: Django's URL routing mechanism maps incoming HTTP


requests to the appropriate view functions based on URL patterns defined in
the project's URL configuration. This allows for clean and organized URL
structures and separation of concerns between different parts of the application.

▪ Task Queues and Background Jobs: For handling long-running or


asynchronous tasks, Python code may use task queue libraries like Celery in
combination with a message broker such as Redis or RabbitMQ. This allows
tasks to be executed asynchronously outside of the request-response cycle,
improving application performance and scalability.

▪ Third-Party Libraries: Python's extensive ecosystem of third-party libraries and


packages may be leveraged for various purposes within the project, such as
handling date/time operations, working with external APIs, performing data
validation, and more.

❖ Django

Django serves as the web framework for building the backend of the application.
Django provides a comprehensive set of tools and conventions for building web
applications quickly and efficiently. Its batteries-included approach, robust security
features, and thriving ecosystem of third-party packages make it a popular choice
for building scalable and maintainable web applications.

▪ Model-View-Template (MVT) Architecture: Django follows the MVT


architectural pattern, which is a variation of the traditional Model-View-
Controller (MVC) pattern. In Django, models represent the data structure,

27
views handle the logic to process requests and generate responses, and
templates are used for rendering HTML pages.

▪ URL Routing: Django's URL dispatcher maps URL patterns to view functions
or classes, allowing developers to define how different URLs should be
handled by the application. URL patterns are typically defined in the project's
`urls.py` file and may include regular expressions or path converters to capture
dynamic parts of the URL.

▪ Models and ORM: Django provides an Object-Relational Mapping (ORM)


layer that allows developers to define database models using Python classes.
Models represent database tables, and fields within models represent table
columns. Django's ORM abstracts away the need to write SQL queries directly,
making it easier to interact with the database using Python code.

▪ Admin Interface: Django comes with a built-in administration interface that


can be automatically generated based on the project's models. This admin
interface allows authorized users to view, create, update, and delete records in
the database without writing any custom code. Admin functionality can be
customized and extended as needed.

▪ Forms and Validation: Django provides a forms library for handling HTML
forms and form data. Forms can be created using Python classes, and Django
handles tasks such as form rendering, data validation, and error handling
automatically. Forms can be used in views to process user input and interact
with the database.

▪ Middleware: Django middleware allows for processing of requests and


responses at various points in the request-response cycle. Middleware
components can perform tasks such as authentication, request/response
logging, CORS handling, and more. Middleware can be applied globally to all
requests or selectively to specific URL patterns.

▪ Authentication and Authorization: Django provides built-in support for user


authentication and authorization. The authentication system handles tasks such
as user login, logout, password management, and session management.

28
Authorization can be enforced using decorators or middleware to restrict
access to certain views or resources.

▪ Template Engine: Django's template engine allows developers to create HTML


templates that can be dynamically rendered with data from views. Templates
support template inheritance, template tags and filters, and other features to
facilitate code reuse and maintainability.

▪ Static Files and Media Handling: Django provides utilities for managing static
files (e.g., CSS, JavaScript) and media files (e.g., user-uploaded images,
videos). Static files are typically served directly by the web server in
production, while media files are stored locally or on a cloud storage service
like Amazon S3.

▪ Internationalization and Localization: Django supports internationalization


(i18n) and localization (l10n) out of the box, allowing developers to build
applications that support multiple languages and locales. Translation strings
can be marked for translation in Python code and templates, and Django
provides tools for generating translated versions of the application's content.

➢ API

❖ Spotify API:

The Spotify API is utilized to integrate music playback and management


functionality into the application. The integration of the Spotify API enhances the
functionality of the application by allowing users to access and control their
Spotify accounts directly within the application. This integration enables features
such as music playback, playlist management, and personalized recommendations,
enriching the user experience and making the application more engaging and
interactive.

▪ Authentication: The application implements OAuth 2.0 authentication to allow


users to connect their Spotify accounts. This involves obtaining authorization
from Spotify to access the user's account data and playback functionality.
Users are redirected to the Spotify authorization page, where they grant
permission to the application. Upon authorization, the application receives an

29
access token, which is used to make authenticated requests to the Spotify API
on behalf of the user.

▪ Authorization Code Flow: The application uses the authorization code flow to
authenticate users with Spotify. This flow involves redirecting the user to the
Spotify authorization page with specific parameters, including the client ID,
redirect URI, and requested scopes (permissions). After the user grants
permission, Spotify redirects back to the application with an authorization
code, which is exchanged for an access token and refresh token.

▪ Fetching Current Song: The application periodically fetches information about


the currently playing song from the Spotify API. This information includes
details such as the song title, artist, album, playback progress, and album cover
art. The fetched data is then displayed to the user in the application's user
interface, allowing them to see what song is currently playing.

▪ Playback Control: The application allows users to control playback actions


such as play, pause, and skip through the Spotify API. When a user interacts
with playback controls in the application's user interface, corresponding
requests are sent to the Spotify API to perform the desired action on the user's
active playback session.

▪ Error Handling and Edge Cases: The application handles potential errors and
edge cases that may arise during interactions with the Spotify API. This
includes scenarios such as invalid access tokens, expired tokens, rate limiting,
and network errors. Error handling mechanisms ensure that the application
provides a smooth and reliable user experience even in the face of API-related
issues.

30
 Scalability:

• The system should be designed to scale horizontally to accommodate future


growth in user base and usage.

4.5.6 Appendices

 Include any additional information relevant to the software requirements, such as use
case diagrams, data flow diagrams, or mockups.

4.6 SOFTWARE ENGINEERING PARADIGM APPLIED


The software engineering paradigm applied for this project is likely Agile. Agile
methodology emphasizes iterative development, collaboration, and flexibility, which are
crucial for a dynamic project like a collaborative music playback system. Here's how Agile
principles align with the project's requirements:

31
4.6.1 Iterative Development: The project can be broken down into smaller increments or
iterations, allowing for continuous improvement and feedback throughout the development
process. Features can be implemented incrementally, with regular demonstrations to
stakeholders for feedback and validation.

4.6.2 Collaborative Approach: Agile promotes collaboration among cross-functional teams,


including developers, designers, and stakeholders. In the context of this project, collaboration
is essential between frontend and backend developers, UI/UX designers, and potentially
external stakeholders such as music streaming service providers.

4.6.3 Adaptability to Change: Agile methodologies prioritize adaptability to changing


requirements and priorities. Given the dynamic nature of the music industry and user
preferences, the project needs to be flexible in accommodating new features, enhancements,
and adjustments based on user feedback and market trends.

4.6.4 Customer-Centric Focus: Agile places a strong emphasis on delivering value to the
customer. In this project, the customer-centric focus means prioritizing features and
functionalities that align with user needs and preferences, ensuring a positive user experience.

4.6.5 Continuous Delivery: Agile encourages frequent releases of working software,


allowing for rapid feedback and validation from users. Continuous integration and
deployment practices enable the team to deliver updates and improvements to the
collaborative music playback system efficiently and reliably.

4.6.6 Sprint Planning: The project team conducts regular sprint planning meetings to
prioritize tasks and set goals for each iteration. This ensures that development efforts are
focused on delivering the most valuable features incrementally.

4.6.7 Daily Stand-ups: Daily stand-up meetings are held to provide a forum for team
members to discuss progress, identify any impediments, and coordinate their efforts. These
short, focused meetings help maintain alignment and address any issues promptly.

4.6.8 Iterative Feedback: Agile encourages continuous feedback loops, both from
stakeholders and end-users. Regular demos and reviews allow stakeholders to provide
feedback on the product's features and functionality, facilitating early course correction and
improvement.

32
4.6.9 Empowered Teams: Agile principles promote self-organizing, empowered teams that
take ownership of their work. Team members have the autonomy to make decisions and
adapt to changing requirements, fostering a sense of accountability and commitment to
project success.

4.6.10 Continuous Improvement: Agile embraces a culture of continuous improvement,


where teams reflect on their processes and outcomes at the end of each iteration.
Retrospective meetings provide an opportunity to identify what went well, what could be
improved, and actionable steps for enhancement in subsequent iterations.

4.6.11 Adaptive Planning: Agile methodologies recognize that requirements and priorities
may evolve over time. The project plan remains flexible, allowing for adjustments based on
feedback, changes in market conditions, or emerging opportunities.

4.6.12 Transparency and Communication: Agile promotes transparency and open


communication within the project team and with stakeholders. Regular progress updates,
clear documentation, and collaboration tools facilitate effective communication and
alignment of objectives.

33
4. SYSTEM DESIGN AND SPECIFICATIONS
The system design and specifications for this project outline the architecture, components,
and functionality of the collaborative music playback system. Here's an overview:

❖ Architecture:

 The system follows a client-server architecture, where the server hosts the backend
logic and data storage, while the client interacts with the user through a web-based
interface.

 Backend components include Django framework for server-side logic, Spotify API
integration for music playback functionality, and a PostgreSQL database for storing
user data and room information.

 Frontend components utilize React.js for building interactive user interfaces and
managing state.

❖ Components:

 Backend Components:

• Django REST framework for building RESTful APIs to handle user


authentication, room management, music playback control, and voting.

• Spotify API integration for authenticating users, accessing music catalogs,


controlling playback, and retrieving song information.

• PostgreSQL database for storing user profiles, room details, playback history, and
voting data.

 Frontend Components:

• React.js for building modular UI components, managing state, and handling user
interactions.

• Material-UI library for designing responsive and visually appealing user interfaces.

• React Router for client-side routing to navigate between different views within the
application.

34
❖ Functionality:

 User Authentication: Users can log in to the system using their Spotify accounts to
access the collaborative music playback features.

 Room Management: Hosts can create a room and generate a unique code that other
users can use to join the room. Hosts can also set room preferences such as playback
control permissions and voting requirements.

 Music Playback: Users can play, pause, skip tracks, and adjust playback volume
within the room. Playback control permissions are determined by the host's settings.

 Synchronization: Playback is synchronized across all connected users in the same


room to ensure a consistent listening experience.

 Voting System: Users can vote to skip tracks, and tracks are skipped when the
required number of votes is reached.

 Real-time Updates: Hosts can update playback control settings and voting
requirements in real-time, reflecting changes immediately for all users in the room.

❖ Specifications:

 System supports concurrent user sessions with efficient handling of authentication and
session management.

 Integration with Spotify API ensures seamless access to music catalogs, playback
control, and user authentication.

 Web-based interface is responsive, user-friendly, and accessible across different


devices and screen sizes.

 Backend APIs follow RESTful principles, with clear endpoints, request/response


formats, and error handling mechanisms.

 Data storage and retrieval operations are optimized for performance and scalability,
ensuring smooth operation even under high user loads.

35
❖ SOFTWARE DESIGN

In designing the software following principles are followed:

 Modularity and partitioning: Software is designed such that, each system should
consists of hierarchy of modules and serve to partition into separate function.

 Coupling: Modules should have little dependence on other modules of a system.

 Cohesion: Modules should carry out in a single processing function.

 Shared use: Avoid duplication by allowing a single module be called by other that
need the function it provides.

❖ MODULE DESIGN

The major modules of the project are:

 Home Module

 Spotify Login Module

 Create Room Module

 Join Room Module

 Update Room Module

 Music Player Module

 Home Module:

 Displays the home page of the application.

 Provides options for users to create or join rooms..

 Includes features for browsing and searching for existing rooms.

 Spotify Login Module:

 Integrates Spotify authentication for user login.

36
 Handles the OAuth flow for obtaining user authorization.

 Retrieves user profile information and access tokens for Spotify API interaction.

 Create Room Module:

 Allows authenticated users to create new rooms.

 Generates a unique room code for each created room.

 Sets room preferences such as playback control and voting options.

 Join Room Module:

 Enables users to join existing rooms using room codes.

 Validates room codes and grants access to authorized users.

 Provides feedback on successful or failed room joining attempts.

 Update Room Module:

 Facilitates room settings updates by the host.

 Allows hosts to modify playback control permissions, voting rules, etc.

 Ensures that only authorized hosts can update room settings.

 Music Player Module:

 Displays information about the currently playing song, including the title, artist,
album cover, playback progress, and voting details.

 Users can interact with the music player through buttons such as play, pause, and
skip. These buttons trigger actions to control the playback accordingly.

 It also displays the number of votes each song has received for skipping

 Allows users to vote on whether to skip the current track.

37
❖ DATABASE DESIGN

 MODEL NAME: Room


Field name Data Type
code CharField
host CharField
guest_can_pause BooleanField
votes_to_skip IntegerField
created_at DateTimeField
current_song CharField

 MODEL NAME: SpotifyToken


Field name Data Type
user CharField
created_at DateTimeField
refresh_token CharField
access_token CharField
expires_in DateTimeField
token_type CharField

 MODEL NAME: Vote


Field name Data Type
user CharField
created_at DateTimeField
song_id CharField
room CharField

38
❖ INPUT/OUTPUT DESIGN

 Input Design
The input design for the collaborative music playback system involves defining how
users interact with the application to input commands, preferences, and data. Here's an
overview of the input design:

o User Interface (UI):

 The UI includes various input elements such as text fields, buttons, dropdowns,
and sliders.

 Users interact with these elements to perform actions like logging in, creating
rooms, joining rooms, controlling playback, and voting on tracks.

o Authentication Inputs:

 Input fields for users to enter their login credentials (username/email and
password) during the authentication process.

 OAuth login buttons to initiate authentication with third-party services like


Spotify.

o Room Creation Inputs:

 Text fields for specifying room preferences such as room name, playback
control permissions, and voting rules.

 Buttons to confirm room creation and submit the preferences.

o Room Joining Inputs:

 Text field for entering the room code when joining an existing room.

 Button to submit the room code and join the room.

o Room Update Inputs:

 Input fields or dropdowns to adjust room settings such as playback control


permissions, voting thresholds, and other configurations.

 Buttons to apply the changes and update the room settings.

39
o Playback Control Inputs:

 Playback control buttons for playing, pausing, skipping tracks, adjusting


volume, and seeking within tracks.

 Slider or input field for controlling volume level.

o Voting Inputs:

 Voting buttons or checkboxes displayed during track playback to allow users to


vote on track skipping.

 Feedback messages indicating the status of the vote .

 Output Design
The output design of the project involves presenting information and feedback to
users based on their interactions with the system. Here's an overview of the output
design elements in our collaborative music playback system:

 User Interface: The system provides a user-friendly interface using React and
Material-UI components. It includes screens for different functionalities like
home, room creation, room joining, music playback, and settings.

 Room Information: Upon joining a room or creating a new one, users see
relevant information such as the room code, current song details, playback
controls, and voting status.

 Music Playback: The output design includes a music player interface with
controls for play, pause, and skip. It also displays the current song's title, artist,
album cover, playback progress, and voting details.

 Real-time Updates: Users receive real-time updates on song changes,


playback status, and voting results. This ensures that everyone in the room
stays synchronized with the latest information.

40
5.1 DATA MODEL(LIKE DFD)

A Data Flow Diagram (DFD) is a traditional visual representation of the information flows
within a system. A neat and clear DFD can depict the right amount of the system requirement
graphically. It can be manual, automated, or a combination of both.

It shows how data enters and leaves the system, what changes the information, and where
data is stored.

The objective of a DFD is to show the scope and boundaries of a system as a whole. It may
be used as a communication tool between a system analyst and any person who plays a part
in the order that acts as a starting point for redesigning a system. The DFD is also called as a
data flow graph or bubble chart.

Data Flow Diagrams are of two types:

1) Physical Data Flow Diagrams: These are implementation-dependent i.e.,


they show the actual devices, departments, people, etc., involved in the
system.
2) Logical Data Flow Diagrams: These diagrams describe the system
independently of how it is actually implemented, they show what takes
places, rather than how an activity is accomplished.
Standard Symbol of DFD
➢ Data Flow: Data move in a specific direction from an origin to destination. The
data flow is a “packet” of data.

➢ Process: People, procedures or devices that produce data. The physical


component is not identified.

41
➢ Source or Destination of Data: External sources or destinations of data, which
may be people or organizations or other entities.

➢ Data Source: Here a process references the data in the system.

5.1.1 LEVEL 0 DFD


This is the highest-level DFD, which provides an overview of the entire system. It shows
the major processes, data flows, and data stores in the system, without providing any details
about the internal workings of these processes.

It is also known as a context diagram. It’s designed to be an abstraction view, showing the
system as a single process with its relationship to external entities. It represents the entire
system as a single bubble with input and output data indicated by incoming/outgoing
arrows.

42
5.1.2 Level 1 DFD
This level provides a more detailed view of the system by breaking down the major
processes identified in the level 0 DFD into sub-processes. Each sub-process is depicted as
a separate process on the level 1 DFD. The data flows and data stores associated with each
sub-process are also shown.

In 1-level DFD, the context diagram is decomposed into multiple bubbles/processes. In this
level, we highlight the main functions of the system and breakdown the high-level process
of 0-level DFD into subprocesses.

43
5.2 ENTITY RELATIONSHIP MODEL
ER model stands for an Entity-Relationship model. It is a high-level data model. This model
is used to define the data elements and relationship for a specified system.

It develops a conceptual design for the database. It also develops a very simple and easy to
design view of data.

In ER modeling, the database structure is portrayed as a diagram called an entity-relationship


diagram.

5.3 USE CASE DIAGRAM


A Use Case Diagram is a type of Unified Modeling Language (UML) diagram that
represents the interaction between actors (users or external systems) and a system under
consideration to accomplish specific goals. It provides a high-level view of the system’s
functionality by illustrating the various ways users can interact with it.

44
5.4 CLASS DIAGRAM
Class diagrams are a type of UML (Unified Modeling Language) diagram used in software
engineering to visually represent the structure and relationships of classes within a system
i.e. used to construct and visualize object-oriented systems.

45
Class diagrams provide a high-level overview of a system’s design, helping to
communicate and document the structure of the software. They are a fundamental tool in
object-oriented design and play a crucial role in the software development lifecycle.

46
5.5 STATE DIAGRAM/SEQUENCE DIAGRAM
A sequence diagram shows process interactions arranged in time sequence. This diagram
depicts the processes and objects involved and the sequence of messages exchanged as
needed to carry out the functionality.

47
5. SOURCE CODE
6.1 HTML template that provides structure to the application

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>Tune Troop</title>

{% load static %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<link

rel="stylesheet"

href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"

/>

<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"

/>

</head>

<body>

<div id="gradient">

<div id="main">

<div id="app"></div>

</div>

</div>

<script src="{% static "frontend/main.js" %}"></script>

</body>

</html>

48
6.2 CSS for styling
html,

body {

height: 100%;

margin: 0;

padding: 0;

#main {

position: fixed;

width: 100%;
height: 100%;

left: 0;

top: 0;

#app {

width: 100%;

height: 100%;

.center {

position: absolute;

top: 50%;
left: 50%;

transform: translate(-50%, -50%);

#gradient {

49
width: 100%;

height: 800px;

padding: 0px;

margin: 0px;

6.3 JavaScript to dynamically update the background


import App from "./components/App";

var colors = new Array(

[62,35,255],

[60,255,60],

[255,35,98],

[45,175,230],

[255,0,255],

[255,128,0]);

var step = 0;

//color table indices for:

// current color left

// next color left

// current color right

// next color right

var colorIndices = [0,1,2,3];

//transition speed

var gradientSpeed = 0.002;

function updateGradient()

50
{

if ( $===undefined ) return;

var c0_0 = colors[colorIndices[0]];

var c0_1 = colors[colorIndices[1]];

var c1_0 = colors[colorIndices[2]];

var c1_1 = colors[colorIndices[3]];

var istep = 1 - step;

var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);

var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);

var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);

var color1 = "rgb("+r1+","+g1+","+b1+")";

var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);

var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);

var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);

var color2 = "rgb("+r2+","+g2+","+b2+")";

$('#gradient').css({

background: "-webkit-gradient(linear, left top, right top, from("+color1+"),


to("+color2+"))"}).css({

background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});

step += gradientSpeed;

if ( step >= 1 )

step %= 1;

51
colorIndices[0] = colorIndices[1];

colorIndices[2] = colorIndices[3];

//pick two new target color indices

//do not pick the same as the current one

colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

setInterval(updateGradient,10);

6.4 Creation of Django model ‘Room’


from django.db import models

import string

import random

def generate_unique_code():

length = 6

while True:

code = ''.join(random.choices(string.ascii_uppercase, k=length))

if Room.objects.filter(code=code).count() == 0:

break

return code

52
class Room(models.Model):

code = models.CharField(

max_length=8, default=generate_unique_code, unique=True)

host = models.CharField(max_length=50, unique=True)

guest_can_pause = models.BooleanField(null=False, default=False)

votes_to_skip = models.IntegerField(null=False, default=1)

created_at = models.DateTimeField(auto_now_add=True)

current_song = models.CharField(max_length=50, null=True)

6.5 Creation of serializers for the ‘Room’ model in the Django REST
Framework
from rest_framework import serializers

from .models import Room

class RoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('id', 'code', 'host', 'guest_can_pause',

'votes_to_skip', 'created_at')

class CreateRoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('guest_can_pause', 'votes_to_skip')

class UpdateRoomSerializer(serializers.ModelSerializer):

code = serializers.CharField(validators=[])

53
class Meta:

model = Room
fields = ('guest_can_pause', 'votes_to_skip', 'code')

6.6 Django views for handling room-related operations


from django.shortcuts import render

from rest_framework import generics, status

from .serializers import RoomSerializer, CreateRoomSerializer, UpdateRoomSerializer

from .models import Room

from rest_framework.views import APIView

from rest_framework.response import Response

from django.http import JsonResponse

class RoomView(generics.ListAPIView):

queryset = Room.objects.all()

serializer_class = RoomSerializer

class GetRoom(APIView):

serializer_class = RoomSerializer

lookup_url_kwarg = 'code'

def get(self, request, format=None):

code = request.GET.get(self.lookup_url_kwarg)

if code != None:

room = Room.objects.filter(code=code)

if len(room) > 0:

data = RoomSerializer(room[0]).data

data['is_host'] = self.request.session.session_key == room[0].host

54
return Response(data, status=status.HTTP_200_OK)

return Response({'Room Not Found': 'Invalid Room Code.'},


status=status.HTTP_404_NOT_FOUND)

return Response({'Bad Request': 'Code paramater not found in request'},


status=status.HTTP_400_BAD_REQUEST)

class JoinRoom(APIView):

lookup_url_kwarg = 'code'

def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

code = request.data.get(self.lookup_url_kwarg)

if code != None:

room_result = Room.objects.filter(code=code)

if len(room_result) > 0:

room = room_result[0]

self.request.session['room_code'] = code

return Response({'message': 'Room Joined!'}, status=status.HTTP_200_OK)

return Response({'Bad Request': 'Invalid Room Code'},


status=status.HTTP_400_BAD_REQUEST)

return Response({'Bad Request': 'Invalid post data, did not find a code key'},
status=status.HTTP_400_BAD_REQUEST)

class CreateRoomView(APIView):

serializer_class = CreateRoomSerializer

55
def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

host = self.request.session.session_key

queryset = Room.objects.filter(host=host)

if queryset.exists():

room = queryset[0]

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

else:

room = Room(host=host, guest_can_pause=guest_can_pause,

votes_to_skip=votes_to_skip)
room.save()

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)

return Response({'Bad Request': 'Invalid data...'},


status=status.HTTP_400_BAD_REQUEST)

class UserInRoom(APIView):

56
def get(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

data = {

'code': self.request.session.get('room_code')

return JsonResponse(data, status=status.HTTP_200_OK)

class LeaveRoom(APIView):

def post(self, request, format=None):

if 'room_code' in self.request.session:

self.request.session.pop('room_code')

host_id = self.request.session.session_key

room_results = Room.objects.filter(host=host_id)

if len(room_results) > 0:

room = room_results[0]

room.delete()

return Response({'Message': 'Success'}, status=status.HTTP_200_OK)

class UpdateRoom(APIView):

serializer_class = UpdateRoomSerializer

def patch(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

57
if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

code = serializer.data.get('code')

queryset = Room.objects.filter(code=code)
if not queryset.exists():

return Response({'msg': 'Room not found.'},


status=status.HTTP_404_NOT_FOUND)

room = queryset[0]

user_id = self.request.session.session_key

if room.host != user_id:

return Response({'msg': 'You are not the host of this room.'},


status=status.HTTP_403_FORBIDDEN)

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

return Response({'Bad Request': "Invalid Data..."},


status=status.HTTP_400_BAD_REQUEST)

6.7 URL Patterns for routing HTTP requests


from django.urls import path

from .views import RoomView, CreateRoomView, GetRoom, JoinRoom, UserInRoom,


LeaveRoom, UpdateRoom

58
urlpatterns = [

path('room', RoomView.as_view()),

path('create-room', CreateRoomView.as_view()),

path('get-room', GetRoom.as_view()),

path('join-room', JoinRoom.as_view()),

path('user-in-room', UserInRoom.as_view()),

path('leave-room', LeaveRoom.as_view()),

path('update-room', UpdateRoom.as_view())

6.8 Root Component of React application


import React, { Component } from "react";

import { render } from "react-dom";

import HomePage from "./HomePage";

export default class App extends Component {

constructor(props) {
super(props);

render() {

return (

<div className="center">

<HomePage />

</div>

);

59
const appDiv = document.getElementById("app");

render(<App />, appDiv);

6.9 Main Page of the application


import React, { Component } from 'react';
import RoomJoinPage from './RoomJoinPage';
import CreateRoomPage from './CreateRoomPage';

import { Grid, Button, ButtonGroup, Typography } from '@mui/material';

import { BrowserRouter as Router, Routes, Route, Link, Redirect, Navigate } from 'react-
router-dom';

import Room from './Room';

export default class HomePage extends Component{

constructor(props){

super(props);

this.state={

roomCode: null,

};

this.clearRoomCode=this.clearRoomCode.bind(this);

async componentDidMount(){

fetch('/api/user-in-room')

.then((response)=>response.json()).

then((data)=>{

this.setState({

roomCode:data.code,

});

});

60
}

renderHomePage(){

if(this.state.roomCode){

return(

<Navigate to={`/room/${this.state.roomCode}`} replace={true}/>

);

}else{

return(

<Grid container spacing={3}>

<Grid item xs={12} align="center">

<Typography variant='h3' compact='h3'>

Tune Troop

</Typography>

</Grid>

<Grid item xs={12} align="center">

<ButtonGroup disableElevation variant='contained' color='primary'>

<Button color='secondary' to='/create' component={Link}>

Create a Room

</Button>

<Button color='primary' to='/join' component={Link}>

Join a Room
</Button>

</ButtonGroup>

</Grid>

</Grid>

);

61
clearRoomCode(){

this.setState({

roomCode:null,

});

render(){

return (<Router>

<Routes>

<Route path="/" element={this.renderHomePage()}

/>

<Route path="/join" element={<RoomJoinPage/>}></Route>

<Route path="/create" element={<CreateRoomPage/>}></Route>

<Route path="/room/:roomCode" element={<Room


clearRoomCodeCallback={this.clearRoomCode}/>}>

</Route>

</Routes>

</Router>);

6.10 Create or Update Room Component


import React, { Component, useState } from "react";
import { Button } from "@mui/material";

import {Grid} from "@mui/material";

import {Typography} from "@mui/material";

import { TextField } from "@mui/material";

62
import {FormHelperText} from "@mui/material";

import {FormControl} from "@mui/material";

import {Link} from "react-router-dom";

import {Radio} from "@mui/material";

import {RadioGroup} from "@mui/material";

import {FormControlLabel} from "@mui/material";

import { useNavigate } from "react-router-dom";

import {Collapse} from "@mui/material"

import Alert from "@mui/material/Alert";

function CreateRoomPage(props){

const navigate=useNavigate();

const[guestCanPause,setguestCanPause]=useState(props.guestCanPause);

const[votesToSkip,setgvotesToSkip]=useState(props.votesToSkip);

const[errorMsg,setErrorMsg]=useState("");

const[successMsg,setSuccessMsg]=useState("");

const handleVotesChange=()=>{

setgvotesToSkip(event.target.value);

};

const handleGuestCanPauseChange=()=>{

setguestCanPause(event.target.value==="true"?true:false);

};

const handleRoomButtonPressed=()=>{

const requestOptions = {

method: 'POST',

63
headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

}),

};

fetch('/api/create-room', requestOptions)

.then((response)=>response.json())

.then((data)=> navigate("/room/"+ data.code));

};

const handleUpdateButtonPressed=()=>{

const requestOptions = {

method: 'PATCH',

headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

code:props.roomCode,

}),

};

fetch('/api/update-room', requestOptions)

.then((response)=>{

if(response.ok){

setSuccessMsg("Room updated successfully!");

}else{

setErrorMsg("Error updating room");

props.updateCallback();

64
});

};

const renderCreateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleRoomButtonPressed}>Create A Room</Button>

</Grid>

<Grid item xs={12} align="center">

<Button color="secondary" variant="contained" to="/"


component={Link}>Back</Button>

</Grid>

</Grid>

);

};

const renderUpdateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleUpdateButtonPressed}>Update Room</Button>

</Grid>

</Grid>

);

};

65
const title=props.update? "Update Room" : "Create a Room";

return (

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Collapse in={errorMsg!="" || successMsg!=""}>

{successMsg!=""?(

<Alert

severity="success"

onClose={()=>{

setSuccessMsg("");

}}>

{successMsg}

</Alert>

):(

<Alert

severity="error"

onClose={()=>{

setErrorMsg("");
}}>

{errorMsg}

</Alert>

)}

</Collapse>

</Grid>

<Grid item xs={12} align="center">

<Typography component='h4' variant='h4'>

{title}

</Typography>

66
</Grid>

<Grid item xs={12} align="center">

<FormControl component="fieldset">

<FormHelperText component="div">

<div align='center'>Guest Control of Playback State</div>

</FormHelperText>

<RadioGroup row defaultValue={props.guestCanPause.toString()}


onChange={handleGuestCanPauseChange}>

<FormControlLabel value="true" control={<Radio color="primary"></Radio>}


label="Play/Pause"
labelPlacement="bottom"></FormControlLabel>

<FormControlLabel value="false" control={<Radio color="secondary"></Radio>}


label="No Control"

labelPlacement="bottom"></FormControlLabel>

</RadioGroup>

</FormControl>

</Grid>

<Grid item xs={12} align="center">

<FormControl>

<TextField required={true} type="number" onChange={handleVotesChange}


defaultValue={votesToSkip}

inputProps={{min:1, style:{textAlign:"center"},}}></TextField>

<FormHelperText component="div">

<div align="center">

Votes Required To Skip Song

</div>

</FormHelperText>

</FormControl>

67
</Grid>

{props.update?renderUpdateButtons(): renderCreateButtons()}

</Grid>

);

CreateRoomPage.defaultProps={

votesToSkip:2,

guestCanPause:true,

update: false,

roomCode:null,

updateCallback:()=>{},

};

export default CreateRoomPage;

6.11 Room Join Component


import React, {useState, Component } from 'react';

import { TextField, Button, Grid, Typography } from '@mui/material';

import { Link } from "react-router-dom";

import {useNavigate} from "react-router-dom";

export default function RoomJoinPage(props){

const navigate=useNavigate();

const[roomCode, setroomCode]=useState('');

const[errorMsg,seterrorMsg]=useState('');

const[error,seterror]=useState(false);

const handleTextFieldChange=()=>{

68
setroomCode(event.target.value);

};

const roomButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

body:JSON.stringify({

code:roomCode,

}),

};

fetch("/api/join-room",requestOptions).

then((response)=>{

if(response.ok){

navigate("/room/"+ roomCode)

}else{

seterror(true);

seterrorMsg("Room not found");


}

})

.catch((error)=>{

console.log(error);

});

};

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant="h4" component="h4">

Join a Room

69
</Typography>

</Grid>

<Grid item xs={12} align="center">

<TextField

error={error}

label="Code"

placeholder='Enter a Room Code'

value={roomCode}

helperText={errorMsg}

variant='outlined'

onChange={handleTextFieldChange}>

</TextField>

</Grid>

<Grid item xs={12} align="center">

<Button

variant='contained'

color='primary'

onClick={roomButtonPressed}>

Enter Room

</Button>

</Grid>

<Grid item xs={12} align="center">

<Button variant='contained'

color='secondary' to="/" component={Link}>

Back

</Button>

</Grid>

</Grid>

70
);

6.12 Room Component


import React, {useState, useEffect} from 'react';

import {useParams,Navigate} from "react-router-dom";

import {Grid, Button, Typography} from '@mui/material';

import {useNavigate} from "react-router-dom";

import CreateRoomPage from './CreateRoomPage';

import MusicPlayer from './MusicPlayer';

function Room(props){

const navigate=useNavigate();

const{roomCode}=useParams()

const initialState={

votesToSkip:2,

guestCanPause:false,

isHost:false,

showSettings: false,

spotifyAuthenticated: false,

song:{},
}

const[roomData, setRoomData]=useState(initialState)

useEffect(() => {

getRoomDetails();

const interval=setInterval(getCurrentSong, 1000);

return ()=>clearInterval(interval);

},[roomCode]);

71
const getRoomDetails = () => {

fetch("/api/get-room" + "?code=" + roomCode)

.then((response) => {

if (!response.ok) {

props.clearRoomCodeCallback();

navigate("/");

return response.json();

})

.then((data) => {

setRoomData(prevState=>({

...prevState,

votesToSkip: data.votes_to_skip,

guestCanPause: data.guest_can_pause,

isHost: data.is_host

}));

if(data.is_host){

authenticateSpotify();

});

};

const authenticateSpotify=()=>{

fetch("/spotify/is-authenticated")

.then((response) => response.json())

.then((data) => {

setRoomData(prevState=>({...prevState, spotifyAuthenticated: data.status }));

console.log(data.status);

if (!data.status) {

72
fetch("/spotify/get-auth-url")

.then((response) => response.json())

.then((data) => {

window.location.replace(data.url);

});

});

};

const getCurrentSong = () => {

fetch('/spotify/current-song')

.then((response) => {

if (!response.ok) {

return {};

} else {

return response.json();

})

.then((data) => {

setRoomData(prevState => ({ ...prevState, song: data }));

console.log(data);
});

};

const leaveButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

};

73
fetch('/api/leave-room',requestOptions).

then((response)=>{

props.clearRoomCodeCallback();

navigate('/');

});

};

const updateShowSettings=(value)=>{

setRoomData({

...roomData,

showSettings:value,

});

};

const renderSettings=()=>{

return(
<Grid container spacing={1}>

<Grid item xs={12} align="center">

<CreateRoomPage

update={true}

votesToSkip={roomData.votesToSkip}

guestCanPause={roomData.guestCanPause}

roomCode={roomCode}

updateCallback={getRoomDetails}

getRoomDetails={getRoomDetails}
/>

</Grid>

<Grid item xs={12} align="center" >

<Button

74
variant='contained'

color='secondary'
onClick={()=>updateShowSettings(false)}

>

Close

</Button>

</Grid>

</Grid>

);

};

const renderSettingsButton=()=>{

return(

<Grid item xs={12} align="center">

<Button variant='contained' color='primary'


onClick={()=>updateShowSettings(true)}>

Settings

</Button>

</Grid>

);

};

return roomData.showSettings?(

renderSettings()

):(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant='h4' component='h4'>

75
Code:{roomCode}

</Typography>

</Grid>

<MusicPlayer {...roomData.song}/>

{roomData.isHost?renderSettingsButton():null}

<Grid item xs={12} align="center">

<Button variant="contained" color='secondary' onClick={leaveButtonPressed}>

Leave Room

</Button>

</Grid>

</Grid>

export default Room

6.13 Music Player Component


import React, { useState } from "react";
import {

Grid,

Typography,

Card,

IconButton,

LinearProgress,

} from '@mui/material';

import { Pause, PlayArrowRounded, SkipNext } from '@mui/icons-material';

const MusicPlayer = (props) => {

const skipSong = () => {

76
const requestOptions = {

method: "POST",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/skip", requestOptions);

};

const pauseSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/pause", requestOptions);

};

const playSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/play", requestOptions);

};

const songProgress = (props.time / props.duration) * 100;

return (

<Card>

<Grid container alignItems="center">

<Grid item align="center" xs={4}>

<img src={props.image_url} height="100%" width="100%" alt="song cover" />

</Grid>

77
<Grid item align="center" xs={8}>

<Typography component="h5" variant="h5">

{props.title}

</Typography>

<Typography color="textSecondary" variant="subtitle1">

{props.artist}

</Typography>

<div>

<IconButton onClick={()=>{props.is_playing? pauseSong(): playSong()}}>

{props.is_playing ? <Pause></Pause> :
<PlayArrowRounded></PlayArrowRounded>}

</IconButton>

<IconButton onClick={()=>skipSong()}>

{props.votes}/{" "}{props.votes_required}

<SkipNext></SkipNext>

</IconButton>

</div>

</Grid>

</Grid>

<LinearProgress variant="determinate" value={songProgress} />

</Card>

);

};

export default MusicPlayer;

78
6.14 Django model for storing Spotify authentication tokens and user votes
from django.db import models

from api.models import Room

class SpotifyToken(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

refresh_token = models.CharField(max_length=150)

access_token = models.CharField(max_length=150)

expires_in = models.DateTimeField()

token_type = models.CharField(max_length=50)

class Vote(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

song_id = models.CharField(max_length=50)

room = models.ForeignKey(Room, on_delete=models.CASCADE)

6.15 Credentials for authentication with Spotify API


CLIENT_ID = "08cb230a331944c7bfa503dfc73dd46c"
CLIENT_SECRET = "f78338ef85e74cf2be80970a90406b69"

REDIRECT_URI = "http://127.0.0.1:8000/spotify/redirect"

6.16 Django views for handling music player operations


from django.shortcuts import render, redirect

from .credentials import REDIRECT_URI, CLIENT_SECRET, CLIENT_ID

from rest_framework.views import APIView

from requests import Request, post

from rest_framework import status

79
from rest_framework.response import Response

from .util import *

from api.models import Room

from .models import Vote

class AuthURL(APIView):

def get(self, request, fornat=None):

scopes = 'user-read-playback-state user-modify-playback-state user-read-currently-


playing'

url = Request('GET', 'https://accounts.spotify.com/authorize', params={

'scope': scopes,

'response_type': 'code',

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID

}).prepare().url

return Response({'url': url}, status=status.HTTP_200_OK)

def spotify_callback(request, format=None):

code = request.GET.get('code')

error = request.GET.get('error')

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'authorization_code',

'code': code,

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

80
}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

refresh_token = response.get('refresh_token')

expires_in = response.get('expires_in')
error = response.get('error')

if not request.session.exists(request.session.session_key):

request.session.create()

update_or_create_user_tokens(

request.session.session_key, access_token, token_type, expires_in, refresh_token)

return redirect('frontend:')

class IsAuthenticated(APIView):

def get(self, request, format=None):

is_authenticated = is_spotify_authenticated(
self.request.session.session_key)

return Response({'status': is_authenticated}, status=status.HTTP_200_OK)

class CurrentSong(APIView):

def get(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)

if room.exists():

room = room[0]

else:

81
return Response({}, status=status.HTTP_404_NOT_FOUND)

host = room.host
endpoint = "player/currently-playing"

response = execute_spotify_api_request(host, endpoint)

if 'error' in response or 'item' not in response:

return Response({}, status=status.HTTP_204_NO_CONTENT)

item = response.get('item')

duration = item.get('duration_ms')

progress = response.get('progress_ms')

album_cover = item.get('album').get('images')[0].get('url')

is_playing = response.get('is_playing')

song_id = item.get('id')

artist_string = ""

for i, artist in enumerate(item.get('artists')):

if i > 0:

artist_string += ", "

name = artist.get('name')

artist_string += name

votes = len(Vote.objects.filter(room=room, song_id=song_id))

song = {

'title': item.get('name'),

'artist': artist_string,

'duration': duration,

'time': progress,

82
'image_url': album_cover,

'is_playing': is_playing,

'votes': votes,

'votes_required': room.votes_to_skip,

'id': song_id

self.update_room_song(room, song_id)

return Response(song, status=status.HTTP_200_OK)

def update_room_song(self, room, song_id):

current_song = room.current_song

if current_song != song_id:

room.current_song = song_id

room.save(update_fields=['current_song'])
votes = Vote.objects.filter(room=room).delete()

class PauseSong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

pause_song(room.host)

return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

83
class PlaySong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

play_song(room.host)
return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

class SkipSong(APIView):

def post(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

votes = Vote.objects.filter(room=room, song_id=room.current_song)

votes_needed = room.votes_to_skip

if self.request.session.session_key == room.host or len(votes) + 1 >= votes_needed:

votes.delete()

skip_song(room.host)

else:

vote = Vote(user=self.request.session.session_key,

room=room, song_id=room.current_song)

vote.save()

return Response({}, status.HTTP_204_NO_CONTENT)

84
6.17 To handle Spotify authentication and integration using Spotify API
from .models import SpotifyToken

from django.utils import timezone

from datetime import timedelta

from .credentials import CLIENT_ID, CLIENT_SECRET

from requests import post, put, get

BASE_URL = "https://api.spotify.com/v1/me/"

def get_user_tokens(session_id):

user_tokens = SpotifyToken.objects.filter(user=session_id)

if user_tokens.exists():

return user_tokens[0]

else:

return None

def update_or_create_user_tokens(session_id, access_token, token_type, expires_in,


refresh_token):

tokens = get_user_tokens(session_id)

expires_in = timezone.now() + timedelta(seconds=expires_in)

if tokens:

tokens.access_token = access_token

tokens.refresh_token = refresh_token

tokens.expires_in = expires_in

tokens.token_type = token_type

tokens.save(update_fields=['access_token',
'refresh_token', 'expires_in', 'token_type'])

85
else:

tokens = SpotifyToken(user=session_id, access_token=access_token,

refresh_token=refresh_token, token_type=token_type,
expires_in=expires_in)

tokens.save()

def is_spotify_authenticated(session_id):

tokens = get_user_tokens(session_id)

if tokens:

expiry = tokens.expires_in

if expiry <= timezone.now():

refresh_spotify_token(session_id)

return True

return False

def refresh_spotify_token(session_id):

refresh_token = get_user_tokens(session_id).refresh_token

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'refresh_token',

'refresh_token': refresh_token,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

86
expires_in = response.get('expires_in')

update_or_create_user_tokens(

session_id, access_token, token_type, expires_in, refresh_token)

def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):

tokens = get_user_tokens(session_id)

headers = {'Content-Type': 'application/json',

'Authorization': "Bearer " + tokens.access_token}

if post_:

post(BASE_URL + endpoint, headers=headers)

if put_:

put(BASE_URL + endpoint, headers=headers)

response = get(BASE_URL + endpoint, {}, headers=headers)

try:

return response.json()

except:
return {'Error': 'Issue with request'}

def play_song(session_id):

return execute_spotify_api_request(session_id, "player/play", put_=True)

def pause_song(session_id):

return execute_spotify_api_request(session_id, "player/pause", put_=True)

def skip_song(session_id):

return execute_spotify_api_request(session_id, "player/next", post_=True)

87
6.18 URL patterns for the API views
from django.urls import path

from .views import *

urlpatterns = [

path('get-auth-url', AuthURL.as_view()),

path('redirect', spotify_callback),

path('is-authenticated', IsAuthenticated.as_view()),

path('current-song', CurrentSong.as_view()),

path('pause', PauseSong.as_view()),

path('play', PlaySong.as_view()),

path('skip', SkipSong.as_view())

6.19 URL pattern to include URLS from different parts of the application
from django.contrib import admin

from django.urls import path, include

urlpatterns = [

path('admin/', admin.site.urls),

path('api/', include('api.urls')),

path('', include('frontend.urls')),

path('spotify/', include('spotify.urls'))

88
6. SCREENSHOT

7.1 HOME PAGE

7.2 CREATE ROOM PAGE

89
7.3 SPOTIFY ACCOUNT LOGIN PAGE

7.4 MUSIC PLAYER PAGE FOR HOST

90
7.5 UPDATE ROOM PAGE

7.6 JOIN ROOM PAGE

91
E-COMMERECE WEB APPLICATION

A Project submitted
in partial fulfilment of the requirements
for the Degree of

MASTER OF COMPUTER APPLICATIONS

By

BIKASH PRADHAN

BIPIN KUAMAR BHADRA

BIBHULI KUMAR BHOLA

REGISTRATION NO

22PG030331
22PG0303332
22PG030

Under the Supervision of

MRS .SUCHETA KRUPALINI MOHARANA

DEPARTMENT OF COMPUTER SCIENCE & APPLICATIONS


GIET UNIVERSITY, GUNUPUR-765022, ODISHA

2023-2024
GIET UNIVERSITY,GUNUPUR
Department of Computer Science & Applications
Dist. - Rayagada, Odisha-765022

CERTIFICATE

This is to certify that the project work entitled “E-COMMERECE


WEB APPLICATION” is done by Bikash Pradhan(22PG030331),
Bipin Kumar Bhadra(22PG030332),Bibhuli kumar
Bholo(22PG030346) in partially fulfils the requirements for the 4th
Semester Examination of Master of Computer Applications during the
academic year 2023-24. This work is submitted to the department as
part of the 4th Semester Major Project evaluation.

Project Supervisor Project Coordinator

External Examiner HOD


Computer Science and Applications
ACKNOWLEDGEMENT

We express our sincere gratitude to Prof. Satya Narayan Das, Head of The Department of
Computer Science and Applications for allowing me to accomplish the project. With his
active support and guidance, this project report has been completed.

We also thank Mr. Ashutosh Mallik our Project Coordinator for guidance and help.

We also thank Mrs. Sucheta Krupalini Moharana our Project Supervisor for guidance and help.

Signature of the Students


Contents

Page Number

Abstract 1

1. Introduction 2-4
1.1 Purpose 2
1.2 Project Scope 2
1.3 Project Features 3-4
2. Literature Review 5-7
3. Problem Statement 8-10
4. System Analysis 11-33
4.1 Identification of Need 11
4.2 Preliminary Investigation 12-13
4.3 Feasibility Study 13 -14
4.4 Project Planning 15-17
4.5 Software Requirement Specifications (SRS) 17-31
4.6 Software Engineering Paradigm Applied 31-33
5. System Design &Specifications 34-47
5.1 Data models (like DFD) 41-43
5.2 Entity Relationship Model 44
5.3 Use-case Diagrams 44-45
5.4 Class Diagrams 45-46
5.5 State Diagrams/Sequence Diagrams 47
6. Source Code 48-88
7. Screenshots 89-92
8. Testing 93-100
8.1 Testing Techniques and Testing Strategies Used Testing Plan used 94-96
8.2 Test Reports for Unit Test Cases and System Test Cases 96-100
9. Conclusion 101-102
10. Future Enhancement 103-105
11. References / Bibliography 106
ABSTRACT

Title: Development of an E-STORE Using Python, D jango, HTML, CSS, and Bootstrap

Abstract:
In today's digital age, online shopping has become increasingly popular, especially for
essential items like groceries. This project aims to develop a comprehensive online
grocery shop using Python, Django, HTML, CSS, and Bootstrap.

The system will provide users with a convenient platform to browse through a wide
range of grocery products, add them to their cart, and securely complete their purchases.
The backend will be powered by Django, a high-level Python web framework, which
will handle user authentication, product management, order processing, and database
interactions.

The frontend will be developed using HTML, CSS, and Bootstrap to create a visually
appealing and responsive user interface. Bootstrap's grid system and components will
ensure that the website is accessible across various devices and screen sizes, providing a
seamless shopping experience for users on desktops, laptops, tablets, and smartphones.

Key features of the online grocery shop will include user registration and login, product
categorization and search functionality, product details and images, shopping cart
management, secure payment processing integration, order tracking, and email
notifications.

Overall, this project aims to leverage modern web development technologies to create
an efficient and user-friendly online grocery shopping platform, catering to the needs of
today's digitally savvy consumers.

1
INTRODUCTION
 PURPOSE :

The purpose of developing an online grocery shop using Python, Django,


HTML, CSS, and Bootstrap is multi-faceted:

1. Convenience: The primary aim is to provide consumers with a convenient


way to purchase groceries from the comfort of their homes. By offering an
online platform, customers can browse, select, and order groceries at any
time, eliminating the need to physically visit a store.
2. Accessibility: An online grocery shop enhances accessibility for
individuals who may have mobility issues or live in remote areas with
limited access to physical stores. They can access a wide range of grocery
products with just an internet connection.
3. Time-saving: By streamlining the shopping process, customers can save
time that would have been spent commuting to and from a store, searching
for items, and waiting in checkout lines. The online platform allows for
quick browsing, searching, and purchasing of products.
4. Product variety: Online grocery shops can offer a broader range of
products compared to traditional brick-and-mortar stores. Customers can
explore a diverse selection of brands, flavors, and specialty items without the
constraints of physical shelf space.
5. Personalization: Through user accounts and preferences tracking, online
grocery shops can offer personalized recommendations and promotions
tailored to individual shopping habits and preferences. This enhances the
shopping experience and encourages customer loyalty.
6. Scalability: By leveraging Python and Django for backend development
and HTML, CSS, and Bootstrap for frontend design, the online grocery shop
can be built to scale. It can accommodate a growing customer base and
expand its offerings and features as needed.

In essence, the purpose of developing an online grocery shop using these


technologies is to create a modern, user-friendly, and efficient platform that
meets the evolving needs of consumers in today's digital landscape.

2
 PROJECT FEATURES :

Here's a breakdown of the project features for the online grocery shop developed using Python,
Django, HTML, CSS, and Bootstrap:
1. User Registration and Authentication:
- Allow users to register with the platform by providing necessary details.
- Implement authentication mechanisms to ensure secure access to user accounts.
- Enable users to log in and log out of their accounts securely.
2. Product Management:
- Provide functionality for administrators to add, edit, and delete grocery products.
- Include fields such as product name, description, price, quantity, and images.
- Implement product categorization and tagging for easy navigation.
3. Browsing and Searching:
- Enable users to browse through the available grocery products conveniently.
- Implement search functionality to allow users to find specific products quickly.
- Provide filtering options based on categories, prices, and other attributes.
4. Shopping Cart Management:
- Allow users to add products to their shopping carts while browsing.
- Provide options to update the quantity or remove items from the cart.
- Display the total cost and summary of items in the shopping cart.
5. Checkout Process:
- Implement a streamlined checkout process for users to complete their purchases.
- Include forms for users to provide shipping and billing information.
- Integrate secure payment gateways for processing transactions (e.g., PayPal, Stripe).

6. Order Tracking and History:

3
1.1.1 Error Handling and Security: Robust error handling mechanisms and security
measures are implemented to ensure data integrity, user privacy, and protection against
unauthorized access.

4
1. LITERATURE REVIEW
Collaborative music playback systems have emerged as a novel way for users to engage with
music in shared listening experiences. These systems enable multiple users to synchronize
their music playback across devices, allowing for collaborative playlist creation, voting on
tracks, and real-time interaction. This literature review aims to provide a comprehensive
overview of existing research and developments in collaborative music playback systems,
focusing on design principles, technical implementations, user experiences, and the social
impact of these systems.

2.1 DESIGN PRINCIPLES AND TECHINCAL IMPLEMENTATION


Research in collaborative music playback systems has explored various design principles and
technical implementations to facilitate seamless synchronization and interaction among users.
One key aspect is the architecture of the system, which may be centralized, decentralized, or
hybrid. Centralized architectures typically rely on a server to manage playback
synchronization and user interactions, while decentralized architectures leverage peer-to-peer
or mesh networking to distribute control among connected devices. Hybrid approaches
combine elements of both centralized and decentralized architectures to optimize
performance and scalability.

In terms of synchronization techniques, real-time algorithms play a crucial role in ensuring


accurate timing alignment between audio streams across devices. These algorithms must
account for factors such as network latency, device processing capabilities, and audio
buffering to deliver a consistent listening experience. Additionally, researchers have
investigated protocols for communication and data exchange between devices, considering
factors like reliability, efficiency, and compatibility with existing standards.

2.2 USER EXPERIENCE AND IINTERFACE DESIGN


User experience (UX) plays a crucial role in the success of collaborative music playback
systems. Studies have investigated various UX factors, such as interface design, interaction
patterns, and social features, to enhance user engagement and satisfaction. Intuitive interfaces
with intuitive controls enable users to navigate, search, and manage playlists effortlessly.
Social features like chat, voting, and collaborative playlist creation foster a sense of
5
community and encourage active participation among users. Furthermore, personalized
recommendations and adaptive interfaces tailor the music listening experience to individual
preferences, enhancing user satisfaction and retention. Adaptive interfaces that adapt to user
behavior, context, and feedback can enhance user satisfaction and retention. Additionally,
accessibility features ensure that the system is inclusive and usable for users with diverse
needs and abilities.

2.3 SOCIAL IMPACT AND USER ENGAGEMENT


Collaborative music playback systems have a significant impact on music consumption habits
and social interactions. Research has shown that shared listening experiences strengthen
social bonds and promote collaborative behaviors among users. Users engage in activities
like co-curating playlists, discovering new music together, and engaging in real-time
interactions like voting on tracks or controlling playback. Moreover, collaborative music
playback systems encourage exploration and serendipitous discovery, exposing users to a
diverse range of musical genres and artists they might not encounter otherwise. This
collaborative discovery process fosters a deeper appreciation for music and cultivates a sense
of belonging within online communities.

2.4 CHALLENGES AND FUTURE DIRECTIONS


Despite the benefits, collaborative music playback systems face several challenges, including
technical constraints, privacy concerns, and scalability issues. Synchronizing playback across
devices while minimizing latency remains a significant challenge, particularly in
heterogeneous network environments with varying bandwidth and latency characteristics.
Moreover, ensuring data privacy and security is crucial, as collaborative music playback
systems often involve sharing personal music preferences and listening habits. Additionally,
scalability becomes a concern as the number of users and concurrent sessions grows,
necessitating robust infrastructure and optimization techniques to handle increasing load and
maintain performance.

Looking ahead, future research directions in collaborative music playback systems may
include exploring novel interaction paradigms, integrating emerging technologies like virtual
reality and spatial audio, and investigating the social and cultural implications of shared

6
listening experiences. Moreover, interdisciplinary collaborations between researchers,
designers, musicians, and industry stakeholders can lead to innovative solutions that redefine
how people discover, share, and enjoy music together in the digital age.

In conclusion, collaborative music playback systems offer exciting opportunities to enhance


social interaction, foster musical discovery, and transform the way people engage with music.
By addressing design challenges, improving user experiences, and exploring new avenues for
innovation, researchers and practitioners can continue to advance the field of collaborative
music playback systems and create meaningful experiences for music enthusiasts worldwide.

7
2. PROBLEM STATEMENT
The problem statement for the project revolves around the need for a collaborative music
playback system that allows multiple users to join a virtual room, synchronize playback, and
control music playback together. Existing music streaming platforms lack real-time
collaboration features, limiting the ability for users to enjoy music together simultaneously.
Therefore, there is a need to develop a platform that enables users to create and join rooms,
interact with other users in real-time, and collectively control music playback. This project
aims to address these limitations by implementing features such as room creation, user
authentication through Spotify, real-time synchronization of playback, and control of
playback features by both hosts and guests.

3.1 KEY CHALLENGES


The key challenges of this project include:

3.1.1 Real-Time Synchronization: Ensuring that all users in a room experience


synchronized music playback without significant latency or delays is crucial. Achieving this
requires efficient data handling and synchronization techniques.

3.1.2 User Authentication and Integration with Spotify API: Integrating user
authentication via Spotify and leveraging the Spotify API to retrieve and control music
playback requires handling OAuth flows securely and managing access tokens effectively.

3.1.3 Room Management and Data Consistency: Managing rooms dynamically, including
creation, joining, and leaving, while maintaining data consistency and integrity across
connected users presents challenges in database design and synchronization.

3.1.4 Playback Control Permissions: Implementing logic to allow hosts to control playback
permissions for guests, such as play, pause, and skip, requires robust authorization
mechanisms.

3.1.5 Real-Time Updates and Notifications: Enabling real-time updates for playback
control and room settings poses challenges in handling WebSocket communications and
ensuring efficient event propagation.

8
3.1.6 Error Handling and Resilience: Implementing robust error handling mechanisms to
address potential failures in API calls, user authentication, or real-time synchronization is
essential for maintaining a seamless user experience.

3.2 SOLUTION REQUIREMENTS


The solution requirements to address the challenges of the project include:

3.2.1 Real-Time Synchronization

• Implement WebSocket communication to enable real-time synchronization of


playback events and updates across all connected users.

• Utilize efficient data structures and algorithms for managing playback state and
ensuring synchronized playback experiences.

3.2.2 User Authentication and Integration with Spotify API

• Implement OAuth 2.0 authentication flow securely to authenticate users with their
Spotify accounts.

• Utilize Spotify API endpoints to retrieve user-specific music data, control playback,
and manage user permissions.

3.2.3 Room Management and Data Consistency

• Design a robust database schema to manage rooms, users, and playback state
efficiently.

• Implement transactional operations and data synchronization mechanisms to ensure


data consistency across connected users.

3.2.4 Playback Control Permissions

• Implement role-based access control (RBAC) mechanisms to manage user roles (host
vs. guest) and permissions for controlling playback.

• Design intuitive user interfaces to allow hosts to manage playback permissions


effectively.

9
3.2.5 Real-Time Updates and Notifications

• Implement WebSocket-based pub-sub systems to propagate real-time updates and


notifications to all connected users.

• Design event-driven architectures to handle and process events related to playback


control, room management, and user interactions.

3.2.6 Error Handling and Resilience

• Implement robust error handling mechanisms to gracefully handle errors and failures
in API calls, authentication flows, and real-time communication.

• Utilize logging and monitoring tools to track and diagnose errors in real-time,
ensuring quick resolution and minimal disruption to the user experience.

10
3. SYSTEM ANALYSIS

4.1 IDENTIFICATION OF NEED


The identification of the need for this project stems from several factors:

4.1.1 Rising Popularity of Music Streaming Platforms

• With the increasing popularity of music streaming services like Spotify, there's a
growing demand for collaborative music playback systems that allow users to listen
to music together in real-time.

4.1.2 Desire for Social Music Listening Experiences

• Many users enjoy listening to music with friends or family members, whether they're
in the same location or miles apart. A collaborative music playback system fulfills
the need for shared music listening experiences.

4.1.3 Enhanced Engagement and Interaction

• Collaborative music playback systems provide an interactive platform where users


can engage with each other while listening to music. It creates opportunities for
social interaction, discussion, and shared enjoyment of music.

4.1.4 Virtual Events and Gatherings

• With the rise of virtual events and gatherings, there's a need for platforms that enable
participants to listen to music together during online parties, virtual hangouts, or
remote celebrations.

4.1.5 Support for Remote Work and Learning

• In remote work and learning environments, collaborative music playback systems can
serve as icebreakers, team-building tools, or background entertainment during
virtual meetings and study sessions.

4.1.6 Customization and Personalization

• Users often have diverse musical preferences and tastes. A collaborative music
playback system allows users to share and discover music based on their individual
preferences, creating personalized listening experiences.

11
4.2 PRELIMINARY INVESTIGATION:
The preliminary investigation of this project involves cconducting initial research and
analysis to gather information and assess the feasibility of the project. It includes the
following steps:

4.2.1 Identifying Stakeholders

• Determine the primary stakeholders involved in the project, including users,


developers, music streaming platforms, and potential collaborators.

4.2.2 Defining Objectives

• Clarify the project's goals and objectives, such as developing a collaborative music
playback system, integrating with the Spotify API, enabling real-time
synchronization of playback, and providing user-friendly interfaces.

4.2.3 Gathering Requirements

• Collect requirements from stakeholders regarding functionality, user experience,


platform compatibility, security, scalability, and other relevant aspects.

4.2.4 Market Analysis

• Conduct a market analysis to understand the current landscape of music streaming


platforms, collaborative music playback systems, and related technologies. Identify
existing solutions, their features, strengths, and weaknesses.

4.2.5 Technical Feasibility

• Assess the technical feasibility of implementing the project, considering factors such
as available resources (e.g., technology stack, development tools), integration with
third-party APIs (e.g., Spotify), and scalability requirements.

4.2.6 Resource Allocation

• Determine the resources needed for the project, including personnel, time, budget,
hardware, and software. Allocate resources effectively to ensure successful project
execution.

12
4.2.7 Risk Assessment

• Identify potential risks and challenges associated with the project, such as technical
complexities, data security concerns, regulatory compliance, and dependencies on
external factors (e.g., API changes).

4.2.8 Cost-Benefit Analysis

• Evaluate the costs and benefits of implementing the project, considering factors such
as development costs, potential revenue streams, market demand, competitive
advantage, and long-term sustainability.

4.3 FEASIBILITY STUDY


A feasibility study for this project would involve evaluating various aspects to determine if
the project is viable and achievable. Here's how it can be approached:

4.3.1 Technical Feasibility

• Assess the technical requirements of integrating with the Spotify API and
implementing real-time synchronization of playback across multiple users.

• Evaluate the compatibility of chosen technologies (Python, Django, React) with the
project requirements.

• Determine if the project can be implemented within the constraints of available


technology stack and development resources.

4.3.2 Financial Feasibility

• Estimate the costs associated with development, including personnel, infrastructure,


software licenses, and any third-party services (such as hosting or Spotify API
access).

• Compare the projected costs with the budget allocated for the project to ensure
financial viability.

• Consider potential revenue streams, such as subscription fees, in-app purchases, or


advertising, to offset development costs.

13
4.3.3 Operational Feasibility

• Evaluate the operational aspects of the project, including how it will be managed,
maintained, and supported post-launch.

• Assess the availability of skilled personnel to develop, deploy, and maintain the
application.

• Consider scalability requirements and whether the project can accommodate growth
in user base and usage over time.

4.3.4 Legal and Regulatory Feasibility

• Identify any legal or regulatory requirements related to music streaming, user data
privacy, copyright, and licensing.

• Ensure compliance with relevant laws and regulations to avoid legal issues and
penalties.

4.3.5 Market Feasibility

• Analyze the market demand for collaborative music playback systems and the
potential user base for the application.

• Identify competitors and assess their offerings, strengths, and weaknesses.

• Determine if the project fills a gap in the market and offers unique features or
advantages compared to existing solutions.

4.3.6 Schedule Feasibility:

• Develop a realistic timeline for project development, testing, and deployment.

• Consider any dependencies, constraints, or risks that may impact the project schedule.

• Ensure that the proposed timeline aligns with stakeholders' expectations and business
objectives.

14
4.4 PROJECT PLANNING
Project planning for this collaborative music playback system involves organizing tasks,
allocating resources, and establishing timelines to ensure successful development and
deployment. Here's an outline of the project planning process:

4.4.1 Define Project Scope and Objectives

• Clearly articulate the goals and objectives of the project, including the features and
functionality of the collaborative music playback system.

• Define the target audience and user requirements to guide development.

4.4.2 Create Work Breakdown Structure (WBS)

• Break down the project into smaller, manageable tasks and subtasks.

• Organize tasks into a hierarchical structure to facilitate planning and resource


allocation.

4.4.3 Estimate Time and Resources

• Estimate the time required to complete each task based on factors such as complexity,
dependencies, and available resources.

• Determine the resources needed for development, including personnel, equipment,


and software tools.

4.4.4 Develop Project Schedule

• Create a project timeline or Gantt chart that outlines the sequence of tasks, milestones,
and deadlines.

• Allocate resources and establish dependencies between tasks to ensure smooth


progress.

4.4.5 Identify Risks and Mitigation Strategies

• Identify potential risks and uncertainties that may impact the project schedule, budget,
or quality.

• Develop strategies to mitigate risks and minimize their impact on the project.

15
• Establish contingency plans to address unforeseen challenges that may arise during
development.

4.4.6 Allocate Responsibilities

• Assign roles and responsibilities to team members based on their skills, expertise, and
availability.

• Clearly communicate expectations and deliverables to ensure accountability and


collaboration.

4.4.7 Monitor and Control Progress

• Regularly monitor project progress against the established schedule and milestones.

• Track resource utilization, budget expenditures, and any deviations from the plan.

• Implement corrective actions as needed to keep the project on track and address any
issues or delays.

4.4.8 Communicate with Stakeholders

• Maintain open communication channels with stakeholders, including clients, team


members, and project sponsors.

• Provide regular updates on project status, accomplishments, and challenges.

• Solicit feedback and address any concerns to ensure stakeholder satisfaction and
alignment with project goals.

4.4.9 Project closure

• Prepare comprehensive documentation that captures all aspects of the project,


including requirements, design decisions, implementation details, and testing results.

• Conduct a post-project review to assess the overall success of the collaborative music
playback system. Evaluate the project against its original objectives, budget, and
schedule.

• Ensure a smooth transition of the collaborative music playback system to the


appropriate stakeholders, such as end-users or operations teams.

16
• Prepare a formal project closure report summarizing the project's outcomes,
achievements, and recommendations for future improvements.

4.5 SOFTWARE REQUIREMENT SPECIFICATIONS (SRS)


The Software Requirements Specification (SRS) for the collaborative music playback system
outlines the functional and non-functional requirements of the software. Here's an overview
of the SRS:

4.5.1 Introduction

 Provide an overview of the collaborative music playback system.

 Describe the purpose, scope, and objectives of the software.

 Identify stakeholders and their roles in the project.

4.5.2 Functional Requirements

• User Management

• Users can register and log in using their Spotify accounts.

• Hosts can create rooms and manage room settings.

• Guests can join rooms using unique codes generated by hosts.

• Music Playback

• Users can play, pause, skip, and control playback of music tracks.

• Hosts can control playback permissions for guests.

• Real-time Synchronization

• Music playback is synchronized across all connected users in the same room.

• Voting System

• Users can vote to skip tracks, with the option for hosts to set the minimum
number of votes required.

17
• Room Management

• Hosts can set room parameters such as maximum number of participants,


playback control options, and voting system settings.

• Hosts can close the room, preventing new participants from joining.

• User Interaction

• Users can chat with other participants in the same room, enhancing social
interaction.

• Hosts can broadcast messages to all participants in the room, such as


announcements or song dedications.

• Playback History

• The system maintains a playback history for each room, allowing users to
view previously played tracks and their associated metadata.

• Guest Permissions

• Hosts can grant specific permissions to individual guests, such as allowing


certain users to control playback or skip tracks.

• Playlist Management

• Users can create and manage playlists within the application, adding or
removing tracks from their personal collection.

• Hosts can create shared playlists for the entire room to collaborate on.

4.5.3 Non-Functional Requirements

• Performance

• The system should have low latency for real-time synchronization.

• It should support a large number of concurrent users without degradation in


performance.

• Security

• User authentication and authorization should be implemented securely


using OAuth 2.0.
18
• Data transmission should be encrypted to protect user privacy.

• Reliability

• The system should be highly available and resilient to failures.

• It should gracefully handle errors and recover from faults.

• Usability

• The user interface should be intuitive and user-friendly.

• It should provide feedback and guidance to users as they interact with the
system.

• Accessibility

• The user interface should be accessible to users with disabilities, complying


with accessibility standards such as WCAG (Web Content Accessibility
Guidelines).

• Support for screen readers and keyboard navigation should be provided.

• Scalability

• The system should be designed to scale both vertically and horizontally to


handle increases in user traffic and data volume.

• Load balancing and caching mechanisms should be implemented to distribute


workload efficiently.

• Internationalization and Localization

• The application should support multiple languages and locales to


accommodate users from different regions.

• Text and user interface elements should be easily translatable and


customizable.

• Data Privacy and GDPR Compliance

• The system should adhere to data privacy regulations such as GDPR (General
Data Protection Regulation).

19
• User consent mechanisms should be implemented for data collection and
processing activities.

• Error Handling and Logging

• Comprehensive error handling should be in place to gracefully manage


exceptions and errors.

• Logs should be generated for system events, user actions, and error conditions,
aiding in troubleshooting and auditing.

4.5.4 External Interfaces

 Spotify API

• Integration with the Spotify API for music playback and user authentication.

 Frontend Interface

• Interaction with the frontend application developed using React.js.

 Database Interface

• Interaction with the database to store user information, room settings, and playback
data.

4.5.5 Constraints

 Technology Stack

➢ Front-End Development

❖ HTML(Hypertext Markup Language)

HTML, or Hypertext Markup Language, is the standard language used to create and
design web pages. It provides the structure for web content by using various tags and
attributes to define elements on a page. HTML is the backbone of web development,
providing the foundation for creating visually appealing and interactive web pages. It
works hand in hand with CSS (Cascading Style Sheets) for styling and JavaScript for
interactivity, forming the core technologies of the World Wide Web.

20
Overview of HTML

▪ Tags: HTML is built on tags, which are enclosed in angle brackets `< >`. Tags
are used to define different types of content on a webpage, such as headings,
paragraphs, images, links, and more.

▪ Elements: HTML elements are made up of tags and the content they surround.
For example, a paragraph element `<p>` starts with an opening tag and ends with
a closing tag `</p>`, enclosing the paragraph text.

▪ Attributes: Tags can have attributes that provide additional information about an
element. Attributes are placed within the opening tag and typically come inname-
value pairs, such as `href` in an anchor tag `<a href="https://example.com">`.

▪ Document Structure: HTML documents have a specific structure consisting of an


opening `<html>` tag followed by `<head>` and `<body>` tags. The `<head>`
section typically contains metadata like the page title, links to stylesheets, and
scripts. The `<body>` section contains the visible content of the webpage.

▪ Semantic Markup: HTML5 introduced semantic elements that provide more


meaning to the content, making it easier for search engines and assistive
technologies to understand. Examples include `<header>`, `<footer>`, `<nav>`,
`<article>`, `<section>`, `<aside>`, etc.

HTML Tags Used

▪ HTML: The HTML element (`<html>`) is the root element of an HTML page. It
wraps all the content on the page.

▪ Head: The head element (`<head>`) contains metadata and links to external
resources used by the HTML document. It doesn't display any content directly to
the user.

▪ Meta: The meta element (`<meta>`) is used to provide metadata about the HTML
document. Common uses include specifying the character encoding (`charset`
attribute) and setting the viewport for responsive design (`viewport` attribute).

21
▪ Title: The title element (`<title>`) sets the title of the HTML document, which is
displayed in the browser's title bar or tab. It's also used by search engines for page
indexing and in bookmarks.

▪ Script:The script element (`<script>`) is used to embed or reference executable


code, typically JavaScript, within an HTML document. It can be used to add
interactivity, handle events, manipulate the DOM, and more.

▪ Div: The div element (`<div>`) is a generic container used to group and style
HTML elements. It's often used to create sections or divisions within a webpage
and is styled using CSS.

▪ Body: The body element (`<body>`) contains the content of the HTML document
that's displayed to the user. It includes text, images, links, forms, and other
elements that make up the visible part of the webpage.

❖ CSS(Cascading Style Sheets)

CSS (Cascading Style Sheets) is a language used for describing the presentation
of a document written in HTML (HyperText Markup Language). Here's an overview
of CSS:

▪ Selectors: CSS selectors are patterns used to select the elements you want to
style. They can select elements based on their tag name, class, ID, attributes, and
more. They are a fundamental part of CSS syntax and play a crucial role in
styling web pages.

▪ Properties and Values: CSS properties are the styling attributes you can apply to
selected elements. Each property has a specific value associated with it that
defines how the property should be applied. Examples of properties include
`color`, `font-size`, `background-color`, `margin`, `padding`, and `border`.

▪ Cascading: CSS stands for "Cascading" Style Sheets, which refers to the way
styles are applied to elements. Styles can be inherited from parent elements,
overridden by more specific selectors, or overwritten by inline styles.

▪ Units: CSS supports different units of measurement for specifying sizes and
distances, such as pixels (`px`), percentages (`%`), ems (`em`), rems (`rem`), and
viewport units (`vw`, `vh`, `vmin`, `vmax`).

22
❖ JavaScript

JavaScript (JS) serves as the primary language for adding interactivity and
dynamic behavior to web pages. Here's an overview of JavaScript within the
project context:

▪ Client-Side Scripting: JavaScript is primarily used for client-side scripting,


meaning it runs in the user's web browser rather than on the server. This
allows for dynamic content manipulation without needing to reload the entire
page.

▪ DOM Manipulation: One of the core features of JavaScript is its ability to


manipulate the Document Object Model (DOM). The DOM represents the
structure of HTML elements on a web page, and JavaScript can be used to
access, modify, or delete these elements dynamically.

▪ Event Handling: JavaScript enables event-driven programming, where


functions (event handlers) are executed in response to user actions or system
events. Common events include clicks, mouse movements, keyboard inputs,
form submissions, and page loads.

▪ AJAX (Asynchronous JavaScript and XML): AJAX allows for asynchronous


communication between the web browser and the server, enabling data to be
exchanged with the server in the background without interfering with the
current page. This is commonly used to update parts of a web page without
requiring a full reload.

▪ API Integration: JavaScript can interact with various APIs (Application


Programming Interfaces) to access external services and data. This includes
fetching data from servers, integrating with third-party services (e.g., social
media platforms, mapping services), and performing operations like
authentication and authorization.

▪ Form Validation: JavaScript can be used to validate form inputs in real-time,


providing instant feedback to users and preventing invalid data submission.
This helps improve the user experience and ensures data integrity.

23
▪ Animation and Effects: JavaScript can create animations and visual effects on
web pages using techniques like CSS animations, transitions, and
libraries/frameworks such as jQuery or GSAP (GreenSock Animation
Platform).

▪ Error Handling and Debugging: JavaScript provides mechanisms for error


handling and debugging, including try-catch blocks, console logging, and
browser developer tools. Proper error handling ensures graceful degradation
in case of errors and helps developers identify and fix issues.

▪ Modularization and Libraries: JavaScript supports modular programming


through the use of modules, allowing code to be organized into reusable
components. Additionally, developers often leverage third-party libraries and
frameworks (e.g., React.js, Vue.js, AngularJS) to streamline development and
add advanced features.

▪ Security Considerations: When working with JavaScript, security is a critical


consideration. Developers must be mindful of potential security
vulnerabilities such as cross-site scripting (XSS) attacks and implement best
practices to protect against them.

❖ React

React is a JavaScript library used for building user interfaces, particularly for
single-page applications (SPAs) where content is dynamically updated without
requiring full page reloads. Here's an overview of React within this project:

▪ Component-Based Architecture: React follows a component-based


architecture, where UIs are composed of reusable components. Each
component encapsulates its own logic, state, and markup, making it easier
to manage and maintain complex user interfaces.

▪ Virtual DOM: React uses a virtual DOM (Document Object Model) to


efficiently update the UI. Instead of directly manipulating the browser's
DOM, React creates a lightweight in-memory representation of the DOM
and updates it as needed. This approach minimizes unnecessary DOM
manipulation and leads to better performance.

24
▪ JSX (JavaScript XML): React utilizes JSX, a syntax extension that allows
developers to write HTML-like code within JavaScript. JSX makes it
easier to describe UI components and their structure, combining HTML
markup with JavaScript logic seamlessly.

▪ State Management: React components can have state, which represents


data that can change over time. By using the `useState` hook (or `setState`
method in class components), developers can manage and update
component state, triggering re-renders as necessary to reflect state changes
in the UI.

▪ Props (Properties): React components can receive data via props, which
are essentially read-only inputs passed from parent to child components.
Props allow for communication between components and enable
component customization and reusability.

▪ Lifecycle Methods (Class Components): Class components in React have


lifecycle methods that are invoked at different stages of a component's
lifecycle, such as mounting, updating, and unmounting. These methods
can be used to perform initialization, data fetching, and cleanup tasks.

▪ Hooks (Functional Components): Functional components in React can use


hooks to add state and other features previously exclusive to class
components. Hooks like `useEffect`, `useContext`, and `useReducer`
enable functional components to manage state, perform side effects, and
access context without needing to use class syntax.

▪ Routing: React applications often use a router library (such as React


Router) to handle client-side routing and navigation. This allows for the
creation of multi-page experiences within a single-page application, with
different components rendered based on the URL.

▪ Server-Side Rendering (SSR): While not necessarily applicable to all


React projects, SSR is a technique used to render React components on
the server side and send HTML to the client. This can improve
performance and SEO by providing faster initial page loads and ensuring
content is indexable by search engines.

25
▪ Component Libraries and Ecosystem: React has a rich ecosystem of third-
party libraries and tools that extend its capabilities. This includes state
management libraries like Redux, UI component libraries like Material-UI
or Ant Design, and development tools like React DevTools and Create
React App.

➢ Back-End Development

❖ Python

Python serves as the backend language, responsible for handling server-side logic,
database interactions, and API endpoints. Python serves as the backend language,
responsible for handling server-side logic, database interactions, and API
endpoints.

▪ Django Framework: The project likely uses the Django web framework, which
is a high-level Python web framework that encourages rapid development and
clean, pragmatic design. Django provides a set of built-in tools and
conventions for handling common web development tasks, such as URL
routing, database modeling, and user authentication.

▪ API Endpoints: Python code defines API endpoints using Django's `django-
rest-framework` or similar libraries. These endpoints handle incoming HTTP
requests from the frontend, perform necessary data processing or database
operations, and return appropriate HTTP responses (usually in JSON format)
containing the requested data or indicating the outcome of the request.

▪ Model-View-Controller (MVC) Architecture: Django follows the MVC


architectural pattern, although in Django's terminology it's referred to as
Model-View-Template (MVT). Models define the structure and behavior of the
application's data, views handle the presentation logic and interact with
models, and templates render HTML pages to be served to the client.

▪ ORM (Object-Relational Mapping): Django provides an ORM layer that


abstracts away the details of database interaction, allowing developers to work
with database tables and records using Python classes and methods. Models in
Django represent database tables, and queries are performed using Python
syntax rather than raw SQL.
26
▪ Middleware: Django middleware allows for processing of requests and
responses before and after they reach the view layer. Middleware can perform
tasks such as authentication, request/response logging, error handling, and
more.

▪ Session Management and Authentication: Django provides built-in support for


user authentication and session management. Developers can easily integrate
features like user registration, login, logout, password management, and access
control using Django's authentication system.

▪ URL Routing: Django's URL routing mechanism maps incoming HTTP


requests to the appropriate view functions based on URL patterns defined in
the project's URL configuration. This allows for clean and organized URL
structures and separation of concerns between different parts of the application.

▪ Task Queues and Background Jobs: For handling long-running or


asynchronous tasks, Python code may use task queue libraries like Celery in
combination with a message broker such as Redis or RabbitMQ. This allows
tasks to be executed asynchronously outside of the request-response cycle,
improving application performance and scalability.

▪ Third-Party Libraries: Python's extensive ecosystem of third-party libraries and


packages may be leveraged for various purposes within the project, such as
handling date/time operations, working with external APIs, performing data
validation, and more.

❖ Django

Django serves as the web framework for building the backend of the application.
Django provides a comprehensive set of tools and conventions for building web
applications quickly and efficiently. Its batteries-included approach, robust security
features, and thriving ecosystem of third-party packages make it a popular choice
for building scalable and maintainable web applications.

▪ Model-View-Template (MVT) Architecture: Django follows the MVT


architectural pattern, which is a variation of the traditional Model-View-
Controller (MVC) pattern. In Django, models represent the data structure,

27
views handle the logic to process requests and generate responses, and
templates are used for rendering HTML pages.

▪ URL Routing: Django's URL dispatcher maps URL patterns to view functions
or classes, allowing developers to define how different URLs should be
handled by the application. URL patterns are typically defined in the project's
`urls.py` file and may include regular expressions or path converters to capture
dynamic parts of the URL.

▪ Models and ORM: Django provides an Object-Relational Mapping (ORM)


layer that allows developers to define database models using Python classes.
Models represent database tables, and fields within models represent table
columns. Django's ORM abstracts away the need to write SQL queries directly,
making it easier to interact with the database using Python code.

▪ Admin Interface: Django comes with a built-in administration interface that


can be automatically generated based on the project's models. This admin
interface allows authorized users to view, create, update, and delete records in
the database without writing any custom code. Admin functionality can be
customized and extended as needed.

▪ Forms and Validation: Django provides a forms library for handling HTML
forms and form data. Forms can be created using Python classes, and Django
handles tasks such as form rendering, data validation, and error handling
automatically. Forms can be used in views to process user input and interact
with the database.

▪ Middleware: Django middleware allows for processing of requests and


responses at various points in the request-response cycle. Middleware
components can perform tasks such as authentication, request/response
logging, CORS handling, and more. Middleware can be applied globally to all
requests or selectively to specific URL patterns.

▪ Authentication and Authorization: Django provides built-in support for user


authentication and authorization. The authentication system handles tasks such
as user login, logout, password management, and session management.

28
Authorization can be enforced using decorators or middleware to restrict
access to certain views or resources.

▪ Template Engine: Django's template engine allows developers to create HTML


templates that can be dynamically rendered with data from views. Templates
support template inheritance, template tags and filters, and other features to
facilitate code reuse and maintainability.

▪ Static Files and Media Handling: Django provides utilities for managing static
files (e.g., CSS, JavaScript) and media files (e.g., user-uploaded images,
videos). Static files are typically served directly by the web server in
production, while media files are stored locally or on a cloud storage service
like Amazon S3.

▪ Internationalization and Localization: Django supports internationalization


(i18n) and localization (l10n) out of the box, allowing developers to build
applications that support multiple languages and locales. Translation strings
can be marked for translation in Python code and templates, and Django
provides tools for generating translated versions of the application's content.

➢ API

❖ Spotify API:

The Spotify API is utilized to integrate music playback and management


functionality into the application. The integration of the Spotify API enhances the
functionality of the application by allowing users to access and control their
Spotify accounts directly within the application. This integration enables features
such as music playback, playlist management, and personalized recommendations,
enriching the user experience and making the application more engaging and
interactive.

▪ Authentication: The application implements OAuth 2.0 authentication to allow


users to connect their Spotify accounts. This involves obtaining authorization
from Spotify to access the user's account data and playback functionality.
Users are redirected to the Spotify authorization page, where they grant
permission to the application. Upon authorization, the application receives an

29
access token, which is used to make authenticated requests to the Spotify API
on behalf of the user.

▪ Authorization Code Flow: The application uses the authorization code flow to
authenticate users with Spotify. This flow involves redirecting the user to the
Spotify authorization page with specific parameters, including the client ID,
redirect URI, and requested scopes (permissions). After the user grants
permission, Spotify redirects back to the application with an authorization
code, which is exchanged for an access token and refresh token.

▪ Fetching Current Song: The application periodically fetches information about


the currently playing song from the Spotify API. This information includes
details such as the song title, artist, album, playback progress, and album cover
art. The fetched data is then displayed to the user in the application's user
interface, allowing them to see what song is currently playing.

▪ Playback Control: The application allows users to control playback actions


such as play, pause, and skip through the Spotify API. When a user interacts
with playback controls in the application's user interface, corresponding
requests are sent to the Spotify API to perform the desired action on the user's
active playback session.

▪ Error Handling and Edge Cases: The application handles potential errors and
edge cases that may arise during interactions with the Spotify API. This
includes scenarios such as invalid access tokens, expired tokens, rate limiting,
and network errors. Error handling mechanisms ensure that the application
provides a smooth and reliable user experience even in the face of API-related
issues.

30
 Scalability:

• The system should be designed to scale horizontally to accommodate future


growth in user base and usage.

4.5.6 Appendices

 Include any additional information relevant to the software requirements, such as use
case diagrams, data flow diagrams, or mockups.

4.6 SOFTWARE ENGINEERING PARADIGM APPLIED


The software engineering paradigm applied for this project is likely Agile. Agile
methodology emphasizes iterative development, collaboration, and flexibility, which are
crucial for a dynamic project like a collaborative music playback system. Here's how Agile
principles align with the project's requirements:

31
4.6.1 Iterative Development: The project can be broken down into smaller increments or
iterations, allowing for continuous improvement and feedback throughout the development
process. Features can be implemented incrementally, with regular demonstrations to
stakeholders for feedback and validation.

4.6.2 Collaborative Approach: Agile promotes collaboration among cross-functional teams,


including developers, designers, and stakeholders. In the context of this project, collaboration
is essential between frontend and backend developers, UI/UX designers, and potentially
external stakeholders such as music streaming service providers.

4.6.3 Adaptability to Change: Agile methodologies prioritize adaptability to changing


requirements and priorities. Given the dynamic nature of the music industry and user
preferences, the project needs to be flexible in accommodating new features, enhancements,
and adjustments based on user feedback and market trends.

4.6.4 Customer-Centric Focus: Agile places a strong emphasis on delivering value to the
customer. In this project, the customer-centric focus means prioritizing features and
functionalities that align with user needs and preferences, ensuring a positive user experience.

4.6.5 Continuous Delivery: Agile encourages frequent releases of working software,


allowing for rapid feedback and validation from users. Continuous integration and
deployment practices enable the team to deliver updates and improvements to the
collaborative music playback system efficiently and reliably.

4.6.6 Sprint Planning: The project team conducts regular sprint planning meetings to
prioritize tasks and set goals for each iteration. This ensures that development efforts are
focused on delivering the most valuable features incrementally.

4.6.7 Daily Stand-ups: Daily stand-up meetings are held to provide a forum for team
members to discuss progress, identify any impediments, and coordinate their efforts. These
short, focused meetings help maintain alignment and address any issues promptly.

4.6.8 Iterative Feedback: Agile encourages continuous feedback loops, both from
stakeholders and end-users. Regular demos and reviews allow stakeholders to provide
feedback on the product's features and functionality, facilitating early course correction and
improvement.

32
4.6.9 Empowered Teams: Agile principles promote self-organizing, empowered teams that
take ownership of their work. Team members have the autonomy to make decisions and
adapt to changing requirements, fostering a sense of accountability and commitment to
project success.

4.6.10 Continuous Improvement: Agile embraces a culture of continuous improvement,


where teams reflect on their processes and outcomes at the end of each iteration.
Retrospective meetings provide an opportunity to identify what went well, what could be
improved, and actionable steps for enhancement in subsequent iterations.

4.6.11 Adaptive Planning: Agile methodologies recognize that requirements and priorities
may evolve over time. The project plan remains flexible, allowing for adjustments based on
feedback, changes in market conditions, or emerging opportunities.

4.6.12 Transparency and Communication: Agile promotes transparency and open


communication within the project team and with stakeholders. Regular progress updates,
clear documentation, and collaboration tools facilitate effective communication and
alignment of objectives.

33
4. SYSTEM DESIGN AND SPECIFICATIONS
The system design and specifications for this project outline the architecture, components,
and functionality of the collaborative music playback system. Here's an overview:

❖ Architecture:

 The system follows a client-server architecture, where the server hosts the backend
logic and data storage, while the client interacts with the user through a web-based
interface.

 Backend components include Django framework for server-side logic, Spotify API
integration for music playback functionality, and a PostgreSQL database for storing
user data and room information.

 Frontend components utilize React.js for building interactive user interfaces and
managing state.

❖ Components:

 Backend Components:

• Django REST framework for building RESTful APIs to handle user


authentication, room management, music playback control, and voting.

• Spotify API integration for authenticating users, accessing music catalogs,


controlling playback, and retrieving song information.

• PostgreSQL database for storing user profiles, room details, playback history, and
voting data.

 Frontend Components:

• React.js for building modular UI components, managing state, and handling user
interactions.

• Material-UI library for designing responsive and visually appealing user interfaces.

• React Router for client-side routing to navigate between different views within the
application.

34
❖ Functionality:

 User Authentication: Users can log in to the system using their Spotify accounts to
access the collaborative music playback features.

 Room Management: Hosts can create a room and generate a unique code that other
users can use to join the room. Hosts can also set room preferences such as playback
control permissions and voting requirements.

 Music Playback: Users can play, pause, skip tracks, and adjust playback volume
within the room. Playback control permissions are determined by the host's settings.

 Synchronization: Playback is synchronized across all connected users in the same


room to ensure a consistent listening experience.

 Voting System: Users can vote to skip tracks, and tracks are skipped when the
required number of votes is reached.

 Real-time Updates: Hosts can update playback control settings and voting
requirements in real-time, reflecting changes immediately for all users in the room.

❖ Specifications:

 System supports concurrent user sessions with efficient handling of authentication and
session management.

 Integration with Spotify API ensures seamless access to music catalogs, playback
control, and user authentication.

 Web-based interface is responsive, user-friendly, and accessible across different


devices and screen sizes.

 Backend APIs follow RESTful principles, with clear endpoints, request/response


formats, and error handling mechanisms.

 Data storage and retrieval operations are optimized for performance and scalability,
ensuring smooth operation even under high user loads.

35
❖ SOFTWARE DESIGN

In designing the software following principles are followed:

 Modularity and partitioning: Software is designed such that, each system should
consists of hierarchy of modules and serve to partition into separate function.

 Coupling: Modules should have little dependence on other modules of a system.

 Cohesion: Modules should carry out in a single processing function.

 Shared use: Avoid duplication by allowing a single module be called by other that
need the function it provides.

❖ MODULE DESIGN

The major modules of the project are:

 Home Module

 Spotify Login Module

 Create Room Module

 Join Room Module

 Update Room Module

 Music Player Module

 Home Module:

 Displays the home page of the application.

 Provides options for users to create or join rooms..

 Includes features for browsing and searching for existing rooms.

 Spotify Login Module:

 Integrates Spotify authentication for user login.

36
 Handles the OAuth flow for obtaining user authorization.

 Retrieves user profile information and access tokens for Spotify API interaction.

 Create Room Module:

 Allows authenticated users to create new rooms.

 Generates a unique room code for each created room.

 Sets room preferences such as playback control and voting options.

 Join Room Module:

 Enables users to join existing rooms using room codes.

 Validates room codes and grants access to authorized users.

 Provides feedback on successful or failed room joining attempts.

 Update Room Module:

 Facilitates room settings updates by the host.

 Allows hosts to modify playback control permissions, voting rules, etc.

 Ensures that only authorized hosts can update room settings.

 Music Player Module:

 Displays information about the currently playing song, including the title, artist,
album cover, playback progress, and voting details.

 Users can interact with the music player through buttons such as play, pause, and
skip. These buttons trigger actions to control the playback accordingly.

 It also displays the number of votes each song has received for skipping

 Allows users to vote on whether to skip the current track.

37
❖ DATABASE DESIGN

 MODEL NAME: Room


Field name Data Type
code CharField
host CharField
guest_can_pause BooleanField
votes_to_skip IntegerField
created_at DateTimeField
current_song CharField

 MODEL NAME: SpotifyToken


Field name Data Type
user CharField
created_at DateTimeField
refresh_token CharField
access_token CharField
expires_in DateTimeField
token_type CharField

 MODEL NAME: Vote


Field name Data Type
user CharField
created_at DateTimeField
song_id CharField
room CharField

38
❖ INPUT/OUTPUT DESIGN

 Input Design
The input design for the collaborative music playback system involves defining how
users interact with the application to input commands, preferences, and data. Here's an
overview of the input design:

o User Interface (UI):

 The UI includes various input elements such as text fields, buttons, dropdowns,
and sliders.

 Users interact with these elements to perform actions like logging in, creating
rooms, joining rooms, controlling playback, and voting on tracks.

o Authentication Inputs:

 Input fields for users to enter their login credentials (username/email and
password) during the authentication process.

 OAuth login buttons to initiate authentication with third-party services like


Spotify.

o Room Creation Inputs:

 Text fields for specifying room preferences such as room name, playback
control permissions, and voting rules.

 Buttons to confirm room creation and submit the preferences.

o Room Joining Inputs:

 Text field for entering the room code when joining an existing room.

 Button to submit the room code and join the room.

o Room Update Inputs:

 Input fields or dropdowns to adjust room settings such as playback control


permissions, voting thresholds, and other configurations.

 Buttons to apply the changes and update the room settings.

39
o Playback Control Inputs:

 Playback control buttons for playing, pausing, skipping tracks, adjusting


volume, and seeking within tracks.

 Slider or input field for controlling volume level.

o Voting Inputs:

 Voting buttons or checkboxes displayed during track playback to allow users to


vote on track skipping.

 Feedback messages indicating the status of the vote .

 Output Design
The output design of the project involves presenting information and feedback to
users based on their interactions with the system. Here's an overview of the output
design elements in our collaborative music playback system:

 User Interface: The system provides a user-friendly interface using React and
Material-UI components. It includes screens for different functionalities like
home, room creation, room joining, music playback, and settings.

 Room Information: Upon joining a room or creating a new one, users see
relevant information such as the room code, current song details, playback
controls, and voting status.

 Music Playback: The output design includes a music player interface with
controls for play, pause, and skip. It also displays the current song's title, artist,
album cover, playback progress, and voting details.

 Real-time Updates: Users receive real-time updates on song changes,


playback status, and voting results. This ensures that everyone in the room
stays synchronized with the latest information.

40
5.1 DATA MODEL(LIKE DFD)

A Data Flow Diagram (DFD) is a traditional visual representation of the information flows
within a system. A neat and clear DFD can depict the right amount of the system requirement
graphically. It can be manual, automated, or a combination of both.

It shows how data enters and leaves the system, what changes the information, and where
data is stored.

The objective of a DFD is to show the scope and boundaries of a system as a whole. It may
be used as a communication tool between a system analyst and any person who plays a part
in the order that acts as a starting point for redesigning a system. The DFD is also called as a
data flow graph or bubble chart.

Data Flow Diagrams are of two types:

1) Physical Data Flow Diagrams: These are implementation-dependent i.e.,


they show the actual devices, departments, people, etc., involved in the
system.
2) Logical Data Flow Diagrams: These diagrams describe the system
independently of how it is actually implemented, they show what takes
places, rather than how an activity is accomplished.
Standard Symbol of DFD
➢ Data Flow: Data move in a specific direction from an origin to destination. The
data flow is a “packet” of data.

➢ Process: People, procedures or devices that produce data. The physical


component is not identified.

41
➢ Source or Destination of Data: External sources or destinations of data, which
may be people or organizations or other entities.

➢ Data Source: Here a process references the data in the system.

5.1.1 LEVEL 0 DFD


This is the highest-level DFD, which provides an overview of the entire system. It shows
the major processes, data flows, and data stores in the system, without providing any details
about the internal workings of these processes.

It is also known as a context diagram. It’s designed to be an abstraction view, showing the
system as a single process with its relationship to external entities. It represents the entire
system as a single bubble with input and output data indicated by incoming/outgoing
arrows.

42
5.1.2 Level 1 DFD
This level provides a more detailed view of the system by breaking down the major
processes identified in the level 0 DFD into sub-processes. Each sub-process is depicted as
a separate process on the level 1 DFD. The data flows and data stores associated with each
sub-process are also shown.

In 1-level DFD, the context diagram is decomposed into multiple bubbles/processes. In this
level, we highlight the main functions of the system and breakdown the high-level process
of 0-level DFD into subprocesses.

43
5.2 ENTITY RELATIONSHIP MODEL
ER model stands for an Entity-Relationship model. It is a high-level data model. This model
is used to define the data elements and relationship for a specified system.

It develops a conceptual design for the database. It also develops a very simple and easy to
design view of data.

In ER modeling, the database structure is portrayed as a diagram called an entity-relationship


diagram.

5.3 USE CASE DIAGRAM


A Use Case Diagram is a type of Unified Modeling Language (UML) diagram that
represents the interaction between actors (users or external systems) and a system under
consideration to accomplish specific goals. It provides a high-level view of the system’s
functionality by illustrating the various ways users can interact with it.

44
5.4 CLASS DIAGRAM
Class diagrams are a type of UML (Unified Modeling Language) diagram used in software
engineering to visually represent the structure and relationships of classes within a system
i.e. used to construct and visualize object-oriented systems.

45
Class diagrams provide a high-level overview of a system’s design, helping to
communicate and document the structure of the software. They are a fundamental tool in
object-oriented design and play a crucial role in the software development lifecycle.

46
5.5 STATE DIAGRAM/SEQUENCE DIAGRAM
A sequence diagram shows process interactions arranged in time sequence. This diagram
depicts the processes and objects involved and the sequence of messages exchanged as
needed to carry out the functionality.

47
5. SOURCE CODE
6.1 HTML template that provides structure to the application

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>Tune Troop</title>

{% load static %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<link

rel="stylesheet"

href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"

/>

<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"

/>

</head>

<body>

<div id="gradient">

<div id="main">

<div id="app"></div>

</div>

</div>

<script src="{% static "frontend/main.js" %}"></script>

</body>

</html>

48
6.2 CSS for styling
html,

body {

height: 100%;

margin: 0;

padding: 0;

#main {

position: fixed;

width: 100%;
height: 100%;

left: 0;

top: 0;

#app {

width: 100%;

height: 100%;

.center {

position: absolute;

top: 50%;
left: 50%;

transform: translate(-50%, -50%);

#gradient {

49
width: 100%;

height: 800px;

padding: 0px;

margin: 0px;

6.3 JavaScript to dynamically update the background


import App from "./components/App";

var colors = new Array(

[62,35,255],

[60,255,60],

[255,35,98],

[45,175,230],

[255,0,255],

[255,128,0]);

var step = 0;

//color table indices for:

// current color left

// next color left

// current color right

// next color right

var colorIndices = [0,1,2,3];

//transition speed

var gradientSpeed = 0.002;

function updateGradient()

50
{

if ( $===undefined ) return;

var c0_0 = colors[colorIndices[0]];

var c0_1 = colors[colorIndices[1]];

var c1_0 = colors[colorIndices[2]];

var c1_1 = colors[colorIndices[3]];

var istep = 1 - step;

var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);

var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);

var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);

var color1 = "rgb("+r1+","+g1+","+b1+")";

var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);

var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);

var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);

var color2 = "rgb("+r2+","+g2+","+b2+")";

$('#gradient').css({

background: "-webkit-gradient(linear, left top, right top, from("+color1+"),


to("+color2+"))"}).css({

background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});

step += gradientSpeed;

if ( step >= 1 )

step %= 1;

51
colorIndices[0] = colorIndices[1];

colorIndices[2] = colorIndices[3];

//pick two new target color indices

//do not pick the same as the current one

colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

setInterval(updateGradient,10);

6.4 Creation of Django model ‘Room’


from django.db import models

import string

import random

def generate_unique_code():

length = 6

while True:

code = ''.join(random.choices(string.ascii_uppercase, k=length))

if Room.objects.filter(code=code).count() == 0:

break

return code

52
class Room(models.Model):

code = models.CharField(

max_length=8, default=generate_unique_code, unique=True)

host = models.CharField(max_length=50, unique=True)

guest_can_pause = models.BooleanField(null=False, default=False)

votes_to_skip = models.IntegerField(null=False, default=1)

created_at = models.DateTimeField(auto_now_add=True)

current_song = models.CharField(max_length=50, null=True)

6.5 Creation of serializers for the ‘Room’ model in the Django REST
Framework
from rest_framework import serializers

from .models import Room

class RoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('id', 'code', 'host', 'guest_can_pause',

'votes_to_skip', 'created_at')

class CreateRoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('guest_can_pause', 'votes_to_skip')

class UpdateRoomSerializer(serializers.ModelSerializer):

code = serializers.CharField(validators=[])

53
class Meta:

model = Room
fields = ('guest_can_pause', 'votes_to_skip', 'code')

6.6 Django views for handling room-related operations


from django.shortcuts import render

from rest_framework import generics, status

from .serializers import RoomSerializer, CreateRoomSerializer, UpdateRoomSerializer

from .models import Room

from rest_framework.views import APIView

from rest_framework.response import Response

from django.http import JsonResponse

class RoomView(generics.ListAPIView):

queryset = Room.objects.all()

serializer_class = RoomSerializer

class GetRoom(APIView):

serializer_class = RoomSerializer

lookup_url_kwarg = 'code'

def get(self, request, format=None):

code = request.GET.get(self.lookup_url_kwarg)

if code != None:

room = Room.objects.filter(code=code)

if len(room) > 0:

data = RoomSerializer(room[0]).data

data['is_host'] = self.request.session.session_key == room[0].host

54
return Response(data, status=status.HTTP_200_OK)

return Response({'Room Not Found': 'Invalid Room Code.'},


status=status.HTTP_404_NOT_FOUND)

return Response({'Bad Request': 'Code paramater not found in request'},


status=status.HTTP_400_BAD_REQUEST)

class JoinRoom(APIView):

lookup_url_kwarg = 'code'

def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

code = request.data.get(self.lookup_url_kwarg)

if code != None:

room_result = Room.objects.filter(code=code)

if len(room_result) > 0:

room = room_result[0]

self.request.session['room_code'] = code

return Response({'message': 'Room Joined!'}, status=status.HTTP_200_OK)

return Response({'Bad Request': 'Invalid Room Code'},


status=status.HTTP_400_BAD_REQUEST)

return Response({'Bad Request': 'Invalid post data, did not find a code key'},
status=status.HTTP_400_BAD_REQUEST)

class CreateRoomView(APIView):

serializer_class = CreateRoomSerializer

55
def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

host = self.request.session.session_key

queryset = Room.objects.filter(host=host)

if queryset.exists():

room = queryset[0]

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

else:

room = Room(host=host, guest_can_pause=guest_can_pause,

votes_to_skip=votes_to_skip)
room.save()

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)

return Response({'Bad Request': 'Invalid data...'},


status=status.HTTP_400_BAD_REQUEST)

class UserInRoom(APIView):

56
def get(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

data = {

'code': self.request.session.get('room_code')

return JsonResponse(data, status=status.HTTP_200_OK)

class LeaveRoom(APIView):

def post(self, request, format=None):

if 'room_code' in self.request.session:

self.request.session.pop('room_code')

host_id = self.request.session.session_key

room_results = Room.objects.filter(host=host_id)

if len(room_results) > 0:

room = room_results[0]

room.delete()

return Response({'Message': 'Success'}, status=status.HTTP_200_OK)

class UpdateRoom(APIView):

serializer_class = UpdateRoomSerializer

def patch(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

57
if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

code = serializer.data.get('code')

queryset = Room.objects.filter(code=code)
if not queryset.exists():

return Response({'msg': 'Room not found.'},


status=status.HTTP_404_NOT_FOUND)

room = queryset[0]

user_id = self.request.session.session_key

if room.host != user_id:

return Response({'msg': 'You are not the host of this room.'},


status=status.HTTP_403_FORBIDDEN)

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

return Response({'Bad Request': "Invalid Data..."},


status=status.HTTP_400_BAD_REQUEST)

6.7 URL Patterns for routing HTTP requests


from django.urls import path

from .views import RoomView, CreateRoomView, GetRoom, JoinRoom, UserInRoom,


LeaveRoom, UpdateRoom

58
urlpatterns = [

path('room', RoomView.as_view()),

path('create-room', CreateRoomView.as_view()),

path('get-room', GetRoom.as_view()),

path('join-room', JoinRoom.as_view()),

path('user-in-room', UserInRoom.as_view()),

path('leave-room', LeaveRoom.as_view()),

path('update-room', UpdateRoom.as_view())

6.8 Root Component of React application


import React, { Component } from "react";

import { render } from "react-dom";

import HomePage from "./HomePage";

export default class App extends Component {

constructor(props) {
super(props);

render() {

return (

<div className="center">

<HomePage />

</div>

);

59
const appDiv = document.getElementById("app");

render(<App />, appDiv);

6.9 Main Page of the application


import React, { Component } from 'react';
import RoomJoinPage from './RoomJoinPage';
import CreateRoomPage from './CreateRoomPage';

import { Grid, Button, ButtonGroup, Typography } from '@mui/material';

import { BrowserRouter as Router, Routes, Route, Link, Redirect, Navigate } from 'react-
router-dom';

import Room from './Room';

export default class HomePage extends Component{

constructor(props){

super(props);

this.state={

roomCode: null,

};

this.clearRoomCode=this.clearRoomCode.bind(this);

async componentDidMount(){

fetch('/api/user-in-room')

.then((response)=>response.json()).

then((data)=>{

this.setState({

roomCode:data.code,

});

});

60
}

renderHomePage(){

if(this.state.roomCode){

return(

<Navigate to={`/room/${this.state.roomCode}`} replace={true}/>

);

}else{

return(

<Grid container spacing={3}>

<Grid item xs={12} align="center">

<Typography variant='h3' compact='h3'>

Tune Troop

</Typography>

</Grid>

<Grid item xs={12} align="center">

<ButtonGroup disableElevation variant='contained' color='primary'>

<Button color='secondary' to='/create' component={Link}>

Create a Room

</Button>

<Button color='primary' to='/join' component={Link}>

Join a Room
</Button>

</ButtonGroup>

</Grid>

</Grid>

);

61
clearRoomCode(){

this.setState({

roomCode:null,

});

render(){

return (<Router>

<Routes>

<Route path="/" element={this.renderHomePage()}

/>

<Route path="/join" element={<RoomJoinPage/>}></Route>

<Route path="/create" element={<CreateRoomPage/>}></Route>

<Route path="/room/:roomCode" element={<Room


clearRoomCodeCallback={this.clearRoomCode}/>}>

</Route>

</Routes>

</Router>);

6.10 Create or Update Room Component


import React, { Component, useState } from "react";
import { Button } from "@mui/material";

import {Grid} from "@mui/material";

import {Typography} from "@mui/material";

import { TextField } from "@mui/material";

62
import {FormHelperText} from "@mui/material";

import {FormControl} from "@mui/material";

import {Link} from "react-router-dom";

import {Radio} from "@mui/material";

import {RadioGroup} from "@mui/material";

import {FormControlLabel} from "@mui/material";

import { useNavigate } from "react-router-dom";

import {Collapse} from "@mui/material"

import Alert from "@mui/material/Alert";

function CreateRoomPage(props){

const navigate=useNavigate();

const[guestCanPause,setguestCanPause]=useState(props.guestCanPause);

const[votesToSkip,setgvotesToSkip]=useState(props.votesToSkip);

const[errorMsg,setErrorMsg]=useState("");

const[successMsg,setSuccessMsg]=useState("");

const handleVotesChange=()=>{

setgvotesToSkip(event.target.value);

};

const handleGuestCanPauseChange=()=>{

setguestCanPause(event.target.value==="true"?true:false);

};

const handleRoomButtonPressed=()=>{

const requestOptions = {

method: 'POST',

63
headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

}),

};

fetch('/api/create-room', requestOptions)

.then((response)=>response.json())

.then((data)=> navigate("/room/"+ data.code));

};

const handleUpdateButtonPressed=()=>{

const requestOptions = {

method: 'PATCH',

headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

code:props.roomCode,

}),

};

fetch('/api/update-room', requestOptions)

.then((response)=>{

if(response.ok){

setSuccessMsg("Room updated successfully!");

}else{

setErrorMsg("Error updating room");

props.updateCallback();

64
});

};

const renderCreateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleRoomButtonPressed}>Create A Room</Button>

</Grid>

<Grid item xs={12} align="center">

<Button color="secondary" variant="contained" to="/"


component={Link}>Back</Button>

</Grid>

</Grid>

);

};

const renderUpdateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleUpdateButtonPressed}>Update Room</Button>

</Grid>

</Grid>

);

};

65
const title=props.update? "Update Room" : "Create a Room";

return (

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Collapse in={errorMsg!="" || successMsg!=""}>

{successMsg!=""?(

<Alert

severity="success"

onClose={()=>{

setSuccessMsg("");

}}>

{successMsg}

</Alert>

):(

<Alert

severity="error"

onClose={()=>{

setErrorMsg("");
}}>

{errorMsg}

</Alert>

)}

</Collapse>

</Grid>

<Grid item xs={12} align="center">

<Typography component='h4' variant='h4'>

{title}

</Typography>

66
</Grid>

<Grid item xs={12} align="center">

<FormControl component="fieldset">

<FormHelperText component="div">

<div align='center'>Guest Control of Playback State</div>

</FormHelperText>

<RadioGroup row defaultValue={props.guestCanPause.toString()}


onChange={handleGuestCanPauseChange}>

<FormControlLabel value="true" control={<Radio color="primary"></Radio>}


label="Play/Pause"
labelPlacement="bottom"></FormControlLabel>

<FormControlLabel value="false" control={<Radio color="secondary"></Radio>}


label="No Control"

labelPlacement="bottom"></FormControlLabel>

</RadioGroup>

</FormControl>

</Grid>

<Grid item xs={12} align="center">

<FormControl>

<TextField required={true} type="number" onChange={handleVotesChange}


defaultValue={votesToSkip}

inputProps={{min:1, style:{textAlign:"center"},}}></TextField>

<FormHelperText component="div">

<div align="center">

Votes Required To Skip Song

</div>

</FormHelperText>

</FormControl>

67
</Grid>

{props.update?renderUpdateButtons(): renderCreateButtons()}

</Grid>

);

CreateRoomPage.defaultProps={

votesToSkip:2,

guestCanPause:true,

update: false,

roomCode:null,

updateCallback:()=>{},

};

export default CreateRoomPage;

6.11 Room Join Component


import React, {useState, Component } from 'react';

import { TextField, Button, Grid, Typography } from '@mui/material';

import { Link } from "react-router-dom";

import {useNavigate} from "react-router-dom";

export default function RoomJoinPage(props){

const navigate=useNavigate();

const[roomCode, setroomCode]=useState('');

const[errorMsg,seterrorMsg]=useState('');

const[error,seterror]=useState(false);

const handleTextFieldChange=()=>{

68
setroomCode(event.target.value);

};

const roomButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

body:JSON.stringify({

code:roomCode,

}),

};

fetch("/api/join-room",requestOptions).

then((response)=>{

if(response.ok){

navigate("/room/"+ roomCode)

}else{

seterror(true);

seterrorMsg("Room not found");


}

})

.catch((error)=>{

console.log(error);

});

};

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant="h4" component="h4">

Join a Room

69
</Typography>

</Grid>

<Grid item xs={12} align="center">

<TextField

error={error}

label="Code"

placeholder='Enter a Room Code'

value={roomCode}

helperText={errorMsg}

variant='outlined'

onChange={handleTextFieldChange}>

</TextField>

</Grid>

<Grid item xs={12} align="center">

<Button

variant='contained'

color='primary'

onClick={roomButtonPressed}>

Enter Room

</Button>

</Grid>

<Grid item xs={12} align="center">

<Button variant='contained'

color='secondary' to="/" component={Link}>

Back

</Button>

</Grid>

</Grid>

70
);

6.12 Room Component


import React, {useState, useEffect} from 'react';

import {useParams,Navigate} from "react-router-dom";

import {Grid, Button, Typography} from '@mui/material';

import {useNavigate} from "react-router-dom";

import CreateRoomPage from './CreateRoomPage';

import MusicPlayer from './MusicPlayer';

function Room(props){

const navigate=useNavigate();

const{roomCode}=useParams()

const initialState={

votesToSkip:2,

guestCanPause:false,

isHost:false,

showSettings: false,

spotifyAuthenticated: false,

song:{},
}

const[roomData, setRoomData]=useState(initialState)

useEffect(() => {

getRoomDetails();

const interval=setInterval(getCurrentSong, 1000);

return ()=>clearInterval(interval);

},[roomCode]);

71
const getRoomDetails = () => {

fetch("/api/get-room" + "?code=" + roomCode)

.then((response) => {

if (!response.ok) {

props.clearRoomCodeCallback();

navigate("/");

return response.json();

})

.then((data) => {

setRoomData(prevState=>({

...prevState,

votesToSkip: data.votes_to_skip,

guestCanPause: data.guest_can_pause,

isHost: data.is_host

}));

if(data.is_host){

authenticateSpotify();

});

};

const authenticateSpotify=()=>{

fetch("/spotify/is-authenticated")

.then((response) => response.json())

.then((data) => {

setRoomData(prevState=>({...prevState, spotifyAuthenticated: data.status }));

console.log(data.status);

if (!data.status) {

72
fetch("/spotify/get-auth-url")

.then((response) => response.json())

.then((data) => {

window.location.replace(data.url);

});

});

};

const getCurrentSong = () => {

fetch('/spotify/current-song')

.then((response) => {

if (!response.ok) {

return {};

} else {

return response.json();

})

.then((data) => {

setRoomData(prevState => ({ ...prevState, song: data }));

console.log(data);
});

};

const leaveButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

};

73
fetch('/api/leave-room',requestOptions).

then((response)=>{

props.clearRoomCodeCallback();

navigate('/');

});

};

const updateShowSettings=(value)=>{

setRoomData({

...roomData,

showSettings:value,

});

};

const renderSettings=()=>{

return(
<Grid container spacing={1}>

<Grid item xs={12} align="center">

<CreateRoomPage

update={true}

votesToSkip={roomData.votesToSkip}

guestCanPause={roomData.guestCanPause}

roomCode={roomCode}

updateCallback={getRoomDetails}

getRoomDetails={getRoomDetails}
/>

</Grid>

<Grid item xs={12} align="center" >

<Button

74
variant='contained'

color='secondary'
onClick={()=>updateShowSettings(false)}

>

Close

</Button>

</Grid>

</Grid>

);

};

const renderSettingsButton=()=>{

return(

<Grid item xs={12} align="center">

<Button variant='contained' color='primary'


onClick={()=>updateShowSettings(true)}>

Settings

</Button>

</Grid>

);

};

return roomData.showSettings?(

renderSettings()

):(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant='h4' component='h4'>

75
Code:{roomCode}

</Typography>

</Grid>

<MusicPlayer {...roomData.song}/>

{roomData.isHost?renderSettingsButton():null}

<Grid item xs={12} align="center">

<Button variant="contained" color='secondary' onClick={leaveButtonPressed}>

Leave Room

</Button>

</Grid>

</Grid>

export default Room

6.13 Music Player Component


import React, { useState } from "react";
import {

Grid,

Typography,

Card,

IconButton,

LinearProgress,

} from '@mui/material';

import { Pause, PlayArrowRounded, SkipNext } from '@mui/icons-material';

const MusicPlayer = (props) => {

const skipSong = () => {

76
const requestOptions = {

method: "POST",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/skip", requestOptions);

};

const pauseSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/pause", requestOptions);

};

const playSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/play", requestOptions);

};

const songProgress = (props.time / props.duration) * 100;

return (

<Card>

<Grid container alignItems="center">

<Grid item align="center" xs={4}>

<img src={props.image_url} height="100%" width="100%" alt="song cover" />

</Grid>

77
<Grid item align="center" xs={8}>

<Typography component="h5" variant="h5">

{props.title}

</Typography>

<Typography color="textSecondary" variant="subtitle1">

{props.artist}

</Typography>

<div>

<IconButton onClick={()=>{props.is_playing? pauseSong(): playSong()}}>

{props.is_playing ? <Pause></Pause> :
<PlayArrowRounded></PlayArrowRounded>}

</IconButton>

<IconButton onClick={()=>skipSong()}>

{props.votes}/{" "}{props.votes_required}

<SkipNext></SkipNext>

</IconButton>

</div>

</Grid>

</Grid>

<LinearProgress variant="determinate" value={songProgress} />

</Card>

);

};

export default MusicPlayer;

78
6.14 Django model for storing Spotify authentication tokens and user votes
from django.db import models

from api.models import Room

class SpotifyToken(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

refresh_token = models.CharField(max_length=150)

access_token = models.CharField(max_length=150)

expires_in = models.DateTimeField()

token_type = models.CharField(max_length=50)

class Vote(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

song_id = models.CharField(max_length=50)

room = models.ForeignKey(Room, on_delete=models.CASCADE)

6.15 Credentials for authentication with Spotify API


CLIENT_ID = "08cb230a331944c7bfa503dfc73dd46c"
CLIENT_SECRET = "f78338ef85e74cf2be80970a90406b69"

REDIRECT_URI = "http://127.0.0.1:8000/spotify/redirect"

6.16 Django views for handling music player operations


from django.shortcuts import render, redirect

from .credentials import REDIRECT_URI, CLIENT_SECRET, CLIENT_ID

from rest_framework.views import APIView

from requests import Request, post

from rest_framework import status

79
from rest_framework.response import Response

from .util import *

from api.models import Room

from .models import Vote

class AuthURL(APIView):

def get(self, request, fornat=None):

scopes = 'user-read-playback-state user-modify-playback-state user-read-currently-


playing'

url = Request('GET', 'https://accounts.spotify.com/authorize', params={

'scope': scopes,

'response_type': 'code',

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID

}).prepare().url

return Response({'url': url}, status=status.HTTP_200_OK)

def spotify_callback(request, format=None):

code = request.GET.get('code')

error = request.GET.get('error')

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'authorization_code',

'code': code,

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

80
}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

refresh_token = response.get('refresh_token')

expires_in = response.get('expires_in')
error = response.get('error')

if not request.session.exists(request.session.session_key):

request.session.create()

update_or_create_user_tokens(

request.session.session_key, access_token, token_type, expires_in, refresh_token)

return redirect('frontend:')

class IsAuthenticated(APIView):

def get(self, request, format=None):

is_authenticated = is_spotify_authenticated(
self.request.session.session_key)

return Response({'status': is_authenticated}, status=status.HTTP_200_OK)

class CurrentSong(APIView):

def get(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)

if room.exists():

room = room[0]

else:

81
return Response({}, status=status.HTTP_404_NOT_FOUND)

host = room.host
endpoint = "player/currently-playing"

response = execute_spotify_api_request(host, endpoint)

if 'error' in response or 'item' not in response:

return Response({}, status=status.HTTP_204_NO_CONTENT)

item = response.get('item')

duration = item.get('duration_ms')

progress = response.get('progress_ms')

album_cover = item.get('album').get('images')[0].get('url')

is_playing = response.get('is_playing')

song_id = item.get('id')

artist_string = ""

for i, artist in enumerate(item.get('artists')):

if i > 0:

artist_string += ", "

name = artist.get('name')

artist_string += name

votes = len(Vote.objects.filter(room=room, song_id=song_id))

song = {

'title': item.get('name'),

'artist': artist_string,

'duration': duration,

'time': progress,

82
'image_url': album_cover,

'is_playing': is_playing,

'votes': votes,

'votes_required': room.votes_to_skip,

'id': song_id

self.update_room_song(room, song_id)

return Response(song, status=status.HTTP_200_OK)

def update_room_song(self, room, song_id):

current_song = room.current_song

if current_song != song_id:

room.current_song = song_id

room.save(update_fields=['current_song'])
votes = Vote.objects.filter(room=room).delete()

class PauseSong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

pause_song(room.host)

return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

83
class PlaySong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

play_song(room.host)
return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

class SkipSong(APIView):

def post(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

votes = Vote.objects.filter(room=room, song_id=room.current_song)

votes_needed = room.votes_to_skip

if self.request.session.session_key == room.host or len(votes) + 1 >= votes_needed:

votes.delete()

skip_song(room.host)

else:

vote = Vote(user=self.request.session.session_key,

room=room, song_id=room.current_song)

vote.save()

return Response({}, status.HTTP_204_NO_CONTENT)

84
6.17 To handle Spotify authentication and integration using Spotify API
from .models import SpotifyToken

from django.utils import timezone

from datetime import timedelta

from .credentials import CLIENT_ID, CLIENT_SECRET

from requests import post, put, get

BASE_URL = "https://api.spotify.com/v1/me/"

def get_user_tokens(session_id):

user_tokens = SpotifyToken.objects.filter(user=session_id)

if user_tokens.exists():

return user_tokens[0]

else:

return None

def update_or_create_user_tokens(session_id, access_token, token_type, expires_in,


refresh_token):

tokens = get_user_tokens(session_id)

expires_in = timezone.now() + timedelta(seconds=expires_in)

if tokens:

tokens.access_token = access_token

tokens.refresh_token = refresh_token

tokens.expires_in = expires_in

tokens.token_type = token_type

tokens.save(update_fields=['access_token',
'refresh_token', 'expires_in', 'token_type'])

85
else:

tokens = SpotifyToken(user=session_id, access_token=access_token,

refresh_token=refresh_token, token_type=token_type,
expires_in=expires_in)

tokens.save()

def is_spotify_authenticated(session_id):

tokens = get_user_tokens(session_id)

if tokens:

expiry = tokens.expires_in

if expiry <= timezone.now():

refresh_spotify_token(session_id)

return True

return False

def refresh_spotify_token(session_id):

refresh_token = get_user_tokens(session_id).refresh_token

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'refresh_token',

'refresh_token': refresh_token,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

86
expires_in = response.get('expires_in')

update_or_create_user_tokens(

session_id, access_token, token_type, expires_in, refresh_token)

def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):

tokens = get_user_tokens(session_id)

headers = {'Content-Type': 'application/json',

'Authorization': "Bearer " + tokens.access_token}

if post_:

post(BASE_URL + endpoint, headers=headers)

if put_:

put(BASE_URL + endpoint, headers=headers)

response = get(BASE_URL + endpoint, {}, headers=headers)

try:

return response.json()

except:
return {'Error': 'Issue with request'}

def play_song(session_id):

return execute_spotify_api_request(session_id, "player/play", put_=True)

def pause_song(session_id):

return execute_spotify_api_request(session_id, "player/pause", put_=True)

def skip_song(session_id):

return execute_spotify_api_request(session_id, "player/next", post_=True)

87
6.18 URL patterns for the API views
from django.urls import path

from .views import *

urlpatterns = [

path('get-auth-url', AuthURL.as_view()),

path('redirect', spotify_callback),

path('is-authenticated', IsAuthenticated.as_view()),

path('current-song', CurrentSong.as_view()),

path('pause', PauseSong.as_view()),

path('play', PlaySong.as_view()),

path('skip', SkipSong.as_view())

6.19 URL pattern to include URLS from different parts of the application
from django.contrib import admin

from django.urls import path, include

urlpatterns = [

path('admin/', admin.site.urls),

path('api/', include('api.urls')),

path('', include('frontend.urls')),

path('spotify/', include('spotify.urls'))

88
6. SCREENSHOT

7.1 HOME PAGE

7.2 CREATE ROOM PAGE

89
7.3 SPOTIFY ACCOUNT LOGIN PAGE

7.4 MUSIC PLAYER PAGE FOR HOST

90
7.5 UPDATE ROOM PAGE

7.6 JOIN ROOM PAGE

91
7.5 MUSIC PLAYER PAGE FOR GUEST

92
GIET UNIVERSITY,GUNUPUR
Department of Computer Science & Applications
Dist. - Rayagada, Odisha-765022

CERTIFICATE

This is to certify that the project work entitled “E-COMMERECE


WEB APPLICATION” is done by Bikash Pradhan(22PG030331),
Bipin Kumar Bhadra(22PG030332),Bibhuli kumar
Bholo(22PG030346) in partially fulfils the requirements for the 4th
Semester Examination of Master of Computer Applications during the
academic year 2023-24. This work is submitted to the department as
part of the 4th Semester Major Project evaluation.

Project Supervisor Project Coordinator

External Examiner HOD


Computer Science and Applications
ACKNOWLEDGEMENT

We express our sincere gratitude to Prof. Satya Narayan Das, Head of The Department of
Computer Science and Applications for allowing me to accomplish the project. With his
active support and guidance, this project report has been completed.

We also thank Mr. Ashutosh Mallik our Project Coordinator for guidance and help.

We also thank Mrs. Sucheta Krupalini Moharana our Project Supervisor for guidance and help.

Signature of the Students


Contents

Page Number

Abstract 1

1. Introduction 2-4
1.1 Purpose 2
1.2 Project Scope 2
1.3 Project Features 3-4
2. Literature Review 5-7
3. Problem Statement 8-10
4. System Analysis 11-33
4.1 Identification of Need 11
4.2 Preliminary Investigation 12-13
4.3 Feasibility Study 13 -14
4.4 Project Planning 15-17
4.5 Software Requirement Specifications (SRS) 17-31
4.6 Software Engineering Paradigm Applied 31-33
5. System Design &Specifications 34-47
5.1 Data models (like DFD) 41-43
5.2 Entity Relationship Model 44
5.3 Use-case Diagrams 44-45
5.4 Class Diagrams 45-46
5.5 State Diagrams/Sequence Diagrams 47
6. Source Code 48-88
7. Screenshots 89-92
8. Testing 93-100
8.1 Testing Techniques and Testing Strategies Used Testing Plan used 94-96
8.2 Test Reports for Unit Test Cases and System Test Cases 96-100
9. Conclusion 101-102
10. Future Enhancement 103-105
11. References / Bibliography 106
ABSTRACT

Title: Development of an E-STORE Using Python, D jango, HTML, CSS, and Bootstrap

Abstract:
In today's digital age, online shopping has become increasingly popular, especially for
essential items like groceries. This project aims to develop a comprehensive online
grocery shop using Python, Django, HTML, CSS, and Bootstrap.

The system will provide users with a convenient platform to browse through a wide
range of grocery products, add them to their cart, and securely complete their purchases.
The backend will be powered by Django, a high-level Python web framework, which
will handle user authentication, product management, order processing, and database
interactions.

The frontend will be developed using HTML, CSS, and Bootstrap to create a visually
appealing and responsive user interface. Bootstrap's grid system and components will
ensure that the website is accessible across various devices and screen sizes, providing a
seamless shopping experience for users on desktops, laptops, tablets, and smartphones.

Key features of the online grocery shop will include user registration and login, product
categorization and search functionality, product details and images, shopping cart
management, secure payment processing integration, order tracking, and email
notifications.

Overall, this project aims to leverage modern web development technologies to create
an efficient and user-friendly online grocery shopping platform, catering to the needs of
today's digitally savvy consumers.

1
INTRODUCTION
 PURPOSE :

The purpose of developing an online grocery shop using Python, Django,


HTML, CSS, and Bootstrap is multi-faceted:

1. Convenience: The primary aim is to provide consumers with a convenient


way to purchase groceries from the comfort of their homes. By offering an
online platform, customers can browse, select, and order groceries at any
time, eliminating the need to physically visit a store.
2. Accessibility: An online grocery shop enhances accessibility for
individuals who may have mobility issues or live in remote areas with
limited access to physical stores. They can access a wide range of grocery
products with just an internet connection.
3. Time-saving: By streamlining the shopping process, customers can save
time that would have been spent commuting to and from a store, searching
for items, and waiting in checkout lines. The online platform allows for
quick browsing, searching, and purchasing of products.
4. Product variety: Online grocery shops can offer a broader range of
products compared to traditional brick-and-mortar stores. Customers can
explore a diverse selection of brands, flavors, and specialty items without the
constraints of physical shelf space.
5. Personalization: Through user accounts and preferences tracking, online
grocery shops can offer personalized recommendations and promotions
tailored to individual shopping habits and preferences. This enhances the
shopping experience and encourages customer loyalty.
6. Scalability: By leveraging Python and Django for backend development
and HTML, CSS, and Bootstrap for frontend design, the online grocery shop
can be built to scale. It can accommodate a growing customer base and
expand its offerings and features as needed.

In essence, the purpose of developing an online grocery shop using these


technologies is to create a modern, user-friendly, and efficient platform that
meets the evolving needs of consumers in today's digital landscape.

2
 PROJECT FEATURES :

Here's a breakdown of the project features for the online grocery shop developed using Python,
Django, HTML, CSS, and Bootstrap:
1. User Registration and Authentication:
- Allow users to register with the platform by providing necessary details.
- Implement authentication mechanisms to ensure secure access to user accounts.
- Enable users to log in and log out of their accounts securely.
2. Product Management:
- Provide functionality for administrators to add, edit, and delete grocery products.
- Include fields such as product name, description, price, quantity, and images.
- Implement product categorization and tagging for easy navigation.
3. Browsing and Searching:
- Enable users to browse through the available grocery products conveniently.
- Implement search functionality to allow users to find specific products quickly.
- Provide filtering options based on categories, prices, and other attributes.
4. Shopping Cart Management:
- Allow users to add products to their shopping carts while browsing.
- Provide options to update the quantity or remove items from the cart.
- Display the total cost and summary of items in the shopping cart.
5. Checkout Process:
- Implement a streamlined checkout process for users to complete their purchases.
- Include forms for users to provide shipping and billing information.
- Integrate secure payment gateways for processing transactions (e.g., PayPal, Stripe).

6. Order Tracking and History:

3
1.1.1 Error Handling and Security: Robust error handling mechanisms and security
measures are implemented to ensure data integrity, user privacy, and protection against
unauthorized access.

4
1. LITERATURE REVIEW
Collaborative music playback systems have emerged as a novel way for users to engage with
music in shared listening experiences. These systems enable multiple users to synchronize
their music playback across devices, allowing for collaborative playlist creation, voting on
tracks, and real-time interaction. This literature review aims to provide a comprehensive
overview of existing research and developments in collaborative music playback systems,
focusing on design principles, technical implementations, user experiences, and the social
impact of these systems.

2.1 DESIGN PRINCIPLES AND TECHINCAL IMPLEMENTATION


Research in collaborative music playback systems has explored various design principles and
technical implementations to facilitate seamless synchronization and interaction among users.
One key aspect is the architecture of the system, which may be centralized, decentralized, or
hybrid. Centralized architectures typically rely on a server to manage playback
synchronization and user interactions, while decentralized architectures leverage peer-to-peer
or mesh networking to distribute control among connected devices. Hybrid approaches
combine elements of both centralized and decentralized architectures to optimize
performance and scalability.

In terms of synchronization techniques, real-time algorithms play a crucial role in ensuring


accurate timing alignment between audio streams across devices. These algorithms must
account for factors such as network latency, device processing capabilities, and audio
buffering to deliver a consistent listening experience. Additionally, researchers have
investigated protocols for communication and data exchange between devices, considering
factors like reliability, efficiency, and compatibility with existing standards.

2.2 USER EXPERIENCE AND IINTERFACE DESIGN


User experience (UX) plays a crucial role in the success of collaborative music playback
systems. Studies have investigated various UX factors, such as interface design, interaction
patterns, and social features, to enhance user engagement and satisfaction. Intuitive interfaces
with intuitive controls enable users to navigate, search, and manage playlists effortlessly.
Social features like chat, voting, and collaborative playlist creation foster a sense of
5
community and encourage active participation among users. Furthermore, personalized
recommendations and adaptive interfaces tailor the music listening experience to individual
preferences, enhancing user satisfaction and retention. Adaptive interfaces that adapt to user
behavior, context, and feedback can enhance user satisfaction and retention. Additionally,
accessibility features ensure that the system is inclusive and usable for users with diverse
needs and abilities.

2.3 SOCIAL IMPACT AND USER ENGAGEMENT


Collaborative music playback systems have a significant impact on music consumption habits
and social interactions. Research has shown that shared listening experiences strengthen
social bonds and promote collaborative behaviors among users. Users engage in activities
like co-curating playlists, discovering new music together, and engaging in real-time
interactions like voting on tracks or controlling playback. Moreover, collaborative music
playback systems encourage exploration and serendipitous discovery, exposing users to a
diverse range of musical genres and artists they might not encounter otherwise. This
collaborative discovery process fosters a deeper appreciation for music and cultivates a sense
of belonging within online communities.

2.4 CHALLENGES AND FUTURE DIRECTIONS


Despite the benefits, collaborative music playback systems face several challenges, including
technical constraints, privacy concerns, and scalability issues. Synchronizing playback across
devices while minimizing latency remains a significant challenge, particularly in
heterogeneous network environments with varying bandwidth and latency characteristics.
Moreover, ensuring data privacy and security is crucial, as collaborative music playback
systems often involve sharing personal music preferences and listening habits. Additionally,
scalability becomes a concern as the number of users and concurrent sessions grows,
necessitating robust infrastructure and optimization techniques to handle increasing load and
maintain performance.

Looking ahead, future research directions in collaborative music playback systems may
include exploring novel interaction paradigms, integrating emerging technologies like virtual
reality and spatial audio, and investigating the social and cultural implications of shared

6
listening experiences. Moreover, interdisciplinary collaborations between researchers,
designers, musicians, and industry stakeholders can lead to innovative solutions that redefine
how people discover, share, and enjoy music together in the digital age.

In conclusion, collaborative music playback systems offer exciting opportunities to enhance


social interaction, foster musical discovery, and transform the way people engage with music.
By addressing design challenges, improving user experiences, and exploring new avenues for
innovation, researchers and practitioners can continue to advance the field of collaborative
music playback systems and create meaningful experiences for music enthusiasts worldwide.

7
2. PROBLEM STATEMENT
The problem statement for the project revolves around the need for a collaborative music
playback system that allows multiple users to join a virtual room, synchronize playback, and
control music playback together. Existing music streaming platforms lack real-time
collaboration features, limiting the ability for users to enjoy music together simultaneously.
Therefore, there is a need to develop a platform that enables users to create and join rooms,
interact with other users in real-time, and collectively control music playback. This project
aims to address these limitations by implementing features such as room creation, user
authentication through Spotify, real-time synchronization of playback, and control of
playback features by both hosts and guests.

3.1 KEY CHALLENGES


The key challenges of this project include:

3.1.1 Real-Time Synchronization: Ensuring that all users in a room experience


synchronized music playback without significant latency or delays is crucial. Achieving this
requires efficient data handling and synchronization techniques.

3.1.2 User Authentication and Integration with Spotify API: Integrating user
authentication via Spotify and leveraging the Spotify API to retrieve and control music
playback requires handling OAuth flows securely and managing access tokens effectively.

3.1.3 Room Management and Data Consistency: Managing rooms dynamically, including
creation, joining, and leaving, while maintaining data consistency and integrity across
connected users presents challenges in database design and synchronization.

3.1.4 Playback Control Permissions: Implementing logic to allow hosts to control playback
permissions for guests, such as play, pause, and skip, requires robust authorization
mechanisms.

3.1.5 Real-Time Updates and Notifications: Enabling real-time updates for playback
control and room settings poses challenges in handling WebSocket communications and
ensuring efficient event propagation.

8
3.1.6 Error Handling and Resilience: Implementing robust error handling mechanisms to
address potential failures in API calls, user authentication, or real-time synchronization is
essential for maintaining a seamless user experience.

3.2 SOLUTION REQUIREMENTS


The solution requirements to address the challenges of the project include:

3.2.1 Real-Time Synchronization

• Implement WebSocket communication to enable real-time synchronization of


playback events and updates across all connected users.

• Utilize efficient data structures and algorithms for managing playback state and
ensuring synchronized playback experiences.

3.2.2 User Authentication and Integration with Spotify API

• Implement OAuth 2.0 authentication flow securely to authenticate users with their
Spotify accounts.

• Utilize Spotify API endpoints to retrieve user-specific music data, control playback,
and manage user permissions.

3.2.3 Room Management and Data Consistency

• Design a robust database schema to manage rooms, users, and playback state
efficiently.

• Implement transactional operations and data synchronization mechanisms to ensure


data consistency across connected users.

3.2.4 Playback Control Permissions

• Implement role-based access control (RBAC) mechanisms to manage user roles (host
vs. guest) and permissions for controlling playback.

• Design intuitive user interfaces to allow hosts to manage playback permissions


effectively.

9
3.2.5 Real-Time Updates and Notifications

• Implement WebSocket-based pub-sub systems to propagate real-time updates and


notifications to all connected users.

• Design event-driven architectures to handle and process events related to playback


control, room management, and user interactions.

3.2.6 Error Handling and Resilience

• Implement robust error handling mechanisms to gracefully handle errors and failures
in API calls, authentication flows, and real-time communication.

• Utilize logging and monitoring tools to track and diagnose errors in real-time,
ensuring quick resolution and minimal disruption to the user experience.

10
3. SYSTEM ANALYSIS

4.1 IDENTIFICATION OF NEED


The identification of the need for this project stems from several factors:

4.1.1 Rising Popularity of Music Streaming Platforms

• With the increasing popularity of music streaming services like Spotify, there's a
growing demand for collaborative music playback systems that allow users to listen
to music together in real-time.

4.1.2 Desire for Social Music Listening Experiences

• Many users enjoy listening to music with friends or family members, whether they're
in the same location or miles apart. A collaborative music playback system fulfills
the need for shared music listening experiences.

4.1.3 Enhanced Engagement and Interaction

• Collaborative music playback systems provide an interactive platform where users


can engage with each other while listening to music. It creates opportunities for
social interaction, discussion, and shared enjoyment of music.

4.1.4 Virtual Events and Gatherings

• With the rise of virtual events and gatherings, there's a need for platforms that enable
participants to listen to music together during online parties, virtual hangouts, or
remote celebrations.

4.1.5 Support for Remote Work and Learning

• In remote work and learning environments, collaborative music playback systems can
serve as icebreakers, team-building tools, or background entertainment during
virtual meetings and study sessions.

4.1.6 Customization and Personalization

• Users often have diverse musical preferences and tastes. A collaborative music
playback system allows users to share and discover music based on their individual
preferences, creating personalized listening experiences.

11
4.2 PRELIMINARY INVESTIGATION:
The preliminary investigation of this project involves cconducting initial research and
analysis to gather information and assess the feasibility of the project. It includes the
following steps:

4.2.1 Identifying Stakeholders

• Determine the primary stakeholders involved in the project, including users,


developers, music streaming platforms, and potential collaborators.

4.2.2 Defining Objectives

• Clarify the project's goals and objectives, such as developing a collaborative music
playback system, integrating with the Spotify API, enabling real-time
synchronization of playback, and providing user-friendly interfaces.

4.2.3 Gathering Requirements

• Collect requirements from stakeholders regarding functionality, user experience,


platform compatibility, security, scalability, and other relevant aspects.

4.2.4 Market Analysis

• Conduct a market analysis to understand the current landscape of music streaming


platforms, collaborative music playback systems, and related technologies. Identify
existing solutions, their features, strengths, and weaknesses.

4.2.5 Technical Feasibility

• Assess the technical feasibility of implementing the project, considering factors such
as available resources (e.g., technology stack, development tools), integration with
third-party APIs (e.g., Spotify), and scalability requirements.

4.2.6 Resource Allocation

• Determine the resources needed for the project, including personnel, time, budget,
hardware, and software. Allocate resources effectively to ensure successful project
execution.

12
4.2.7 Risk Assessment

• Identify potential risks and challenges associated with the project, such as technical
complexities, data security concerns, regulatory compliance, and dependencies on
external factors (e.g., API changes).

4.2.8 Cost-Benefit Analysis

• Evaluate the costs and benefits of implementing the project, considering factors such
as development costs, potential revenue streams, market demand, competitive
advantage, and long-term sustainability.

4.3 FEASIBILITY STUDY


A feasibility study for this project would involve evaluating various aspects to determine if
the project is viable and achievable. Here's how it can be approached:

4.3.1 Technical Feasibility

• Assess the technical requirements of integrating with the Spotify API and
implementing real-time synchronization of playback across multiple users.

• Evaluate the compatibility of chosen technologies (Python, Django, React) with the
project requirements.

• Determine if the project can be implemented within the constraints of available


technology stack and development resources.

4.3.2 Financial Feasibility

• Estimate the costs associated with development, including personnel, infrastructure,


software licenses, and any third-party services (such as hosting or Spotify API
access).

• Compare the projected costs with the budget allocated for the project to ensure
financial viability.

• Consider potential revenue streams, such as subscription fees, in-app purchases, or


advertising, to offset development costs.

13
4.3.3 Operational Feasibility

• Evaluate the operational aspects of the project, including how it will be managed,
maintained, and supported post-launch.

• Assess the availability of skilled personnel to develop, deploy, and maintain the
application.

• Consider scalability requirements and whether the project can accommodate growth
in user base and usage over time.

4.3.4 Legal and Regulatory Feasibility

• Identify any legal or regulatory requirements related to music streaming, user data
privacy, copyright, and licensing.

• Ensure compliance with relevant laws and regulations to avoid legal issues and
penalties.

4.3.5 Market Feasibility

• Analyze the market demand for collaborative music playback systems and the
potential user base for the application.

• Identify competitors and assess their offerings, strengths, and weaknesses.

• Determine if the project fills a gap in the market and offers unique features or
advantages compared to existing solutions.

4.3.6 Schedule Feasibility:

• Develop a realistic timeline for project development, testing, and deployment.

• Consider any dependencies, constraints, or risks that may impact the project schedule.

• Ensure that the proposed timeline aligns with stakeholders' expectations and business
objectives.

14
4.4 PROJECT PLANNING
Project planning for this collaborative music playback system involves organizing tasks,
allocating resources, and establishing timelines to ensure successful development and
deployment. Here's an outline of the project planning process:

4.4.1 Define Project Scope and Objectives

• Clearly articulate the goals and objectives of the project, including the features and
functionality of the collaborative music playback system.

• Define the target audience and user requirements to guide development.

4.4.2 Create Work Breakdown Structure (WBS)

• Break down the project into smaller, manageable tasks and subtasks.

• Organize tasks into a hierarchical structure to facilitate planning and resource


allocation.

4.4.3 Estimate Time and Resources

• Estimate the time required to complete each task based on factors such as complexity,
dependencies, and available resources.

• Determine the resources needed for development, including personnel, equipment,


and software tools.

4.4.4 Develop Project Schedule

• Create a project timeline or Gantt chart that outlines the sequence of tasks, milestones,
and deadlines.

• Allocate resources and establish dependencies between tasks to ensure smooth


progress.

4.4.5 Identify Risks and Mitigation Strategies

• Identify potential risks and uncertainties that may impact the project schedule, budget,
or quality.

• Develop strategies to mitigate risks and minimize their impact on the project.

15
• Establish contingency plans to address unforeseen challenges that may arise during
development.

4.4.6 Allocate Responsibilities

• Assign roles and responsibilities to team members based on their skills, expertise, and
availability.

• Clearly communicate expectations and deliverables to ensure accountability and


collaboration.

4.4.7 Monitor and Control Progress

• Regularly monitor project progress against the established schedule and milestones.

• Track resource utilization, budget expenditures, and any deviations from the plan.

• Implement corrective actions as needed to keep the project on track and address any
issues or delays.

4.4.8 Communicate with Stakeholders

• Maintain open communication channels with stakeholders, including clients, team


members, and project sponsors.

• Provide regular updates on project status, accomplishments, and challenges.

• Solicit feedback and address any concerns to ensure stakeholder satisfaction and
alignment with project goals.

4.4.9 Project closure

• Prepare comprehensive documentation that captures all aspects of the project,


including requirements, design decisions, implementation details, and testing results.

• Conduct a post-project review to assess the overall success of the collaborative music
playback system. Evaluate the project against its original objectives, budget, and
schedule.

• Ensure a smooth transition of the collaborative music playback system to the


appropriate stakeholders, such as end-users or operations teams.

16
• Prepare a formal project closure report summarizing the project's outcomes,
achievements, and recommendations for future improvements.

4.5 SOFTWARE REQUIREMENT SPECIFICATIONS (SRS)


The Software Requirements Specification (SRS) for the collaborative music playback system
outlines the functional and non-functional requirements of the software. Here's an overview
of the SRS:

4.5.1 Introduction

 Provide an overview of the collaborative music playback system.

 Describe the purpose, scope, and objectives of the software.

 Identify stakeholders and their roles in the project.

4.5.2 Functional Requirements

• User Management

• Users can register and log in using their Spotify accounts.

• Hosts can create rooms and manage room settings.

• Guests can join rooms using unique codes generated by hosts.

• Music Playback

• Users can play, pause, skip, and control playback of music tracks.

• Hosts can control playback permissions for guests.

• Real-time Synchronization

• Music playback is synchronized across all connected users in the same room.

• Voting System

• Users can vote to skip tracks, with the option for hosts to set the minimum
number of votes required.

17
• Room Management

• Hosts can set room parameters such as maximum number of participants,


playback control options, and voting system settings.

• Hosts can close the room, preventing new participants from joining.

• User Interaction

• Users can chat with other participants in the same room, enhancing social
interaction.

• Hosts can broadcast messages to all participants in the room, such as


announcements or song dedications.

• Playback History

• The system maintains a playback history for each room, allowing users to
view previously played tracks and their associated metadata.

• Guest Permissions

• Hosts can grant specific permissions to individual guests, such as allowing


certain users to control playback or skip tracks.

• Playlist Management

• Users can create and manage playlists within the application, adding or
removing tracks from their personal collection.

• Hosts can create shared playlists for the entire room to collaborate on.

4.5.3 Non-Functional Requirements

• Performance

• The system should have low latency for real-time synchronization.

• It should support a large number of concurrent users without degradation in


performance.

• Security

• User authentication and authorization should be implemented securely


using OAuth 2.0.
18
• Data transmission should be encrypted to protect user privacy.

• Reliability

• The system should be highly available and resilient to failures.

• It should gracefully handle errors and recover from faults.

• Usability

• The user interface should be intuitive and user-friendly.

• It should provide feedback and guidance to users as they interact with the
system.

• Accessibility

• The user interface should be accessible to users with disabilities, complying


with accessibility standards such as WCAG (Web Content Accessibility
Guidelines).

• Support for screen readers and keyboard navigation should be provided.

• Scalability

• The system should be designed to scale both vertically and horizontally to


handle increases in user traffic and data volume.

• Load balancing and caching mechanisms should be implemented to distribute


workload efficiently.

• Internationalization and Localization

• The application should support multiple languages and locales to


accommodate users from different regions.

• Text and user interface elements should be easily translatable and


customizable.

• Data Privacy and GDPR Compliance

• The system should adhere to data privacy regulations such as GDPR (General
Data Protection Regulation).

19
• User consent mechanisms should be implemented for data collection and
processing activities.

• Error Handling and Logging

• Comprehensive error handling should be in place to gracefully manage


exceptions and errors.

• Logs should be generated for system events, user actions, and error conditions,
aiding in troubleshooting and auditing.

4.5.4 External Interfaces

 Spotify API

• Integration with the Spotify API for music playback and user authentication.

 Frontend Interface

• Interaction with the frontend application developed using React.js.

 Database Interface

• Interaction with the database to store user information, room settings, and playback
data.

4.5.5 Constraints

 Technology Stack

➢ Front-End Development

❖ HTML(Hypertext Markup Language)

HTML, or Hypertext Markup Language, is the standard language used to create and
design web pages. It provides the structure for web content by using various tags and
attributes to define elements on a page. HTML is the backbone of web development,
providing the foundation for creating visually appealing and interactive web pages. It
works hand in hand with CSS (Cascading Style Sheets) for styling and JavaScript for
interactivity, forming the core technologies of the World Wide Web.

20
Overview of HTML

▪ Tags: HTML is built on tags, which are enclosed in angle brackets `< >`. Tags
are used to define different types of content on a webpage, such as headings,
paragraphs, images, links, and more.

▪ Elements: HTML elements are made up of tags and the content they surround.
For example, a paragraph element `<p>` starts with an opening tag and ends with
a closing tag `</p>`, enclosing the paragraph text.

▪ Attributes: Tags can have attributes that provide additional information about an
element. Attributes are placed within the opening tag and typically come inname-
value pairs, such as `href` in an anchor tag `<a href="https://example.com">`.

▪ Document Structure: HTML documents have a specific structure consisting of an


opening `<html>` tag followed by `<head>` and `<body>` tags. The `<head>`
section typically contains metadata like the page title, links to stylesheets, and
scripts. The `<body>` section contains the visible content of the webpage.

▪ Semantic Markup: HTML5 introduced semantic elements that provide more


meaning to the content, making it easier for search engines and assistive
technologies to understand. Examples include `<header>`, `<footer>`, `<nav>`,
`<article>`, `<section>`, `<aside>`, etc.

HTML Tags Used

▪ HTML: The HTML element (`<html>`) is the root element of an HTML page. It
wraps all the content on the page.

▪ Head: The head element (`<head>`) contains metadata and links to external
resources used by the HTML document. It doesn't display any content directly to
the user.

▪ Meta: The meta element (`<meta>`) is used to provide metadata about the HTML
document. Common uses include specifying the character encoding (`charset`
attribute) and setting the viewport for responsive design (`viewport` attribute).

21
▪ Title: The title element (`<title>`) sets the title of the HTML document, which is
displayed in the browser's title bar or tab. It's also used by search engines for page
indexing and in bookmarks.

▪ Script:The script element (`<script>`) is used to embed or reference executable


code, typically JavaScript, within an HTML document. It can be used to add
interactivity, handle events, manipulate the DOM, and more.

▪ Div: The div element (`<div>`) is a generic container used to group and style
HTML elements. It's often used to create sections or divisions within a webpage
and is styled using CSS.

▪ Body: The body element (`<body>`) contains the content of the HTML document
that's displayed to the user. It includes text, images, links, forms, and other
elements that make up the visible part of the webpage.

❖ CSS(Cascading Style Sheets)

CSS (Cascading Style Sheets) is a language used for describing the presentation
of a document written in HTML (HyperText Markup Language). Here's an overview
of CSS:

▪ Selectors: CSS selectors are patterns used to select the elements you want to
style. They can select elements based on their tag name, class, ID, attributes, and
more. They are a fundamental part of CSS syntax and play a crucial role in
styling web pages.

▪ Properties and Values: CSS properties are the styling attributes you can apply to
selected elements. Each property has a specific value associated with it that
defines how the property should be applied. Examples of properties include
`color`, `font-size`, `background-color`, `margin`, `padding`, and `border`.

▪ Cascading: CSS stands for "Cascading" Style Sheets, which refers to the way
styles are applied to elements. Styles can be inherited from parent elements,
overridden by more specific selectors, or overwritten by inline styles.

▪ Units: CSS supports different units of measurement for specifying sizes and
distances, such as pixels (`px`), percentages (`%`), ems (`em`), rems (`rem`), and
viewport units (`vw`, `vh`, `vmin`, `vmax`).

22
❖ JavaScript

JavaScript (JS) serves as the primary language for adding interactivity and
dynamic behavior to web pages. Here's an overview of JavaScript within the
project context:

▪ Client-Side Scripting: JavaScript is primarily used for client-side scripting,


meaning it runs in the user's web browser rather than on the server. This
allows for dynamic content manipulation without needing to reload the entire
page.

▪ DOM Manipulation: One of the core features of JavaScript is its ability to


manipulate the Document Object Model (DOM). The DOM represents the
structure of HTML elements on a web page, and JavaScript can be used to
access, modify, or delete these elements dynamically.

▪ Event Handling: JavaScript enables event-driven programming, where


functions (event handlers) are executed in response to user actions or system
events. Common events include clicks, mouse movements, keyboard inputs,
form submissions, and page loads.

▪ AJAX (Asynchronous JavaScript and XML): AJAX allows for asynchronous


communication between the web browser and the server, enabling data to be
exchanged with the server in the background without interfering with the
current page. This is commonly used to update parts of a web page without
requiring a full reload.

▪ API Integration: JavaScript can interact with various APIs (Application


Programming Interfaces) to access external services and data. This includes
fetching data from servers, integrating with third-party services (e.g., social
media platforms, mapping services), and performing operations like
authentication and authorization.

▪ Form Validation: JavaScript can be used to validate form inputs in real-time,


providing instant feedback to users and preventing invalid data submission.
This helps improve the user experience and ensures data integrity.

23
▪ Animation and Effects: JavaScript can create animations and visual effects on
web pages using techniques like CSS animations, transitions, and
libraries/frameworks such as jQuery or GSAP (GreenSock Animation
Platform).

▪ Error Handling and Debugging: JavaScript provides mechanisms for error


handling and debugging, including try-catch blocks, console logging, and
browser developer tools. Proper error handling ensures graceful degradation
in case of errors and helps developers identify and fix issues.

▪ Modularization and Libraries: JavaScript supports modular programming


through the use of modules, allowing code to be organized into reusable
components. Additionally, developers often leverage third-party libraries and
frameworks (e.g., React.js, Vue.js, AngularJS) to streamline development and
add advanced features.

▪ Security Considerations: When working with JavaScript, security is a critical


consideration. Developers must be mindful of potential security
vulnerabilities such as cross-site scripting (XSS) attacks and implement best
practices to protect against them.

❖ React

React is a JavaScript library used for building user interfaces, particularly for
single-page applications (SPAs) where content is dynamically updated without
requiring full page reloads. Here's an overview of React within this project:

▪ Component-Based Architecture: React follows a component-based


architecture, where UIs are composed of reusable components. Each
component encapsulates its own logic, state, and markup, making it easier
to manage and maintain complex user interfaces.

▪ Virtual DOM: React uses a virtual DOM (Document Object Model) to


efficiently update the UI. Instead of directly manipulating the browser's
DOM, React creates a lightweight in-memory representation of the DOM
and updates it as needed. This approach minimizes unnecessary DOM
manipulation and leads to better performance.

24
▪ JSX (JavaScript XML): React utilizes JSX, a syntax extension that allows
developers to write HTML-like code within JavaScript. JSX makes it
easier to describe UI components and their structure, combining HTML
markup with JavaScript logic seamlessly.

▪ State Management: React components can have state, which represents


data that can change over time. By using the `useState` hook (or `setState`
method in class components), developers can manage and update
component state, triggering re-renders as necessary to reflect state changes
in the UI.

▪ Props (Properties): React components can receive data via props, which
are essentially read-only inputs passed from parent to child components.
Props allow for communication between components and enable
component customization and reusability.

▪ Lifecycle Methods (Class Components): Class components in React have


lifecycle methods that are invoked at different stages of a component's
lifecycle, such as mounting, updating, and unmounting. These methods
can be used to perform initialization, data fetching, and cleanup tasks.

▪ Hooks (Functional Components): Functional components in React can use


hooks to add state and other features previously exclusive to class
components. Hooks like `useEffect`, `useContext`, and `useReducer`
enable functional components to manage state, perform side effects, and
access context without needing to use class syntax.

▪ Routing: React applications often use a router library (such as React


Router) to handle client-side routing and navigation. This allows for the
creation of multi-page experiences within a single-page application, with
different components rendered based on the URL.

▪ Server-Side Rendering (SSR): While not necessarily applicable to all


React projects, SSR is a technique used to render React components on
the server side and send HTML to the client. This can improve
performance and SEO by providing faster initial page loads and ensuring
content is indexable by search engines.

25
▪ Component Libraries and Ecosystem: React has a rich ecosystem of third-
party libraries and tools that extend its capabilities. This includes state
management libraries like Redux, UI component libraries like Material-UI
or Ant Design, and development tools like React DevTools and Create
React App.

➢ Back-End Development

❖ Python

Python serves as the backend language, responsible for handling server-side logic,
database interactions, and API endpoints. Python serves as the backend language,
responsible for handling server-side logic, database interactions, and API
endpoints.

▪ Django Framework: The project likely uses the Django web framework, which
is a high-level Python web framework that encourages rapid development and
clean, pragmatic design. Django provides a set of built-in tools and
conventions for handling common web development tasks, such as URL
routing, database modeling, and user authentication.

▪ API Endpoints: Python code defines API endpoints using Django's `django-
rest-framework` or similar libraries. These endpoints handle incoming HTTP
requests from the frontend, perform necessary data processing or database
operations, and return appropriate HTTP responses (usually in JSON format)
containing the requested data or indicating the outcome of the request.

▪ Model-View-Controller (MVC) Architecture: Django follows the MVC


architectural pattern, although in Django's terminology it's referred to as
Model-View-Template (MVT). Models define the structure and behavior of the
application's data, views handle the presentation logic and interact with
models, and templates render HTML pages to be served to the client.

▪ ORM (Object-Relational Mapping): Django provides an ORM layer that


abstracts away the details of database interaction, allowing developers to work
with database tables and records using Python classes and methods. Models in
Django represent database tables, and queries are performed using Python
syntax rather than raw SQL.
26
▪ Middleware: Django middleware allows for processing of requests and
responses before and after they reach the view layer. Middleware can perform
tasks such as authentication, request/response logging, error handling, and
more.

▪ Session Management and Authentication: Django provides built-in support for


user authentication and session management. Developers can easily integrate
features like user registration, login, logout, password management, and access
control using Django's authentication system.

▪ URL Routing: Django's URL routing mechanism maps incoming HTTP


requests to the appropriate view functions based on URL patterns defined in
the project's URL configuration. This allows for clean and organized URL
structures and separation of concerns between different parts of the application.

▪ Task Queues and Background Jobs: For handling long-running or


asynchronous tasks, Python code may use task queue libraries like Celery in
combination with a message broker such as Redis or RabbitMQ. This allows
tasks to be executed asynchronously outside of the request-response cycle,
improving application performance and scalability.

▪ Third-Party Libraries: Python's extensive ecosystem of third-party libraries and


packages may be leveraged for various purposes within the project, such as
handling date/time operations, working with external APIs, performing data
validation, and more.

❖ Django

Django serves as the web framework for building the backend of the application.
Django provides a comprehensive set of tools and conventions for building web
applications quickly and efficiently. Its batteries-included approach, robust security
features, and thriving ecosystem of third-party packages make it a popular choice
for building scalable and maintainable web applications.

▪ Model-View-Template (MVT) Architecture: Django follows the MVT


architectural pattern, which is a variation of the traditional Model-View-
Controller (MVC) pattern. In Django, models represent the data structure,

27
views handle the logic to process requests and generate responses, and
templates are used for rendering HTML pages.

▪ URL Routing: Django's URL dispatcher maps URL patterns to view functions
or classes, allowing developers to define how different URLs should be
handled by the application. URL patterns are typically defined in the project's
`urls.py` file and may include regular expressions or path converters to capture
dynamic parts of the URL.

▪ Models and ORM: Django provides an Object-Relational Mapping (ORM)


layer that allows developers to define database models using Python classes.
Models represent database tables, and fields within models represent table
columns. Django's ORM abstracts away the need to write SQL queries directly,
making it easier to interact with the database using Python code.

▪ Admin Interface: Django comes with a built-in administration interface that


can be automatically generated based on the project's models. This admin
interface allows authorized users to view, create, update, and delete records in
the database without writing any custom code. Admin functionality can be
customized and extended as needed.

▪ Forms and Validation: Django provides a forms library for handling HTML
forms and form data. Forms can be created using Python classes, and Django
handles tasks such as form rendering, data validation, and error handling
automatically. Forms can be used in views to process user input and interact
with the database.

▪ Middleware: Django middleware allows for processing of requests and


responses at various points in the request-response cycle. Middleware
components can perform tasks such as authentication, request/response
logging, CORS handling, and more. Middleware can be applied globally to all
requests or selectively to specific URL patterns.

▪ Authentication and Authorization: Django provides built-in support for user


authentication and authorization. The authentication system handles tasks such
as user login, logout, password management, and session management.

28
Authorization can be enforced using decorators or middleware to restrict
access to certain views or resources.

▪ Template Engine: Django's template engine allows developers to create HTML


templates that can be dynamically rendered with data from views. Templates
support template inheritance, template tags and filters, and other features to
facilitate code reuse and maintainability.

▪ Static Files and Media Handling: Django provides utilities for managing static
files (e.g., CSS, JavaScript) and media files (e.g., user-uploaded images,
videos). Static files are typically served directly by the web server in
production, while media files are stored locally or on a cloud storage service
like Amazon S3.

▪ Internationalization and Localization: Django supports internationalization


(i18n) and localization (l10n) out of the box, allowing developers to build
applications that support multiple languages and locales. Translation strings
can be marked for translation in Python code and templates, and Django
provides tools for generating translated versions of the application's content.

➢ API

❖ Spotify API:

The Spotify API is utilized to integrate music playback and management


functionality into the application. The integration of the Spotify API enhances the
functionality of the application by allowing users to access and control their
Spotify accounts directly within the application. This integration enables features
such as music playback, playlist management, and personalized recommendations,
enriching the user experience and making the application more engaging and
interactive.

▪ Authentication: The application implements OAuth 2.0 authentication to allow


users to connect their Spotify accounts. This involves obtaining authorization
from Spotify to access the user's account data and playback functionality.
Users are redirected to the Spotify authorization page, where they grant
permission to the application. Upon authorization, the application receives an

29
access token, which is used to make authenticated requests to the Spotify API
on behalf of the user.

▪ Authorization Code Flow: The application uses the authorization code flow to
authenticate users with Spotify. This flow involves redirecting the user to the
Spotify authorization page with specific parameters, including the client ID,
redirect URI, and requested scopes (permissions). After the user grants
permission, Spotify redirects back to the application with an authorization
code, which is exchanged for an access token and refresh token.

▪ Fetching Current Song: The application periodically fetches information about


the currently playing song from the Spotify API. This information includes
details such as the song title, artist, album, playback progress, and album cover
art. The fetched data is then displayed to the user in the application's user
interface, allowing them to see what song is currently playing.

▪ Playback Control: The application allows users to control playback actions


such as play, pause, and skip through the Spotify API. When a user interacts
with playback controls in the application's user interface, corresponding
requests are sent to the Spotify API to perform the desired action on the user's
active playback session.

▪ Error Handling and Edge Cases: The application handles potential errors and
edge cases that may arise during interactions with the Spotify API. This
includes scenarios such as invalid access tokens, expired tokens, rate limiting,
and network errors. Error handling mechanisms ensure that the application
provides a smooth and reliable user experience even in the face of API-related
issues.

30
 Scalability:

• The system should be designed to scale horizontally to accommodate future


growth in user base and usage.

4.5.6 Appendices

 Include any additional information relevant to the software requirements, such as use
case diagrams, data flow diagrams, or mockups.

4.6 SOFTWARE ENGINEERING PARADIGM APPLIED


The software engineering paradigm applied for this project is likely Agile. Agile
methodology emphasizes iterative development, collaboration, and flexibility, which are
crucial for a dynamic project like a collaborative music playback system. Here's how Agile
principles align with the project's requirements:

31
4.6.1 Iterative Development: The project can be broken down into smaller increments or
iterations, allowing for continuous improvement and feedback throughout the development
process. Features can be implemented incrementally, with regular demonstrations to
stakeholders for feedback and validation.

4.6.2 Collaborative Approach: Agile promotes collaboration among cross-functional teams,


including developers, designers, and stakeholders. In the context of this project, collaboration
is essential between frontend and backend developers, UI/UX designers, and potentially
external stakeholders such as music streaming service providers.

4.6.3 Adaptability to Change: Agile methodologies prioritize adaptability to changing


requirements and priorities. Given the dynamic nature of the music industry and user
preferences, the project needs to be flexible in accommodating new features, enhancements,
and adjustments based on user feedback and market trends.

4.6.4 Customer-Centric Focus: Agile places a strong emphasis on delivering value to the
customer. In this project, the customer-centric focus means prioritizing features and
functionalities that align with user needs and preferences, ensuring a positive user experience.

4.6.5 Continuous Delivery: Agile encourages frequent releases of working software,


allowing for rapid feedback and validation from users. Continuous integration and
deployment practices enable the team to deliver updates and improvements to the
collaborative music playback system efficiently and reliably.

4.6.6 Sprint Planning: The project team conducts regular sprint planning meetings to
prioritize tasks and set goals for each iteration. This ensures that development efforts are
focused on delivering the most valuable features incrementally.

4.6.7 Daily Stand-ups: Daily stand-up meetings are held to provide a forum for team
members to discuss progress, identify any impediments, and coordinate their efforts. These
short, focused meetings help maintain alignment and address any issues promptly.

4.6.8 Iterative Feedback: Agile encourages continuous feedback loops, both from
stakeholders and end-users. Regular demos and reviews allow stakeholders to provide
feedback on the product's features and functionality, facilitating early course correction and
improvement.

32
4.6.9 Empowered Teams: Agile principles promote self-organizing, empowered teams that
take ownership of their work. Team members have the autonomy to make decisions and
adapt to changing requirements, fostering a sense of accountability and commitment to
project success.

4.6.10 Continuous Improvement: Agile embraces a culture of continuous improvement,


where teams reflect on their processes and outcomes at the end of each iteration.
Retrospective meetings provide an opportunity to identify what went well, what could be
improved, and actionable steps for enhancement in subsequent iterations.

4.6.11 Adaptive Planning: Agile methodologies recognize that requirements and priorities
may evolve over time. The project plan remains flexible, allowing for adjustments based on
feedback, changes in market conditions, or emerging opportunities.

4.6.12 Transparency and Communication: Agile promotes transparency and open


communication within the project team and with stakeholders. Regular progress updates,
clear documentation, and collaboration tools facilitate effective communication and
alignment of objectives.

33
4. SYSTEM DESIGN AND SPECIFICATIONS
The system design and specifications for this project outline the architecture, components,
and functionality of the collaborative music playback system. Here's an overview:

❖ Architecture:

 The system follows a client-server architecture, where the server hosts the backend
logic and data storage, while the client interacts with the user through a web-based
interface.

 Backend components include Django framework for server-side logic, Spotify API
integration for music playback functionality, and a PostgreSQL database for storing
user data and room information.

 Frontend components utilize React.js for building interactive user interfaces and
managing state.

❖ Components:

 Backend Components:

• Django REST framework for building RESTful APIs to handle user


authentication, room management, music playback control, and voting.

• Spotify API integration for authenticating users, accessing music catalogs,


controlling playback, and retrieving song information.

• PostgreSQL database for storing user profiles, room details, playback history, and
voting data.

 Frontend Components:

• React.js for building modular UI components, managing state, and handling user
interactions.

• Material-UI library for designing responsive and visually appealing user interfaces.

• React Router for client-side routing to navigate between different views within the
application.

34
❖ Functionality:

 User Authentication: Users can log in to the system using their Spotify accounts to
access the collaborative music playback features.

 Room Management: Hosts can create a room and generate a unique code that other
users can use to join the room. Hosts can also set room preferences such as playback
control permissions and voting requirements.

 Music Playback: Users can play, pause, skip tracks, and adjust playback volume
within the room. Playback control permissions are determined by the host's settings.

 Synchronization: Playback is synchronized across all connected users in the same


room to ensure a consistent listening experience.

 Voting System: Users can vote to skip tracks, and tracks are skipped when the
required number of votes is reached.

 Real-time Updates: Hosts can update playback control settings and voting
requirements in real-time, reflecting changes immediately for all users in the room.

❖ Specifications:

 System supports concurrent user sessions with efficient handling of authentication and
session management.

 Integration with Spotify API ensures seamless access to music catalogs, playback
control, and user authentication.

 Web-based interface is responsive, user-friendly, and accessible across different


devices and screen sizes.

 Backend APIs follow RESTful principles, with clear endpoints, request/response


formats, and error handling mechanisms.

 Data storage and retrieval operations are optimized for performance and scalability,
ensuring smooth operation even under high user loads.

35
❖ SOFTWARE DESIGN

In designing the software following principles are followed:

 Modularity and partitioning: Software is designed such that, each system should
consists of hierarchy of modules and serve to partition into separate function.

 Coupling: Modules should have little dependence on other modules of a system.

 Cohesion: Modules should carry out in a single processing function.

 Shared use: Avoid duplication by allowing a single module be called by other that
need the function it provides.

❖ MODULE DESIGN

The major modules of the project are:

 Home Module

 Spotify Login Module

 Create Room Module

 Join Room Module

 Update Room Module

 Music Player Module

 Home Module:

 Displays the home page of the application.

 Provides options for users to create or join rooms..

 Includes features for browsing and searching for existing rooms.

 Spotify Login Module:

 Integrates Spotify authentication for user login.

36
 Handles the OAuth flow for obtaining user authorization.

 Retrieves user profile information and access tokens for Spotify API interaction.

 Create Room Module:

 Allows authenticated users to create new rooms.

 Generates a unique room code for each created room.

 Sets room preferences such as playback control and voting options.

 Join Room Module:

 Enables users to join existing rooms using room codes.

 Validates room codes and grants access to authorized users.

 Provides feedback on successful or failed room joining attempts.

 Update Room Module:

 Facilitates room settings updates by the host.

 Allows hosts to modify playback control permissions, voting rules, etc.

 Ensures that only authorized hosts can update room settings.

 Music Player Module:

 Displays information about the currently playing song, including the title, artist,
album cover, playback progress, and voting details.

 Users can interact with the music player through buttons such as play, pause, and
skip. These buttons trigger actions to control the playback accordingly.

 It also displays the number of votes each song has received for skipping

 Allows users to vote on whether to skip the current track.

37
❖ DATABASE DESIGN

 MODEL NAME: Room


Field name Data Type
code CharField
host CharField
guest_can_pause BooleanField
votes_to_skip IntegerField
created_at DateTimeField
current_song CharField

 MODEL NAME: SpotifyToken


Field name Data Type
user CharField
created_at DateTimeField
refresh_token CharField
access_token CharField
expires_in DateTimeField
token_type CharField

 MODEL NAME: Vote


Field name Data Type
user CharField
created_at DateTimeField
song_id CharField
room CharField

38
❖ INPUT/OUTPUT DESIGN

 Input Design
The input design for the collaborative music playback system involves defining how
users interact with the application to input commands, preferences, and data. Here's an
overview of the input design:

o User Interface (UI):

 The UI includes various input elements such as text fields, buttons, dropdowns,
and sliders.

 Users interact with these elements to perform actions like logging in, creating
rooms, joining rooms, controlling playback, and voting on tracks.

o Authentication Inputs:

 Input fields for users to enter their login credentials (username/email and
password) during the authentication process.

 OAuth login buttons to initiate authentication with third-party services like


Spotify.

o Room Creation Inputs:

 Text fields for specifying room preferences such as room name, playback
control permissions, and voting rules.

 Buttons to confirm room creation and submit the preferences.

o Room Joining Inputs:

 Text field for entering the room code when joining an existing room.

 Button to submit the room code and join the room.

o Room Update Inputs:

 Input fields or dropdowns to adjust room settings such as playback control


permissions, voting thresholds, and other configurations.

 Buttons to apply the changes and update the room settings.

39
o Playback Control Inputs:

 Playback control buttons for playing, pausing, skipping tracks, adjusting


volume, and seeking within tracks.

 Slider or input field for controlling volume level.

o Voting Inputs:

 Voting buttons or checkboxes displayed during track playback to allow users to


vote on track skipping.

 Feedback messages indicating the status of the vote .

 Output Design
The output design of the project involves presenting information and feedback to
users based on their interactions with the system. Here's an overview of the output
design elements in our collaborative music playback system:

 User Interface: The system provides a user-friendly interface using React and
Material-UI components. It includes screens for different functionalities like
home, room creation, room joining, music playback, and settings.

 Room Information: Upon joining a room or creating a new one, users see
relevant information such as the room code, current song details, playback
controls, and voting status.

 Music Playback: The output design includes a music player interface with
controls for play, pause, and skip. It also displays the current song's title, artist,
album cover, playback progress, and voting details.

 Real-time Updates: Users receive real-time updates on song changes,


playback status, and voting results. This ensures that everyone in the room
stays synchronized with the latest information.

40
5.1 DATA MODEL(LIKE DFD)

A Data Flow Diagram (DFD) is a traditional visual representation of the information flows
within a system. A neat and clear DFD can depict the right amount of the system requirement
graphically. It can be manual, automated, or a combination of both.

It shows how data enters and leaves the system, what changes the information, and where
data is stored.

The objective of a DFD is to show the scope and boundaries of a system as a whole. It may
be used as a communication tool between a system analyst and any person who plays a part
in the order that acts as a starting point for redesigning a system. The DFD is also called as a
data flow graph or bubble chart.

Data Flow Diagrams are of two types:

1) Physical Data Flow Diagrams: These are implementation-dependent i.e.,


they show the actual devices, departments, people, etc., involved in the
system.
2) Logical Data Flow Diagrams: These diagrams describe the system
independently of how it is actually implemented, they show what takes
places, rather than how an activity is accomplished.
Standard Symbol of DFD
➢ Data Flow: Data move in a specific direction from an origin to destination. The
data flow is a “packet” of data.

➢ Process: People, procedures or devices that produce data. The physical


component is not identified.

41
➢ Source or Destination of Data: External sources or destinations of data, which
may be people or organizations or other entities.

➢ Data Source: Here a process references the data in the system.

5.1.1 LEVEL 0 DFD


This is the highest-level DFD, which provides an overview of the entire system. It shows
the major processes, data flows, and data stores in the system, without providing any details
about the internal workings of these processes.

It is also known as a context diagram. It’s designed to be an abstraction view, showing the
system as a single process with its relationship to external entities. It represents the entire
system as a single bubble with input and output data indicated by incoming/outgoing
arrows.

42
5.1.2 Level 1 DFD
This level provides a more detailed view of the system by breaking down the major
processes identified in the level 0 DFD into sub-processes. Each sub-process is depicted as
a separate process on the level 1 DFD. The data flows and data stores associated with each
sub-process are also shown.

In 1-level DFD, the context diagram is decomposed into multiple bubbles/processes. In this
level, we highlight the main functions of the system and breakdown the high-level process
of 0-level DFD into subprocesses.

43
5.2 ENTITY RELATIONSHIP MODEL
ER model stands for an Entity-Relationship model. It is a high-level data model. This model
is used to define the data elements and relationship for a specified system.

It develops a conceptual design for the database. It also develops a very simple and easy to
design view of data.

In ER modeling, the database structure is portrayed as a diagram called an entity-relationship


diagram.

5.3 USE CASE DIAGRAM


A Use Case Diagram is a type of Unified Modeling Language (UML) diagram that
represents the interaction between actors (users or external systems) and a system under
consideration to accomplish specific goals. It provides a high-level view of the system’s
functionality by illustrating the various ways users can interact with it.

44
5.4 CLASS DIAGRAM
Class diagrams are a type of UML (Unified Modeling Language) diagram used in software
engineering to visually represent the structure and relationships of classes within a system
i.e. used to construct and visualize object-oriented systems.

45
Class diagrams provide a high-level overview of a system’s design, helping to
communicate and document the structure of the software. They are a fundamental tool in
object-oriented design and play a crucial role in the software development lifecycle.

46
5.5 STATE DIAGRAM/SEQUENCE DIAGRAM
A sequence diagram shows process interactions arranged in time sequence. This diagram
depicts the processes and objects involved and the sequence of messages exchanged as
needed to carry out the functionality.

47
5. SOURCE CODE
6.1 HTML template that provides structure to the application

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>Tune Troop</title>

{% load static %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<link

rel="stylesheet"

href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"

/>

<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"

/>

</head>

<body>

<div id="gradient">

<div id="main">

<div id="app"></div>

</div>

</div>

<script src="{% static "frontend/main.js" %}"></script>

</body>

</html>

48
6.2 CSS for styling
html,

body {

height: 100%;

margin: 0;

padding: 0;

#main {

position: fixed;

width: 100%;
height: 100%;

left: 0;

top: 0;

#app {

width: 100%;

height: 100%;

.center {

position: absolute;

top: 50%;
left: 50%;

transform: translate(-50%, -50%);

#gradient {

49
width: 100%;

height: 800px;

padding: 0px;

margin: 0px;

6.3 JavaScript to dynamically update the background


import App from "./components/App";

var colors = new Array(

[62,35,255],

[60,255,60],

[255,35,98],

[45,175,230],

[255,0,255],

[255,128,0]);

var step = 0;

//color table indices for:

// current color left

// next color left

// current color right

// next color right

var colorIndices = [0,1,2,3];

//transition speed

var gradientSpeed = 0.002;

function updateGradient()

50
{

if ( $===undefined ) return;

var c0_0 = colors[colorIndices[0]];

var c0_1 = colors[colorIndices[1]];

var c1_0 = colors[colorIndices[2]];

var c1_1 = colors[colorIndices[3]];

var istep = 1 - step;

var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);

var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);

var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);

var color1 = "rgb("+r1+","+g1+","+b1+")";

var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);

var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);

var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);

var color2 = "rgb("+r2+","+g2+","+b2+")";

$('#gradient').css({

background: "-webkit-gradient(linear, left top, right top, from("+color1+"),


to("+color2+"))"}).css({

background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});

step += gradientSpeed;

if ( step >= 1 )

step %= 1;

51
colorIndices[0] = colorIndices[1];

colorIndices[2] = colorIndices[3];

//pick two new target color indices

//do not pick the same as the current one

colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

setInterval(updateGradient,10);

6.4 Creation of Django model ‘Room’


from django.db import models

import string

import random

def generate_unique_code():

length = 6

while True:

code = ''.join(random.choices(string.ascii_uppercase, k=length))

if Room.objects.filter(code=code).count() == 0:

break

return code

52
class Room(models.Model):

code = models.CharField(

max_length=8, default=generate_unique_code, unique=True)

host = models.CharField(max_length=50, unique=True)

guest_can_pause = models.BooleanField(null=False, default=False)

votes_to_skip = models.IntegerField(null=False, default=1)

created_at = models.DateTimeField(auto_now_add=True)

current_song = models.CharField(max_length=50, null=True)

6.5 Creation of serializers for the ‘Room’ model in the Django REST
Framework
from rest_framework import serializers

from .models import Room

class RoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('id', 'code', 'host', 'guest_can_pause',

'votes_to_skip', 'created_at')

class CreateRoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('guest_can_pause', 'votes_to_skip')

class UpdateRoomSerializer(serializers.ModelSerializer):

code = serializers.CharField(validators=[])

53
class Meta:

model = Room
fields = ('guest_can_pause', 'votes_to_skip', 'code')

6.6 Django views for handling room-related operations


from django.shortcuts import render

from rest_framework import generics, status

from .serializers import RoomSerializer, CreateRoomSerializer, UpdateRoomSerializer

from .models import Room

from rest_framework.views import APIView

from rest_framework.response import Response

from django.http import JsonResponse

class RoomView(generics.ListAPIView):

queryset = Room.objects.all()

serializer_class = RoomSerializer

class GetRoom(APIView):

serializer_class = RoomSerializer

lookup_url_kwarg = 'code'

def get(self, request, format=None):

code = request.GET.get(self.lookup_url_kwarg)

if code != None:

room = Room.objects.filter(code=code)

if len(room) > 0:

data = RoomSerializer(room[0]).data

data['is_host'] = self.request.session.session_key == room[0].host

54
return Response(data, status=status.HTTP_200_OK)

return Response({'Room Not Found': 'Invalid Room Code.'},


status=status.HTTP_404_NOT_FOUND)

return Response({'Bad Request': 'Code paramater not found in request'},


status=status.HTTP_400_BAD_REQUEST)

class JoinRoom(APIView):

lookup_url_kwarg = 'code'

def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

code = request.data.get(self.lookup_url_kwarg)

if code != None:

room_result = Room.objects.filter(code=code)

if len(room_result) > 0:

room = room_result[0]

self.request.session['room_code'] = code

return Response({'message': 'Room Joined!'}, status=status.HTTP_200_OK)

return Response({'Bad Request': 'Invalid Room Code'},


status=status.HTTP_400_BAD_REQUEST)

return Response({'Bad Request': 'Invalid post data, did not find a code key'},
status=status.HTTP_400_BAD_REQUEST)

class CreateRoomView(APIView):

serializer_class = CreateRoomSerializer

55
def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

host = self.request.session.session_key

queryset = Room.objects.filter(host=host)

if queryset.exists():

room = queryset[0]

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

else:

room = Room(host=host, guest_can_pause=guest_can_pause,

votes_to_skip=votes_to_skip)
room.save()

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)

return Response({'Bad Request': 'Invalid data...'},


status=status.HTTP_400_BAD_REQUEST)

class UserInRoom(APIView):

56
def get(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

data = {

'code': self.request.session.get('room_code')

return JsonResponse(data, status=status.HTTP_200_OK)

class LeaveRoom(APIView):

def post(self, request, format=None):

if 'room_code' in self.request.session:

self.request.session.pop('room_code')

host_id = self.request.session.session_key

room_results = Room.objects.filter(host=host_id)

if len(room_results) > 0:

room = room_results[0]

room.delete()

return Response({'Message': 'Success'}, status=status.HTTP_200_OK)

class UpdateRoom(APIView):

serializer_class = UpdateRoomSerializer

def patch(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

57
if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

code = serializer.data.get('code')

queryset = Room.objects.filter(code=code)
if not queryset.exists():

return Response({'msg': 'Room not found.'},


status=status.HTTP_404_NOT_FOUND)

room = queryset[0]

user_id = self.request.session.session_key

if room.host != user_id:

return Response({'msg': 'You are not the host of this room.'},


status=status.HTTP_403_FORBIDDEN)

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

return Response({'Bad Request': "Invalid Data..."},


status=status.HTTP_400_BAD_REQUEST)

6.7 URL Patterns for routing HTTP requests


from django.urls import path

from .views import RoomView, CreateRoomView, GetRoom, JoinRoom, UserInRoom,


LeaveRoom, UpdateRoom

58
urlpatterns = [

path('room', RoomView.as_view()),

path('create-room', CreateRoomView.as_view()),

path('get-room', GetRoom.as_view()),

path('join-room', JoinRoom.as_view()),

path('user-in-room', UserInRoom.as_view()),

path('leave-room', LeaveRoom.as_view()),

path('update-room', UpdateRoom.as_view())

6.8 Root Component of React application


import React, { Component } from "react";

import { render } from "react-dom";

import HomePage from "./HomePage";

export default class App extends Component {

constructor(props) {
super(props);

render() {

return (

<div className="center">

<HomePage />

</div>

);

59
const appDiv = document.getElementById("app");

render(<App />, appDiv);

6.9 Main Page of the application


import React, { Component } from 'react';
import RoomJoinPage from './RoomJoinPage';
import CreateRoomPage from './CreateRoomPage';

import { Grid, Button, ButtonGroup, Typography } from '@mui/material';

import { BrowserRouter as Router, Routes, Route, Link, Redirect, Navigate } from 'react-
router-dom';

import Room from './Room';

export default class HomePage extends Component{

constructor(props){

super(props);

this.state={

roomCode: null,

};

this.clearRoomCode=this.clearRoomCode.bind(this);

async componentDidMount(){

fetch('/api/user-in-room')

.then((response)=>response.json()).

then((data)=>{

this.setState({

roomCode:data.code,

});

});

60
}

renderHomePage(){

if(this.state.roomCode){

return(

<Navigate to={`/room/${this.state.roomCode}`} replace={true}/>

);

}else{

return(

<Grid container spacing={3}>

<Grid item xs={12} align="center">

<Typography variant='h3' compact='h3'>

Tune Troop

</Typography>

</Grid>

<Grid item xs={12} align="center">

<ButtonGroup disableElevation variant='contained' color='primary'>

<Button color='secondary' to='/create' component={Link}>

Create a Room

</Button>

<Button color='primary' to='/join' component={Link}>

Join a Room
</Button>

</ButtonGroup>

</Grid>

</Grid>

);

61
clearRoomCode(){

this.setState({

roomCode:null,

});

render(){

return (<Router>

<Routes>

<Route path="/" element={this.renderHomePage()}

/>

<Route path="/join" element={<RoomJoinPage/>}></Route>

<Route path="/create" element={<CreateRoomPage/>}></Route>

<Route path="/room/:roomCode" element={<Room


clearRoomCodeCallback={this.clearRoomCode}/>}>

</Route>

</Routes>

</Router>);

6.10 Create or Update Room Component


import React, { Component, useState } from "react";
import { Button } from "@mui/material";

import {Grid} from "@mui/material";

import {Typography} from "@mui/material";

import { TextField } from "@mui/material";

62
import {FormHelperText} from "@mui/material";

import {FormControl} from "@mui/material";

import {Link} from "react-router-dom";

import {Radio} from "@mui/material";

import {RadioGroup} from "@mui/material";

import {FormControlLabel} from "@mui/material";

import { useNavigate } from "react-router-dom";

import {Collapse} from "@mui/material"

import Alert from "@mui/material/Alert";

function CreateRoomPage(props){

const navigate=useNavigate();

const[guestCanPause,setguestCanPause]=useState(props.guestCanPause);

const[votesToSkip,setgvotesToSkip]=useState(props.votesToSkip);

const[errorMsg,setErrorMsg]=useState("");

const[successMsg,setSuccessMsg]=useState("");

const handleVotesChange=()=>{

setgvotesToSkip(event.target.value);

};

const handleGuestCanPauseChange=()=>{

setguestCanPause(event.target.value==="true"?true:false);

};

const handleRoomButtonPressed=()=>{

const requestOptions = {

method: 'POST',

63
headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

}),

};

fetch('/api/create-room', requestOptions)

.then((response)=>response.json())

.then((data)=> navigate("/room/"+ data.code));

};

const handleUpdateButtonPressed=()=>{

const requestOptions = {

method: 'PATCH',

headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

code:props.roomCode,

}),

};

fetch('/api/update-room', requestOptions)

.then((response)=>{

if(response.ok){

setSuccessMsg("Room updated successfully!");

}else{

setErrorMsg("Error updating room");

props.updateCallback();

64
});

};

const renderCreateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleRoomButtonPressed}>Create A Room</Button>

</Grid>

<Grid item xs={12} align="center">

<Button color="secondary" variant="contained" to="/"


component={Link}>Back</Button>

</Grid>

</Grid>

);

};

const renderUpdateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleUpdateButtonPressed}>Update Room</Button>

</Grid>

</Grid>

);

};

65
const title=props.update? "Update Room" : "Create a Room";

return (

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Collapse in={errorMsg!="" || successMsg!=""}>

{successMsg!=""?(

<Alert

severity="success"

onClose={()=>{

setSuccessMsg("");

}}>

{successMsg}

</Alert>

):(

<Alert

severity="error"

onClose={()=>{

setErrorMsg("");
}}>

{errorMsg}

</Alert>

)}

</Collapse>

</Grid>

<Grid item xs={12} align="center">

<Typography component='h4' variant='h4'>

{title}

</Typography>

66
</Grid>

<Grid item xs={12} align="center">

<FormControl component="fieldset">

<FormHelperText component="div">

<div align='center'>Guest Control of Playback State</div>

</FormHelperText>

<RadioGroup row defaultValue={props.guestCanPause.toString()}


onChange={handleGuestCanPauseChange}>

<FormControlLabel value="true" control={<Radio color="primary"></Radio>}


label="Play/Pause"
labelPlacement="bottom"></FormControlLabel>

<FormControlLabel value="false" control={<Radio color="secondary"></Radio>}


label="No Control"

labelPlacement="bottom"></FormControlLabel>

</RadioGroup>

</FormControl>

</Grid>

<Grid item xs={12} align="center">

<FormControl>

<TextField required={true} type="number" onChange={handleVotesChange}


defaultValue={votesToSkip}

inputProps={{min:1, style:{textAlign:"center"},}}></TextField>

<FormHelperText component="div">

<div align="center">

Votes Required To Skip Song

</div>

</FormHelperText>

</FormControl>

67
</Grid>

{props.update?renderUpdateButtons(): renderCreateButtons()}

</Grid>

);

CreateRoomPage.defaultProps={

votesToSkip:2,

guestCanPause:true,

update: false,

roomCode:null,

updateCallback:()=>{},

};

export default CreateRoomPage;

6.11 Room Join Component


import React, {useState, Component } from 'react';

import { TextField, Button, Grid, Typography } from '@mui/material';

import { Link } from "react-router-dom";

import {useNavigate} from "react-router-dom";

export default function RoomJoinPage(props){

const navigate=useNavigate();

const[roomCode, setroomCode]=useState('');

const[errorMsg,seterrorMsg]=useState('');

const[error,seterror]=useState(false);

const handleTextFieldChange=()=>{

68
setroomCode(event.target.value);

};

const roomButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

body:JSON.stringify({

code:roomCode,

}),

};

fetch("/api/join-room",requestOptions).

then((response)=>{

if(response.ok){

navigate("/room/"+ roomCode)

}else{

seterror(true);

seterrorMsg("Room not found");


}

})

.catch((error)=>{

console.log(error);

});

};

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant="h4" component="h4">

Join a Room

69
</Typography>

</Grid>

<Grid item xs={12} align="center">

<TextField

error={error}

label="Code"

placeholder='Enter a Room Code'

value={roomCode}

helperText={errorMsg}

variant='outlined'

onChange={handleTextFieldChange}>

</TextField>

</Grid>

<Grid item xs={12} align="center">

<Button

variant='contained'

color='primary'

onClick={roomButtonPressed}>

Enter Room

</Button>

</Grid>

<Grid item xs={12} align="center">

<Button variant='contained'

color='secondary' to="/" component={Link}>

Back

</Button>

</Grid>

</Grid>

70
);

6.12 Room Component


import React, {useState, useEffect} from 'react';

import {useParams,Navigate} from "react-router-dom";

import {Grid, Button, Typography} from '@mui/material';

import {useNavigate} from "react-router-dom";

import CreateRoomPage from './CreateRoomPage';

import MusicPlayer from './MusicPlayer';

function Room(props){

const navigate=useNavigate();

const{roomCode}=useParams()

const initialState={

votesToSkip:2,

guestCanPause:false,

isHost:false,

showSettings: false,

spotifyAuthenticated: false,

song:{},
}

const[roomData, setRoomData]=useState(initialState)

useEffect(() => {

getRoomDetails();

const interval=setInterval(getCurrentSong, 1000);

return ()=>clearInterval(interval);

},[roomCode]);

71
const getRoomDetails = () => {

fetch("/api/get-room" + "?code=" + roomCode)

.then((response) => {

if (!response.ok) {

props.clearRoomCodeCallback();

navigate("/");

return response.json();

})

.then((data) => {

setRoomData(prevState=>({

...prevState,

votesToSkip: data.votes_to_skip,

guestCanPause: data.guest_can_pause,

isHost: data.is_host

}));

if(data.is_host){

authenticateSpotify();

});

};

const authenticateSpotify=()=>{

fetch("/spotify/is-authenticated")

.then((response) => response.json())

.then((data) => {

setRoomData(prevState=>({...prevState, spotifyAuthenticated: data.status }));

console.log(data.status);

if (!data.status) {

72
fetch("/spotify/get-auth-url")

.then((response) => response.json())

.then((data) => {

window.location.replace(data.url);

});

});

};

const getCurrentSong = () => {

fetch('/spotify/current-song')

.then((response) => {

if (!response.ok) {

return {};

} else {

return response.json();

})

.then((data) => {

setRoomData(prevState => ({ ...prevState, song: data }));

console.log(data);
});

};

const leaveButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

};

73
fetch('/api/leave-room',requestOptions).

then((response)=>{

props.clearRoomCodeCallback();

navigate('/');

});

};

const updateShowSettings=(value)=>{

setRoomData({

...roomData,

showSettings:value,

});

};

const renderSettings=()=>{

return(
<Grid container spacing={1}>

<Grid item xs={12} align="center">

<CreateRoomPage

update={true}

votesToSkip={roomData.votesToSkip}

guestCanPause={roomData.guestCanPause}

roomCode={roomCode}

updateCallback={getRoomDetails}

getRoomDetails={getRoomDetails}
/>

</Grid>

<Grid item xs={12} align="center" >

<Button

74
variant='contained'

color='secondary'
onClick={()=>updateShowSettings(false)}

>

Close

</Button>

</Grid>

</Grid>

);

};

const renderSettingsButton=()=>{

return(

<Grid item xs={12} align="center">

<Button variant='contained' color='primary'


onClick={()=>updateShowSettings(true)}>

Settings

</Button>

</Grid>

);

};

return roomData.showSettings?(

renderSettings()

):(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant='h4' component='h4'>

75
Code:{roomCode}

</Typography>

</Grid>

<MusicPlayer {...roomData.song}/>

{roomData.isHost?renderSettingsButton():null}

<Grid item xs={12} align="center">

<Button variant="contained" color='secondary' onClick={leaveButtonPressed}>

Leave Room

</Button>

</Grid>

</Grid>

export default Room

6.13 Music Player Component


import React, { useState } from "react";
import {

Grid,

Typography,

Card,

IconButton,

LinearProgress,

} from '@mui/material';

import { Pause, PlayArrowRounded, SkipNext } from '@mui/icons-material';

const MusicPlayer = (props) => {

const skipSong = () => {

76
const requestOptions = {

method: "POST",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/skip", requestOptions);

};

const pauseSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/pause", requestOptions);

};

const playSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/play", requestOptions);

};

const songProgress = (props.time / props.duration) * 100;

return (

<Card>

<Grid container alignItems="center">

<Grid item align="center" xs={4}>

<img src={props.image_url} height="100%" width="100%" alt="song cover" />

</Grid>

77
<Grid item align="center" xs={8}>

<Typography component="h5" variant="h5">

{props.title}

</Typography>

<Typography color="textSecondary" variant="subtitle1">

{props.artist}

</Typography>

<div>

<IconButton onClick={()=>{props.is_playing? pauseSong(): playSong()}}>

{props.is_playing ? <Pause></Pause> :
<PlayArrowRounded></PlayArrowRounded>}

</IconButton>

<IconButton onClick={()=>skipSong()}>

{props.votes}/{" "}{props.votes_required}

<SkipNext></SkipNext>

</IconButton>

</div>

</Grid>

</Grid>

<LinearProgress variant="determinate" value={songProgress} />

</Card>

);

};

export default MusicPlayer;

78
6.14 Django model for storing Spotify authentication tokens and user votes
from django.db import models

from api.models import Room

class SpotifyToken(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

refresh_token = models.CharField(max_length=150)

access_token = models.CharField(max_length=150)

expires_in = models.DateTimeField()

token_type = models.CharField(max_length=50)

class Vote(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

song_id = models.CharField(max_length=50)

room = models.ForeignKey(Room, on_delete=models.CASCADE)

6.15 Credentials for authentication with Spotify API


CLIENT_ID = "08cb230a331944c7bfa503dfc73dd46c"
CLIENT_SECRET = "f78338ef85e74cf2be80970a90406b69"

REDIRECT_URI = "http://127.0.0.1:8000/spotify/redirect"

6.16 Django views for handling music player operations


from django.shortcuts import render, redirect

from .credentials import REDIRECT_URI, CLIENT_SECRET, CLIENT_ID

from rest_framework.views import APIView

from requests import Request, post

from rest_framework import status

79
from rest_framework.response import Response

from .util import *

from api.models import Room

from .models import Vote

class AuthURL(APIView):

def get(self, request, fornat=None):

scopes = 'user-read-playback-state user-modify-playback-state user-read-currently-


playing'

url = Request('GET', 'https://accounts.spotify.com/authorize', params={

'scope': scopes,

'response_type': 'code',

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID

}).prepare().url

return Response({'url': url}, status=status.HTTP_200_OK)

def spotify_callback(request, format=None):

code = request.GET.get('code')

error = request.GET.get('error')

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'authorization_code',

'code': code,

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

80
}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

refresh_token = response.get('refresh_token')

expires_in = response.get('expires_in')
error = response.get('error')

if not request.session.exists(request.session.session_key):

request.session.create()

update_or_create_user_tokens(

request.session.session_key, access_token, token_type, expires_in, refresh_token)

return redirect('frontend:')

class IsAuthenticated(APIView):

def get(self, request, format=None):

is_authenticated = is_spotify_authenticated(
self.request.session.session_key)

return Response({'status': is_authenticated}, status=status.HTTP_200_OK)

class CurrentSong(APIView):

def get(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)

if room.exists():

room = room[0]

else:

81
return Response({}, status=status.HTTP_404_NOT_FOUND)

host = room.host
endpoint = "player/currently-playing"

response = execute_spotify_api_request(host, endpoint)

if 'error' in response or 'item' not in response:

return Response({}, status=status.HTTP_204_NO_CONTENT)

item = response.get('item')

duration = item.get('duration_ms')

progress = response.get('progress_ms')

album_cover = item.get('album').get('images')[0].get('url')

is_playing = response.get('is_playing')

song_id = item.get('id')

artist_string = ""

for i, artist in enumerate(item.get('artists')):

if i > 0:

artist_string += ", "

name = artist.get('name')

artist_string += name

votes = len(Vote.objects.filter(room=room, song_id=song_id))

song = {

'title': item.get('name'),

'artist': artist_string,

'duration': duration,

'time': progress,

82
'image_url': album_cover,

'is_playing': is_playing,

'votes': votes,

'votes_required': room.votes_to_skip,

'id': song_id

self.update_room_song(room, song_id)

return Response(song, status=status.HTTP_200_OK)

def update_room_song(self, room, song_id):

current_song = room.current_song

if current_song != song_id:

room.current_song = song_id

room.save(update_fields=['current_song'])
votes = Vote.objects.filter(room=room).delete()

class PauseSong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

pause_song(room.host)

return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

83
class PlaySong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

play_song(room.host)
return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

class SkipSong(APIView):

def post(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

votes = Vote.objects.filter(room=room, song_id=room.current_song)

votes_needed = room.votes_to_skip

if self.request.session.session_key == room.host or len(votes) + 1 >= votes_needed:

votes.delete()

skip_song(room.host)

else:

vote = Vote(user=self.request.session.session_key,

room=room, song_id=room.current_song)

vote.save()

return Response({}, status.HTTP_204_NO_CONTENT)

84
6.17 To handle Spotify authentication and integration using Spotify API
from .models import SpotifyToken

from django.utils import timezone

from datetime import timedelta

from .credentials import CLIENT_ID, CLIENT_SECRET

from requests import post, put, get

BASE_URL = "https://api.spotify.com/v1/me/"

def get_user_tokens(session_id):

user_tokens = SpotifyToken.objects.filter(user=session_id)

if user_tokens.exists():

return user_tokens[0]

else:

return None

def update_or_create_user_tokens(session_id, access_token, token_type, expires_in,


refresh_token):

tokens = get_user_tokens(session_id)

expires_in = timezone.now() + timedelta(seconds=expires_in)

if tokens:

tokens.access_token = access_token

tokens.refresh_token = refresh_token

tokens.expires_in = expires_in

tokens.token_type = token_type

tokens.save(update_fields=['access_token',
'refresh_token', 'expires_in', 'token_type'])

85
else:

tokens = SpotifyToken(user=session_id, access_token=access_token,

refresh_token=refresh_token, token_type=token_type,
expires_in=expires_in)

tokens.save()

def is_spotify_authenticated(session_id):

tokens = get_user_tokens(session_id)

if tokens:

expiry = tokens.expires_in

if expiry <= timezone.now():

refresh_spotify_token(session_id)

return True

return False

def refresh_spotify_token(session_id):

refresh_token = get_user_tokens(session_id).refresh_token

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'refresh_token',

'refresh_token': refresh_token,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

86
expires_in = response.get('expires_in')

update_or_create_user_tokens(

session_id, access_token, token_type, expires_in, refresh_token)

def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):

tokens = get_user_tokens(session_id)

headers = {'Content-Type': 'application/json',

'Authorization': "Bearer " + tokens.access_token}

if post_:

post(BASE_URL + endpoint, headers=headers)

if put_:

put(BASE_URL + endpoint, headers=headers)

response = get(BASE_URL + endpoint, {}, headers=headers)

try:

return response.json()

except:
return {'Error': 'Issue with request'}

def play_song(session_id):

return execute_spotify_api_request(session_id, "player/play", put_=True)

def pause_song(session_id):

return execute_spotify_api_request(session_id, "player/pause", put_=True)

def skip_song(session_id):

return execute_spotify_api_request(session_id, "player/next", post_=True)

87
6.18 URL patterns for the API views
from django.urls import path

from .views import *

urlpatterns = [

path('get-auth-url', AuthURL.as_view()),

path('redirect', spotify_callback),

path('is-authenticated', IsAuthenticated.as_view()),

path('current-song', CurrentSong.as_view()),

path('pause', PauseSong.as_view()),

path('play', PlaySong.as_view()),

path('skip', SkipSong.as_view())

6.19 URL pattern to include URLS from different parts of the application
from django.contrib import admin

from django.urls import path, include

urlpatterns = [

path('admin/', admin.site.urls),

path('api/', include('api.urls')),

path('', include('frontend.urls')),

path('spotify/', include('spotify.urls'))

88
6. SCREENSHOT

7.1 HOME PAGE

7.2 CREATE ROOM PAGE

89
7.3 SPOTIFY ACCOUNT LOGIN PAGE

7.4 MUSIC PLAYER PAGE FOR HOST

90
7.5 UPDATE ROOM PAGE

7.6 JOIN ROOM PAGE

91
7.5 MUSIC PLAYER PAGE FOR GUEST

92
7. TESTING
Software testing can be stated as the process of verifying and validating whether a software
or application is bug-free, meets the technical requirements as guided by its design and
development, and meets the user requirements effectively and efficiently by handling all
the exceptional and boundary cases.

The purpose of software testing is to identify the errors, faults, or missing requirements in
contrast to actual requirements. It mainly aims at measuring the specification, functionality,
and performance of a software program or application.

The objectives of testing include:

 Validation: Ensure that the software meets the specified requirements and fulfills its
intended purpose effectively and accurately.

 Verification: Confirm that the software conforms to its design specifications and
standards, ensuring consistency and reliability in its behavior.

 Identification of Defects: Detect and identify any defects, bugs, or errors in the
software early in the development process to prevent them from impacting the end-
users or causing issues in production.

 Quality Assurance: Ensure that the software meets predefined quality standards,
including functionality, performance, security, usability, and maintainability.

 Risk Mitigation: Identify and mitigate potential risks associated with the software,
such as security vulnerabilities, performance bottlenecks, and usability issues, to
minimize their impact on the end-users and the organization.

 Optimization: Optimize the software to improve its performance, efficiency, and


reliability, enhancing the user experience and reducing the likelihood of failures or
downtime.

 User Satisfaction: Enhance user satisfaction by delivering a high-quality, reliable,


and user-friendly software product that meets or exceeds the expectations and
requirements of the end-users.

93
 Compliance: Ensure that the software complies with relevant laws, regulations,
standards, and industry best practices, such as accessibility standards, data privacy
regulations, and security guidelines.

 Continuous Improvement: Provide feedback and insights to stakeholders for


continuous improvement of the software development process, methodologies, tools,
and practices, fostering innovation and excellence.

 Cost Reduction: Identify and eliminate defects and inefficiencies early in the
development lifecycle to reduce the overall cost of software development,
maintenance, and support.

8.1 TESTING TECHNIQUES AND TESTING STRATEGIES USED


TESTING PLAN USED
8.1.1 TESTING TECHNIQUES

 Unit Testing: Test individual components or modules in isolation to validate their


functionality.

 Integration Testing: Test the interaction between different components or modules to


ensure they work together as expected.

 System Testing: Test the entire system as a whole to verify that it meets the specified
requirements and functions correctly in its intended environment.

 Acceptance Testing: Test the software from the end-user's perspective to determine if
it meets their needs and expectations.

 Regression Testing: Test previously implemented features to ensure they still function
correctly after new changes or updates are made.

 Performance Testing: Evaluate the software's responsiveness, scalability, and stability


under various load conditions to ensure optimal performance.

 Security Testing: Identify and mitigate potential security vulnerabilities and threats to
protect the software and its users' data.

94
ACKNOWLEDGEMENT

We express our sincere gratitude to Prof. Satya Narayan Das, Head of The Department of
Computer Science and Applications for allowing me to accomplish the project. With his
active support and guidance, this project report has been completed.

We also thank Mr. Ashutosh Mallik our Project Coordinator for guidance and help.

We also thank Mrs. Sucheta Krupalini Moharana our Project Supervisor for guidance and help.

Signature of the Students


Contents

Page Number

Abstract 1

1. Introduction 2-4
1.1 Purpose 2
1.2 Project Scope 2
1.3 Project Features 3-4
2. Literature Review 5-7
3. Problem Statement 8-10
4. System Analysis 11-33
4.1 Identification of Need 11
4.2 Preliminary Investigation 12-13
4.3 Feasibility Study 13 -14
4.4 Project Planning 15-17
4.5 Software Requirement Specifications (SRS) 17-31
4.6 Software Engineering Paradigm Applied 31-33
5. System Design &Specifications 34-47
5.1 Data models (like DFD) 41-43
5.2 Entity Relationship Model 44
5.3 Use-case Diagrams 44-45
5.4 Class Diagrams 45-46
5.5 State Diagrams/Sequence Diagrams 47
6. Source Code 48-88
7. Screenshots 89-92
8. Testing 93-100
8.1 Testing Techniques and Testing Strategies Used Testing Plan used 94-96
8.2 Test Reports for Unit Test Cases and System Test Cases 96-100
9. Conclusion 101-102
10. Future Enhancement 103-105
11. References / Bibliography 106
ABSTRACT

Title: Development of an E-STORE Using Python, D jango, HTML, CSS, and Bootstrap

Abstract:
In today's digital age, online shopping has become increasingly popular, especially for
essential items like groceries. This project aims to develop a comprehensive online
grocery shop using Python, Django, HTML, CSS, and Bootstrap.

The system will provide users with a convenient platform to browse through a wide
range of grocery products, add them to their cart, and securely complete their purchases.
The backend will be powered by Django, a high-level Python web framework, which
will handle user authentication, product management, order processing, and database
interactions.

The frontend will be developed using HTML, CSS, and Bootstrap to create a visually
appealing and responsive user interface. Bootstrap's grid system and components will
ensure that the website is accessible across various devices and screen sizes, providing a
seamless shopping experience for users on desktops, laptops, tablets, and smartphones.

Key features of the online grocery shop will include user registration and login, product
categorization and search functionality, product details and images, shopping cart
management, secure payment processing integration, order tracking, and email
notifications.

Overall, this project aims to leverage modern web development technologies to create
an efficient and user-friendly online grocery shopping platform, catering to the needs of
today's digitally savvy consumers.

1
INTRODUCTION
 PURPOSE :

The purpose of developing an online grocery shop using Python, Django,


HTML, CSS, and Bootstrap is multi-faceted:

1. Convenience: The primary aim is to provide consumers with a convenient


way to purchase groceries from the comfort of their homes. By offering an
online platform, customers can browse, select, and order groceries at any
time, eliminating the need to physically visit a store.
2. Accessibility: An online grocery shop enhances accessibility for
individuals who may have mobility issues or live in remote areas with
limited access to physical stores. They can access a wide range of grocery
products with just an internet connection.
3. Time-saving: By streamlining the shopping process, customers can save
time that would have been spent commuting to and from a store, searching
for items, and waiting in checkout lines. The online platform allows for
quick browsing, searching, and purchasing of products.
4. Product variety: Online grocery shops can offer a broader range of
products compared to traditional brick-and-mortar stores. Customers can
explore a diverse selection of brands, flavors, and specialty items without the
constraints of physical shelf space.
5. Personalization: Through user accounts and preferences tracking, online
grocery shops can offer personalized recommendations and promotions
tailored to individual shopping habits and preferences. This enhances the
shopping experience and encourages customer loyalty.
6. Scalability: By leveraging Python and Django for backend development
and HTML, CSS, and Bootstrap for frontend design, the online grocery shop
can be built to scale. It can accommodate a growing customer base and
expand its offerings and features as needed.

In essence, the purpose of developing an online grocery shop using these


technologies is to create a modern, user-friendly, and efficient platform that
meets the evolving needs of consumers in today's digital landscape.

2
 PROJECT FEATURES :

Here's a breakdown of the project features for the online grocery shop developed using Python,
Django, HTML, CSS, and Bootstrap:
1. User Registration and Authentication:
- Allow users to register with the platform by providing necessary details.
- Implement authentication mechanisms to ensure secure access to user accounts.
- Enable users to log in and log out of their accounts securely.
2. Product Management:
- Provide functionality for administrators to add, edit, and delete grocery products.
- Include fields such as product name, description, price, quantity, and images.
- Implement product categorization and tagging for easy navigation.
3. Browsing and Searching:
- Enable users to browse through the available grocery products conveniently.
- Implement search functionality to allow users to find specific products quickly.
- Provide filtering options based on categories, prices, and other attributes.
4. Shopping Cart Management:
- Allow users to add products to their shopping carts while browsing.
- Provide options to update the quantity or remove items from the cart.
- Display the total cost and summary of items in the shopping cart.
5. Checkout Process:
- Implement a streamlined checkout process for users to complete their purchases.
- Include forms for users to provide shipping and billing information.
- Integrate secure payment gateways for processing transactions (e.g., PayPal, Stripe).

6. Order Tracking and History:

3
1.1.1 Error Handling and Security: Robust error handling mechanisms and security
measures are implemented to ensure data integrity, user privacy, and protection against
unauthorized access.

4
1. LITERATURE REVIEW
Collaborative music playback systems have emerged as a novel way for users to engage with
music in shared listening experiences. These systems enable multiple users to synchronize
their music playback across devices, allowing for collaborative playlist creation, voting on
tracks, and real-time interaction. This literature review aims to provide a comprehensive
overview of existing research and developments in collaborative music playback systems,
focusing on design principles, technical implementations, user experiences, and the social
impact of these systems.

2.1 DESIGN PRINCIPLES AND TECHINCAL IMPLEMENTATION


Research in collaborative music playback systems has explored various design principles and
technical implementations to facilitate seamless synchronization and interaction among users.
One key aspect is the architecture of the system, which may be centralized, decentralized, or
hybrid. Centralized architectures typically rely on a server to manage playback
synchronization and user interactions, while decentralized architectures leverage peer-to-peer
or mesh networking to distribute control among connected devices. Hybrid approaches
combine elements of both centralized and decentralized architectures to optimize
performance and scalability.

In terms of synchronization techniques, real-time algorithms play a crucial role in ensuring


accurate timing alignment between audio streams across devices. These algorithms must
account for factors such as network latency, device processing capabilities, and audio
buffering to deliver a consistent listening experience. Additionally, researchers have
investigated protocols for communication and data exchange between devices, considering
factors like reliability, efficiency, and compatibility with existing standards.

2.2 USER EXPERIENCE AND IINTERFACE DESIGN


User experience (UX) plays a crucial role in the success of collaborative music playback
systems. Studies have investigated various UX factors, such as interface design, interaction
patterns, and social features, to enhance user engagement and satisfaction. Intuitive interfaces
with intuitive controls enable users to navigate, search, and manage playlists effortlessly.
Social features like chat, voting, and collaborative playlist creation foster a sense of
5
community and encourage active participation among users. Furthermore, personalized
recommendations and adaptive interfaces tailor the music listening experience to individual
preferences, enhancing user satisfaction and retention. Adaptive interfaces that adapt to user
behavior, context, and feedback can enhance user satisfaction and retention. Additionally,
accessibility features ensure that the system is inclusive and usable for users with diverse
needs and abilities.

2.3 SOCIAL IMPACT AND USER ENGAGEMENT


Collaborative music playback systems have a significant impact on music consumption habits
and social interactions. Research has shown that shared listening experiences strengthen
social bonds and promote collaborative behaviors among users. Users engage in activities
like co-curating playlists, discovering new music together, and engaging in real-time
interactions like voting on tracks or controlling playback. Moreover, collaborative music
playback systems encourage exploration and serendipitous discovery, exposing users to a
diverse range of musical genres and artists they might not encounter otherwise. This
collaborative discovery process fosters a deeper appreciation for music and cultivates a sense
of belonging within online communities.

2.4 CHALLENGES AND FUTURE DIRECTIONS


Despite the benefits, collaborative music playback systems face several challenges, including
technical constraints, privacy concerns, and scalability issues. Synchronizing playback across
devices while minimizing latency remains a significant challenge, particularly in
heterogeneous network environments with varying bandwidth and latency characteristics.
Moreover, ensuring data privacy and security is crucial, as collaborative music playback
systems often involve sharing personal music preferences and listening habits. Additionally,
scalability becomes a concern as the number of users and concurrent sessions grows,
necessitating robust infrastructure and optimization techniques to handle increasing load and
maintain performance.

Looking ahead, future research directions in collaborative music playback systems may
include exploring novel interaction paradigms, integrating emerging technologies like virtual
reality and spatial audio, and investigating the social and cultural implications of shared

6
listening experiences. Moreover, interdisciplinary collaborations between researchers,
designers, musicians, and industry stakeholders can lead to innovative solutions that redefine
how people discover, share, and enjoy music together in the digital age.

In conclusion, collaborative music playback systems offer exciting opportunities to enhance


social interaction, foster musical discovery, and transform the way people engage with music.
By addressing design challenges, improving user experiences, and exploring new avenues for
innovation, researchers and practitioners can continue to advance the field of collaborative
music playback systems and create meaningful experiences for music enthusiasts worldwide.

7
2. PROBLEM STATEMENT
The problem statement for the project revolves around the need for a collaborative music
playback system that allows multiple users to join a virtual room, synchronize playback, and
control music playback together. Existing music streaming platforms lack real-time
collaboration features, limiting the ability for users to enjoy music together simultaneously.
Therefore, there is a need to develop a platform that enables users to create and join rooms,
interact with other users in real-time, and collectively control music playback. This project
aims to address these limitations by implementing features such as room creation, user
authentication through Spotify, real-time synchronization of playback, and control of
playback features by both hosts and guests.

3.1 KEY CHALLENGES


The key challenges of this project include:

3.1.1 Real-Time Synchronization: Ensuring that all users in a room experience


synchronized music playback without significant latency or delays is crucial. Achieving this
requires efficient data handling and synchronization techniques.

3.1.2 User Authentication and Integration with Spotify API: Integrating user
authentication via Spotify and leveraging the Spotify API to retrieve and control music
playback requires handling OAuth flows securely and managing access tokens effectively.

3.1.3 Room Management and Data Consistency: Managing rooms dynamically, including
creation, joining, and leaving, while maintaining data consistency and integrity across
connected users presents challenges in database design and synchronization.

3.1.4 Playback Control Permissions: Implementing logic to allow hosts to control playback
permissions for guests, such as play, pause, and skip, requires robust authorization
mechanisms.

3.1.5 Real-Time Updates and Notifications: Enabling real-time updates for playback
control and room settings poses challenges in handling WebSocket communications and
ensuring efficient event propagation.

8
3.1.6 Error Handling and Resilience: Implementing robust error handling mechanisms to
address potential failures in API calls, user authentication, or real-time synchronization is
essential for maintaining a seamless user experience.

3.2 SOLUTION REQUIREMENTS


The solution requirements to address the challenges of the project include:

3.2.1 Real-Time Synchronization

• Implement WebSocket communication to enable real-time synchronization of


playback events and updates across all connected users.

• Utilize efficient data structures and algorithms for managing playback state and
ensuring synchronized playback experiences.

3.2.2 User Authentication and Integration with Spotify API

• Implement OAuth 2.0 authentication flow securely to authenticate users with their
Spotify accounts.

• Utilize Spotify API endpoints to retrieve user-specific music data, control playback,
and manage user permissions.

3.2.3 Room Management and Data Consistency

• Design a robust database schema to manage rooms, users, and playback state
efficiently.

• Implement transactional operations and data synchronization mechanisms to ensure


data consistency across connected users.

3.2.4 Playback Control Permissions

• Implement role-based access control (RBAC) mechanisms to manage user roles (host
vs. guest) and permissions for controlling playback.

• Design intuitive user interfaces to allow hosts to manage playback permissions


effectively.

9
3.2.5 Real-Time Updates and Notifications

• Implement WebSocket-based pub-sub systems to propagate real-time updates and


notifications to all connected users.

• Design event-driven architectures to handle and process events related to playback


control, room management, and user interactions.

3.2.6 Error Handling and Resilience

• Implement robust error handling mechanisms to gracefully handle errors and failures
in API calls, authentication flows, and real-time communication.

• Utilize logging and monitoring tools to track and diagnose errors in real-time,
ensuring quick resolution and minimal disruption to the user experience.

10
3. SYSTEM ANALYSIS

4.1 IDENTIFICATION OF NEED


The identification of the need for this project stems from several factors:

4.1.1 Rising Popularity of Music Streaming Platforms

• With the increasing popularity of music streaming services like Spotify, there's a
growing demand for collaborative music playback systems that allow users to listen
to music together in real-time.

4.1.2 Desire for Social Music Listening Experiences

• Many users enjoy listening to music with friends or family members, whether they're
in the same location or miles apart. A collaborative music playback system fulfills
the need for shared music listening experiences.

4.1.3 Enhanced Engagement and Interaction

• Collaborative music playback systems provide an interactive platform where users


can engage with each other while listening to music. It creates opportunities for
social interaction, discussion, and shared enjoyment of music.

4.1.4 Virtual Events and Gatherings

• With the rise of virtual events and gatherings, there's a need for platforms that enable
participants to listen to music together during online parties, virtual hangouts, or
remote celebrations.

4.1.5 Support for Remote Work and Learning

• In remote work and learning environments, collaborative music playback systems can
serve as icebreakers, team-building tools, or background entertainment during
virtual meetings and study sessions.

4.1.6 Customization and Personalization

• Users often have diverse musical preferences and tastes. A collaborative music
playback system allows users to share and discover music based on their individual
preferences, creating personalized listening experiences.

11
4.2 PRELIMINARY INVESTIGATION:
The preliminary investigation of this project involves cconducting initial research and
analysis to gather information and assess the feasibility of the project. It includes the
following steps:

4.2.1 Identifying Stakeholders

• Determine the primary stakeholders involved in the project, including users,


developers, music streaming platforms, and potential collaborators.

4.2.2 Defining Objectives

• Clarify the project's goals and objectives, such as developing a collaborative music
playback system, integrating with the Spotify API, enabling real-time
synchronization of playback, and providing user-friendly interfaces.

4.2.3 Gathering Requirements

• Collect requirements from stakeholders regarding functionality, user experience,


platform compatibility, security, scalability, and other relevant aspects.

4.2.4 Market Analysis

• Conduct a market analysis to understand the current landscape of music streaming


platforms, collaborative music playback systems, and related technologies. Identify
existing solutions, their features, strengths, and weaknesses.

4.2.5 Technical Feasibility

• Assess the technical feasibility of implementing the project, considering factors such
as available resources (e.g., technology stack, development tools), integration with
third-party APIs (e.g., Spotify), and scalability requirements.

4.2.6 Resource Allocation

• Determine the resources needed for the project, including personnel, time, budget,
hardware, and software. Allocate resources effectively to ensure successful project
execution.

12
4.2.7 Risk Assessment

• Identify potential risks and challenges associated with the project, such as technical
complexities, data security concerns, regulatory compliance, and dependencies on
external factors (e.g., API changes).

4.2.8 Cost-Benefit Analysis

• Evaluate the costs and benefits of implementing the project, considering factors such
as development costs, potential revenue streams, market demand, competitive
advantage, and long-term sustainability.

4.3 FEASIBILITY STUDY


A feasibility study for this project would involve evaluating various aspects to determine if
the project is viable and achievable. Here's how it can be approached:

4.3.1 Technical Feasibility

• Assess the technical requirements of integrating with the Spotify API and
implementing real-time synchronization of playback across multiple users.

• Evaluate the compatibility of chosen technologies (Python, Django, React) with the
project requirements.

• Determine if the project can be implemented within the constraints of available


technology stack and development resources.

4.3.2 Financial Feasibility

• Estimate the costs associated with development, including personnel, infrastructure,


software licenses, and any third-party services (such as hosting or Spotify API
access).

• Compare the projected costs with the budget allocated for the project to ensure
financial viability.

• Consider potential revenue streams, such as subscription fees, in-app purchases, or


advertising, to offset development costs.

13
4.3.3 Operational Feasibility

• Evaluate the operational aspects of the project, including how it will be managed,
maintained, and supported post-launch.

• Assess the availability of skilled personnel to develop, deploy, and maintain the
application.

• Consider scalability requirements and whether the project can accommodate growth
in user base and usage over time.

4.3.4 Legal and Regulatory Feasibility

• Identify any legal or regulatory requirements related to music streaming, user data
privacy, copyright, and licensing.

• Ensure compliance with relevant laws and regulations to avoid legal issues and
penalties.

4.3.5 Market Feasibility

• Analyze the market demand for collaborative music playback systems and the
potential user base for the application.

• Identify competitors and assess their offerings, strengths, and weaknesses.

• Determine if the project fills a gap in the market and offers unique features or
advantages compared to existing solutions.

4.3.6 Schedule Feasibility:

• Develop a realistic timeline for project development, testing, and deployment.

• Consider any dependencies, constraints, or risks that may impact the project schedule.

• Ensure that the proposed timeline aligns with stakeholders' expectations and business
objectives.

14
4.4 PROJECT PLANNING
Project planning for this collaborative music playback system involves organizing tasks,
allocating resources, and establishing timelines to ensure successful development and
deployment. Here's an outline of the project planning process:

4.4.1 Define Project Scope and Objectives

• Clearly articulate the goals and objectives of the project, including the features and
functionality of the collaborative music playback system.

• Define the target audience and user requirements to guide development.

4.4.2 Create Work Breakdown Structure (WBS)

• Break down the project into smaller, manageable tasks and subtasks.

• Organize tasks into a hierarchical structure to facilitate planning and resource


allocation.

4.4.3 Estimate Time and Resources

• Estimate the time required to complete each task based on factors such as complexity,
dependencies, and available resources.

• Determine the resources needed for development, including personnel, equipment,


and software tools.

4.4.4 Develop Project Schedule

• Create a project timeline or Gantt chart that outlines the sequence of tasks, milestones,
and deadlines.

• Allocate resources and establish dependencies between tasks to ensure smooth


progress.

4.4.5 Identify Risks and Mitigation Strategies

• Identify potential risks and uncertainties that may impact the project schedule, budget,
or quality.

• Develop strategies to mitigate risks and minimize their impact on the project.

15
• Establish contingency plans to address unforeseen challenges that may arise during
development.

4.4.6 Allocate Responsibilities

• Assign roles and responsibilities to team members based on their skills, expertise, and
availability.

• Clearly communicate expectations and deliverables to ensure accountability and


collaboration.

4.4.7 Monitor and Control Progress

• Regularly monitor project progress against the established schedule and milestones.

• Track resource utilization, budget expenditures, and any deviations from the plan.

• Implement corrective actions as needed to keep the project on track and address any
issues or delays.

4.4.8 Communicate with Stakeholders

• Maintain open communication channels with stakeholders, including clients, team


members, and project sponsors.

• Provide regular updates on project status, accomplishments, and challenges.

• Solicit feedback and address any concerns to ensure stakeholder satisfaction and
alignment with project goals.

4.4.9 Project closure

• Prepare comprehensive documentation that captures all aspects of the project,


including requirements, design decisions, implementation details, and testing results.

• Conduct a post-project review to assess the overall success of the collaborative music
playback system. Evaluate the project against its original objectives, budget, and
schedule.

• Ensure a smooth transition of the collaborative music playback system to the


appropriate stakeholders, such as end-users or operations teams.

16
• Prepare a formal project closure report summarizing the project's outcomes,
achievements, and recommendations for future improvements.

4.5 SOFTWARE REQUIREMENT SPECIFICATIONS (SRS)


The Software Requirements Specification (SRS) for the collaborative music playback system
outlines the functional and non-functional requirements of the software. Here's an overview
of the SRS:

4.5.1 Introduction

 Provide an overview of the collaborative music playback system.

 Describe the purpose, scope, and objectives of the software.

 Identify stakeholders and their roles in the project.

4.5.2 Functional Requirements

• User Management

• Users can register and log in using their Spotify accounts.

• Hosts can create rooms and manage room settings.

• Guests can join rooms using unique codes generated by hosts.

• Music Playback

• Users can play, pause, skip, and control playback of music tracks.

• Hosts can control playback permissions for guests.

• Real-time Synchronization

• Music playback is synchronized across all connected users in the same room.

• Voting System

• Users can vote to skip tracks, with the option for hosts to set the minimum
number of votes required.

17
• Room Management

• Hosts can set room parameters such as maximum number of participants,


playback control options, and voting system settings.

• Hosts can close the room, preventing new participants from joining.

• User Interaction

• Users can chat with other participants in the same room, enhancing social
interaction.

• Hosts can broadcast messages to all participants in the room, such as


announcements or song dedications.

• Playback History

• The system maintains a playback history for each room, allowing users to
view previously played tracks and their associated metadata.

• Guest Permissions

• Hosts can grant specific permissions to individual guests, such as allowing


certain users to control playback or skip tracks.

• Playlist Management

• Users can create and manage playlists within the application, adding or
removing tracks from their personal collection.

• Hosts can create shared playlists for the entire room to collaborate on.

4.5.3 Non-Functional Requirements

• Performance

• The system should have low latency for real-time synchronization.

• It should support a large number of concurrent users without degradation in


performance.

• Security

• User authentication and authorization should be implemented securely


using OAuth 2.0.
18
• Data transmission should be encrypted to protect user privacy.

• Reliability

• The system should be highly available and resilient to failures.

• It should gracefully handle errors and recover from faults.

• Usability

• The user interface should be intuitive and user-friendly.

• It should provide feedback and guidance to users as they interact with the
system.

• Accessibility

• The user interface should be accessible to users with disabilities, complying


with accessibility standards such as WCAG (Web Content Accessibility
Guidelines).

• Support for screen readers and keyboard navigation should be provided.

• Scalability

• The system should be designed to scale both vertically and horizontally to


handle increases in user traffic and data volume.

• Load balancing and caching mechanisms should be implemented to distribute


workload efficiently.

• Internationalization and Localization

• The application should support multiple languages and locales to


accommodate users from different regions.

• Text and user interface elements should be easily translatable and


customizable.

• Data Privacy and GDPR Compliance

• The system should adhere to data privacy regulations such as GDPR (General
Data Protection Regulation).

19
• User consent mechanisms should be implemented for data collection and
processing activities.

• Error Handling and Logging

• Comprehensive error handling should be in place to gracefully manage


exceptions and errors.

• Logs should be generated for system events, user actions, and error conditions,
aiding in troubleshooting and auditing.

4.5.4 External Interfaces

 Spotify API

• Integration with the Spotify API for music playback and user authentication.

 Frontend Interface

• Interaction with the frontend application developed using React.js.

 Database Interface

• Interaction with the database to store user information, room settings, and playback
data.

4.5.5 Constraints

 Technology Stack

➢ Front-End Development

❖ HTML(Hypertext Markup Language)

HTML, or Hypertext Markup Language, is the standard language used to create and
design web pages. It provides the structure for web content by using various tags and
attributes to define elements on a page. HTML is the backbone of web development,
providing the foundation for creating visually appealing and interactive web pages. It
works hand in hand with CSS (Cascading Style Sheets) for styling and JavaScript for
interactivity, forming the core technologies of the World Wide Web.

20
Overview of HTML

▪ Tags: HTML is built on tags, which are enclosed in angle brackets `< >`. Tags
are used to define different types of content on a webpage, such as headings,
paragraphs, images, links, and more.

▪ Elements: HTML elements are made up of tags and the content they surround.
For example, a paragraph element `<p>` starts with an opening tag and ends with
a closing tag `</p>`, enclosing the paragraph text.

▪ Attributes: Tags can have attributes that provide additional information about an
element. Attributes are placed within the opening tag and typically come inname-
value pairs, such as `href` in an anchor tag `<a href="https://example.com">`.

▪ Document Structure: HTML documents have a specific structure consisting of an


opening `<html>` tag followed by `<head>` and `<body>` tags. The `<head>`
section typically contains metadata like the page title, links to stylesheets, and
scripts. The `<body>` section contains the visible content of the webpage.

▪ Semantic Markup: HTML5 introduced semantic elements that provide more


meaning to the content, making it easier for search engines and assistive
technologies to understand. Examples include `<header>`, `<footer>`, `<nav>`,
`<article>`, `<section>`, `<aside>`, etc.

HTML Tags Used

▪ HTML: The HTML element (`<html>`) is the root element of an HTML page. It
wraps all the content on the page.

▪ Head: The head element (`<head>`) contains metadata and links to external
resources used by the HTML document. It doesn't display any content directly to
the user.

▪ Meta: The meta element (`<meta>`) is used to provide metadata about the HTML
document. Common uses include specifying the character encoding (`charset`
attribute) and setting the viewport for responsive design (`viewport` attribute).

21
▪ Title: The title element (`<title>`) sets the title of the HTML document, which is
displayed in the browser's title bar or tab. It's also used by search engines for page
indexing and in bookmarks.

▪ Script:The script element (`<script>`) is used to embed or reference executable


code, typically JavaScript, within an HTML document. It can be used to add
interactivity, handle events, manipulate the DOM, and more.

▪ Div: The div element (`<div>`) is a generic container used to group and style
HTML elements. It's often used to create sections or divisions within a webpage
and is styled using CSS.

▪ Body: The body element (`<body>`) contains the content of the HTML document
that's displayed to the user. It includes text, images, links, forms, and other
elements that make up the visible part of the webpage.

❖ CSS(Cascading Style Sheets)

CSS (Cascading Style Sheets) is a language used for describing the presentation
of a document written in HTML (HyperText Markup Language). Here's an overview
of CSS:

▪ Selectors: CSS selectors are patterns used to select the elements you want to
style. They can select elements based on their tag name, class, ID, attributes, and
more. They are a fundamental part of CSS syntax and play a crucial role in
styling web pages.

▪ Properties and Values: CSS properties are the styling attributes you can apply to
selected elements. Each property has a specific value associated with it that
defines how the property should be applied. Examples of properties include
`color`, `font-size`, `background-color`, `margin`, `padding`, and `border`.

▪ Cascading: CSS stands for "Cascading" Style Sheets, which refers to the way
styles are applied to elements. Styles can be inherited from parent elements,
overridden by more specific selectors, or overwritten by inline styles.

▪ Units: CSS supports different units of measurement for specifying sizes and
distances, such as pixels (`px`), percentages (`%`), ems (`em`), rems (`rem`), and
viewport units (`vw`, `vh`, `vmin`, `vmax`).

22
❖ JavaScript

JavaScript (JS) serves as the primary language for adding interactivity and
dynamic behavior to web pages. Here's an overview of JavaScript within the
project context:

▪ Client-Side Scripting: JavaScript is primarily used for client-side scripting,


meaning it runs in the user's web browser rather than on the server. This
allows for dynamic content manipulation without needing to reload the entire
page.

▪ DOM Manipulation: One of the core features of JavaScript is its ability to


manipulate the Document Object Model (DOM). The DOM represents the
structure of HTML elements on a web page, and JavaScript can be used to
access, modify, or delete these elements dynamically.

▪ Event Handling: JavaScript enables event-driven programming, where


functions (event handlers) are executed in response to user actions or system
events. Common events include clicks, mouse movements, keyboard inputs,
form submissions, and page loads.

▪ AJAX (Asynchronous JavaScript and XML): AJAX allows for asynchronous


communication between the web browser and the server, enabling data to be
exchanged with the server in the background without interfering with the
current page. This is commonly used to update parts of a web page without
requiring a full reload.

▪ API Integration: JavaScript can interact with various APIs (Application


Programming Interfaces) to access external services and data. This includes
fetching data from servers, integrating with third-party services (e.g., social
media platforms, mapping services), and performing operations like
authentication and authorization.

▪ Form Validation: JavaScript can be used to validate form inputs in real-time,


providing instant feedback to users and preventing invalid data submission.
This helps improve the user experience and ensures data integrity.

23
▪ Animation and Effects: JavaScript can create animations and visual effects on
web pages using techniques like CSS animations, transitions, and
libraries/frameworks such as jQuery or GSAP (GreenSock Animation
Platform).

▪ Error Handling and Debugging: JavaScript provides mechanisms for error


handling and debugging, including try-catch blocks, console logging, and
browser developer tools. Proper error handling ensures graceful degradation
in case of errors and helps developers identify and fix issues.

▪ Modularization and Libraries: JavaScript supports modular programming


through the use of modules, allowing code to be organized into reusable
components. Additionally, developers often leverage third-party libraries and
frameworks (e.g., React.js, Vue.js, AngularJS) to streamline development and
add advanced features.

▪ Security Considerations: When working with JavaScript, security is a critical


consideration. Developers must be mindful of potential security
vulnerabilities such as cross-site scripting (XSS) attacks and implement best
practices to protect against them.

❖ React

React is a JavaScript library used for building user interfaces, particularly for
single-page applications (SPAs) where content is dynamically updated without
requiring full page reloads. Here's an overview of React within this project:

▪ Component-Based Architecture: React follows a component-based


architecture, where UIs are composed of reusable components. Each
component encapsulates its own logic, state, and markup, making it easier
to manage and maintain complex user interfaces.

▪ Virtual DOM: React uses a virtual DOM (Document Object Model) to


efficiently update the UI. Instead of directly manipulating the browser's
DOM, React creates a lightweight in-memory representation of the DOM
and updates it as needed. This approach minimizes unnecessary DOM
manipulation and leads to better performance.

24
▪ JSX (JavaScript XML): React utilizes JSX, a syntax extension that allows
developers to write HTML-like code within JavaScript. JSX makes it
easier to describe UI components and their structure, combining HTML
markup with JavaScript logic seamlessly.

▪ State Management: React components can have state, which represents


data that can change over time. By using the `useState` hook (or `setState`
method in class components), developers can manage and update
component state, triggering re-renders as necessary to reflect state changes
in the UI.

▪ Props (Properties): React components can receive data via props, which
are essentially read-only inputs passed from parent to child components.
Props allow for communication between components and enable
component customization and reusability.

▪ Lifecycle Methods (Class Components): Class components in React have


lifecycle methods that are invoked at different stages of a component's
lifecycle, such as mounting, updating, and unmounting. These methods
can be used to perform initialization, data fetching, and cleanup tasks.

▪ Hooks (Functional Components): Functional components in React can use


hooks to add state and other features previously exclusive to class
components. Hooks like `useEffect`, `useContext`, and `useReducer`
enable functional components to manage state, perform side effects, and
access context without needing to use class syntax.

▪ Routing: React applications often use a router library (such as React


Router) to handle client-side routing and navigation. This allows for the
creation of multi-page experiences within a single-page application, with
different components rendered based on the URL.

▪ Server-Side Rendering (SSR): While not necessarily applicable to all


React projects, SSR is a technique used to render React components on
the server side and send HTML to the client. This can improve
performance and SEO by providing faster initial page loads and ensuring
content is indexable by search engines.

25
▪ Component Libraries and Ecosystem: React has a rich ecosystem of third-
party libraries and tools that extend its capabilities. This includes state
management libraries like Redux, UI component libraries like Material-UI
or Ant Design, and development tools like React DevTools and Create
React App.

➢ Back-End Development

❖ Python

Python serves as the backend language, responsible for handling server-side logic,
database interactions, and API endpoints. Python serves as the backend language,
responsible for handling server-side logic, database interactions, and API
endpoints.

▪ Django Framework: The project likely uses the Django web framework, which
is a high-level Python web framework that encourages rapid development and
clean, pragmatic design. Django provides a set of built-in tools and
conventions for handling common web development tasks, such as URL
routing, database modeling, and user authentication.

▪ API Endpoints: Python code defines API endpoints using Django's `django-
rest-framework` or similar libraries. These endpoints handle incoming HTTP
requests from the frontend, perform necessary data processing or database
operations, and return appropriate HTTP responses (usually in JSON format)
containing the requested data or indicating the outcome of the request.

▪ Model-View-Controller (MVC) Architecture: Django follows the MVC


architectural pattern, although in Django's terminology it's referred to as
Model-View-Template (MVT). Models define the structure and behavior of the
application's data, views handle the presentation logic and interact with
models, and templates render HTML pages to be served to the client.

▪ ORM (Object-Relational Mapping): Django provides an ORM layer that


abstracts away the details of database interaction, allowing developers to work
with database tables and records using Python classes and methods. Models in
Django represent database tables, and queries are performed using Python
syntax rather than raw SQL.
26
▪ Middleware: Django middleware allows for processing of requests and
responses before and after they reach the view layer. Middleware can perform
tasks such as authentication, request/response logging, error handling, and
more.

▪ Session Management and Authentication: Django provides built-in support for


user authentication and session management. Developers can easily integrate
features like user registration, login, logout, password management, and access
control using Django's authentication system.

▪ URL Routing: Django's URL routing mechanism maps incoming HTTP


requests to the appropriate view functions based on URL patterns defined in
the project's URL configuration. This allows for clean and organized URL
structures and separation of concerns between different parts of the application.

▪ Task Queues and Background Jobs: For handling long-running or


asynchronous tasks, Python code may use task queue libraries like Celery in
combination with a message broker such as Redis or RabbitMQ. This allows
tasks to be executed asynchronously outside of the request-response cycle,
improving application performance and scalability.

▪ Third-Party Libraries: Python's extensive ecosystem of third-party libraries and


packages may be leveraged for various purposes within the project, such as
handling date/time operations, working with external APIs, performing data
validation, and more.

❖ Django

Django serves as the web framework for building the backend of the application.
Django provides a comprehensive set of tools and conventions for building web
applications quickly and efficiently. Its batteries-included approach, robust security
features, and thriving ecosystem of third-party packages make it a popular choice
for building scalable and maintainable web applications.

▪ Model-View-Template (MVT) Architecture: Django follows the MVT


architectural pattern, which is a variation of the traditional Model-View-
Controller (MVC) pattern. In Django, models represent the data structure,

27
views handle the logic to process requests and generate responses, and
templates are used for rendering HTML pages.

▪ URL Routing: Django's URL dispatcher maps URL patterns to view functions
or classes, allowing developers to define how different URLs should be
handled by the application. URL patterns are typically defined in the project's
`urls.py` file and may include regular expressions or path converters to capture
dynamic parts of the URL.

▪ Models and ORM: Django provides an Object-Relational Mapping (ORM)


layer that allows developers to define database models using Python classes.
Models represent database tables, and fields within models represent table
columns. Django's ORM abstracts away the need to write SQL queries directly,
making it easier to interact with the database using Python code.

▪ Admin Interface: Django comes with a built-in administration interface that


can be automatically generated based on the project's models. This admin
interface allows authorized users to view, create, update, and delete records in
the database without writing any custom code. Admin functionality can be
customized and extended as needed.

▪ Forms and Validation: Django provides a forms library for handling HTML
forms and form data. Forms can be created using Python classes, and Django
handles tasks such as form rendering, data validation, and error handling
automatically. Forms can be used in views to process user input and interact
with the database.

▪ Middleware: Django middleware allows for processing of requests and


responses at various points in the request-response cycle. Middleware
components can perform tasks such as authentication, request/response
logging, CORS handling, and more. Middleware can be applied globally to all
requests or selectively to specific URL patterns.

▪ Authentication and Authorization: Django provides built-in support for user


authentication and authorization. The authentication system handles tasks such
as user login, logout, password management, and session management.

28
Authorization can be enforced using decorators or middleware to restrict
access to certain views or resources.

▪ Template Engine: Django's template engine allows developers to create HTML


templates that can be dynamically rendered with data from views. Templates
support template inheritance, template tags and filters, and other features to
facilitate code reuse and maintainability.

▪ Static Files and Media Handling: Django provides utilities for managing static
files (e.g., CSS, JavaScript) and media files (e.g., user-uploaded images,
videos). Static files are typically served directly by the web server in
production, while media files are stored locally or on a cloud storage service
like Amazon S3.

▪ Internationalization and Localization: Django supports internationalization


(i18n) and localization (l10n) out of the box, allowing developers to build
applications that support multiple languages and locales. Translation strings
can be marked for translation in Python code and templates, and Django
provides tools for generating translated versions of the application's content.

➢ API

❖ Spotify API:

The Spotify API is utilized to integrate music playback and management


functionality into the application. The integration of the Spotify API enhances the
functionality of the application by allowing users to access and control their
Spotify accounts directly within the application. This integration enables features
such as music playback, playlist management, and personalized recommendations,
enriching the user experience and making the application more engaging and
interactive.

▪ Authentication: The application implements OAuth 2.0 authentication to allow


users to connect their Spotify accounts. This involves obtaining authorization
from Spotify to access the user's account data and playback functionality.
Users are redirected to the Spotify authorization page, where they grant
permission to the application. Upon authorization, the application receives an

29
access token, which is used to make authenticated requests to the Spotify API
on behalf of the user.

▪ Authorization Code Flow: The application uses the authorization code flow to
authenticate users with Spotify. This flow involves redirecting the user to the
Spotify authorization page with specific parameters, including the client ID,
redirect URI, and requested scopes (permissions). After the user grants
permission, Spotify redirects back to the application with an authorization
code, which is exchanged for an access token and refresh token.

▪ Fetching Current Song: The application periodically fetches information about


the currently playing song from the Spotify API. This information includes
details such as the song title, artist, album, playback progress, and album cover
art. The fetched data is then displayed to the user in the application's user
interface, allowing them to see what song is currently playing.

▪ Playback Control: The application allows users to control playback actions


such as play, pause, and skip through the Spotify API. When a user interacts
with playback controls in the application's user interface, corresponding
requests are sent to the Spotify API to perform the desired action on the user's
active playback session.

▪ Error Handling and Edge Cases: The application handles potential errors and
edge cases that may arise during interactions with the Spotify API. This
includes scenarios such as invalid access tokens, expired tokens, rate limiting,
and network errors. Error handling mechanisms ensure that the application
provides a smooth and reliable user experience even in the face of API-related
issues.

30
 Scalability:

• The system should be designed to scale horizontally to accommodate future


growth in user base and usage.

4.5.6 Appendices

 Include any additional information relevant to the software requirements, such as use
case diagrams, data flow diagrams, or mockups.

4.6 SOFTWARE ENGINEERING PARADIGM APPLIED


The software engineering paradigm applied for this project is likely Agile. Agile
methodology emphasizes iterative development, collaboration, and flexibility, which are
crucial for a dynamic project like a collaborative music playback system. Here's how Agile
principles align with the project's requirements:

31
4.6.1 Iterative Development: The project can be broken down into smaller increments or
iterations, allowing for continuous improvement and feedback throughout the development
process. Features can be implemented incrementally, with regular demonstrations to
stakeholders for feedback and validation.

4.6.2 Collaborative Approach: Agile promotes collaboration among cross-functional teams,


including developers, designers, and stakeholders. In the context of this project, collaboration
is essential between frontend and backend developers, UI/UX designers, and potentially
external stakeholders such as music streaming service providers.

4.6.3 Adaptability to Change: Agile methodologies prioritize adaptability to changing


requirements and priorities. Given the dynamic nature of the music industry and user
preferences, the project needs to be flexible in accommodating new features, enhancements,
and adjustments based on user feedback and market trends.

4.6.4 Customer-Centric Focus: Agile places a strong emphasis on delivering value to the
customer. In this project, the customer-centric focus means prioritizing features and
functionalities that align with user needs and preferences, ensuring a positive user experience.

4.6.5 Continuous Delivery: Agile encourages frequent releases of working software,


allowing for rapid feedback and validation from users. Continuous integration and
deployment practices enable the team to deliver updates and improvements to the
collaborative music playback system efficiently and reliably.

4.6.6 Sprint Planning: The project team conducts regular sprint planning meetings to
prioritize tasks and set goals for each iteration. This ensures that development efforts are
focused on delivering the most valuable features incrementally.

4.6.7 Daily Stand-ups: Daily stand-up meetings are held to provide a forum for team
members to discuss progress, identify any impediments, and coordinate their efforts. These
short, focused meetings help maintain alignment and address any issues promptly.

4.6.8 Iterative Feedback: Agile encourages continuous feedback loops, both from
stakeholders and end-users. Regular demos and reviews allow stakeholders to provide
feedback on the product's features and functionality, facilitating early course correction and
improvement.

32
4.6.9 Empowered Teams: Agile principles promote self-organizing, empowered teams that
take ownership of their work. Team members have the autonomy to make decisions and
adapt to changing requirements, fostering a sense of accountability and commitment to
project success.

4.6.10 Continuous Improvement: Agile embraces a culture of continuous improvement,


where teams reflect on their processes and outcomes at the end of each iteration.
Retrospective meetings provide an opportunity to identify what went well, what could be
improved, and actionable steps for enhancement in subsequent iterations.

4.6.11 Adaptive Planning: Agile methodologies recognize that requirements and priorities
may evolve over time. The project plan remains flexible, allowing for adjustments based on
feedback, changes in market conditions, or emerging opportunities.

4.6.12 Transparency and Communication: Agile promotes transparency and open


communication within the project team and with stakeholders. Regular progress updates,
clear documentation, and collaboration tools facilitate effective communication and
alignment of objectives.

33
4. SYSTEM DESIGN AND SPECIFICATIONS
The system design and specifications for this project outline the architecture, components,
and functionality of the collaborative music playback system. Here's an overview:

❖ Architecture:

 The system follows a client-server architecture, where the server hosts the backend
logic and data storage, while the client interacts with the user through a web-based
interface.

 Backend components include Django framework for server-side logic, Spotify API
integration for music playback functionality, and a PostgreSQL database for storing
user data and room information.

 Frontend components utilize React.js for building interactive user interfaces and
managing state.

❖ Components:

 Backend Components:

• Django REST framework for building RESTful APIs to handle user


authentication, room management, music playback control, and voting.

• Spotify API integration for authenticating users, accessing music catalogs,


controlling playback, and retrieving song information.

• PostgreSQL database for storing user profiles, room details, playback history, and
voting data.

 Frontend Components:

• React.js for building modular UI components, managing state, and handling user
interactions.

• Material-UI library for designing responsive and visually appealing user interfaces.

• React Router for client-side routing to navigate between different views within the
application.

34
❖ Functionality:

 User Authentication: Users can log in to the system using their Spotify accounts to
access the collaborative music playback features.

 Room Management: Hosts can create a room and generate a unique code that other
users can use to join the room. Hosts can also set room preferences such as playback
control permissions and voting requirements.

 Music Playback: Users can play, pause, skip tracks, and adjust playback volume
within the room. Playback control permissions are determined by the host's settings.

 Synchronization: Playback is synchronized across all connected users in the same


room to ensure a consistent listening experience.

 Voting System: Users can vote to skip tracks, and tracks are skipped when the
required number of votes is reached.

 Real-time Updates: Hosts can update playback control settings and voting
requirements in real-time, reflecting changes immediately for all users in the room.

❖ Specifications:

 System supports concurrent user sessions with efficient handling of authentication and
session management.

 Integration with Spotify API ensures seamless access to music catalogs, playback
control, and user authentication.

 Web-based interface is responsive, user-friendly, and accessible across different


devices and screen sizes.

 Backend APIs follow RESTful principles, with clear endpoints, request/response


formats, and error handling mechanisms.

 Data storage and retrieval operations are optimized for performance and scalability,
ensuring smooth operation even under high user loads.

35
❖ SOFTWARE DESIGN

In designing the software following principles are followed:

 Modularity and partitioning: Software is designed such that, each system should
consists of hierarchy of modules and serve to partition into separate function.

 Coupling: Modules should have little dependence on other modules of a system.

 Cohesion: Modules should carry out in a single processing function.

 Shared use: Avoid duplication by allowing a single module be called by other that
need the function it provides.

❖ MODULE DESIGN

The major modules of the project are:

 Home Module

 Spotify Login Module

 Create Room Module

 Join Room Module

 Update Room Module

 Music Player Module

 Home Module:

 Displays the home page of the application.

 Provides options for users to create or join rooms..

 Includes features for browsing and searching for existing rooms.

 Spotify Login Module:

 Integrates Spotify authentication for user login.

36
 Handles the OAuth flow for obtaining user authorization.

 Retrieves user profile information and access tokens for Spotify API interaction.

 Create Room Module:

 Allows authenticated users to create new rooms.

 Generates a unique room code for each created room.

 Sets room preferences such as playback control and voting options.

 Join Room Module:

 Enables users to join existing rooms using room codes.

 Validates room codes and grants access to authorized users.

 Provides feedback on successful or failed room joining attempts.

 Update Room Module:

 Facilitates room settings updates by the host.

 Allows hosts to modify playback control permissions, voting rules, etc.

 Ensures that only authorized hosts can update room settings.

 Music Player Module:

 Displays information about the currently playing song, including the title, artist,
album cover, playback progress, and voting details.

 Users can interact with the music player through buttons such as play, pause, and
skip. These buttons trigger actions to control the playback accordingly.

 It also displays the number of votes each song has received for skipping

 Allows users to vote on whether to skip the current track.

37
❖ DATABASE DESIGN

 MODEL NAME: Room


Field name Data Type
code CharField
host CharField
guest_can_pause BooleanField
votes_to_skip IntegerField
created_at DateTimeField
current_song CharField

 MODEL NAME: SpotifyToken


Field name Data Type
user CharField
created_at DateTimeField
refresh_token CharField
access_token CharField
expires_in DateTimeField
token_type CharField

 MODEL NAME: Vote


Field name Data Type
user CharField
created_at DateTimeField
song_id CharField
room CharField

38
❖ INPUT/OUTPUT DESIGN

 Input Design
The input design for the collaborative music playback system involves defining how
users interact with the application to input commands, preferences, and data. Here's an
overview of the input design:

o User Interface (UI):

 The UI includes various input elements such as text fields, buttons, dropdowns,
and sliders.

 Users interact with these elements to perform actions like logging in, creating
rooms, joining rooms, controlling playback, and voting on tracks.

o Authentication Inputs:

 Input fields for users to enter their login credentials (username/email and
password) during the authentication process.

 OAuth login buttons to initiate authentication with third-party services like


Spotify.

o Room Creation Inputs:

 Text fields for specifying room preferences such as room name, playback
control permissions, and voting rules.

 Buttons to confirm room creation and submit the preferences.

o Room Joining Inputs:

 Text field for entering the room code when joining an existing room.

 Button to submit the room code and join the room.

o Room Update Inputs:

 Input fields or dropdowns to adjust room settings such as playback control


permissions, voting thresholds, and other configurations.

 Buttons to apply the changes and update the room settings.

39
o Playback Control Inputs:

 Playback control buttons for playing, pausing, skipping tracks, adjusting


volume, and seeking within tracks.

 Slider or input field for controlling volume level.

o Voting Inputs:

 Voting buttons or checkboxes displayed during track playback to allow users to


vote on track skipping.

 Feedback messages indicating the status of the vote .

 Output Design
The output design of the project involves presenting information and feedback to
users based on their interactions with the system. Here's an overview of the output
design elements in our collaborative music playback system:

 User Interface: The system provides a user-friendly interface using React and
Material-UI components. It includes screens for different functionalities like
home, room creation, room joining, music playback, and settings.

 Room Information: Upon joining a room or creating a new one, users see
relevant information such as the room code, current song details, playback
controls, and voting status.

 Music Playback: The output design includes a music player interface with
controls for play, pause, and skip. It also displays the current song's title, artist,
album cover, playback progress, and voting details.

 Real-time Updates: Users receive real-time updates on song changes,


playback status, and voting results. This ensures that everyone in the room
stays synchronized with the latest information.

40
5.1 DATA MODEL(LIKE DFD)

A Data Flow Diagram (DFD) is a traditional visual representation of the information flows
within a system. A neat and clear DFD can depict the right amount of the system requirement
graphically. It can be manual, automated, or a combination of both.

It shows how data enters and leaves the system, what changes the information, and where
data is stored.

The objective of a DFD is to show the scope and boundaries of a system as a whole. It may
be used as a communication tool between a system analyst and any person who plays a part
in the order that acts as a starting point for redesigning a system. The DFD is also called as a
data flow graph or bubble chart.

Data Flow Diagrams are of two types:

1) Physical Data Flow Diagrams: These are implementation-dependent i.e.,


they show the actual devices, departments, people, etc., involved in the
system.
2) Logical Data Flow Diagrams: These diagrams describe the system
independently of how it is actually implemented, they show what takes
places, rather than how an activity is accomplished.
Standard Symbol of DFD
➢ Data Flow: Data move in a specific direction from an origin to destination. The
data flow is a “packet” of data.

➢ Process: People, procedures or devices that produce data. The physical


component is not identified.

41
➢ Source or Destination of Data: External sources or destinations of data, which
may be people or organizations or other entities.

➢ Data Source: Here a process references the data in the system.

5.1.1 LEVEL 0 DFD


This is the highest-level DFD, which provides an overview of the entire system. It shows
the major processes, data flows, and data stores in the system, without providing any details
about the internal workings of these processes.

It is also known as a context diagram. It’s designed to be an abstraction view, showing the
system as a single process with its relationship to external entities. It represents the entire
system as a single bubble with input and output data indicated by incoming/outgoing
arrows.

42
5.1.2 Level 1 DFD
This level provides a more detailed view of the system by breaking down the major
processes identified in the level 0 DFD into sub-processes. Each sub-process is depicted as
a separate process on the level 1 DFD. The data flows and data stores associated with each
sub-process are also shown.

In 1-level DFD, the context diagram is decomposed into multiple bubbles/processes. In this
level, we highlight the main functions of the system and breakdown the high-level process
of 0-level DFD into subprocesses.

43
5.2 ENTITY RELATIONSHIP MODEL
ER model stands for an Entity-Relationship model. It is a high-level data model. This model
is used to define the data elements and relationship for a specified system.

It develops a conceptual design for the database. It also develops a very simple and easy to
design view of data.

In ER modeling, the database structure is portrayed as a diagram called an entity-relationship


diagram.

5.3 USE CASE DIAGRAM


A Use Case Diagram is a type of Unified Modeling Language (UML) diagram that
represents the interaction between actors (users or external systems) and a system under
consideration to accomplish specific goals. It provides a high-level view of the system’s
functionality by illustrating the various ways users can interact with it.

44
5.4 CLASS DIAGRAM
Class diagrams are a type of UML (Unified Modeling Language) diagram used in software
engineering to visually represent the structure and relationships of classes within a system
i.e. used to construct and visualize object-oriented systems.

45
Class diagrams provide a high-level overview of a system’s design, helping to
communicate and document the structure of the software. They are a fundamental tool in
object-oriented design and play a crucial role in the software development lifecycle.

46
5.5 STATE DIAGRAM/SEQUENCE DIAGRAM
A sequence diagram shows process interactions arranged in time sequence. This diagram
depicts the processes and objects involved and the sequence of messages exchanged as
needed to carry out the functionality.

47
5. SOURCE CODE
6.1 HTML template that provides structure to the application

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>Tune Troop</title>

{% load static %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<link

rel="stylesheet"

href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"

/>

<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"

/>

</head>

<body>

<div id="gradient">

<div id="main">

<div id="app"></div>

</div>

</div>

<script src="{% static "frontend/main.js" %}"></script>

</body>

</html>

48
6.2 CSS for styling
html,

body {

height: 100%;

margin: 0;

padding: 0;

#main {

position: fixed;

width: 100%;
height: 100%;

left: 0;

top: 0;

#app {

width: 100%;

height: 100%;

.center {

position: absolute;

top: 50%;
left: 50%;

transform: translate(-50%, -50%);

#gradient {

49
width: 100%;

height: 800px;

padding: 0px;

margin: 0px;

6.3 JavaScript to dynamically update the background


import App from "./components/App";

var colors = new Array(

[62,35,255],

[60,255,60],

[255,35,98],

[45,175,230],

[255,0,255],

[255,128,0]);

var step = 0;

//color table indices for:

// current color left

// next color left

// current color right

// next color right

var colorIndices = [0,1,2,3];

//transition speed

var gradientSpeed = 0.002;

function updateGradient()

50
{

if ( $===undefined ) return;

var c0_0 = colors[colorIndices[0]];

var c0_1 = colors[colorIndices[1]];

var c1_0 = colors[colorIndices[2]];

var c1_1 = colors[colorIndices[3]];

var istep = 1 - step;

var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);

var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);

var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);

var color1 = "rgb("+r1+","+g1+","+b1+")";

var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);

var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);

var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);

var color2 = "rgb("+r2+","+g2+","+b2+")";

$('#gradient').css({

background: "-webkit-gradient(linear, left top, right top, from("+color1+"),


to("+color2+"))"}).css({

background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});

step += gradientSpeed;

if ( step >= 1 )

step %= 1;

51
colorIndices[0] = colorIndices[1];

colorIndices[2] = colorIndices[3];

//pick two new target color indices

//do not pick the same as the current one

colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length -


1))) % colors.length;

setInterval(updateGradient,10);

6.4 Creation of Django model ‘Room’


from django.db import models

import string

import random

def generate_unique_code():

length = 6

while True:

code = ''.join(random.choices(string.ascii_uppercase, k=length))

if Room.objects.filter(code=code).count() == 0:

break

return code

52
class Room(models.Model):

code = models.CharField(

max_length=8, default=generate_unique_code, unique=True)

host = models.CharField(max_length=50, unique=True)

guest_can_pause = models.BooleanField(null=False, default=False)

votes_to_skip = models.IntegerField(null=False, default=1)

created_at = models.DateTimeField(auto_now_add=True)

current_song = models.CharField(max_length=50, null=True)

6.5 Creation of serializers for the ‘Room’ model in the Django REST
Framework
from rest_framework import serializers

from .models import Room

class RoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('id', 'code', 'host', 'guest_can_pause',

'votes_to_skip', 'created_at')

class CreateRoomSerializer(serializers.ModelSerializer):

class Meta:

model = Room

fields = ('guest_can_pause', 'votes_to_skip')

class UpdateRoomSerializer(serializers.ModelSerializer):

code = serializers.CharField(validators=[])

53
class Meta:

model = Room
fields = ('guest_can_pause', 'votes_to_skip', 'code')

6.6 Django views for handling room-related operations


from django.shortcuts import render

from rest_framework import generics, status

from .serializers import RoomSerializer, CreateRoomSerializer, UpdateRoomSerializer

from .models import Room

from rest_framework.views import APIView

from rest_framework.response import Response

from django.http import JsonResponse

class RoomView(generics.ListAPIView):

queryset = Room.objects.all()

serializer_class = RoomSerializer

class GetRoom(APIView):

serializer_class = RoomSerializer

lookup_url_kwarg = 'code'

def get(self, request, format=None):

code = request.GET.get(self.lookup_url_kwarg)

if code != None:

room = Room.objects.filter(code=code)

if len(room) > 0:

data = RoomSerializer(room[0]).data

data['is_host'] = self.request.session.session_key == room[0].host

54
return Response(data, status=status.HTTP_200_OK)

return Response({'Room Not Found': 'Invalid Room Code.'},


status=status.HTTP_404_NOT_FOUND)

return Response({'Bad Request': 'Code paramater not found in request'},


status=status.HTTP_400_BAD_REQUEST)

class JoinRoom(APIView):

lookup_url_kwarg = 'code'

def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

code = request.data.get(self.lookup_url_kwarg)

if code != None:

room_result = Room.objects.filter(code=code)

if len(room_result) > 0:

room = room_result[0]

self.request.session['room_code'] = code

return Response({'message': 'Room Joined!'}, status=status.HTTP_200_OK)

return Response({'Bad Request': 'Invalid Room Code'},


status=status.HTTP_400_BAD_REQUEST)

return Response({'Bad Request': 'Invalid post data, did not find a code key'},
status=status.HTTP_400_BAD_REQUEST)

class CreateRoomView(APIView):

serializer_class = CreateRoomSerializer

55
def post(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

host = self.request.session.session_key

queryset = Room.objects.filter(host=host)

if queryset.exists():

room = queryset[0]

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

else:

room = Room(host=host, guest_can_pause=guest_can_pause,

votes_to_skip=votes_to_skip)
room.save()

self.request.session['room_code'] = room.code

return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)

return Response({'Bad Request': 'Invalid data...'},


status=status.HTTP_400_BAD_REQUEST)

class UserInRoom(APIView):

56
def get(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

data = {

'code': self.request.session.get('room_code')

return JsonResponse(data, status=status.HTTP_200_OK)

class LeaveRoom(APIView):

def post(self, request, format=None):

if 'room_code' in self.request.session:

self.request.session.pop('room_code')

host_id = self.request.session.session_key

room_results = Room.objects.filter(host=host_id)

if len(room_results) > 0:

room = room_results[0]

room.delete()

return Response({'Message': 'Success'}, status=status.HTTP_200_OK)

class UpdateRoom(APIView):

serializer_class = UpdateRoomSerializer

def patch(self, request, format=None):

if not self.request.session.exists(self.request.session.session_key):

self.request.session.create()

serializer = self.serializer_class(data=request.data)

57
if serializer.is_valid():

guest_can_pause = serializer.data.get('guest_can_pause')

votes_to_skip = serializer.data.get('votes_to_skip')

code = serializer.data.get('code')

queryset = Room.objects.filter(code=code)
if not queryset.exists():

return Response({'msg': 'Room not found.'},


status=status.HTTP_404_NOT_FOUND)

room = queryset[0]

user_id = self.request.session.session_key

if room.host != user_id:

return Response({'msg': 'You are not the host of this room.'},


status=status.HTTP_403_FORBIDDEN)

room.guest_can_pause = guest_can_pause

room.votes_to_skip = votes_to_skip

room.save(update_fields=['guest_can_pause', 'votes_to_skip'])

return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)

return Response({'Bad Request': "Invalid Data..."},


status=status.HTTP_400_BAD_REQUEST)

6.7 URL Patterns for routing HTTP requests


from django.urls import path

from .views import RoomView, CreateRoomView, GetRoom, JoinRoom, UserInRoom,


LeaveRoom, UpdateRoom

58
urlpatterns = [

path('room', RoomView.as_view()),

path('create-room', CreateRoomView.as_view()),

path('get-room', GetRoom.as_view()),

path('join-room', JoinRoom.as_view()),

path('user-in-room', UserInRoom.as_view()),

path('leave-room', LeaveRoom.as_view()),

path('update-room', UpdateRoom.as_view())

6.8 Root Component of React application


import React, { Component } from "react";

import { render } from "react-dom";

import HomePage from "./HomePage";

export default class App extends Component {

constructor(props) {
super(props);

render() {

return (

<div className="center">

<HomePage />

</div>

);

59
const appDiv = document.getElementById("app");

render(<App />, appDiv);

6.9 Main Page of the application


import React, { Component } from 'react';
import RoomJoinPage from './RoomJoinPage';
import CreateRoomPage from './CreateRoomPage';

import { Grid, Button, ButtonGroup, Typography } from '@mui/material';

import { BrowserRouter as Router, Routes, Route, Link, Redirect, Navigate } from 'react-
router-dom';

import Room from './Room';

export default class HomePage extends Component{

constructor(props){

super(props);

this.state={

roomCode: null,

};

this.clearRoomCode=this.clearRoomCode.bind(this);

async componentDidMount(){

fetch('/api/user-in-room')

.then((response)=>response.json()).

then((data)=>{

this.setState({

roomCode:data.code,

});

});

60
}

renderHomePage(){

if(this.state.roomCode){

return(

<Navigate to={`/room/${this.state.roomCode}`} replace={true}/>

);

}else{

return(

<Grid container spacing={3}>

<Grid item xs={12} align="center">

<Typography variant='h3' compact='h3'>

Tune Troop

</Typography>

</Grid>

<Grid item xs={12} align="center">

<ButtonGroup disableElevation variant='contained' color='primary'>

<Button color='secondary' to='/create' component={Link}>

Create a Room

</Button>

<Button color='primary' to='/join' component={Link}>

Join a Room
</Button>

</ButtonGroup>

</Grid>

</Grid>

);

61
clearRoomCode(){

this.setState({

roomCode:null,

});

render(){

return (<Router>

<Routes>

<Route path="/" element={this.renderHomePage()}

/>

<Route path="/join" element={<RoomJoinPage/>}></Route>

<Route path="/create" element={<CreateRoomPage/>}></Route>

<Route path="/room/:roomCode" element={<Room


clearRoomCodeCallback={this.clearRoomCode}/>}>

</Route>

</Routes>

</Router>);

6.10 Create or Update Room Component


import React, { Component, useState } from "react";
import { Button } from "@mui/material";

import {Grid} from "@mui/material";

import {Typography} from "@mui/material";

import { TextField } from "@mui/material";

62
import {FormHelperText} from "@mui/material";

import {FormControl} from "@mui/material";

import {Link} from "react-router-dom";

import {Radio} from "@mui/material";

import {RadioGroup} from "@mui/material";

import {FormControlLabel} from "@mui/material";

import { useNavigate } from "react-router-dom";

import {Collapse} from "@mui/material"

import Alert from "@mui/material/Alert";

function CreateRoomPage(props){

const navigate=useNavigate();

const[guestCanPause,setguestCanPause]=useState(props.guestCanPause);

const[votesToSkip,setgvotesToSkip]=useState(props.votesToSkip);

const[errorMsg,setErrorMsg]=useState("");

const[successMsg,setSuccessMsg]=useState("");

const handleVotesChange=()=>{

setgvotesToSkip(event.target.value);

};

const handleGuestCanPauseChange=()=>{

setguestCanPause(event.target.value==="true"?true:false);

};

const handleRoomButtonPressed=()=>{

const requestOptions = {

method: 'POST',

63
headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

}),

};

fetch('/api/create-room', requestOptions)

.then((response)=>response.json())

.then((data)=> navigate("/room/"+ data.code));

};

const handleUpdateButtonPressed=()=>{

const requestOptions = {

method: 'PATCH',

headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

votes_to_skip:votesToSkip,

guest_can_pause:guestCanPause,

code:props.roomCode,

}),

};

fetch('/api/update-room', requestOptions)

.then((response)=>{

if(response.ok){

setSuccessMsg("Room updated successfully!");

}else{

setErrorMsg("Error updating room");

props.updateCallback();

64
});

};

const renderCreateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleRoomButtonPressed}>Create A Room</Button>

</Grid>

<Grid item xs={12} align="center">

<Button color="secondary" variant="contained" to="/"


component={Link}>Back</Button>

</Grid>

</Grid>

);

};

const renderUpdateButtons=()=>{

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Button color="primary" variant="contained"


onClick={handleUpdateButtonPressed}>Update Room</Button>

</Grid>

</Grid>

);

};

65
const title=props.update? "Update Room" : "Create a Room";

return (

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Collapse in={errorMsg!="" || successMsg!=""}>

{successMsg!=""?(

<Alert

severity="success"

onClose={()=>{

setSuccessMsg("");

}}>

{successMsg}

</Alert>

):(

<Alert

severity="error"

onClose={()=>{

setErrorMsg("");
}}>

{errorMsg}

</Alert>

)}

</Collapse>

</Grid>

<Grid item xs={12} align="center">

<Typography component='h4' variant='h4'>

{title}

</Typography>

66
</Grid>

<Grid item xs={12} align="center">

<FormControl component="fieldset">

<FormHelperText component="div">

<div align='center'>Guest Control of Playback State</div>

</FormHelperText>

<RadioGroup row defaultValue={props.guestCanPause.toString()}


onChange={handleGuestCanPauseChange}>

<FormControlLabel value="true" control={<Radio color="primary"></Radio>}


label="Play/Pause"
labelPlacement="bottom"></FormControlLabel>

<FormControlLabel value="false" control={<Radio color="secondary"></Radio>}


label="No Control"

labelPlacement="bottom"></FormControlLabel>

</RadioGroup>

</FormControl>

</Grid>

<Grid item xs={12} align="center">

<FormControl>

<TextField required={true} type="number" onChange={handleVotesChange}


defaultValue={votesToSkip}

inputProps={{min:1, style:{textAlign:"center"},}}></TextField>

<FormHelperText component="div">

<div align="center">

Votes Required To Skip Song

</div>

</FormHelperText>

</FormControl>

67
</Grid>

{props.update?renderUpdateButtons(): renderCreateButtons()}

</Grid>

);

CreateRoomPage.defaultProps={

votesToSkip:2,

guestCanPause:true,

update: false,

roomCode:null,

updateCallback:()=>{},

};

export default CreateRoomPage;

6.11 Room Join Component


import React, {useState, Component } from 'react';

import { TextField, Button, Grid, Typography } from '@mui/material';

import { Link } from "react-router-dom";

import {useNavigate} from "react-router-dom";

export default function RoomJoinPage(props){

const navigate=useNavigate();

const[roomCode, setroomCode]=useState('');

const[errorMsg,seterrorMsg]=useState('');

const[error,seterror]=useState(false);

const handleTextFieldChange=()=>{

68
setroomCode(event.target.value);

};

const roomButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

body:JSON.stringify({

code:roomCode,

}),

};

fetch("/api/join-room",requestOptions).

then((response)=>{

if(response.ok){

navigate("/room/"+ roomCode)

}else{

seterror(true);

seterrorMsg("Room not found");


}

})

.catch((error)=>{

console.log(error);

});

};

return(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant="h4" component="h4">

Join a Room

69
</Typography>

</Grid>

<Grid item xs={12} align="center">

<TextField

error={error}

label="Code"

placeholder='Enter a Room Code'

value={roomCode}

helperText={errorMsg}

variant='outlined'

onChange={handleTextFieldChange}>

</TextField>

</Grid>

<Grid item xs={12} align="center">

<Button

variant='contained'

color='primary'

onClick={roomButtonPressed}>

Enter Room

</Button>

</Grid>

<Grid item xs={12} align="center">

<Button variant='contained'

color='secondary' to="/" component={Link}>

Back

</Button>

</Grid>

</Grid>

70
);

6.12 Room Component


import React, {useState, useEffect} from 'react';

import {useParams,Navigate} from "react-router-dom";

import {Grid, Button, Typography} from '@mui/material';

import {useNavigate} from "react-router-dom";

import CreateRoomPage from './CreateRoomPage';

import MusicPlayer from './MusicPlayer';

function Room(props){

const navigate=useNavigate();

const{roomCode}=useParams()

const initialState={

votesToSkip:2,

guestCanPause:false,

isHost:false,

showSettings: false,

spotifyAuthenticated: false,

song:{},
}

const[roomData, setRoomData]=useState(initialState)

useEffect(() => {

getRoomDetails();

const interval=setInterval(getCurrentSong, 1000);

return ()=>clearInterval(interval);

},[roomCode]);

71
const getRoomDetails = () => {

fetch("/api/get-room" + "?code=" + roomCode)

.then((response) => {

if (!response.ok) {

props.clearRoomCodeCallback();

navigate("/");

return response.json();

})

.then((data) => {

setRoomData(prevState=>({

...prevState,

votesToSkip: data.votes_to_skip,

guestCanPause: data.guest_can_pause,

isHost: data.is_host

}));

if(data.is_host){

authenticateSpotify();

});

};

const authenticateSpotify=()=>{

fetch("/spotify/is-authenticated")

.then((response) => response.json())

.then((data) => {

setRoomData(prevState=>({...prevState, spotifyAuthenticated: data.status }));

console.log(data.status);

if (!data.status) {

72
fetch("/spotify/get-auth-url")

.then((response) => response.json())

.then((data) => {

window.location.replace(data.url);

});

});

};

const getCurrentSong = () => {

fetch('/spotify/current-song')

.then((response) => {

if (!response.ok) {

return {};

} else {

return response.json();

})

.then((data) => {

setRoomData(prevState => ({ ...prevState, song: data }));

console.log(data);
});

};

const leaveButtonPressed=()=>{

const requestOptions={

method: "POST",

headers:{"Content-Type": "application/json"},

};

73
fetch('/api/leave-room',requestOptions).

then((response)=>{

props.clearRoomCodeCallback();

navigate('/');

});

};

const updateShowSettings=(value)=>{

setRoomData({

...roomData,

showSettings:value,

});

};

const renderSettings=()=>{

return(
<Grid container spacing={1}>

<Grid item xs={12} align="center">

<CreateRoomPage

update={true}

votesToSkip={roomData.votesToSkip}

guestCanPause={roomData.guestCanPause}

roomCode={roomCode}

updateCallback={getRoomDetails}

getRoomDetails={getRoomDetails}
/>

</Grid>

<Grid item xs={12} align="center" >

<Button

74
variant='contained'

color='secondary'
onClick={()=>updateShowSettings(false)}

>

Close

</Button>

</Grid>

</Grid>

);

};

const renderSettingsButton=()=>{

return(

<Grid item xs={12} align="center">

<Button variant='contained' color='primary'


onClick={()=>updateShowSettings(true)}>

Settings

</Button>

</Grid>

);

};

return roomData.showSettings?(

renderSettings()

):(

<Grid container spacing={1}>

<Grid item xs={12} align="center">

<Typography variant='h4' component='h4'>

75
Code:{roomCode}

</Typography>

</Grid>

<MusicPlayer {...roomData.song}/>

{roomData.isHost?renderSettingsButton():null}

<Grid item xs={12} align="center">

<Button variant="contained" color='secondary' onClick={leaveButtonPressed}>

Leave Room

</Button>

</Grid>

</Grid>

export default Room

6.13 Music Player Component


import React, { useState } from "react";
import {

Grid,

Typography,

Card,

IconButton,

LinearProgress,

} from '@mui/material';

import { Pause, PlayArrowRounded, SkipNext } from '@mui/icons-material';

const MusicPlayer = (props) => {

const skipSong = () => {

76
const requestOptions = {

method: "POST",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/skip", requestOptions);

};

const pauseSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/pause", requestOptions);

};

const playSong = () => {

const requestOptions = {

method: "PUT",
headers: { "Content-Type": "application/json" },

};

fetch("/spotify/play", requestOptions);

};

const songProgress = (props.time / props.duration) * 100;

return (

<Card>

<Grid container alignItems="center">

<Grid item align="center" xs={4}>

<img src={props.image_url} height="100%" width="100%" alt="song cover" />

</Grid>

77
<Grid item align="center" xs={8}>

<Typography component="h5" variant="h5">

{props.title}

</Typography>

<Typography color="textSecondary" variant="subtitle1">

{props.artist}

</Typography>

<div>

<IconButton onClick={()=>{props.is_playing? pauseSong(): playSong()}}>

{props.is_playing ? <Pause></Pause> :
<PlayArrowRounded></PlayArrowRounded>}

</IconButton>

<IconButton onClick={()=>skipSong()}>

{props.votes}/{" "}{props.votes_required}

<SkipNext></SkipNext>

</IconButton>

</div>

</Grid>

</Grid>

<LinearProgress variant="determinate" value={songProgress} />

</Card>

);

};

export default MusicPlayer;

78
6.14 Django model for storing Spotify authentication tokens and user votes
from django.db import models

from api.models import Room

class SpotifyToken(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

refresh_token = models.CharField(max_length=150)

access_token = models.CharField(max_length=150)

expires_in = models.DateTimeField()

token_type = models.CharField(max_length=50)

class Vote(models.Model):

user = models.CharField(max_length=50, unique=True)

created_at = models.DateTimeField(auto_now_add=True)

song_id = models.CharField(max_length=50)

room = models.ForeignKey(Room, on_delete=models.CASCADE)

6.15 Credentials for authentication with Spotify API


CLIENT_ID = "08cb230a331944c7bfa503dfc73dd46c"
CLIENT_SECRET = "f78338ef85e74cf2be80970a90406b69"

REDIRECT_URI = "http://127.0.0.1:8000/spotify/redirect"

6.16 Django views for handling music player operations


from django.shortcuts import render, redirect

from .credentials import REDIRECT_URI, CLIENT_SECRET, CLIENT_ID

from rest_framework.views import APIView

from requests import Request, post

from rest_framework import status

79
from rest_framework.response import Response

from .util import *

from api.models import Room

from .models import Vote

class AuthURL(APIView):

def get(self, request, fornat=None):

scopes = 'user-read-playback-state user-modify-playback-state user-read-currently-


playing'

url = Request('GET', 'https://accounts.spotify.com/authorize', params={

'scope': scopes,

'response_type': 'code',

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID

}).prepare().url

return Response({'url': url}, status=status.HTTP_200_OK)

def spotify_callback(request, format=None):

code = request.GET.get('code')

error = request.GET.get('error')

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'authorization_code',

'code': code,

'redirect_uri': REDIRECT_URI,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

80
}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

refresh_token = response.get('refresh_token')

expires_in = response.get('expires_in')
error = response.get('error')

if not request.session.exists(request.session.session_key):

request.session.create()

update_or_create_user_tokens(

request.session.session_key, access_token, token_type, expires_in, refresh_token)

return redirect('frontend:')

class IsAuthenticated(APIView):

def get(self, request, format=None):

is_authenticated = is_spotify_authenticated(
self.request.session.session_key)

return Response({'status': is_authenticated}, status=status.HTTP_200_OK)

class CurrentSong(APIView):

def get(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)

if room.exists():

room = room[0]

else:

81
return Response({}, status=status.HTTP_404_NOT_FOUND)

host = room.host
endpoint = "player/currently-playing"

response = execute_spotify_api_request(host, endpoint)

if 'error' in response or 'item' not in response:

return Response({}, status=status.HTTP_204_NO_CONTENT)

item = response.get('item')

duration = item.get('duration_ms')

progress = response.get('progress_ms')

album_cover = item.get('album').get('images')[0].get('url')

is_playing = response.get('is_playing')

song_id = item.get('id')

artist_string = ""

for i, artist in enumerate(item.get('artists')):

if i > 0:

artist_string += ", "

name = artist.get('name')

artist_string += name

votes = len(Vote.objects.filter(room=room, song_id=song_id))

song = {

'title': item.get('name'),

'artist': artist_string,

'duration': duration,

'time': progress,

82
'image_url': album_cover,

'is_playing': is_playing,

'votes': votes,

'votes_required': room.votes_to_skip,

'id': song_id

self.update_room_song(room, song_id)

return Response(song, status=status.HTTP_200_OK)

def update_room_song(self, room, song_id):

current_song = room.current_song

if current_song != song_id:

room.current_song = song_id

room.save(update_fields=['current_song'])
votes = Vote.objects.filter(room=room).delete()

class PauseSong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

pause_song(room.host)

return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

83
class PlaySong(APIView):

def put(self, response, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

if self.request.session.session_key == room.host or room.guest_can_pause:

play_song(room.host)
return Response({}, status=status.HTTP_204_NO_CONTENT)

return Response({}, status=status.HTTP_403_FORBIDDEN)

class SkipSong(APIView):

def post(self, request, format=None):

room_code = self.request.session.get('room_code')

room = Room.objects.filter(code=room_code)[0]

votes = Vote.objects.filter(room=room, song_id=room.current_song)

votes_needed = room.votes_to_skip

if self.request.session.session_key == room.host or len(votes) + 1 >= votes_needed:

votes.delete()

skip_song(room.host)

else:

vote = Vote(user=self.request.session.session_key,

room=room, song_id=room.current_song)

vote.save()

return Response({}, status.HTTP_204_NO_CONTENT)

84
6.17 To handle Spotify authentication and integration using Spotify API
from .models import SpotifyToken

from django.utils import timezone

from datetime import timedelta

from .credentials import CLIENT_ID, CLIENT_SECRET

from requests import post, put, get

BASE_URL = "https://api.spotify.com/v1/me/"

def get_user_tokens(session_id):

user_tokens = SpotifyToken.objects.filter(user=session_id)

if user_tokens.exists():

return user_tokens[0]

else:

return None

def update_or_create_user_tokens(session_id, access_token, token_type, expires_in,


refresh_token):

tokens = get_user_tokens(session_id)

expires_in = timezone.now() + timedelta(seconds=expires_in)

if tokens:

tokens.access_token = access_token

tokens.refresh_token = refresh_token

tokens.expires_in = expires_in

tokens.token_type = token_type

tokens.save(update_fields=['access_token',
'refresh_token', 'expires_in', 'token_type'])

85
else:

tokens = SpotifyToken(user=session_id, access_token=access_token,

refresh_token=refresh_token, token_type=token_type,
expires_in=expires_in)

tokens.save()

def is_spotify_authenticated(session_id):

tokens = get_user_tokens(session_id)

if tokens:

expiry = tokens.expires_in

if expiry <= timezone.now():

refresh_spotify_token(session_id)

return True

return False

def refresh_spotify_token(session_id):

refresh_token = get_user_tokens(session_id).refresh_token

response = post('https://accounts.spotify.com/api/token', data={

'grant_type': 'refresh_token',

'refresh_token': refresh_token,

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET

}).json()

access_token = response.get('access_token')

token_type = response.get('token_type')

86
expires_in = response.get('expires_in')

update_or_create_user_tokens(

session_id, access_token, token_type, expires_in, refresh_token)

def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):

tokens = get_user_tokens(session_id)

headers = {'Content-Type': 'application/json',

'Authorization': "Bearer " + tokens.access_token}

if post_:

post(BASE_URL + endpoint, headers=headers)

if put_:

put(BASE_URL + endpoint, headers=headers)

response = get(BASE_URL + endpoint, {}, headers=headers)

try:

return response.json()

except:
return {'Error': 'Issue with request'}

def play_song(session_id):

return execute_spotify_api_request(session_id, "player/play", put_=True)

def pause_song(session_id):

return execute_spotify_api_request(session_id, "player/pause", put_=True)

def skip_song(session_id):

return execute_spotify_api_request(session_id, "player/next", post_=True)

87
6.18 URL patterns for the API views
from django.urls import path

from .views import *

urlpatterns = [

path('get-auth-url', AuthURL.as_view()),

path('redirect', spotify_callback),

path('is-authenticated', IsAuthenticated.as_view()),

path('current-song', CurrentSong.as_view()),

path('pause', PauseSong.as_view()),

path('play', PlaySong.as_view()),

path('skip', SkipSong.as_view())

6.19 URL pattern to include URLS from different parts of the application
from django.contrib import admin

from django.urls import path, include

urlpatterns = [

path('admin/', admin.site.urls),

path('api/', include('api.urls')),

path('', include('frontend.urls')),

path('spotify/', include('spotify.urls'))

88
6. SCREENSHOT

7.1 HOME PAGE

7.2 CREATE ROOM PAGE

89
7.3 SPOTIFY ACCOUNT LOGIN PAGE

7.4 MUSIC PLAYER PAGE FOR HOST

90
7.5 UPDATE ROOM PAGE

7.6 JOIN ROOM PAGE

91
7.5 MUSIC PLAYER PAGE FOR GUEST

92
7. TESTING
Software testing can be stated as the process of verifying and validating whether a software
or application is bug-free, meets the technical requirements as guided by its design and
development, and meets the user requirements effectively and efficiently by handling all
the exceptional and boundary cases.

The purpose of software testing is to identify the errors, faults, or missing requirements in
contrast to actual requirements. It mainly aims at measuring the specification, functionality,
and performance of a software program or application.

The objectives of testing include:

 Validation: Ensure that the software meets the specified requirements and fulfills its
intended purpose effectively and accurately.

 Verification: Confirm that the software conforms to its design specifications and
standards, ensuring consistency and reliability in its behavior.

 Identification of Defects: Detect and identify any defects, bugs, or errors in the
software early in the development process to prevent them from impacting the end-
users or causing issues in production.

 Quality Assurance: Ensure that the software meets predefined quality standards,
including functionality, performance, security, usability, and maintainability.

 Risk Mitigation: Identify and mitigate potential risks associated with the software,
such as security vulnerabilities, performance bottlenecks, and usability issues, to
minimize their impact on the end-users and the organization.

 Optimization: Optimize the software to improve its performance, efficiency, and


reliability, enhancing the user experience and reducing the likelihood of failures or
downtime.

 User Satisfaction: Enhance user satisfaction by delivering a high-quality, reliable,


and user-friendly software product that meets or exceeds the expectations and
requirements of the end-users.

93
 Compliance: Ensure that the software complies with relevant laws, regulations,
standards, and industry best practices, such as accessibility standards, data privacy
regulations, and security guidelines.

 Continuous Improvement: Provide feedback and insights to stakeholders for


continuous improvement of the software development process, methodologies, tools,
and practices, fostering innovation and excellence.

 Cost Reduction: Identify and eliminate defects and inefficiencies early in the
development lifecycle to reduce the overall cost of software development,
maintenance, and support.

8.1 TESTING TECHNIQUES AND TESTING STRATEGIES USED


TESTING PLAN USED
8.1.1 TESTING TECHNIQUES

 Unit Testing: Test individual components or modules in isolation to validate their


functionality.

 Integration Testing: Test the interaction between different components or modules to


ensure they work together as expected.

 System Testing: Test the entire system as a whole to verify that it meets the specified
requirements and functions correctly in its intended environment.

 Acceptance Testing: Test the software from the end-user's perspective to determine if
it meets their needs and expectations.

 Regression Testing: Test previously implemented features to ensure they still function
correctly after new changes or updates are made.

 Performance Testing: Evaluate the software's responsiveness, scalability, and stability


under various load conditions to ensure optimal performance.

 Security Testing: Identify and mitigate potential security vulnerabilities and threats to
protect the software and its users' data.

94
 Usability Testing: Evaluate the software's user interface and overall user experience to
ensure it is intuitive, easy to use, and meets the users' needs.

 Exploratory Testing: Investigate the software's functionality, features, and potential


defects through ad-hoc testing without predefined test cases.

8.1.2. TESTING STRATERGIES

 Risk-Based Testing: Prioritize testing efforts based on the criticality and impact of
identified risks to ensure the most important areas are thoroughly tested.

 Agile Testing: Integrate testing activities into the Agile development process, with
frequent iterations and continuous feedback loops to ensure rapid and reliable
delivery of software increments.

 Continuous Integration/Continuous Deployment (CI/CD): Automate testing and


deployment processes to ensure that changes are thoroughly tested and deployed to
production quickly and reliably.

 Shift-Left Testing: Begin testing activities early in the software development lifecycle
to detect and address defects as soon as possible, reducing the cost and effort of
fixing them later.

 Black Box and White Box Testing: Employ a combination of black box testing
(testing based on external behavior) and white box testing (testing based on internal
code structure) to ensure comprehensive test coverage.

8.1.3 TESTING PLAN

 Scope: Define the scope of testing, including the features, functionalities, and
components to be tested.

 Objectives: Clearly state the objectives of testing, such as validating requirements,


identifying defects, and ensuring quality.

 Test Environment: Specify the test environment, including hardware, software, tools,
and configurations required for testing.

95

You might also like