Implemented user settings page.
This commit is contained in:
@ -8,8 +8,6 @@ from django.db import models
|
||||
from django.db.models.functions import Lower
|
||||
from YtManagerApp.utils.youtube import YoutubeAPI, YoutubeChannelInfo, YoutubePlaylistInfo
|
||||
|
||||
|
||||
|
||||
# help_text = user shown text
|
||||
# verbose_name = user shown name
|
||||
# null = nullable, blank = user is allowed to set value to empty
|
||||
@ -17,20 +15,87 @@ from YtManagerApp.utils.youtube import YoutubeAPI, YoutubeChannelInfo, YoutubePl
|
||||
|
||||
class UserSettings(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
mark_deleted_as_watched = models.BooleanField(null=True)
|
||||
delete_watched = models.BooleanField(null=True)
|
||||
auto_download = models.BooleanField(null=True)
|
||||
download_global_limit = models.IntegerField(null=True)
|
||||
download_subscription_limit = models.IntegerField(null=True)
|
||||
download_order = models.TextField(null=True)
|
||||
download_path = models.TextField(null=True)
|
||||
download_file_pattern = models.TextField(null=True)
|
||||
download_format = models.TextField(null=True)
|
||||
download_subtitles = models.BooleanField(null=True)
|
||||
download_autogenerated_subtitles = models.BooleanField(null=True)
|
||||
download_subtitles_all = models.BooleanField(null=True)
|
||||
download_subtitles_langs = models.TextField(null=True)
|
||||
download_subtitles_format = models.TextField(null=True)
|
||||
|
||||
mark_deleted_as_watched = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='When a downloaded video is deleted from the system, it will be marked as \'watched\'.')
|
||||
|
||||
delete_watched = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='Videos marked as watched are automatically deleted.')
|
||||
|
||||
auto_download = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='Enables or disables automatic downloading.')
|
||||
|
||||
download_global_limit = models.IntegerField(
|
||||
null=True, blank=True,
|
||||
help_text='Limits the total number of videos downloaded (-1 = no limit).')
|
||||
|
||||
download_subscription_limit = models.IntegerField(
|
||||
null=True, blank=True,
|
||||
help_text='Limits the number of videos downloaded per subscription (-1 = no limit). '
|
||||
' This setting can be overriden for each individual subscription in the subscription edit dialog.')
|
||||
|
||||
download_order = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=100,
|
||||
help_text='The order in which videos will be downloaded.'
|
||||
)
|
||||
|
||||
download_path = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=1024,
|
||||
help_text='Path on the disk where downloaded videos are stored. '
|
||||
' You can use environment variables using syntax: <code>${env:...}</code>'
|
||||
)
|
||||
|
||||
download_file_pattern = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=1024,
|
||||
help_text='A pattern which describes how downloaded files are organized. Extensions are automatically appended.'
|
||||
' You can use the following fields, using the <code>${field}</code> syntax:'
|
||||
' channel, channel_id, playlist, playlist_id, playlist_index, title, id.'
|
||||
' Example: <code>${channel}/${playlist}/S01E${playlist_index} - ${title} [${id}]</code>')
|
||||
|
||||
download_format = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=256,
|
||||
help_text='Download format that will be passed to youtube-dl. '
|
||||
' See the <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#format-selection">'
|
||||
' youtube-dl documentation</a> for more details.')
|
||||
|
||||
download_subtitles = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='Enable downloading subtitles for the videos.'
|
||||
' The flag is passed directly to youtube-dl. You can find more information'
|
||||
' <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#subtitle-options">here</a>.')
|
||||
|
||||
download_autogenerated_subtitles = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='Enables downloading the automatically generated subtitle.'
|
||||
' The flag is passed directly to youtube-dl. You can find more information'
|
||||
' <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#subtitle-options">here</a>.')
|
||||
|
||||
download_subtitles_all = models.BooleanField(
|
||||
null=True, blank=True,
|
||||
help_text='If enabled, all the subtitles in all the available languages will be downloaded.'
|
||||
' The flag is passed directly to youtube-dl. You can find more information'
|
||||
' <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#subtitle-options">here</a>.')
|
||||
|
||||
download_subtitles_langs = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=250,
|
||||
help_text='Comma separated list of languages for which subtitles will be downloaded.'
|
||||
' The flag is passed directly to youtube-dl. You can find more information'
|
||||
' <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#subtitle-options">here</a>.')
|
||||
|
||||
download_subtitles_format = models.CharField(
|
||||
null=True, blank=True,
|
||||
max_length=100,
|
||||
help_text='Subtitles format preference. Examples: srt/ass/best'
|
||||
' The flag is passed directly to youtube-dl. You can find more information'
|
||||
' <a href="https://github.com/rg3/youtube-dl/blob/master/README.md#subtitle-options">here</a>.')
|
||||
|
||||
@staticmethod
|
||||
def find_by_user(user: User):
|
||||
|
@ -1,4 +1,7 @@
|
||||
.footer {
|
||||
#main_body {
|
||||
margin-bottom: 4rem; }
|
||||
|
||||
#main_footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAEA,OAAQ;EACJ,QAAQ,EAAE,KAAK;EACf,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,SAAS;EAClB,OAAO,EAAE,IAAI;EACb,aAAa,EAAE,MAAM;EACrB,SAAS,EAAE,IAAI;;AAqBnB,uBAAuB;AACvB,kBAAmB;EAlBf,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAa;EACpB,MAAM,EAAE,IAAa;EAErB,wBAAQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,IAAa;IACpB,MAAM,EAAE,IAAa;IACrB,MAAM,EAAE,GAAG;IACX,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,iBAAkC;IAC1C,YAAY,EAAE,uCAAmD;IACjE,SAAS,EAAE,sCAAsC;;AASzD,wBAAyB;EAtBrB,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAa;EACpB,MAAM,EAAE,IAAa;EAErB,8BAAQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,IAAa;IACpB,MAAM,EAAE,IAAa;IACrB,MAAM,EAAE,GAAG;IACX,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,mBAAkC;IAC1C,YAAY,EAAE,uCAAmD;IACjE,SAAS,EAAE,sCAAsC;;AAazD,4BAOC;EANG,EAAG;IACC,SAAS,EAAE,YAAY;EAE3B,IAAK;IACD,SAAS,EAAE,cAAc;AAIjC,gCAAiC;EAC7B,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,GAAG;EACR,IAAI,EAAE,GAAG;EACT,UAAU,EAAE,KAAK;EACjB,WAAW,EAAE,KAAK;;AAGtB,cAAe;EACX,QAAQ,EAAE,KAAK;EAAE,oCAAoC;EACrD,OAAO,EAAE,IAAI;EAAE,uBAAuB;EACtC,KAAK,EAAE,IAAI;EAAE,uCAAuC;EACpD,MAAM,EAAE,IAAI;EAAE,wCAAwC;EACtD,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,gBAAgB,EAAE,kBAAe;EAAE,mCAAmC;EACtE,OAAO,EAAE,CAAC;EAAE,qFAAqF;EACjG,MAAM,EAAE,OAAO;EAAE,4BAA4B;;AAI7C,4BAAc;EACV,OAAO,EAAE,MAAM;EACf,aAAa,EAAE,KAAK;AAGpB,+BAAW;EACP,OAAO,EAAE,MAAM;AAEnB,+BAAW;EACP,SAAS,EAAE,IAAI;EACf,aAAa,EAAE,KAAK;AAExB,gCAAY;EACR,SAAS,EAAE,IAAI;EACf,aAAa,EAAE,KAAK;EAEpB,uCAAO;IACH,SAAS,EAAE,GAAG;AAGtB,iCAAa;EACT,OAAO,EAAE,YAAY;AAGzB,+BAAW;EACP,YAAY,EAAE,QAAQ;EACtB,qCAAQ;IACJ,eAAe,EAAE,IAAI;AAO7B,8BAAU;EACN,KAAK,EAAE,KAAK;AAKpB,8BAAgB;EACZ,KAAK,EAnHE,OAAO;AAqHlB,6BAAe;EACX,KAAK,EAAE,OAAO;;AAItB,WAAY;EACR,SAAS,EAAE,KAAK;EAChB,MAAM,EAAE,MAAM;;AAId,2BAAe;EACX,OAAO,EAAE,IAAI;;AAIrB,kBAAmB;EACf,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EAEjB,qBAAG;IACC,MAAM,EAAE,CAAC;;AAIjB,YAAa;EACT,OAAO,EAAE,YAAY;EACrB,aAAa,EAAE,MAAM",
|
||||
"mappings": "AAEA,UAAW;EACP,aAAa,EAAE,IAAI;;AAGvB,YAAa;EACT,QAAQ,EAAE,KAAK;EACf,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,IAAI;EACjB,OAAO,EAAE,SAAS;EAClB,OAAO,EAAE,IAAI;EACb,aAAa,EAAE,MAAM;EACrB,SAAS,EAAE,IAAI;;AAqBnB,uBAAuB;AACvB,kBAAmB;EAlBf,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAa;EACpB,MAAM,EAAE,IAAa;EAErB,wBAAQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,IAAa;IACpB,MAAM,EAAE,IAAa;IACrB,MAAM,EAAE,GAAG;IACX,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,iBAAkC;IAC1C,YAAY,EAAE,uCAAmD;IACjE,SAAS,EAAE,sCAAsC;;AASzD,wBAAyB;EAtBrB,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAa;EACpB,MAAM,EAAE,IAAa;EAErB,8BAAQ;IACJ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,IAAa;IACpB,MAAM,EAAE,IAAa;IACrB,MAAM,EAAE,GAAG;IACX,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,mBAAkC;IAC1C,YAAY,EAAE,uCAAmD;IACjE,SAAS,EAAE,sCAAsC;;AAazD,4BAOC;EANG,EAAG;IACC,SAAS,EAAE,YAAY;EAE3B,IAAK;IACD,SAAS,EAAE,cAAc;AAIjC,gCAAiC;EAC7B,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,GAAG;EACR,IAAI,EAAE,GAAG;EACT,UAAU,EAAE,KAAK;EACjB,WAAW,EAAE,KAAK;;AAGtB,cAAe;EACX,QAAQ,EAAE,KAAK;EAAE,oCAAoC;EACrD,OAAO,EAAE,IAAI;EAAE,uBAAuB;EACtC,KAAK,EAAE,IAAI;EAAE,uCAAuC;EACpD,MAAM,EAAE,IAAI;EAAE,wCAAwC;EACtD,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,gBAAgB,EAAE,kBAAe;EAAE,mCAAmC;EACtE,OAAO,EAAE,CAAC;EAAE,qFAAqF;EACjG,MAAM,EAAE,OAAO;EAAE,4BAA4B;;AAI7C,4BAAc;EACV,OAAO,EAAE,MAAM;EACf,aAAa,EAAE,KAAK;AAGpB,+BAAW;EACP,OAAO,EAAE,MAAM;AAEnB,+BAAW;EACP,SAAS,EAAE,IAAI;EACf,aAAa,EAAE,KAAK;AAExB,gCAAY;EACR,SAAS,EAAE,IAAI;EACf,aAAa,EAAE,KAAK;EAEpB,uCAAO;IACH,SAAS,EAAE,GAAG;AAGtB,iCAAa;EACT,OAAO,EAAE,YAAY;AAGzB,+BAAW;EACP,YAAY,EAAE,QAAQ;EACtB,qCAAQ;IACJ,eAAe,EAAE,IAAI;AAO7B,8BAAU;EACN,KAAK,EAAE,KAAK;AAKpB,8BAAgB;EACZ,KAAK,EAvHE,OAAO;AAyHlB,6BAAe;EACX,KAAK,EAAE,OAAO;;AAItB,WAAY;EACR,SAAS,EAAE,KAAK;EAChB,MAAM,EAAE,MAAM;;AAId,2BAAe;EACX,OAAO,EAAE,IAAI;;AAIrB,kBAAmB;EACf,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EAEjB,qBAAG;IACC,MAAM,EAAE,CAAC;;AAIjB,YAAa;EACT,OAAO,EAAE,YAAY;EACrB,aAAa,EAAE,MAAM",
|
||||
"sources": ["style.scss"],
|
||||
"names": [],
|
||||
"file": "style.css"
|
||||
|
@ -1,6 +1,10 @@
|
||||
$accent-color: #007bff;
|
||||
|
||||
.footer {
|
||||
#main_body {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
#main_footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
@ -43,7 +43,7 @@
|
||||
{% endif %}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="#">Settings</a>
|
||||
<a class="dropdown-item" href="{% url 'settings' %}">Settings</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{% url 'logout' %}">Log out</a>
|
||||
</div>
|
||||
@ -61,12 +61,12 @@
|
||||
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div id="main_body" class="container-fluid">
|
||||
{% block body %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer class="footer bg-light">
|
||||
<footer id="main_footer" class="footer bg-light">
|
||||
<span class="ml-auto text-muted">Last synchronized: just now</span>
|
||||
<button id="btn_sync_now" class="btn btn-sm btn-light" title="Synchronize now!">
|
||||
<span class="typcn typcn-arrow-sync" aria-hidden="true"></span>
|
||||
|
12
YtManagerApp/templates/YtManagerApp/settings.html
Normal file
12
YtManagerApp/templates/YtManagerApp/settings.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% extends "YtManagerApp/master_default.html" %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="container">
|
||||
<h1>Settings</h1>
|
||||
<p>If no value is set, the server's defaults will be used.</p>
|
||||
{% crispy form %}
|
||||
</div>
|
||||
|
||||
{% endblock body %}
|
@ -18,12 +18,12 @@ from django.conf.urls import include
|
||||
from django.conf.urls.static import static
|
||||
from django.urls import path
|
||||
|
||||
from .views.auth import ExtendedLoginView, RegisterView, RegisterDoneView
|
||||
from .views.index import index, ajax_get_tree, ajax_get_videos, CreateFolderModal, UpdateFolderModal, DeleteFolderModal,\
|
||||
CreateSubscriptionModal, UpdateSubscriptionModal, DeleteSubscriptionModal
|
||||
from .views.actions import SyncNowView, DeleteVideoFilesView, DownloadVideoFilesView, MarkVideoWatchedView, \
|
||||
MarkVideoUnwatchedView
|
||||
from .views import old_views
|
||||
from .views.auth import ExtendedLoginView, RegisterView, RegisterDoneView
|
||||
from .views.index import index, ajax_get_tree, ajax_get_videos, CreateFolderModal, UpdateFolderModal, DeleteFolderModal, \
|
||||
CreateSubscriptionModal, UpdateSubscriptionModal, DeleteSubscriptionModal
|
||||
from .views.settings import SettingsView
|
||||
|
||||
urlpatterns = [
|
||||
# Authentication URLs
|
||||
@ -53,17 +53,8 @@ urlpatterns = [
|
||||
path('modal/update_subscription/<int:pk>/', UpdateSubscriptionModal.as_view(), name='modal_update_subscription'),
|
||||
path('modal/delete_subscription/<int:pk>/', DeleteSubscriptionModal.as_view(), name='modal_delete_subscription'),
|
||||
|
||||
# Index
|
||||
# Pages
|
||||
path('', index, name='home'),
|
||||
path('settings/', SettingsView.as_view(), name='settings'),
|
||||
|
||||
|
||||
# Old stuff
|
||||
path('ajax/get_children', old_views.ajax_get_children, name='ajax_get_children'),
|
||||
path('ajax/get_folders', old_views.ajax_get_folders, name='ajax_get_folders'),
|
||||
path('ajax/edit_folder', old_views.ajax_edit_folder, name='ajax_edit_folder'),
|
||||
path('ajax/delete_folder/<int:fid>/', old_views.ajax_delete_folder, name='ajax_delete_folder'),
|
||||
path('ajax/edit_subscription', old_views.ajax_edit_subscription, name='ajax_edit_subscription'),
|
||||
path('ajax/delete_subscription/<int:sid>/', old_views.ajax_delete_subscription, name='ajax_delete_subscription'),
|
||||
path('ajax/list_videos', old_views.ajax_list_videos, name='ajax_list_videos'),
|
||||
# path('', old_views.index, name='home')
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
@ -1,103 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse, HttpRequest, JsonResponse
|
||||
from YtManagerApp.models import SubscriptionFolder, Subscription
|
||||
from YtManagerApp.management.management import FolderManager, SubscriptionManager
|
||||
|
||||
|
||||
def get_children_recurse(parent_id):
|
||||
children = []
|
||||
|
||||
for folder in SubscriptionFolder.objects.filter(parent_id=parent_id).order_by('name'):
|
||||
children.append({
|
||||
"id": "folder" + str(folder.id),
|
||||
"text": folder.name,
|
||||
"type": "folder",
|
||||
"state": {"opened": True},
|
||||
"children": get_children_recurse(folder.id)
|
||||
})
|
||||
|
||||
for sub in Subscription.objects.filter(parent_folder_id=parent_id).order_by('name'):
|
||||
children.append({
|
||||
"id": "sub" + str(sub.id),
|
||||
"type": "sub",
|
||||
"text": sub.name,
|
||||
"icon": sub.icon_default
|
||||
})
|
||||
|
||||
return children
|
||||
|
||||
|
||||
def get_folders(parent_id, path=""):
|
||||
folders = []
|
||||
prefix = path + "/"
|
||||
if len(path) == 0:
|
||||
prefix = ""
|
||||
|
||||
for folder in SubscriptionFolder.objects.filter(parent_id=parent_id).order_by('name'):
|
||||
folder_path = prefix + folder.name
|
||||
folders.append({
|
||||
"id": folder.id,
|
||||
"text": folder_path
|
||||
})
|
||||
folders.extend(get_folders(folder.id, folder_path))
|
||||
|
||||
return folders
|
||||
|
||||
|
||||
def ajax_get_children(request: HttpRequest):
|
||||
return JsonResponse(get_children_recurse(None), safe=False)
|
||||
|
||||
|
||||
def ajax_get_folders(request: HttpRequest):
|
||||
return JsonResponse(get_folders(None), safe=False)
|
||||
|
||||
|
||||
def ajax_edit_folder(request: HttpRequest):
|
||||
if request.method == 'POST':
|
||||
fid = request.POST['id']
|
||||
name = request.POST['name']
|
||||
parent_id = request.POST['parent']
|
||||
FolderManager.create_or_edit(fid, name, parent_id)
|
||||
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def ajax_delete_folder(request: HttpRequest, fid):
|
||||
FolderManager.delete(fid)
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def ajax_edit_subscription(request: HttpRequest):
|
||||
if request.method == 'POST':
|
||||
sid = request.POST['id']
|
||||
name = request.POST['name']
|
||||
url = request.POST['url']
|
||||
parent_id = request.POST['parent']
|
||||
SubscriptionManager.create_or_edit(sid, url, name, parent_id)
|
||||
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def ajax_delete_subscription(request: HttpRequest, sid):
|
||||
SubscriptionManager.delete(sid)
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def ajax_list_videos(request: HttpRequest):
|
||||
if request.method == 'POST':
|
||||
type = request.POST['type']
|
||||
id = request.POST['id']
|
||||
context = {}
|
||||
|
||||
if type == 'sub':
|
||||
context['videos'] = SubscriptionManager.list_videos(int(id))
|
||||
else:
|
||||
context['videos'] = FolderManager.list_videos(int(id))
|
||||
|
||||
return render(request, 'YtManagerApp/index_videos.html', context)
|
||||
|
||||
|
||||
def index(request: HttpRequest):
|
||||
context = {}
|
||||
return render(request, 'YtManagerApp/index.html', context)
|
||||
|
50
YtManagerApp/views/settings.py
Normal file
50
YtManagerApp/views/settings.py
Normal file
@ -0,0 +1,50 @@
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, HTML, Submit
|
||||
from django import forms
|
||||
from django.views.generic import UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from YtManagerApp.models import UserSettings
|
||||
|
||||
|
||||
class SettingsForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = UserSettings
|
||||
exclude = ['user']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_class = 'form-horizontal'
|
||||
self.helper.label_class = 'col-lg-3'
|
||||
self.helper.field_class = 'col-lg-9'
|
||||
self.helper.layout = Layout(
|
||||
'mark_deleted_as_watched',
|
||||
'delete_watched',
|
||||
HTML('<h2>Download settings</h2>'),
|
||||
'auto_download',
|
||||
'download_path',
|
||||
'download_file_pattern',
|
||||
'download_format',
|
||||
'download_order',
|
||||
'download_global_limit',
|
||||
'download_subscription_limit',
|
||||
HTML('<h2>Subtitles download settings</h2>'),
|
||||
'download_subtitles',
|
||||
'download_subtitles_langs',
|
||||
'download_subtitles_all',
|
||||
'download_autogenerated_subtitles',
|
||||
'download_subtitles_format',
|
||||
Submit('submit', value='Save')
|
||||
)
|
||||
|
||||
|
||||
class SettingsView(UpdateView):
|
||||
form_class = SettingsForm
|
||||
model = UserSettings
|
||||
template_name = 'YtManagerApp/settings.html'
|
||||
success_url = reverse_lazy('home')
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
obj, _ = self.model.objects.get_or_create(user=self.request.user)
|
||||
return obj
|
Reference in New Issue
Block a user