Initial migration
This commit is contained in:
parent
21a9ec3cf2
commit
9bcf3ddb60
25
crontab_file.txt
Normal file
25
crontab_file.txt
Normal file
@ -0,0 +1,25 @@
|
||||
# Edit this file to introduce tasks to be run by cron.
|
||||
#
|
||||
# Each task to run has to be defined through a single line
|
||||
# indicating with different fields when the task will be run
|
||||
# and what command to run for the task
|
||||
#
|
||||
# To define the time you can provide concrete values for
|
||||
# minute (m), hour (h), day of month (dom), month (mon),
|
||||
# and day of week (dow) or use '*' in these fields (for 'any').
|
||||
#
|
||||
# Notice that tasks will be started based on the cron's system
|
||||
# daemon's notion of time and timezones.
|
||||
#
|
||||
# Output of the crontab jobs (including errors) is sent through
|
||||
# email to the user the crontab file belongs to (unless redirected).
|
||||
#
|
||||
# For example, you can run a backup of all your user accounts
|
||||
# at 5 a.m every week with:
|
||||
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
|
||||
#
|
||||
# For more information see the manual pages of crontab(5) and cron(8)
|
||||
#
|
||||
# m h dom mon dow command
|
||||
@reboot $HOME/update.sh >> $HOME/logfile.log
|
||||
@reboot sleep 10 && DISPLAY=:0 firefox --kiosk http://localhost:5000/display
|
||||
112
display1.html
Normal file
112
display1.html
Normal file
@ -0,0 +1,112 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Now Playing</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
background-color: #0f0f0f;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
h1 {
|
||||
color: #999;
|
||||
font-size: 5vw;
|
||||
}
|
||||
span{
|
||||
color:#999;
|
||||
font-size: 1vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
#now-playing {
|
||||
font-size: 3vw;
|
||||
color: #007bff;
|
||||
}
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
height: 5vh;
|
||||
width: 75vw;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
height: 2vh;
|
||||
border-radius: 1vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 2vh;
|
||||
background-color: #007BFF;
|
||||
width: 0%;
|
||||
border-radius: 1vh;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
#album-art {
|
||||
/*width: 200px; /* Adjust width as needed */
|
||||
height: 20vh; /* Maintain aspect ratio */
|
||||
width: auto;
|
||||
border-radius: 1vh; /* Rounded corners */
|
||||
margin-bottom: 1vh; /* Space between the image and text */
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Now Playing</h1>
|
||||
<img id="album-art" src="mao.jpg" alt="Album Art">
|
||||
<div id="now-playing">Nothing is playing</div>
|
||||
<h1></h1>
|
||||
<div class="progress-container">
|
||||
<span id="current-time">0:00</span>
|
||||
<div class="progress-bar">
|
||||
<div class="progress" id="progress" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span id="duration">4:00</span>
|
||||
</div>
|
||||
<script>
|
||||
function fetchNowPlaying() {
|
||||
fetch('/current')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.getElementById('now-playing').textContent = data.title || 'Nothing is playing';
|
||||
});
|
||||
}
|
||||
setInterval(fetchNowPlaying, 1000);
|
||||
fetchNowPlaying();
|
||||
function updateProgressBar(percentage) {
|
||||
const progressBar = document.getElementById('progress');
|
||||
progressBar.style.width = percentage + '%';
|
||||
}
|
||||
|
||||
// Example: Update progress bar every second
|
||||
setInterval(function() {
|
||||
// This would be dynamic, typically set by the current play time over total duration
|
||||
const currentTime = 60; // current time in seconds
|
||||
const duration = 240; // total duration in seconds
|
||||
const percentage = (currentTime / duration) * 100;
|
||||
updateProgressBar(percentage);
|
||||
|
||||
// Update time display
|
||||
document.getElementById('current-time').innerText = formatTime(currentTime);
|
||||
document.getElementById('duration').innerText = formatTime(duration);
|
||||
}, 1000);
|
||||
|
||||
function formatTime(seconds) {
|
||||
const min = Math.floor(seconds / 60);
|
||||
const sec = seconds % 60;
|
||||
return `${min}:${sec < 10 ? '0' : ''}${sec}`;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
112
display2.html
Normal file
112
display2.html
Normal file
@ -0,0 +1,112 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Now Playing</title>
|
||||
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.js">-->
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
background-color: #0f0f0f;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
h1 {
|
||||
color: #999;
|
||||
font-size: 5vw;
|
||||
}
|
||||
span{
|
||||
color:#999;
|
||||
font-size: 1vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
#now-playing {
|
||||
font-size: 3vw;
|
||||
color: #007bff;
|
||||
}
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
height: 5vh;
|
||||
width: 75vw;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
height: 2vh;
|
||||
border-radius: 1vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 2vh;
|
||||
background-color: #007BFF;
|
||||
width: 0%;
|
||||
border-radius: 1vh;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
#album-art {
|
||||
height: 20vh;
|
||||
width: auto;
|
||||
border-radius: 1vh;
|
||||
margin-bottom: 1vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Now Playing</h1>
|
||||
<img id="album-art" src="mao.jpg">
|
||||
<div id="now-playing">Nothing is playing</div>
|
||||
<h1></h1>
|
||||
<div class="progress-container">
|
||||
<span id="current-time">0:00</span>
|
||||
<div class="progress-bar">
|
||||
<div class="progress" id="progress" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span id="duration">4:00</span>
|
||||
</div>
|
||||
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
|
||||
<script>
|
||||
const socket = io(); // Connect to WebSocket server
|
||||
|
||||
socket.on('connect', function() {
|
||||
console.log('Connected to WebSocket server!');
|
||||
loadCurrent();
|
||||
});
|
||||
|
||||
socket.on('current', function(data) {
|
||||
console.log(data);
|
||||
document.getElementById('now-playing').textContent = data.title || 'Nothing is playing';
|
||||
});
|
||||
|
||||
socket.on('progress_update', function(data) {
|
||||
updateProgressBar(data.percentage);
|
||||
document.getElementById('current-time').innerText = formatTime(data.current_time);
|
||||
document.getElementById('duration').innerText = formatTime(data.total_duration);
|
||||
});
|
||||
|
||||
function updateProgressBar(percentage) {
|
||||
const progressBar = document.getElementById('progress');
|
||||
progressBar.style.width = percentage + '%';
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
const min = Math.floor(seconds / 60);
|
||||
const sec = seconds % 60;
|
||||
return `${min}:${sec < 10 ? '0' : ''}${sec}`;
|
||||
}
|
||||
|
||||
function loadCurrent() {
|
||||
socket.emit('current_song');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
90
htmltest.html
Normal file
90
htmltest.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Simple Music Player</title>
|
||||
<style>
|
||||
.music-player {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
.info, .progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
position: relative;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 8px;
|
||||
background-color: #007BFF;
|
||||
width: 0%;
|
||||
border-radius: 4px;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="music-player">
|
||||
<div class="info">
|
||||
<span id="song-title">Song Title</span>
|
||||
</div>
|
||||
<div class="progress-container">
|
||||
<span id="current-time">0:00</span>
|
||||
<div class="progress-bar">
|
||||
<div class="progress" id="progress" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span id="duration">4:00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateProgressBar(percentage) {
|
||||
const progressBar = document.getElementById('progress');
|
||||
progressBar.style.width = percentage + '%';
|
||||
}
|
||||
|
||||
// Example: Update progress bar every second
|
||||
setInterval(function() {
|
||||
// This would be dynamic, typically set by the current play time over total duration
|
||||
const currentTime = 60; // current time in seconds
|
||||
const duration = 240; // total duration in seconds
|
||||
const percentage = (currentTime / duration) * 100;
|
||||
updateProgressBar(percentage);
|
||||
|
||||
// Update time display
|
||||
document.getElementById('current-time').innerText = formatTime(currentTime);
|
||||
document.getElementById('duration').innerText = formatTime(duration);
|
||||
}, 1000);
|
||||
|
||||
function formatTime(seconds) {
|
||||
const min = Math.floor(seconds / 60);
|
||||
const sec = seconds % 60;
|
||||
return `${min}:${sec < 10 ? '0' : ''}${sec}`;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
22
install.sh
Normal file
22
install.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Use /bin/bash to run this script, even when called manually
|
||||
|
||||
SOURCE_DIR="$HOME/GR-Jukebox"
|
||||
TARGET_DIR="$HOME"
|
||||
|
||||
for file in $SOURCE_DIR/*; do
|
||||
filename=$(basename "$file")
|
||||
if [ "$filename" != "install.sh" ]; then
|
||||
# Move the file
|
||||
cp -f "$file" "$TARGET_DIR/"
|
||||
|
||||
# Check if the file should be executable (modify this condition to fit your needs)
|
||||
if [[ "$filename" == *.sh || "$filename" == *.py ]]; then
|
||||
chmod +x "$TARGET_DIR/$filename"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
crontab crontab_file.txt
|
||||
|
||||
echo "Installation complete. All files have been moved to $TARGET_DIR."
|
||||
137
main1.py
Normal file
137
main1.py
Normal file
@ -0,0 +1,137 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, jsonify
|
||||
from flask_cors import CORS
|
||||
import yt_dlp
|
||||
import vlc
|
||||
import time
|
||||
import os
|
||||
import eyed3
|
||||
|
||||
home_directory = os.path.expanduser("~")
|
||||
#app = Flask(__name__,template_folder=home_directory)
|
||||
app = Flask(__name__,template_folder=(home_directory+"/Code/GR/GR-Jukebox"))
|
||||
CORS(app, resources={r"/*": {"origins": "*"}})
|
||||
player = vlc.MediaPlayer()
|
||||
music_queue = []
|
||||
title_queue = []
|
||||
music_directory = os.path.expanduser('~/Music') # Adjust path as necessary
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('manage1.html')
|
||||
|
||||
@app.route('/display')
|
||||
def display():
|
||||
return render_template('display1.html')
|
||||
|
||||
@app.route('/music')
|
||||
def list_music():
|
||||
music_files = []
|
||||
for filename in os.listdir(music_directory):
|
||||
if filename.endswith('.mp3'):
|
||||
path = os.path.join(music_directory, filename)
|
||||
audiofile = eyed3.load(path)
|
||||
title = audiofile.tag.title if audiofile.tag else 'Unknown Title'
|
||||
music_files.append({'id': filename.split('.')[0], 'title': title})
|
||||
return jsonify(music_files)
|
||||
|
||||
@app.route('/download', methods=['POST'])
|
||||
def download():
|
||||
url = request.form['youtube_url']
|
||||
if 'youtube.com' in url:
|
||||
video_id = url.split('=')[1][:11] # Extract the video ID from the YouTube URL
|
||||
elif 'youtu.be' in url:
|
||||
video_id = url.split('youtu.be/')[1][:11]
|
||||
else:
|
||||
return jsonify({'status': 'error', 'message': 'Invalid YouTube URL'})
|
||||
output_path = os.path.expanduser(f'{home_directory}/Music/{video_id}.mp3') # Path where the file will be saved
|
||||
|
||||
if not os.path.exists(output_path):
|
||||
print("Downloading...")
|
||||
# Configure yt-dlp to download best audio quality
|
||||
ydl_opts = {
|
||||
'format': 'bestaudio/best',
|
||||
'postprocessors': [{
|
||||
'key': 'FFmpegExtractAudio',
|
||||
'preferredcodec': 'mp3',
|
||||
'preferredquality': '192',
|
||||
}],
|
||||
'noplaylist': True,
|
||||
'quiet': True,
|
||||
'outtmpl': output_path[:-4] # Use the custom path as the output template
|
||||
}
|
||||
|
||||
# Use yt-dlp to extract information and download the audio file
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(url, download=True)
|
||||
title = info.get('title') # Extract the title from video information
|
||||
|
||||
# Load the downloaded file using eyed3 and add ID3 tags
|
||||
audiofile = eyed3.load(output_path)
|
||||
if audiofile.tag is None: # Create an ID3 tag if none exist
|
||||
audiofile.tag = eyed3.id3.Tag()
|
||||
audiofile.tag.file_info = eyed3.id3.FileInfo(output_path)
|
||||
|
||||
print(f"Downloaded: {title}")
|
||||
audiofile.tag.title = title
|
||||
audiofile.tag.save() # Save the metadata
|
||||
#return redirect(url_for('index')) # Redirect back to the main page
|
||||
return jsonify({'status': 'success', 'message': 'Song added successfully'})
|
||||
|
||||
playing_thread = False
|
||||
@app.route('/play', methods=['POST'])
|
||||
def play():
|
||||
global music_queue
|
||||
global title_queue
|
||||
global playing_thread
|
||||
global player
|
||||
music_queue.append(request.json['songId'])
|
||||
title_queue.append(request.json['songTitle'])
|
||||
if not playing_thread:
|
||||
while len(music_queue) > 0:
|
||||
playing_thread = True
|
||||
player = vlc.MediaPlayer(f'{home_directory}/Music/{music_queue[0]}.mp3')
|
||||
player.play()
|
||||
# Wait for the audio to start playing and check periodically if it is still playing
|
||||
time.sleep(1) # Short initial delay to allow playback to start
|
||||
while player.is_playing():
|
||||
print('Playing...')
|
||||
time.sleep(0.5) # Check every second if it is still playing
|
||||
player.stop()
|
||||
music_queue.pop(0)
|
||||
title_queue.pop(0)
|
||||
playing_thread = False
|
||||
return jsonify({'status': 'success', 'message': 'Playing song'})
|
||||
|
||||
@app.route('/queue')
|
||||
def get_queue():
|
||||
global title_queue
|
||||
return jsonify([{'id': idx, 'title': title} for idx, title in enumerate(title_queue)])
|
||||
|
||||
@app.route('/remove_from_queue', methods=['POST'])
|
||||
def remove_from_queue():
|
||||
global music_queue
|
||||
global title_queue
|
||||
global player
|
||||
data = request.json
|
||||
song_id = int(data['songId'])
|
||||
try:
|
||||
#del music_queue[song_id]
|
||||
#del title_queue[song_id]
|
||||
if song_id == 0:
|
||||
player.stop()
|
||||
else:
|
||||
music_queue.pop(song_id)
|
||||
title_queue.pop(song_id)
|
||||
return jsonify({'status': 'success', 'message': 'Song removed successfully'})
|
||||
except IndexError:
|
||||
return jsonify({'status': 'error', 'message': 'Invalid song ID'}), 400
|
||||
|
||||
@app.route('/current')
|
||||
def current():
|
||||
global title_queue
|
||||
if len(title_queue) > 0:
|
||||
return {'title': title_queue[0]}
|
||||
return {'title': 'Nothing is playing'}
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0', debug=True, port=5000)
|
||||
154
main2.py
Normal file
154
main2.py
Normal file
@ -0,0 +1,154 @@
|
||||
from flask import Flask, render_template, jsonify
|
||||
from flask_socketio import SocketIO, emit
|
||||
from flask_cors import CORS
|
||||
import yt_dlp
|
||||
import vlc
|
||||
import os
|
||||
import eyed3
|
||||
import time
|
||||
|
||||
home_directory = os.path.expanduser("~")
|
||||
music_directory = os.path.expanduser('~/Music') # Adjust path as necessary
|
||||
|
||||
#app = Flask(__name__,template_folder=home_directory)
|
||||
app = Flask(__name__, template_folder=f"{home_directory}/Code/GR/GR-Jukebox")
|
||||
CORS(app, resources={r"/*": {"origins": "*"}})
|
||||
socketio = SocketIO(app)
|
||||
player = vlc.MediaPlayer()
|
||||
music_queue = []
|
||||
title_queue = []
|
||||
|
||||
@socketio.on('connect')
|
||||
def handle_connect():
|
||||
emit('response', {'message': 'Connected to WebSocket server'})
|
||||
|
||||
@socketio.on('list_music')
|
||||
def handle_list_music():
|
||||
music_files = []
|
||||
for filename in os.listdir(music_directory):
|
||||
if filename.endswith('.mp3'):
|
||||
path = os.path.join(music_directory, filename)
|
||||
audiofile = eyed3.load(path)
|
||||
title = audiofile.tag.title if audiofile.tag else 'Unknown Title'
|
||||
music_files.append({'id': filename.split('.')[0], 'title': title})
|
||||
print({'music_files':music_files})
|
||||
emit('music_list', {'music_files': music_files})
|
||||
|
||||
@socketio.on('download')
|
||||
def handle_download(data):
|
||||
url = data['youtube_url']
|
||||
if 'youtube.com' in url:
|
||||
video_id = url.split('=')[1][:11] # Extract the video ID from the YouTube URL
|
||||
elif 'youtu.be' in url:
|
||||
video_id = url.split('youtu.be/')[1][:11]
|
||||
else:
|
||||
#return jsonify({'status': 'error', 'message': 'Invalid YouTube URL'})
|
||||
emit('download_status', {'status': 'error', 'message': 'Invalid YouTube URL'})
|
||||
output_path = os.path.expanduser(f'{home_directory}/Music/{video_id}.mp3') # Path where the file will be saved
|
||||
|
||||
if not os.path.exists(output_path):
|
||||
print("Downloading...")
|
||||
# Configure yt-dlp to download best audio quality
|
||||
ydl_opts = {
|
||||
'format': 'bestaudio/best',
|
||||
'postprocessors': [{
|
||||
'key': 'FFmpegExtractAudio',
|
||||
'preferredcodec': 'mp3',
|
||||
'preferredquality': '192',
|
||||
}],
|
||||
'noplaylist': True,
|
||||
'quiet': True,
|
||||
'outtmpl': output_path[:-4] # Use the custom path as the output template
|
||||
}
|
||||
|
||||
# Use yt-dlp to extract information and download the audio file
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(url, download=True)
|
||||
title = info.get('title') # Extract the title from video information
|
||||
|
||||
# Load the downloaded file using eyed3 and add ID3 tags
|
||||
audiofile = eyed3.load(output_path)
|
||||
if audiofile.tag is None: # Create an ID3 tag if none exist
|
||||
audiofile.tag = eyed3.id3.Tag()
|
||||
audiofile.tag.file_info = eyed3.id3.FileInfo(output_path)
|
||||
|
||||
print(f"Downloaded: {title}")
|
||||
audiofile.tag.title = title
|
||||
audiofile.tag.save() # Save the metadata
|
||||
emit('download_status', {'status': 'success', 'message': 'Song added successfully'})
|
||||
|
||||
playing_thread = False
|
||||
@socketio.on('play')
|
||||
def handle_play(data):
|
||||
global music_queue
|
||||
global title_queue
|
||||
global playing_thread
|
||||
global player
|
||||
music_queue.append(data['songId'])
|
||||
title_queue.append(data['songTitle'])
|
||||
if not playing_thread:
|
||||
while len(music_queue) > 0:
|
||||
playing_thread = True
|
||||
player = vlc.MediaPlayer(f'{home_directory}/Music/{music_queue[0]}.mp3')
|
||||
player.play()
|
||||
print(f"Playing: {title_queue[0]}")
|
||||
emit('current', {'title': title_queue[0]})
|
||||
emit('queue', [{'id': idx, 'title': title} for idx, title in enumerate(title_queue)])
|
||||
# Wait for the audio to start playing and check periodically if it is still playing
|
||||
time.sleep(1) # Short initial delay to allow playback to start
|
||||
while player.is_playing():
|
||||
#print('Playing...')
|
||||
time.sleep(0.5) # Check every second if it is still playing
|
||||
#emit('time', {'time': player.get_time()})
|
||||
#print(player.get_time())
|
||||
#print(player.get_length())
|
||||
#print((player.get_time()/player.get_length()))
|
||||
emit('time', {'time': (player.get_time()/player.get_length())})
|
||||
player.stop()
|
||||
music_queue.pop(0)
|
||||
title_queue.pop(0)
|
||||
playing_thread = False
|
||||
emit('play_return', {'status': 'success', 'message': 'Playing song'})
|
||||
|
||||
@socketio.on('get_queue')
|
||||
def handle_get_queue():
|
||||
emit('queue', [{'id': idx, 'title': title} for idx, title in enumerate(title_queue)])
|
||||
|
||||
@socketio.on('remove_from_queue')
|
||||
def handle_remove_from_queue(data):
|
||||
global music_queue
|
||||
global title_queue
|
||||
global player
|
||||
#data = request.json
|
||||
song_id = int(data['songId'])
|
||||
try:
|
||||
#del music_queue[song_id]
|
||||
#del title_queue[song_id]
|
||||
if song_id == 0:
|
||||
player.stop()
|
||||
else:
|
||||
music_queue.pop(song_id)
|
||||
title_queue.pop(song_id)
|
||||
#return jsonify({'status': 'success', 'message': 'Song removed successfully'})
|
||||
emit('remove_return', {'status': 'success', 'message': 'Song removed successfully'})
|
||||
except IndexError:
|
||||
#return jsonify({'status': 'error', 'message': 'Invalid song ID'}), 400
|
||||
emit('remove_return', {'status': 'error', 'message': 'Invalid song ID'})
|
||||
|
||||
@socketio.on('current_song')
|
||||
def handle_current_song():
|
||||
if title_queue:
|
||||
emit('current', {'title': title_queue[0]})
|
||||
else:
|
||||
emit('current', {'title': 'Nothing is playing'})
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('manage2.html')
|
||||
|
||||
@app.route('/display')
|
||||
def display():
|
||||
return render_template('display2.html')
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', debug=True, port=5000)
|
||||
328
manage1.html
Normal file
328
manage1.html
Normal file
@ -0,0 +1,328 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Manage Queue</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background-color: #0f0f0f;
|
||||
}
|
||||
.column {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
#musicQueue, #allMusic {
|
||||
height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.queueItem {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.queueItem button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
input[type="text"] {
|
||||
width: calc(100% - 22px); /* Full width minus padding and border */
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.loader {
|
||||
border: 5px solid #f3f3f3; /* Light grey */
|
||||
border-top: 5px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.musicItem {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.musicItem button {
|
||||
margin-right: 10px; /* Adds space between the button and the title */
|
||||
}
|
||||
|
||||
.musicItem span {
|
||||
flex-grow: 1; /* Allows the title span to take up the remaining space */
|
||||
text-align: left; /* Ensures text is left-aligned */
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Hide loader by default */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #999;
|
||||
font-size: 3vh;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
height: 5vh;
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
height: 2vh;
|
||||
border-radius: 1vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 2vh;
|
||||
background-color: #007BFF;
|
||||
width: 0%;
|
||||
border-radius: 1vh;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
#album-art {
|
||||
/*width: 200px; /* Adjust width as needed */
|
||||
height: 20vh; /* Maintain aspect ratio */
|
||||
width: auto;
|
||||
border-radius: 1vh; /* Rounded corners */
|
||||
margin-bottom: 1vh; /* Space between the image and text */
|
||||
}
|
||||
span{
|
||||
color:#999;
|
||||
font-size: 1vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="column">
|
||||
<h2>Download New Song</h2>
|
||||
<form id="downloadForm">
|
||||
<input type="text" id="youtubeUrl" name="youtube_url" placeholder="Enter YouTube URL here" required>
|
||||
<button type="button" id="downloadButton" onclick="submitDownload()">Download</button>
|
||||
<div id="loader" class="loader hidden"></div>
|
||||
</form>
|
||||
<div>
|
||||
<img id="album-art" src="mao.jpg" alt="Album Art">
|
||||
<div class="progress-container">
|
||||
<span id="current-time">0:00</span>
|
||||
<div class="progress-bar">
|
||||
<div class="progress" id="progress" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span id="duration">4:00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column" id="queueControls">
|
||||
<h2>Music Queue</h2>
|
||||
<!--<button onclick="skipTrack()">Skip</button>
|
||||
<button onclick="toggleLoop()">Loop</button>
|
||||
<button onclick="toggleShuffle()">Shuffle</button>
|
||||
<button onclick="clearQueue()">Clear</button>-->
|
||||
<div id="musicQueue">
|
||||
<!-- Dynamically filled with JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>All Music</h2>
|
||||
<input type="text" id="searchMusic" placeholder="Search music..." onkeyup="filterMusic()">
|
||||
<div id="allMusic">
|
||||
<!-- Dynamically filled with JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function skipTrack() {
|
||||
// Implementation of skipping the current track
|
||||
}
|
||||
|
||||
function toggleLoop() {
|
||||
// Toggle loop mode
|
||||
}
|
||||
|
||||
function toggleShuffle() {
|
||||
// Toggle shuffle mode
|
||||
}
|
||||
|
||||
function clearQueue() {
|
||||
// Clear the entire queue
|
||||
}
|
||||
|
||||
function playSong(songId, songTitle) {
|
||||
fetch('/play', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ songId: songId, songTitle: songTitle })
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to add song to queue');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Song added to queue:', data);
|
||||
})
|
||||
.catch(error => console.error('Error adding song to queue:', error));
|
||||
loadQueue(); // Reloads the queue after a song is added
|
||||
}
|
||||
|
||||
function loadMusic() {
|
||||
const musicList = document.getElementById('allMusic');
|
||||
//musicList.innerHTML = ''; // Clear the list before populating it again
|
||||
fetch('/music')
|
||||
.then(response => response.json())
|
||||
.then(musicFiles => {
|
||||
musicList.innerHTML = '';
|
||||
musicFiles.forEach(song => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'musicItem';
|
||||
|
||||
// Create a button for adding to the queue
|
||||
const addButton = document.createElement('button');
|
||||
addButton.textContent = 'Add to Queue';
|
||||
addButton.onclick = function() { playSong(song.id,song.title); };
|
||||
|
||||
// Create a span to hold the song title
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = song.title;
|
||||
|
||||
|
||||
// Append the button and title to the div
|
||||
div.appendChild(addButton);
|
||||
div.appendChild(titleSpan);
|
||||
musicList.appendChild(div);
|
||||
});
|
||||
})
|
||||
.catch(error => console.error('Failed to load music:', error));
|
||||
}
|
||||
|
||||
function filterMusic() {
|
||||
const search = document.getElementById('searchMusic').value.toLowerCase();
|
||||
const musicItems = document.getElementById('allMusic').getElementsByClassName('musicItem');
|
||||
for (let i = 0; i < musicItems.length; i++) {
|
||||
let item = musicItems[i];
|
||||
let text = item.textContent || item.innerText;
|
||||
if (text.toLowerCase().indexOf(search) > -1) {
|
||||
item.style.display = "";
|
||||
} else {
|
||||
item.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadQueue() {
|
||||
const queueElement = document.getElementById('musicQueue');
|
||||
//queueElement.innerHTML = ''; // Clear the queue before loading new items
|
||||
|
||||
fetch('/queue')
|
||||
.then(response => response.json())
|
||||
.then(queue => {
|
||||
queueElement.innerHTML = '';
|
||||
queue.forEach(song => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'queueItem';
|
||||
|
||||
// Create a button for removing from the queue
|
||||
const removeButton = document.createElement('button');
|
||||
removeButton.textContent = 'Remove';
|
||||
removeButton.onclick = function() { removeFromQueue(song.id); };
|
||||
|
||||
// Create a span to hold the song title
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = song.title;
|
||||
|
||||
// Append the button and title to the div
|
||||
div.appendChild(removeButton);
|
||||
div.appendChild(titleSpan);
|
||||
queueElement.appendChild(div);
|
||||
});
|
||||
})
|
||||
.catch(error => console.error('Failed to load queue:', error));
|
||||
}
|
||||
|
||||
function removeFromQueue(songId) {
|
||||
fetch('/remove_from_queue', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ songId: songId })
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to remove song from queue');
|
||||
}
|
||||
loadQueue(); // Reloads the queue after removing a song
|
||||
})
|
||||
.catch(error => console.error('Error removing song from queue:', error));
|
||||
}
|
||||
|
||||
function submitDownload() {
|
||||
const formData = new FormData(document.getElementById('downloadForm'));
|
||||
const loader = document.getElementById('loader');
|
||||
const youtubeUrl = document.getElementById('youtubeUrl');
|
||||
const downloadButton = document.getElementById('downloadButton');
|
||||
|
||||
youtubeUrl.disabled = true;
|
||||
downloadButton.disabled = true;
|
||||
loader.classList.remove('hidden'); // Show the loader
|
||||
|
||||
fetch('/download', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
youtubeUrl.disabled = false;
|
||||
downloadButton.disabled = false;
|
||||
loader.classList.add('hidden'); // Hide the loader
|
||||
youtubeUrl.value = ''; // Clear the input field
|
||||
if (response.ok) {
|
||||
loadMusic(); // Reloads the music list after successful download
|
||||
} else {
|
||||
throw new Error('Failed to download song');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
youtubeUrl.disabled = false;
|
||||
downloadButton.disabled = false;
|
||||
loader.classList.add('hidden'); // Ensure loader is hidden on error
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(loadQueue, 1000);
|
||||
//setInterval(loadMusic, 5000);
|
||||
document.addEventListener('DOMContentLoaded', loadMusic); // Ensure music loads when the page is ready
|
||||
|
||||
// Functionality to dynamically populate queues and handle music items could be added here.
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
227
manage2.html
Normal file
227
manage2.html
Normal file
@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Manage Queue</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background-color: #0f0f0f;
|
||||
}
|
||||
.column {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
#musicQueue, #allMusic {
|
||||
height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.queueItem {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.queueItem button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
input[type="text"] {
|
||||
width: calc(100% - 22px); /* Full width minus padding and border */
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.loader {
|
||||
border: 5px solid #f3f3f3; /* Light grey */
|
||||
border-top: 5px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.musicItem {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.musicItem button {
|
||||
margin-right: 10px; /* Adds space between the button and the title */
|
||||
}
|
||||
|
||||
.musicItem span {
|
||||
flex-grow: 1; /* Allows the title span to take up the remaining space */
|
||||
text-align: left; /* Ensures text is left-aligned */
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Hide loader by default */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #999;
|
||||
font-size: 3vh;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
height: 5vh;
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
height: 2vh;
|
||||
border-radius: 1vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 2vh;
|
||||
background-color: #007BFF;
|
||||
width: 0%;
|
||||
border-radius: 1vh;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
#album-art {
|
||||
/*width: 200px; /* Adjust width as needed */
|
||||
height: 20vh; /* Maintain aspect ratio */
|
||||
width: auto;
|
||||
border-radius: 1vh; /* Rounded corners */
|
||||
margin-bottom: 1vh; /* Space between the image and text */
|
||||
}
|
||||
span{
|
||||
color:#999;
|
||||
font-size: 1vw;
|
||||
margin: 1vw;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="column">
|
||||
<h2>Download New Song</h2>
|
||||
<input type="text" id="youtubeUrl" placeholder="Enter YouTube URL here" required>
|
||||
<button id="downloadButton" onclick="submitDownload()">Download</button>
|
||||
<div id="loader" class="loader hidden"></div>
|
||||
</div>
|
||||
|
||||
<div class="column" id="queueControls">
|
||||
<h2>Music Queue</h2>
|
||||
<div id="musicQueue"></div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h2>All Music</h2>
|
||||
<input type="text" id="searchMusic" placeholder="Search music..." onkeyup="filterMusic()">
|
||||
<div id="allMusic"></div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
|
||||
<script>
|
||||
const socket = io(); // Connect to WebSocket server
|
||||
|
||||
socket.on('connect', function() {
|
||||
console.log('Connected to WebSocket server!');
|
||||
loadMusic(); // Load music when connected
|
||||
loadQueue(); // Load queue when connected
|
||||
});
|
||||
|
||||
socket.on('music_list', function(data) {
|
||||
//console.log(data)
|
||||
//console.log(data.music_files)
|
||||
populateMusicList(data.music_files);
|
||||
});
|
||||
|
||||
socket.on('queue', function(data) {
|
||||
//console.log(data)
|
||||
//populateQueue(data.queue);
|
||||
populateQueue(data);
|
||||
});
|
||||
|
||||
function submitDownload() {
|
||||
const youtubeUrl = document.getElementById('youtubeUrl').value;
|
||||
socket.emit('download', { youtube_url: youtubeUrl });
|
||||
}
|
||||
|
||||
function playSong(songId, songTitle) {
|
||||
socket.emit('play', { songId: songId, songTitle: songTitle });
|
||||
}
|
||||
|
||||
function removeFromQueue(songId) {
|
||||
socket.emit('remove_from_queue', { songId: songId });
|
||||
}
|
||||
|
||||
function loadMusic() {
|
||||
socket.emit('list_music');
|
||||
}
|
||||
|
||||
function loadQueue() {
|
||||
socket.emit('get_queue');
|
||||
}
|
||||
|
||||
function populateMusicList(musicFiles) {
|
||||
console.log(musicFiles);
|
||||
const musicList = document.getElementById('allMusic');
|
||||
musicList.innerHTML = ''; // Clear the list before populating
|
||||
musicFiles.forEach(song => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'musicItem';
|
||||
const addButton = document.createElement('button');
|
||||
addButton.textContent = 'Add to Queue';
|
||||
addButton.onclick = () => playSong(song.id, song.title);
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = song.title;
|
||||
div.appendChild(addButton);
|
||||
div.appendChild(titleSpan);
|
||||
musicList.appendChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
function populateQueue(queue) {
|
||||
const queueElement = document.getElementById('musicQueue');
|
||||
queueElement.innerHTML = ''; // Clear the queue before loading new items
|
||||
queue.forEach(song => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'queueItem';
|
||||
const removeButton = document.createElement('button');
|
||||
removeButton.textContent = 'Remove';
|
||||
removeButton.onclick = () => removeFromQueue(song.id);
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = song.title;
|
||||
div.appendChild(removeButton);
|
||||
div.appendChild(titleSpan);
|
||||
queueElement.appendChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
function filterMusic() {
|
||||
const search = document.getElementById('searchMusic').value.toLowerCase();
|
||||
const musicItems = document.querySelectorAll('.musicItem');
|
||||
musicItems.forEach(item => {
|
||||
const isVisible = item.textContent.toLowerCase().includes(search);
|
||||
item.style.display = isVisible ? '' : 'none';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
55
playtest.py
Normal file
55
playtest.py
Normal file
@ -0,0 +1,55 @@
|
||||
import os
|
||||
import yt_dlp
|
||||
import vlc
|
||||
import time
|
||||
import eyed3
|
||||
|
||||
def download_and_play(url):
|
||||
video_id = url.split('=')[1][:11] # Extract the video ID from the YouTube URL
|
||||
output_path = os.path.expanduser(f'/home/generalized/Music/{video_id}.mp3') # Path where the file will be saved
|
||||
|
||||
if not os.path.exists(output_path):
|
||||
print("Downloading...")
|
||||
# Configure yt-dlp to download best audio quality
|
||||
ydl_opts = {
|
||||
'format': 'bestaudio/best',
|
||||
'postprocessors': [{
|
||||
'key': 'FFmpegExtractAudio',
|
||||
'preferredcodec': 'mp3',
|
||||
'preferredquality': '192',
|
||||
}],
|
||||
'noplaylist': True,
|
||||
'quiet': True,
|
||||
'outtmpl': output_path[:-4] # Use the custom path as the output template
|
||||
}
|
||||
|
||||
# Use yt-dlp to extract information and download the audio file
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(url, download=True)
|
||||
title = info.get('title') # Extract the title from video information
|
||||
|
||||
# Load the downloaded file using eyed3 and add ID3 tags
|
||||
audiofile = eyed3.load(output_path)
|
||||
if audiofile.tag is None: # Create an ID3 tag if none exist
|
||||
audiofile.tag = eyed3.id3.Tag()
|
||||
audiofile.tag.file_info = eyed3.id3.FileInfo(output_path)
|
||||
|
||||
print(f"Downloaded: {title}")
|
||||
audiofile.tag.title = title
|
||||
audiofile.tag.save() # Save the metadata
|
||||
|
||||
# Use VLC to play the downloaded audio file
|
||||
player = vlc.MediaPlayer(output_path)
|
||||
player.play()
|
||||
|
||||
# Wait for the audio to start playing and check periodically if it is still playing
|
||||
time.sleep(1) # Short initial delay to allow playback to start
|
||||
while player.is_playing():
|
||||
time.sleep(1) # Check every second if it is still playing
|
||||
|
||||
player.stop() # Stop playing after the audio is done
|
||||
|
||||
if __name__ == "__main__":
|
||||
#youtube_url = "https://www.youtube.com/watch?v=szeXkBYq5HU"
|
||||
youtube_url = "https://www.youtube.com/watch?v=BYiraKCTViY&list=PLdQb1ybxFDih_SbfzdjGIlf3Tylztpc4Q"
|
||||
download_and_play(youtube_url)
|
||||
36
pull_from_cloud.sh
Normal file
36
pull_from_cloud.sh
Normal file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define directories and files
|
||||
REPO_DIR="$HOME/GR-Jukebox"
|
||||
VERSION_FILE_PATH="$REPO_DIR/version.txt"
|
||||
INSTALLED_VERSION_FILE="$HOME/version.txt"
|
||||
|
||||
# Function to get version from a file
|
||||
get_version() {
|
||||
if [[ -f "$1" ]]; then
|
||||
cat "$1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Read the currently installed version and the version in the repository
|
||||
INSTALLED_VERSION=$(get_version "$INSTALLED_VERSION_FILE")
|
||||
REPO_VERSION=$(get_version "$VERSION_FILE_PATH")
|
||||
|
||||
# Check network connectivity to github.com
|
||||
while ! ping -c 1 -W 1 git-codecommit.us-east-2.amazonaws.com > /dev/null; do
|
||||
echo "Waiting for amazonaws.com - network interface might be down..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Fetch and compare the latest version on GitHub without pulling all files
|
||||
cd "$REPO_DIR"
|
||||
git fetch origin
|
||||
REMOTE_VERSION=$(git show origin/master:version.txt)
|
||||
|
||||
if [[ "$INSTALLED_VERSION" != "$REMOTE_VERSION" ]]; then
|
||||
echo "New version available on AWS. Starting download in background."
|
||||
# Pull the latest changes from the remote repository
|
||||
( git pull origin master & )
|
||||
fi
|
||||
0
requirements.txt
Normal file
0
requirements.txt
Normal file
35
update.sh
Normal file
35
update.sh
Normal file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define directories and files
|
||||
REPO_DIR="$HOME/GR-Jukebox"
|
||||
VERSION_FILE_PATH="$REPO_DIR/version.txt"
|
||||
INSTALLED_VERSION_FILE="$HOME/version.txt"
|
||||
|
||||
# Function to get version from a file
|
||||
get_version() {
|
||||
if [[ -f "$1" ]]; then
|
||||
cat "$1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Read the currently installed version and the version in the repository
|
||||
INSTALLED_VERSION=$(get_version "$INSTALLED_VERSION_FILE")
|
||||
REPO_VERSION=$(get_version "$VERSION_FILE_PATH")
|
||||
|
||||
echo "Installed version: $INSTALLED_VERSION"
|
||||
|
||||
# Check if installed version matches the version in the repository directory
|
||||
if [[ "$INSTALLED_VERSION" != "$REPO_VERSION" ]]; then
|
||||
echo "Version mismatch. Running install script and exiting updater."
|
||||
echo "New version: $REPO_VERSION"
|
||||
/bin/bash "$REPO_DIR/install.sh"
|
||||
( /bin/bash "$HOME/update.sh" & )
|
||||
exit 0
|
||||
fi
|
||||
|
||||
( /bin/bash "$HOME/pull_from_cloud.sh" & )
|
||||
|
||||
source "$HOME/jukebox/bin/activate"
|
||||
python3 "$HOME/main1.py"
|
||||
1
version.txt
Normal file
1
version.txt
Normal file
@ -0,0 +1 @@
|
||||
1.0.2
|
||||
Loading…
x
Reference in New Issue
Block a user