mirror of
				https://github.com/chibicitiberiu/ytsm.git
				synced 2024-02-24 05:43:31 +00:00 
			
		
		
		
	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