You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.7 KiB
Python
182 lines
6.7 KiB
Python
from django.conf import settings
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db import transaction
|
|
from django.db.models import F, Min
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from re import match
|
|
|
|
from .forms import AddBreakContentForm, CreatePlaylistForm
|
|
from .models import BreakContent
|
|
from .spreadsheet import get_sheet_data
|
|
from ..core.models import Artist, Playlist, Session
|
|
|
|
def get_absolute_join_session_url(request, session):
|
|
return request.build_absolute_uri(reverse('join_session', args=(session.pk,)))
|
|
|
|
# Create your views here.
|
|
|
|
@login_required
|
|
@transaction.atomic
|
|
def create_playlist(request):
|
|
form = CreatePlaylistForm()
|
|
|
|
if request.method == 'POST':
|
|
form = CreatePlaylistForm(request.POST)
|
|
if not form.is_valid():
|
|
return render(request, 'host/create_playlist.html', {'error': None, 'form': form})
|
|
|
|
m = match(r'https://docs.google.com/spreadsheets/d/([-0-9A-Z_a-z]{44})', form.cleaned_data['spreadsheet_url'])
|
|
if m == None:
|
|
return render(request, 'host/create_playlist.html', {'error': 'Der eingegebene Link führt nicht zu einer Google Tabelle.', 'form': CreatePlaylistForm()})
|
|
|
|
spreadsheet_id = m[1]
|
|
if Playlist.objects.filter(pk=spreadsheet_id).exists():
|
|
return redirect('playlist', spreadsheet_id)
|
|
|
|
playlist = Playlist(spreadsheet_id=spreadsheet_id)
|
|
|
|
data = get_sheet_data(spreadsheet_id)
|
|
mapping = {}
|
|
artist_names = set()
|
|
artists = []
|
|
for row in data:
|
|
row = list(map(lambda s: s.strip(), row))
|
|
|
|
if not mapping:
|
|
if settings.REQUIRED_FIELDS[0] in row:
|
|
required_fields = set(settings.REQUIRED_FIELDS)
|
|
for index, heading in enumerate(row):
|
|
if heading in required_fields:
|
|
mapping[heading] = index
|
|
required_fields.remove(heading)
|
|
if len(required_fields) == 0:
|
|
break
|
|
if len(required_fields) != 0:
|
|
return render(request, 'host/create_playlist.html', {'error': 'Die Tabelle ist nicht im passenden Format.', 'form': CreatePlaylistForm()})
|
|
|
|
playlist.field_indices = mapping
|
|
playlist.save()
|
|
continue
|
|
|
|
values = {}
|
|
for field in settings.REQUIRED_FIELDS:
|
|
index = mapping[field]
|
|
model_field, blank = settings.SHEET_TO_MODEL[field]
|
|
if index >= len(row):
|
|
if not blank:
|
|
values = {}
|
|
break
|
|
continue
|
|
|
|
value = row[index]
|
|
if not (value or blank) or model_field == 'name' and value in artist_names:
|
|
values = {}
|
|
break
|
|
|
|
values[model_field] = value
|
|
if model_field == 'name':
|
|
artist_names.add(value)
|
|
|
|
if values:
|
|
artists.append(Artist(playlist=playlist, **values))
|
|
|
|
Artist.objects.bulk_create(artists)
|
|
|
|
return redirect('playlist', playlist=spreadsheet_id)
|
|
|
|
return render(request, 'host/create_playlist.html', {'error': None, 'form': form})
|
|
|
|
@login_required
|
|
def break_view(request):
|
|
if request.method == 'POST':
|
|
session = get_object_or_404(Session, pk=request.session.get('session'))
|
|
session.last_break = timezone.now()
|
|
session.save()
|
|
return redirect('view_artist', session.playlist.pk, session.offset)
|
|
|
|
min_use_count = BreakContent.objects.aggregate(Min('use_count'))['use_count__min']
|
|
content = BreakContent.objects.filter(use_count=min_use_count).order_by('?')[0]
|
|
content.use_count = F('use_count') + 1
|
|
content.save()
|
|
|
|
return render(request, 'host/break.html', {'video_id': content.video_id})
|
|
|
|
@login_required
|
|
def add_break_content(request):
|
|
form = AddBreakContentForm()
|
|
|
|
if request.method == 'POST':
|
|
form = AddBreakContentForm(request.POST)
|
|
if not form.is_valid():
|
|
return redirect('add_break_content')
|
|
|
|
m = match(settings.YOUTUBE_RE, form.cleaned_data['video_url'])
|
|
if m == None:
|
|
return redirect('add_break_content')
|
|
|
|
min_use_count = BreakContent.objects.aggregate(Min('use_count'))['use_count__min']
|
|
|
|
content = BreakContent(video_id=m[1], use_count=min_use_count or 0)
|
|
content.save()
|
|
|
|
return redirect('add_break_content')
|
|
|
|
return render(request, 'host/add_break_content.html', {'form': form})
|
|
|
|
@login_required
|
|
def session(request):
|
|
if 'session' in request.session:
|
|
try:
|
|
session = Session.objects.get(pk=request.session['session'])
|
|
return render(request, 'host/session.html', {'session': session, 'session_url': get_absolute_join_session_url(request, session)})
|
|
except Session.DoesNotExist:
|
|
del request.session['session']
|
|
|
|
return redirect('create_playlist')
|
|
|
|
@login_required
|
|
def playlist(request, playlist):
|
|
playlist = get_object_or_404(Playlist, pk=playlist)
|
|
return render(request, 'host/playlist.html', {'num_artists': playlist.artist_set.count()})
|
|
|
|
@login_required
|
|
def start_session(request, playlist):
|
|
playlist = get_object_or_404(Playlist, pk=playlist)
|
|
|
|
if request.method == 'POST':
|
|
if 'session' in request.session:
|
|
return redirect('session')
|
|
|
|
session = Session(playlist=playlist)
|
|
session.save()
|
|
|
|
request.session['session'] = session.token
|
|
return redirect('session')
|
|
|
|
return redirect('playlist', playlist=playlist.pk)
|
|
|
|
@login_required
|
|
def view_artist(request, playlist, offset):
|
|
artists = get_object_or_404(Playlist, pk=playlist).artist_set
|
|
artist = artists.order_by('id')[offset]
|
|
links = (('youtube', m[1]) if (m := match(settings.YOUTUBE_RE, link)) else ('other', link) for link in (artist.link_1, artist.link_2) if link)
|
|
|
|
session_url = None
|
|
if 'session' in request.session:
|
|
try:
|
|
session = Session.objects.get(pk=request.session['session'])
|
|
session_url = get_absolute_join_session_url(request, session)
|
|
|
|
if session.offset < offset:
|
|
session.offset = offset
|
|
session.save()
|
|
|
|
if (timezone.now()-session.last_break).total_seconds() >= settings.BREAK_INTERVAL*60:
|
|
return redirect('break')
|
|
except Session.DoesNotExist:
|
|
del request.session['session']
|
|
|
|
return render(request, 'host/view_artist.html', {'artist': artist, 'count': artists.count(), 'links': links, 'offset': offset, 'playlist': playlist, 'session_url': session_url})
|