Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions music_player/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
{
'name': "musicPlayer",
'name': "musicPLayer",

'summary': """
Short (1 phrase/line) summary of the module's purpose, used as
Expand Down Expand Up @@ -32,6 +32,8 @@
'demo': [
'demo/demo.xml',
],
'installable': True,
'application': True,


'installable':True,
'application':True,
}
Binary file removed music_player/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file added music_player/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
55 changes: 32 additions & 23 deletions music_player/controllers/controllers.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
# -*- coding: utf-8 -*-
import json
from odoo import http
from odoo.http import Response
from odoo.http import request, Response
import json
from odoo.modules.module import get_module_resource


class MusicPlayer(http.Controller):
@http.route('/music', auth='public')
def index(self, **kw):
return http.request.render('music_player.music_template')

@http.route('/music/search', auth='public', type="http", methods=["GET"])
def search(self, **kw):
# Retrieve the song name from the search query
song_name = kw.get('song_name')
# you will be facing you are not allowed to acces this model ---> add to manifest the csv file. remove group for now
musics = http.request.env['music_player.music_player'].search_read([('name', 'ilike', song_name)],fields={"name", "url"})
if not musics:
musics = "Song not Found"

return Response(json.dumps({'result': musics}), content_type='application/json')

# A controller to play song from the audio

@http.route('/music/<model("music_player.music_player"):music>', type='http', auth="public", methods=["GET"])
def load(self, music, **kw):
music_file_path = get_module_resource('music_player', 'static/songs', music.filename)
file = open(music_file_path, 'rb').read()
@http.route('/music', auth='public')
def index(self, **kw):
return http.request.render('music_player.music_template')

@http.route('/music/search', auth='public',type="http",methods=["GET"])
def search(self,**kw):
song_name=kw.get('song_name')
print(song_name)
songs=request.env['music_player.music_player'].search_read([('name','ilike',song_name)],fields={"name","url"})
print(songs)
if not songs:
songs='song not found'

return Response(json.dumps({'result':songs}),content_type='application/json')

@http.route('/music/<model("music_player.music_player"):music>', auth='public')
def object(self, music, **kw):
music_file_path=get_module_resource("music_player","static/songs",music.filename)
file=open(music_file_path,'rb').read()
return file










2 changes: 1 addition & 1 deletion music_player/demo/demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
<field name="name">Temp-song-3</field>
<field name="filename">Temp-song-3.mp3</field>
</record>
</odoo>
</odoo>
Binary file not shown.
Binary file not shown.
Binary file removed music_player/models/__pycache__/models.cpython-310.pyc
Binary file not shown.
Binary file not shown.
Binary file removed music_player/models/__pycache__/player.cpython-310.pyc
Binary file not shown.
Binary file not shown.
11 changes: 6 additions & 5 deletions music_player/models/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ class music_player(models.Model):
_name = 'music_player.music_player'
_description = 'music_player.music_player'

name = fields.Char('Song Name')
filename = fields.Char("File name")
url = fields.Char(compute="_compute_url") # for a computed url
name = fields.Char('Song name')
filename=fields.Char('File name')
url=fields.Char(compute="_compute_url")

def _compute_url(self):
for record in self:
record.url = record.get_base_url() + '/music/' + str(record.id)
record.url=record.get_base_url()+'/music/'+str(record.id)

224 changes: 118 additions & 106 deletions music_player/static/app.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,141 @@
/** @odoo-module**/

const { Component, xml, mount, setup, useState } = owl;
const{Component,xml,mount,useState}=owl;

let audio='';
class PlayList extends Component{
static template=xml`
<div style="position:absolute;right:0px;top:0px;">
<p id="playlist">PLAYLIST</p>
<t t-foreach="props.selectedPlaylist" t-as="song" t-key="song.id">
<p><t t-out="song.name"/></p>
<button t-att-value="song.url" t-on-click="removeSong">Remove from Playlist</button>
<button t-att-value="song.url" t-on-click="playSong">Play Song</button>


</t>

</div>`;
removeSong(ev){
const selectedSongUrl = ev.target.getAttribute('value');
const selectedSong = this.props.selectedPlaylist.findIndex(song => song.url===selectedSongUrl);
this.props.selectedPlaylist.splice(selectedSong,1);



let audio = '';
class Player extends Component {
static template = xml`
<div style="position:absolute;bottom:0px">
<h2 id="song-title">Song Title</h2>
<div>
<button id="pause-button" t-on-click="pauseThisSong">Pause</button>
<button id="play_btn" t-on-click="playThisSong">Play</button>
<button id="stop-button" t-on-click="stopThisSong">Stop</button>
</div>
</div>`;

playThisSong() {
if (!audio) {
return;
}
audio.play();
}
pauseThisSong() {
if (!audio) {
return;
}
audio.pause();
}
stopThisSong() {
if (!audio) {
return;
}
audio.pause();
audio.currentTime = 0;
}
}
playSong(ev) {
const selectedSongUrl = ev.target.getAttribute('value');
const selectedSong = this.props.selectedPlaylist.find(song => song.url===selectedSongUrl);
document.getElementById("song_title").textContent = selectedSong.name;
audio = new Audio(selectedSongUrl);
audio.play();
}
static props=["selectedPlaylist"]
}
class Player extends Component{
static template=xml`
<div style="position:absolute;bottom:0px">
<h2 id="song_title">Song Title</h2>
<div>
<button id="pause_button" t-on-click="pauseThisSong">Pause</button>
<button id="play_button" t-on-click="playThisSong">Play</button>
<button id="stop_button" t-on-click="stopThisSong">Stop</button>

// class PlayList extends Component {
// static template = xml`
// <div style="float:right">

// </div>
// `;

// }
</div>
</div>
`;

class MusicList extends Component {
static template = xml`
<div id="MusicList" style="float:left">
<t t-if="props.searchData[0] and props.searchData[0] !== 'Song not Found'">
<h2>List of Songs</h2>
<t t-foreach="props.searchData[0]" t-as="song" t-key="song.id">
<p><t t-out="song.name"/></p>
<button t-att-value="song.url" t-on-click="addSongToPlaylist">Add to playlist</button>
<button t-att-value="song.url" t-on-click="playSong">Play song</button>
</t>
</t>
<Player/>
</div>
`;

addSongToPlaylist () {
//TAsk:
// add Playlist component as the child of root component and when addSongToPlaylist method is called update the
//PlayList component template with the song thats added.
// hint use callback method as which update the props u are passing to PlayList component.
playThisSong(){
if(!audio){
return;
}
audio.play();
}

playSong(ev) {
// in case a audio is already playing stop it to play another.
if (audio) {
audio.pause();
audio.currentTime = 0;
}
const selectedSongUrl = ev.target.getAttribute('value');
const selectedSong = this.props.searchData[0].find(song => song.url === selectedSongUrl);
document.getElementById('song-title').textContent = selectedSong.name;
audio = new Audio(selectedSongUrl);
audio.play();
}
static props = ['searchData'];

static components = { Player };
pauseThisSong(){
if(!audio){
return;
}
audio.pause()
}
stopThisSong(){
if(!audio){
return;
}
audio.pause();
audio.currentTime = 0;
}
}

class Search extends Component {
static template = xml `
<div style="text-align:center">
<input type="text" id="searchSong" placeholder="Search a music" value="Akon"/>
<button t-on-click="getMusic" id="SearchButton">Search</button>
<MusicList searchData="searchData"/>
class MusicList extends Component{
static template=xml`
<div style="float:left;">
<t t-if="props.searchData[0] and props.searchData[0] !== 'Song Not Found'">
<h2>List of Songs</h2>
<t t-foreach="props.searchData[0]" t-as="song" t-key="song.id">
<p><t t-out="song.name"/></p>
<button t-att-value="song.url" t-on-click="addSongToPlayList">Add to Playlist</button>
<button t-att-value="song.url" t-on-click="playSong">Play Song</button>
</t>
</t>
<Player />
<PlayList selectedPlaylist="selectedPlaylist"/>
</div>
`;
setup() {
this.searchData = useState([]);
setup(){
this.selectedPlaylist=useState([]);
}

async getMusic() {
const findSong = document.getElementById('searchSong').value;
const response = await fetch(`/music/search?song_name=${findSong}`);
const {result : newData}= await response.json();
this.searchData.pop(); // add pop to remove previously searched data.
this.searchData.push(newData);
addSongToPlayList(ev){
const selectedSongUrl = ev.target.getAttribute('value');
const selectedSong = this.props.searchData[0].find(song=> song.url === selectedSongUrl)
console.log(selectedSong)
document.getElementById('playlist').textContent = selectedSong.name;
this.selectedPlaylist.push(selectedSong)

}
playSong(ev){
const selectedSongUrl = ev.target.getAttribute('value');
const selectedSong = this.props.searchData[0].find(song=> song.url === selectedSongUrl)
document.getElementById('song_title').textContent = selectedSong.name;
audio= new Audio(selectedSongUrl);
audio.play()
}

static components = { MusicList }
static props=["searchData"];
static components={Player,PlayList};
}

class Root extends Component { // import from owl
// import from owl
static template = xml `
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
}
</style>
<div id="Container" style="position:relative;height:100%">
<Search/>
class Search extends Component{
static template=xml`
<div style="text-align:center;">
<input type="text" id="searchsong" placeholder="music search" value="Freedom"/>
<button t-on-click="getMusic" id="searchButton">search</button>
<MusicList searchData="searchData"/>
</div>
`;

static components = { Search };
setup(){
this.searchData=useState([]);
}
async getMusic(){
const findSong=document.getElementById("searchsong").value;
const response=await fetch(`/music/search?song_name=${findSong}`);
const {result: newData}=await response.json();
this.searchData.push(newData);
}
static components={MusicList};
}

window.onload = function() {
mount(Root, document.body);
};
class Root extends Component{
static template=xml`
<div> I am root
<Search/>
</div>
`;
static components={Search};
}
window.onload=function(){
mount(Root,document.body);
}
Loading