mirror of
https://github.com/chibicitiberiu/ytsm.git
synced 2024-02-24 05:43:31 +00:00
First time setup improvements
This commit is contained in:
parent
899de7adf5
commit
022d3aa4f5
@ -1,6 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from django.conf import settings as dj_settings
|
from django.conf import settings as dj_settings
|
||||||
|
|
||||||
@ -9,20 +10,29 @@ from .management.jobs.synchronize import schedule_synchronize_global
|
|||||||
from .scheduler import initialize_scheduler
|
from .scheduler import initialize_scheduler
|
||||||
from django.db.utils import OperationalError
|
from django.db.utils import OperationalError
|
||||||
|
|
||||||
|
|
||||||
def __initialize_logger():
|
def __initialize_logger():
|
||||||
log_dir = os.path.join(dj_settings.DATA_DIR, 'logs')
|
log_dir = os.path.join(dj_settings.DATA_DIR, 'logs')
|
||||||
os.makedirs(log_dir, exist_ok=True)
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
|
|
||||||
|
handlers = []
|
||||||
|
|
||||||
file_handler = logging.handlers.RotatingFileHandler(
|
file_handler = logging.handlers.RotatingFileHandler(
|
||||||
os.path.join(log_dir, "log.log"),
|
os.path.join(log_dir, "log.log"),
|
||||||
maxBytes=1024 * 1024,
|
maxBytes=1024 * 1024,
|
||||||
backupCount=5
|
backupCount=5
|
||||||
)
|
)
|
||||||
|
handlers.append(file_handler)
|
||||||
|
|
||||||
|
if dj_settings.DEBUG:
|
||||||
|
console_handler = logging.StreamHandler(stream=sys.stdout)
|
||||||
|
console_handler.setLevel(logging.DEBUG)
|
||||||
|
handlers.append(console_handler)
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=dj_settings.LOG_LEVEL,
|
level=dj_settings.LOG_LEVEL,
|
||||||
format=dj_settings.LOG_FORMAT,
|
format=dj_settings.LOG_FORMAT,
|
||||||
handlers=[file_handler]
|
handlers=handlers
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#main_body {
|
#main_body {
|
||||||
margin-bottom: 4rem; }
|
margin-bottom: 4rem;
|
||||||
|
margin-top: 2rem; }
|
||||||
|
|
||||||
#main_footer {
|
#main_footer {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"mappings": "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",
|
"mappings": "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",
|
||||||
"sources": ["style.scss"],
|
"sources": ["style.scss"],
|
||||||
"names": [],
|
"names": [],
|
||||||
"file": "style.css"
|
"file": "style.css"
|
||||||
|
@ -2,6 +2,7 @@ $accent-color: #007bff;
|
|||||||
|
|
||||||
#main_body {
|
#main_body {
|
||||||
margin-bottom: 4rem;
|
margin-bottom: 4rem;
|
||||||
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main_footer {
|
#main_footer {
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
<h1>Step 1: Set up YouTube API key (optional)</h1>
|
<h1>Step 1: Set up YouTube API key (optional)</h1>
|
||||||
<p>This program uses the YouTube API in order to obtain information about videos, channels and playlists.
|
<p>This program uses the YouTube API in order to obtain information about videos, channels and playlists.
|
||||||
In order to access this API, YouTube requires that we register on their site and request an API key. YouTube
|
To access this API, YouTube requires users to register on their site and request an API key. YouTube
|
||||||
uses this key in order to limit the number of requests made to their platform, in order to prevent abuses.</p>
|
uses this key to control access and limit the number of requests made to their platform, in order to prevent abuses.</p>
|
||||||
|
|
||||||
<p>To use this program, it is <em>recommended</em> that you create an API key for your own account. While a key
|
<p>To use this program, it is <em>recommended</em>, but not required, that you create an API key for your own account. While a key
|
||||||
is already provided the developer, there is a chance that the quota limits will be reached, which will prevent
|
is already provided the developer, there is a chance that the quota limits will be reached, which will prevent
|
||||||
this program from reaching YouTube. Follow the steps below, or press <strong>Skip</strong> to use the provided key.</p>
|
this program from reaching YouTube. Follow the steps below, or press <strong>Skip</strong> to use the provided key.</p>
|
||||||
|
|
||||||
@ -59,8 +59,6 @@
|
|||||||
|
|
||||||
{% crispy form %}
|
{% crispy form %}
|
||||||
|
|
||||||
<a href="{% url 'first_time_2' %}">Skip</a>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
@ -24,12 +24,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if is_first_user %}
|
|
||||||
<div class="alert alert-info" role="alert">
|
|
||||||
Since this is the first user to register, it will be the system administrator.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5>Register</h5>
|
<h5>Register</h5>
|
||||||
|
|
||||||
{% crispy form %}
|
{% crispy form %}
|
||||||
|
@ -64,6 +64,7 @@ urlpatterns = [
|
|||||||
path('first_time/step0_welcome', first_time.Step0WelcomeView.as_view(), name='first_time_0'),
|
path('first_time/step0_welcome', first_time.Step0WelcomeView.as_view(), name='first_time_0'),
|
||||||
path('first_time/step1_apikey', first_time.Step1ApiKeyView.as_view(), name='first_time_1'),
|
path('first_time/step1_apikey', first_time.Step1ApiKeyView.as_view(), name='first_time_1'),
|
||||||
path('first_time/step2_admin', first_time.Step2CreateAdminUserView.as_view(), name='first_time_2'),
|
path('first_time/step2_admin', first_time.Step2CreateAdminUserView.as_view(), name='first_time_2'),
|
||||||
|
path('first_time/step2_login', first_time.Step2LoginAdminUserView.as_view(), name='first_time_2_login'),
|
||||||
path('first_time/step3_config', first_time.Step3ConfigureView.as_view(), name='first_time_3'),
|
path('first_time/step3_config', first_time.Step3ConfigureView.as_view(), name='first_time_3'),
|
||||||
path('first_time/done', first_time.DoneView.as_view(), name='first_time_done'),
|
path('first_time/done', first_time.DoneView.as_view(), name='first_time_done'),
|
||||||
|
|
||||||
|
@ -58,13 +58,8 @@ class RegisterView(FormView):
|
|||||||
success_url = reverse_lazy('register_done')
|
success_url = reverse_lazy('register_done')
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
is_first_user = (User.objects.count() == 0)
|
|
||||||
|
|
||||||
user = form.save()
|
form.save()
|
||||||
if is_first_user:
|
|
||||||
user.is_staff = True
|
|
||||||
user.is_superuser = True
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
username = form.cleaned_data.get('username')
|
username = form.cleaned_data.get('username')
|
||||||
password = form.cleaned_data.get('password1')
|
password = form.cleaned_data.get('password1')
|
||||||
|
@ -1,26 +1,35 @@
|
|||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
from crispy_forms.layout import Layout, HTML, Submit
|
from crispy_forms.layout import Layout, HTML, Submit, Column
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.contrib.auth import authenticate, login
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic import UpdateView, FormView
|
from django.views.generic import UpdateView, FormView
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from YtManagerApp.views.auth import RegisterView
|
from YtManagerApp.views.auth import RegisterView, ExtendedUserCreationForm, ExtendedAuthenticationForm
|
||||||
from YtManagerApp.models import UserSettings
|
from YtManagerApp.models import UserSettings
|
||||||
|
|
||||||
from YtManagerApp.management.appconfig import global_prefs
|
from YtManagerApp.management.appconfig import global_prefs
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger("FirstTimeWizard")
|
||||||
|
|
||||||
|
|
||||||
class ProtectInitializedMixin(object):
|
class ProtectInitializedMixin(object):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
if global_prefs['hidden__initialized']:
|
if global_prefs['hidden__initialized']:
|
||||||
|
logger.debug(f"Attempted to access {request.path}, but first time setup already run. Redirected to home page.")
|
||||||
return redirect('home')
|
return redirect('home')
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if global_prefs['hidden__initialized']:
|
if global_prefs['hidden__initialized']:
|
||||||
|
logger.debug(f"Attempted to post {request.path}, but first time setup already run.")
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
return super().post(request, *args, **kwargs)
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
@ -54,7 +63,10 @@ class Step1ApiKeyForm(forms.Form):
|
|||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.layout = Layout(
|
self.helper.layout = Layout(
|
||||||
'api_key',
|
'api_key',
|
||||||
Submit('submit', value='Continue'),
|
Column(
|
||||||
|
Submit('submit', value='Continue'),
|
||||||
|
HTML('<a href="{% url \'first_time_2\' %}" class="btn">Skip</a>')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -73,9 +85,50 @@ class Step1ApiKeyView(ProtectInitializedMixin, FormView):
|
|||||||
#
|
#
|
||||||
# Step 2: create admin user
|
# Step 2: create admin user
|
||||||
#
|
#
|
||||||
class Step2CreateAdminUserView(ProtectInitializedMixin, RegisterView):
|
class Step2CreateAdminUserView(ProtectInitializedMixin, FormView):
|
||||||
template_name = 'YtManagerApp/first_time_setup/step2_admin.html'
|
template_name = 'YtManagerApp/first_time_setup/step2_admin.html'
|
||||||
success_url = reverse_lazy('first_time_3')
|
success_url = reverse_lazy('first_time_3')
|
||||||
|
form_class = ExtendedUserCreationForm
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
# Skip if admin is already logged in
|
||||||
|
if request.user.is_authenticated and request.user.is_superuser:
|
||||||
|
logger.debug("Admin user already exists and is logged in!")
|
||||||
|
return redirect(self.success_url)
|
||||||
|
|
||||||
|
# Check if an admin user already exists
|
||||||
|
if User.objects.filter(is_superuser=True).count() > 0:
|
||||||
|
logger.warn("Admin user already exists! Will redirect to login page!")
|
||||||
|
return redirect('first_time_2_login')
|
||||||
|
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
user = form.save()
|
||||||
|
user.is_staff = True
|
||||||
|
user.is_superuser = True
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
username = form.cleaned_data.get('username')
|
||||||
|
password = form.cleaned_data.get('password1')
|
||||||
|
user = authenticate(username=username, password=password)
|
||||||
|
login(self.request, user)
|
||||||
|
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Step 2: create admin user
|
||||||
|
#
|
||||||
|
class Step2LoginAdminUserView(ProtectInitializedMixin, FormView):
|
||||||
|
template_name = 'YtManagerApp/first_time_setup/step2_admin.html'
|
||||||
|
success_url = reverse_lazy('first_time_3')
|
||||||
|
form_class = ExtendedAuthenticationForm
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
login(self.request, form.get_user())
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user