mirror of
https://github.com/rudy3333/eversync.git
synced 2025-07-01 08:36:02 +00:00
added api to stream music, currently only API. also updated the dockerfile to automatically install ffmpeg (its git ignored)
This commit is contained in:
parent
8f54ac72b1
commit
c4859dd4e5
5 changed files with 73 additions and 19 deletions
|
@ -49,6 +49,7 @@ urlpatterns = [
|
|||
path('inbox/', views.inbox, name='inbox'),
|
||||
path('chat', views.chat_page, name="chat"),
|
||||
path('delete/<int:message_id>/', views.delete_message, name='delete_message'),
|
||||
path('stream_song/', views.stream_song, name='stream_song'),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.http import HttpResponse, JsonResponse, FileResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm
|
||||
# Create your views here.
|
||||
|
@ -19,6 +19,8 @@ from webpush import send_user_notification
|
|||
from icalendar import Calendar, Event as IcalEvent
|
||||
from django.utils.text import slugify
|
||||
import json
|
||||
import tempfile
|
||||
from yt_dlp import YoutubeDL
|
||||
|
||||
providers = micawber.bootstrap_basic()
|
||||
|
||||
|
@ -515,4 +517,27 @@ def delete_message(request, message_id):
|
|||
if request.method == "POST":
|
||||
message = get_object_or_404(Message, id=message_id, sender=request.user)
|
||||
message.delete()
|
||||
return redirect('chat')
|
||||
return redirect('chat')
|
||||
|
||||
def stream_song(request):
|
||||
query = request.GET.get("query")
|
||||
if not query:
|
||||
return JsonResponse({"error": "No search query provided"}, status=400)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
ytpdl_options = {
|
||||
'format': 'bestaudio[ext=m4a]/bestaudio/best',
|
||||
'noplaylist': 'true',
|
||||
'outtmpl': f'{tmpdir}/%(title)s.%(ext)s',
|
||||
'postprocessors': [{
|
||||
'key': 'FFmpegExtractAudio',
|
||||
'preferredcodec': 'mp3',
|
||||
}],
|
||||
'quiet': True
|
||||
}
|
||||
|
||||
with YoutubeDL(ytpdl_options) as ytpdl:
|
||||
info = ytpdl.extract_info(f"ytsearch1:{query} audio", download=True)
|
||||
filepath = ytpdl.prepare_filename(info['entries'][0]).replace('.webm', '.mp3').replace('.m4a', '.mp3')
|
||||
return FileResponse(open(filepath, 'rb'), content_type='audio/mpeg')
|
||||
|
|
@ -164,6 +164,11 @@
|
|||
chat
|
||||
</div></a>
|
||||
|
||||
<a href="/music" style="text-decoration: none;"><div class="service-button music">
|
||||
<i class="fa-solid fa-music"></i>
|
||||
music
|
||||
</div></a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,12 @@
|
|||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
#pomodoro-settings {
|
||||
margin-top: 20px;
|
||||
font-size: 1.2rem;
|
||||
display: none;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -45,6 +51,15 @@
|
|||
<p id="timer-display">25:00</p>
|
||||
<button onclick="startPomodoro()">Start</button>
|
||||
<button onclick="stopPomodoro()">Stop</button>
|
||||
<button onclick="toggleSettings()">Settings</button>
|
||||
|
||||
<div id="pomodoro-settings">
|
||||
<h4>Settings</h4>
|
||||
<label for="session-minutes">Session Length (minutes):</label>
|
||||
<input type="number" id="session-minutes" min="1" value="25" style="font-size: 1.2rem; width: 60px;">
|
||||
<br><br>
|
||||
<button onclick="applySettings()">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
|
@ -74,21 +89,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
// Dropdown menu code
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const toggle = document.querySelector('.dropdown-toggle');
|
||||
const menu = document.querySelector('.dropdown-menu');
|
||||
toggle.addEventListener('click', function () {
|
||||
menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
|
||||
});
|
||||
});
|
||||
|
||||
// Pomodoro timer code
|
||||
let pomodoroInterval = null;
|
||||
let totalSeconds = 25 * 60;
|
||||
let sessionLength = 25;
|
||||
let running = false;
|
||||
|
||||
function updateDisplay() {
|
||||
|
@ -97,6 +101,13 @@
|
|||
document.getElementById('timer-display').textContent = `${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
function applySettings() {
|
||||
const input = document.getElementById('session-minutes');
|
||||
sessionLength = parseInt(input.value) || 25;
|
||||
totalSeconds = sessionLength * 60;
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
function startPomodoro() {
|
||||
if (running) return;
|
||||
running = true;
|
||||
|
@ -113,7 +124,7 @@
|
|||
function stopPomodoro() {
|
||||
running = false;
|
||||
clearInterval(pomodoroInterval);
|
||||
totalSeconds = 25 * 60;
|
||||
totalSeconds = sessionLength * 60;
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
|
@ -121,10 +132,21 @@
|
|||
document.getElementById('pomodoro-box').style.display = 'block';
|
||||
}
|
||||
|
||||
function toggleSettings() {
|
||||
const settings = document.getElementById('pomodoro-settings');
|
||||
settings.style.display = settings.style.display === 'block' ? 'none' : 'block';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
togglePomodoro(); // Automatically show the timer when the page loads
|
||||
togglePomodoro();
|
||||
updateDisplay();
|
||||
|
||||
const dropdownToggle = document.querySelector('.dropdown-toggle');
|
||||
const dropdownMenu = document.querySelector('.dropdown-menu');
|
||||
dropdownToggle.addEventListener('click', () => {
|
||||
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
|
@ -19,4 +19,5 @@ micawber
|
|||
requests
|
||||
django-webpush
|
||||
icalendar
|
||||
sentry-sdk[django]
|
||||
sentry-sdk[django]
|
||||
yt-dlp
|
Loading…
Add table
Add a link
Reference in a new issue