Worked on folder modals.

This commit is contained in:
Tiberiu Chibici 2018-10-15 00:45:08 +03:00
parent 1d5c7ea24b
commit c3e3bfa33c
18 changed files with 756 additions and 406 deletions

629
.idea/workspace.xml generated
View File

@ -2,63 +2,24 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="245751b6-c863-4572-8723-8499964fe105" name="Default Changelist" comment=""> <list default="true" id="245751b6-c863-4572-8723-8499964fe105" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" /> <change afterPath="$PROJECT_DIR$/YtManagerApp/migrations/0004_auto_20181014_1702.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/management/videos.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_modal.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/migrations/0002_subscriptionfolder_user.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_delete_modal.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/migrations/0003_auto_20181013_2018.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_update_modal.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/login.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_unauthenticated.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/master_default.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/logged_out.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/login.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_complete.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_confirm.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_done.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_email.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_form.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/register.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/templates/registration/register_done.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/utils/iterutils.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/views/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/views/auth.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/views/controls/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/views/controls/modal.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/YtManagerApp/views/index.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources/2dac2136-d902-4d27-8789-9371934602fd.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/2dac2136-d902-4d27-8789-9371934602fd.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManager/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManager/settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManager/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManager/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/appconfig.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/appconfig.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/appmain.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/appmain.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/management/downloader.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/downloader.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/management/folders.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/folders.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/management/folders.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/folders.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/management/jobs/download_video.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/jobs/download_video.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/management/jobs/synchronize.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/jobs/synchronize.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/management/management.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/management/management.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0001_initial.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/migrations/0001_initial.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0002_auto_20181003_0923.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0003_auto_20181003_1825.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0004_auto_20181005_1626.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0005_auto_20181007_2015.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0006_auto_20181008_0037.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/migrations/0007_auto_20181009_0209.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/models.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/scheduler.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/scheduler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css.map" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css.map" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css.map" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.css.map" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_edit_dialog.html" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/main_default.html" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/main_master_detail.html" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/main_videos.html" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_videos.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/urls.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/YtManagerApp/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/views/old_views.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/views/controls/modal.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/views/controls/modal.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/config.ini" beforeDir="false" afterPath="$PROJECT_DIR$/config/config.ini" afterDir="false" /> <change beforePath="$PROJECT_DIR$/YtManagerApp/views/index.py" beforeDir="false" afterPath="$PROJECT_DIR$/YtManagerApp/views/index.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/config.ini.default" beforeDir="false" afterPath="$PROJECT_DIR$/config/config.ini.default" afterDir="false" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@ -68,6 +29,7 @@
</component> </component>
<component name="CoverageDataManager"> <component name="CoverageDataManager">
<SUITE FILE_PATH="coverage/youtube_channel_manager$parser.coverage" NAME="parser Coverage Results" MODIFIED="1539086601330" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/../YoutubeApi-tests" /> <SUITE FILE_PATH="coverage/youtube_channel_manager$parser.coverage" NAME="parser Coverage Results" MODIFIED="1539086601330" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/../YoutubeApi-tests" />
<SUITE FILE_PATH="coverage/youtube_channel_manager$multiinheritance.coverage" NAME="multiinheritance Coverage Results" MODIFIED="1539546128127" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/../YoutubeApi-tests" />
<SUITE FILE_PATH="coverage/youtube_channel_manager$configparser.coverage" NAME="configparser Coverage Results" MODIFIED="1539108958932" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/../YoutubeApi-tests" /> <SUITE FILE_PATH="coverage/youtube_channel_manager$configparser.coverage" NAME="configparser Coverage Results" MODIFIED="1539108958932" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/../YoutubeApi-tests" />
</component> </component>
<component name="DatabaseView"> <component name="DatabaseView">
@ -114,9 +76,9 @@
<entry key="project.open.time.14" value="2" /> <entry key="project.open.time.14" value="2" />
<entry key="project.open.time.15" value="1" /> <entry key="project.open.time.15" value="1" />
<entry key="project.open.time.3" value="1" /> <entry key="project.open.time.3" value="1" />
<entry key="project.open.time.8" value="1" /> <entry key="project.open.time.8" value="2" />
<entry key="project.open.time.9" value="1" /> <entry key="project.open.time.9" value="1" />
<entry key="project.opened" value="9" /> <entry key="project.opened" value="10" />
</counts> </counts>
</usages-collector> </usages-collector>
<usages-collector id="statistics.file.extensions.edit"> <usages-collector id="statistics.file.extensions.edit">
@ -125,27 +87,27 @@
<entry key="cell" value="32" /> <entry key="cell" value="32" />
<entry key="css" value="40" /> <entry key="css" value="40" />
<entry key="default" value="206" /> <entry key="default" value="206" />
<entry key="dummy" value="38" /> <entry key="dummy" value="60" />
<entry key="html" value="5958" /> <entry key="html" value="6428" />
<entry key="ini" value="2545" /> <entry key="ini" value="2545" />
<entry key="js" value="5731" /> <entry key="js" value="8856" />
<entry key="less" value="38" /> <entry key="less" value="38" />
<entry key="py" value="41890" /> <entry key="py" value="45125" />
<entry key="py@youtube-channel-manager" value="250" /> <entry key="py@youtube-channel-manager" value="265" />
<entry key="scss" value="1054" /> <entry key="scss" value="1178" />
</counts> </counts>
</usages-collector> </usages-collector>
<usages-collector id="statistics.file.types.edit"> <usages-collector id="statistics.file.types.edit">
<counts> <counts>
<entry key="CSS" value="40" /> <entry key="CSS" value="40" />
<entry key="CommandLine" value="133" /> <entry key="CommandLine" value="148" />
<entry key="HTML" value="5958" /> <entry key="HTML" value="6428" />
<entry key="Ini" value="2545" /> <entry key="Ini" value="2545" />
<entry key="JavaScript" value="5731" /> <entry key="JavaScript" value="8856" />
<entry key="Less" value="38" /> <entry key="Less" value="38" />
<entry key="PLAIN_TEXT" value="361" /> <entry key="PLAIN_TEXT" value="383" />
<entry key="Python" value="42144" /> <entry key="Python" value="45379" />
<entry key="SCSS" value="1054" /> <entry key="SCSS" value="1178" />
<entry key="Scratch" value="32" /> <entry key="Scratch" value="32" />
</counts> </counts>
</usages-collector> </usages-collector>
@ -155,82 +117,80 @@
<entry key="css" value="4" /> <entry key="css" value="4" />
<entry key="default" value="2" /> <entry key="default" value="2" />
<entry key="gif" value="1" /> <entry key="gif" value="1" />
<entry key="html" value="67" /> <entry key="html" value="81" />
<entry key="ini" value="9" /> <entry key="ini" value="9" />
<entry key="js" value="9" /> <entry key="js" value="13" />
<entry key="less" value="1" /> <entry key="less" value="1" />
<entry key="py" value="184" /> <entry key="py" value="202" />
<entry key="rnc" value="1" /> <entry key="rnc" value="1" />
<entry key="scss" value="18" /> <entry key="scss" value="22" />
<entry key="ytmanagerapp_channel" value="3" /> <entry key="ytmanagerapp_channel" value="3" />
<entry key="ytmanagerapp_subscription" value="5" /> <entry key="ytmanagerapp_subscription" value="5" />
<entry key="ytmanagerapp_subscriptionfolder" value="2" /> <entry key="ytmanagerapp_subscriptionfolder" value="4" />
<entry key="ytmanagerapp_video" value="9" /> <entry key="ytmanagerapp_video" value="9" />
</counts> </counts>
</usages-collector> </usages-collector>
<usages-collector id="statistics.file.types.open"> <usages-collector id="statistics.file.types.open">
<counts> <counts>
<entry key="CSS" value="4" /> <entry key="CSS" value="4" />
<entry key="Database Element" value="25" /> <entry key="Database Element" value="27" />
<entry key="HTML" value="67" /> <entry key="HTML" value="81" />
<entry key="Image" value="1" /> <entry key="Image" value="1" />
<entry key="Ini" value="9" /> <entry key="Ini" value="9" />
<entry key="JavaScript" value="9" /> <entry key="JavaScript" value="13" />
<entry key="Less" value="1" /> <entry key="Less" value="1" />
<entry key="PLAIN_TEXT" value="2" /> <entry key="PLAIN_TEXT" value="2" />
<entry key="Python" value="184" /> <entry key="Python" value="202" />
<entry key="RNG Compact" value="1" /> <entry key="RNG Compact" value="1" />
<entry key="SCSS" value="18" /> <entry key="SCSS" value="22" />
</counts> </counts>
</usages-collector> </usages-collector>
</session> </session>
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<splitter split-orientation="horizontal" split-proportion="0.5"> <splitter split-orientation="horizontal" split-proportion="0.52003336">
<split-first> <split-first>
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="true"> <file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/YtManagerApp/views/index.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/views/index.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="758"> <state relative-caret-position="159">
<caret line="169" lean-forward="true" selection-start-line="169" selection-end-line="169" /> <caret line="225" lean-forward="true" selection-start-line="225" selection-end-line="225" />
<folding> <folding>
<element signature="e#0#73#0" expanded="true" /> <element signature="e#0#73#0" expanded="true" />
<marker date="1539460834452" expanded="true" signature="3042:3224" ph="..." /> <marker date="1539549416716" expanded="true" signature="3137:3319" ph="..." />
<marker date="1539460834452" expanded="true" signature="3256:3257" ph="..." /> <marker date="1539549416716" expanded="true" signature="3351:3352" ph="..." />
<marker date="1539460834452" expanded="true" signature="3563:3564" ph="..." /> <marker date="1539549416716" expanded="true" signature="3658:3659" ph="..." />
<marker date="1539460834452" expanded="true" signature="3563:4290" ph="..." /> <marker date="1539549416716" expanded="true" signature="3658:4385" ph="..." />
<marker date="1539460834452" expanded="true" signature="3585:4196" ph="..." /> <marker date="1539549416716" expanded="true" signature="3680:4291" ph="..." />
<marker date="1539460834452" expanded="true" signature="4335:4339" ph="..." /> <marker date="1539549416716" expanded="true" signature="4430:4434" ph="..." />
<marker date="1539460834452" expanded="true" signature="5124:5129" ph="..." /> <marker date="1539549416716" expanded="true" signature="5219:6590" ph="..." />
<marker date="1539549416716" expanded="true" signature="5463:5468" ph="..." />
<marker date="1539549416716" expanded="true" signature="5489:5564" ph="..." />
<marker date="1539549416716" expanded="true" signature="6638:6639" ph="..." />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/views/controls/modal.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="340"> <state relative-caret-position="593">
<caret line="20" lean-forward="true" selection-start-line="20" selection-end-line="20" /> <caret line="51" lean-forward="true" selection-start-line="51" selection-end-line="51" />
<folding>
<element signature="e#0#50#0" expanded="true" />
<marker date="1539546362621" expanded="true" signature="199:204" ph="..." />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204"> <state relative-caret-position="-2">
<caret line="12" column="35" lean-forward="true" selection-start-line="12" selection-start-column="35" selection-end-line="12" selection-end-column="35" /> <caret line="53" column="8" lean-forward="true" selection-start-line="53" selection-start-column="8" selection-end-line="53" selection-end-column="8" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_videos.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="238">
<caret line="14" column="22" selection-start-line="14" selection-start-column="22" selection-end-line="14" selection-end-column="22" />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -238,21 +198,64 @@
</leaf> </leaf>
</split-first> </split-first>
<split-second> <split-second>
<leaf> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="true"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/models.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_update_modal.html">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="253"> <state relative-caret-position="136">
<caret line="70" column="6" selection-start-line="70" selection-start-column="6" selection-end-line="70" selection-end-column="6" /> <caret line="8" column="64" selection-start-line="8" selection-start-column="64" selection-end-line="8" selection-end-column="64" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="142">
<caret line="45" column="29" lean-forward="true" selection-start-line="45" selection-start-column="29" selection-end-line="45" selection-end-column="29" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="193">
<caret line="40" lean-forward="true" selection-start-line="40" selection-end-line="40" />
<folding> <folding>
<element signature="e#0#28#0" expanded="true" /> <element signature="e#643#675#0" expanded="true" />
<marker date="1539443280343" expanded="true" signature="237:3043" ph="..." />
<marker date="1539443280343" expanded="true" signature="1150:1295" ph="..." />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_delete_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="105">
<caret line="7" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://C:/Python36/Lib/site-packages/django/template/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="99">
<caret line="903" selection-start-line="903" selection-end-line="903" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="249" column="35" lean-forward="true" selection-start-line="249" selection-start-column="35" selection-end-line="249" selection-end-column="36" />
</state>
</provider>
</entry>
</file>
</leaf> </leaf>
</split-second> </split-second>
</splitter> </splitter>
@ -270,10 +273,6 @@
</component> </component>
<component name="FindInProjectRecents"> <component name="FindInProjectRecents">
<findStrings> <findStrings>
<find>lds</find>
<find>get_selected</find>
<find>url</find>
<find>delete_fo</find>
<find>folder</find> <find>folder</find>
<find>modal</find> <find>modal</find>
<find>folderEditDialog</find> <find>folderEditDialog</find>
@ -298,6 +297,12 @@
<find>dialog_</find> <find>dialog_</find>
<find>.find</find> <find>.find</find>
<find>.show</find> <find>.show</find>
<find>videos_wrapper</find>
<find>videos_loading</find>
<find>submit</find>
<find>modal_edit_folder</find>
<find>modal_update_folder</find>
<find>modal_delete_folder</find>
</findStrings> </findStrings>
<replaceStrings> <replaceStrings>
<replace>loading</replace> <replace>loading</replace>
@ -308,6 +313,8 @@
<replace>=</replace> <replace>=</replace>
<replace>dj_settings</replace> <replace>dj_settings</replace>
<replace>modal_</replace> <replace>modal_</replace>
<replace>videos-wrapper</replace>
<replace>videos-loading</replace>
</replaceStrings> </replaceStrings>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
@ -316,11 +323,6 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/YtManagerApp/management/__init__.py" />
<option value="$PROJECT_DIR$/YtManagerApp/appmain.py" />
<option value="$PROJECT_DIR$/YtManagerApp/management/management.py" />
<option value="$PROJECT_DIR$/YtManagerApp/management/downloader.py" />
<option value="$PROJECT_DIR$/YtManagerApp/appconfig.py" />
<option value="$PROJECT_DIR$/config/config.ini" /> <option value="$PROJECT_DIR$/config/config.ini" />
<option value="$PROJECT_DIR$/config/config.ini.default" /> <option value="$PROJECT_DIR$/config/config.ini.default" />
<option value="$PROJECT_DIR$/YtManagerApp/management/jobs/download_video.py" /> <option value="$PROJECT_DIR$/YtManagerApp/management/jobs/download_video.py" />
@ -346,7 +348,6 @@
<option value="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_complete.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_complete.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_unauth.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_unauth.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_unauthenticated.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index_unauthenticated.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_edit_dialog.html" />
<option value="$PROJECT_DIR$/YtManagerApp/views/auth.py" /> <option value="$PROJECT_DIR$/YtManagerApp/views/auth.py" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/dialog.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/dialog.html" />
<option value="$PROJECT_DIR$/YtManagerApp/views/dialog.py" /> <option value="$PROJECT_DIR$/YtManagerApp/views/dialog.py" />
@ -354,18 +355,24 @@
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/common.js" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/common.js" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/master_default.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/master_default.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js" />
<option value="$PROJECT_DIR$/YtManagerApp/utils/iterutils.py" /> <option value="$PROJECT_DIR$/YtManagerApp/utils/iterutils.py" />
<option value="$PROJECT_DIR$/YtManagerApp/models.py" />
<option value="$PROJECT_DIR$/YtManagerApp/management/folders.py" />
<option value="$PROJECT_DIR$/YtManagerApp/management/videos.py" /> <option value="$PROJECT_DIR$/YtManagerApp/management/videos.py" />
<option value="$PROJECT_DIR$/YtManagerApp/urls.py" />
<option value="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal_form.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal_form.html" />
<option value="$PROJECT_DIR$/YtManagerApp/views/controls/modal.py" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html" /> <option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html" />
<option value="$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js" />
<option value="$PROJECT_DIR$/YtManagerApp/management/folders.py" />
<option value="$PROJECT_DIR$/YtManagerApp/models.py" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_edit_dialog.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_modal.html" />
<option value="$PROJECT_DIR$/../YoutubeApi-tests/multiinheritance.py" />
<option value="$PROJECT_DIR$/YtManagerApp/views/controls/modal.py" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_edit_modal.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_delete_modal.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_update_modal.html" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html" />
<option value="$PROJECT_DIR$/YtManagerApp/urls.py" />
<option value="$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js" />
<option value="$PROJECT_DIR$/YtManagerApp/views/index.py" /> <option value="$PROJECT_DIR$/YtManagerApp/views/index.py" />
</list> </list>
</option> </option>
@ -382,10 +389,10 @@
</packageJsonPaths> </packageJsonPaths>
</component> </component>
<component name="ProjectFrameBounds" extendedState="6"> <component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="367" /> <option name="x" value="1101" />
<option name="y" value="-21" /> <option name="y" value="-63" />
<option name="width" value="651" /> <option name="width" value="1953" />
<option name="height" value="642" /> <option name="height" value="1926" />
</component> </component>
<component name="ProjectInspectionProfilesVisibleTreeState"> <component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default"> <entry key="Project Default">
@ -530,13 +537,6 @@
<item name="YtManagerApp" type="462c0819:PsiDirectoryNode" /> <item name="YtManagerApp" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" /> <item name="views" type="462c0819:PsiDirectoryNode" />
</path> </path>
<path>
<item name="youtube-channel-manager" type="b2602c69:ProjectViewProjectNode" />
<item name="youtube-channel-manager" type="462c0819:PsiDirectoryNode" />
<item name="YtManagerApp" type="462c0819:PsiDirectoryNode" />
<item name="views" type="462c0819:PsiDirectoryNode" />
<item name="controls" type="462c0819:PsiDirectoryNode" />
</path>
</expand> </expand>
<select /> <select />
</subPane> </subPane>
@ -556,6 +556,11 @@
<property name="settings.editor.selected.configurable" value="preferences.sourceCode.SCSS" /> <property name="settings.editor.selected.configurable" value="preferences.sourceCode.SCSS" />
</component> </component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp\controls" />
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\registration" />
<recent name="D:\Dev\youtube-channel-manager\config" />
</key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp\js" /> <recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp\js" />
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\views\controls" /> <recent name="D:\Dev\youtube-channel-manager\YtManagerApp\views\controls" />
@ -563,11 +568,6 @@
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp" /> <recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp" />
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\static\YtManagerApp" /> <recent name="D:\Dev\youtube-channel-manager\YtManagerApp\static\YtManagerApp" />
</key> </key>
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\registration" />
<recent name="D:\Dev\youtube-channel-manager\config" />
<recent name="D:\Dev\youtube-channel-manager\YtManagerApp\templates\YtManagerApp\controls" />
</key>
</component> </component>
<component name="RunDashboard"> <component name="RunDashboard">
<option name="ruleStates"> <option name="ruleStates">
@ -581,7 +581,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="RunManager" selected="Django server.youtube-channel-manager"> <component name="RunManager" selected="Python.multiinheritance">
<configuration name="configparser" type="PythonConfigurationType" factoryName="Python" temporary="true"> <configuration name="configparser" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="youtube-channel-manager" /> <module name="youtube-channel-manager" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -604,6 +604,28 @@
<option name="INPUT_FILE" value="" /> <option name="INPUT_FILE" value="" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="multiinheritance" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="youtube-channel-manager" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../YoutubeApi-tests" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/../YoutubeApi-tests/multiinheritance.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="parser" type="PythonConfigurationType" factoryName="Python" temporary="true"> <configuration name="parser" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="youtube-channel-manager" /> <module name="youtube-channel-manager" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -654,9 +676,11 @@
<item itemvalue="Django server.youtube-channel-manager" /> <item itemvalue="Django server.youtube-channel-manager" />
<item itemvalue="Python.parser" /> <item itemvalue="Python.parser" />
<item itemvalue="Python.configparser" /> <item itemvalue="Python.configparser" />
<item itemvalue="Python.multiinheritance" />
</list> </list>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Python.multiinheritance" />
<item itemvalue="Python.configparser" /> <item itemvalue="Python.configparser" />
<item itemvalue="Python.parser" /> <item itemvalue="Python.parser" />
</list> </list>
@ -676,15 +700,15 @@
<servers /> <servers />
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="-8" y="-8" width="1936" height="1056" extended-state="6" /> <frame x="-6" y="-6" width="1292" height="692" extended-state="6" />
<editor active="true" /> <editor active="true" />
<layout> <layout>
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.17803837" /> <window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.19579288" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" /> <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" /> <window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" /> <window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" sideWeight="0.4978678" weight="0.329718" /> <window_info anchor="bottom" id="Find" order="1" sideWeight="0.4978678" weight="0.329718" />
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.53038377" weight="0.26789588" /> <window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.5299353" visible="true" weight="0.42628774" />
<window_info anchor="bottom" id="Debug" order="3" sideWeight="0.49946696" weight="0.3991323" /> <window_info anchor="bottom" id="Debug" order="3" sideWeight="0.49946696" weight="0.3991323" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
@ -692,7 +716,7 @@
<window_info anchor="bottom" id="manage.py@youtube-channel-manager" order="7" sideWeight="0.49733475" weight="0.28199565" /> <window_info anchor="bottom" id="manage.py@youtube-channel-manager" order="7" sideWeight="0.49733475" weight="0.28199565" />
<window_info anchor="bottom" id="Docker" order="8" show_stripe_button="false" /> <window_info anchor="bottom" id="Docker" order="8" show_stripe_button="false" />
<window_info anchor="bottom" id="Database Changes" order="9" /> <window_info anchor="bottom" id="Database Changes" order="9" />
<window_info anchor="bottom" id="Event Log" order="10" sideWeight="0.4696162" side_tool="true" weight="0.26789588" /> <window_info anchor="bottom" id="Event Log" order="10" sideWeight="0.47006473" side_tool="true" weight="0.42628774" />
<window_info anchor="bottom" id="Version Control" order="11" sideWeight="0.49946696" weight="0.329718" /> <window_info anchor="bottom" id="Version Control" order="11" sideWeight="0.49946696" weight="0.329718" />
<window_info anchor="bottom" id="Terminal" order="12" sideWeight="0.49733475" weight="0.35791758" /> <window_info anchor="bottom" id="Terminal" order="12" sideWeight="0.49733475" weight="0.35791758" />
<window_info anchor="bottom" id="Python Console" order="13" sideWeight="0.4978678" weight="0.335141" /> <window_info anchor="bottom" id="Python Console" order="13" sideWeight="0.4978678" weight="0.335141" />
@ -701,7 +725,7 @@
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="right" id="SciView" order="3" weight="0.32995737" /> <window_info anchor="right" id="SciView" order="3" weight="0.32995737" />
<window_info anchor="right" id="Database" order="4" weight="0.18176973" /> <window_info anchor="right" id="Database" order="4" weight="0.27588996" />
</layout> </layout>
<layout-to-restore> <layout-to-restore>
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.15138593" /> <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.15138593" />
@ -747,36 +771,6 @@
</breakpoint-manager> </breakpoint-manager>
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/YtManagerApp/apps.py">
<provider selected="true" editor-type-id="text-editor">
<state>
<folding>
<element signature="e#0#33#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManager/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="646">
<caret line="38" column="13" lean-forward="true" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102">
<caret line="6" lean-forward="true" selection-start-line="6" selection-end-line="6" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/views/generic/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="165">
<caret line="107" column="6" selection-start-line="107" selection-start-column="6" selection-end-line="107" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/contrib/auth/forms.py"> <entry file="file://C:/Python36/Lib/site-packages/django/contrib/auth/forms.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17"> <state relative-caret-position="17">
@ -847,13 +841,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="das://2dac2136-d902-4d27-8789-9371934602fd/schema/main/table/ytmanagerapp_subscriptionfolder">
<provider selected="true" editor-type-id="com.intellij.database.editor.DatabaseTableFileEditorProvider">
<state>
<filtering enabled="true" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_email.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/registration/password_reset_email.html">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17"> <state relative-caret-position="17">
@ -905,13 +892,7 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/main_master_detail.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/main_master_detail.html" />
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="221">
<caret line="13" column="10" lean-forward="true" selection-start-line="13" selection-start-column="10" selection-end-line="13" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/master_default.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/master_default.html">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306"> <state relative-caret-position="306">
@ -919,13 +900,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js">
<provider selected="true" editor-type-id="text-editor">
<state>
<caret column="12" lean-forward="true" selection-start-column="12" selection-end-column="12" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/utils/iterutils.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/utils/iterutils.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136"> <state relative-caret-position="136">
@ -974,17 +948,6 @@
<entry file="file://$PROJECT_DIR$/YtManagerApp/management/subscriptions.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/management/subscriptions.py">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/management/folders.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="4" lean-forward="true" selection-start-line="4" selection-end-line="4" />
<folding>
<element signature="e#0#64#0" expanded="true" />
<marker date="1539445455052" expanded="true" signature="355:430" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/core/handlers/base.py"> <entry file="file://C:/Python36/Lib/site-packages/django/core/handlers/base.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="216"> <state relative-caret-position="216">
@ -992,26 +955,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="389">
<caret line="60" column="57" selection-start-line="60" selection-start-column="57" selection-end-line="60" selection-end-column="57" />
<folding>
<element signature="n#style#0;n#div#2;n#div#1;n#div#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442">
<caret line="32" column="78" selection-start-line="32" selection-start-column="57" selection-end-line="32" selection-end-column="78" />
<folding>
<element signature="e#643#675#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/views/old_views.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/views/old_views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="154"> <state relative-caret-position="154">
@ -1032,20 +975,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="6120">
<caret line="360" lean-forward="true" selection-start-line="360" selection-end-line="360" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="406">
<caret line="78" column="1" lean-forward="true" selection-start-line="78" selection-start-column="1" selection-end-line="78" selection-end-column="1" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/management/management.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/management/management.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="316"> <state relative-caret-position="316">
@ -1056,60 +985,11 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal_form.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal_form.html" />
<entry file="file://C:/Python36/Lib/site-packages/django/forms/models.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102"> <state relative-caret-position="595">
<caret line="6" column="28" lean-forward="true" selection-start-line="6" selection-start-column="28" selection-end-line="6" selection-end-column="28" /> <caret line="550" column="60" lean-forward="true" selection-start-line="550" selection-start-column="60" selection-end-line="550" selection-end-column="60" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_edit_dialog.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" column="25" selection-start-line="7" selection-start-column="25" selection-end-line="7" selection-end-column="25" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="340">
<caret line="20" lean-forward="true" selection-start-line="20" selection-end-line="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/views/controls/modal.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="24" lean-forward="true" selection-start-line="9" selection-start-column="26" selection-end-line="10" selection-end-column="24" />
<folding>
<marker date="1539455039825" expanded="true" signature="134:139" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="253">
<caret line="70" column="6" selection-start-line="70" selection-start-column="6" selection-end-line="70" selection-end-column="6" />
<folding>
<element signature="e#0#28#0" expanded="true" />
<marker date="1539443280343" expanded="true" signature="237:3043" ph="..." />
<marker date="1539443280343" expanded="true" signature="1150:1295" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/views/generic/detail.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-329">
<caret line="110" column="6" selection-start-line="110" selection-start-column="6" selection-end-line="110" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/views/generic/edit.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="367">
<caret line="121" lean-forward="true" selection-start-line="121" selection-end-line="121" />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -1120,29 +1000,166 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_dialog.html"> <entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/common.js">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204"> <state relative-caret-position="496">
<caret line="12" column="35" lean-forward="true" selection-start-line="12" selection-start-column="35" selection-end-line="12" selection-end-column="35" /> <caret line="136" column="17" lean-forward="true" selection-start-line="136" selection-start-column="17" selection-end-line="136" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_create_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="16" lean-forward="true" selection-start-line="16" selection-end-line="16" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/views/generic/edit.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="5">
<caret line="201" column="6" selection-start-line="201" selection-start-column="6" selection-end-line="201" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/../YoutubeApi-tests/multiinheritance.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="406">
<caret line="27" lean-forward="true" selection-start-line="27" selection-end-line="27" />
<folding>
<marker date="1539546125122" expanded="true" signature="16:21" ph="..." />
<marker date="1539546125122" expanded="true" signature="71:76" ph="..." />
<marker date="1539546125122" expanded="true" signature="121:126" ph="..." />
<marker date="1539546125122" expanded="true" signature="197:202" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="289">
<caret line="20" selection-start-line="20" selection-end-line="20" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/views/generic/detail.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="72" selection-start-line="72" selection-end-line="72" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/management/folders.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="336">
<caret line="38" lean-forward="true" selection-start-line="38" selection-end-line="38" />
<folding>
<element signature="e#0#64#0" expanded="true" />
<marker date="1539536477025" expanded="true" signature="400:475" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="das://2dac2136-d902-4d27-8789-9371934602fd/schema/main/table/ytmanagerapp_subscriptionfolder">
<provider selected="true" editor-type-id="com.intellij.database.editor.DatabaseTableFileEditorProvider">
<state>
<filtering enabled="true" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" />
<folding>
<element signature="e#0#28#0" expanded="true" />
<marker date="1539536691307" expanded="true" signature="282:3088" ph="..." />
<marker date="1539536691307" expanded="true" signature="1195:1340" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/index.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="142">
<caret line="45" column="29" lean-forward="true" selection-start-line="45" selection-start-column="29" selection-end-line="45" selection-end-column="29" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_update_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" column="64" selection-start-line="8" selection-start-column="64" selection-end-line="8" selection-end-column="64" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/views/controls/modal.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="593">
<caret line="51" lean-forward="true" selection-start-line="51" selection-end-line="51" />
<folding>
<element signature="e#0#50#0" expanded="true" />
<marker date="1539546362621" expanded="true" signature="199:204" ph="..." />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/static/YtManagerApp/css/style.scss">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-2">
<caret line="53" column="8" lean-forward="true" selection-start-line="53" selection-start-column="8" selection-end-line="53" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/js/subscription_tree.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="249" column="35" lean-forward="true" selection-start-line="249" selection-start-column="35" selection-end-line="249" selection-end-column="36" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/views/index.py"> <entry file="file://$PROJECT_DIR$/YtManagerApp/views/index.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="758"> <state relative-caret-position="159">
<caret line="169" lean-forward="true" selection-start-line="169" selection-end-line="169" /> <caret line="225" lean-forward="true" selection-start-line="225" selection-end-line="225" />
<folding> <folding>
<element signature="e#0#73#0" expanded="true" /> <element signature="e#0#73#0" expanded="true" />
<marker date="1539460834452" expanded="true" signature="3042:3224" ph="..." /> <marker date="1539549416716" expanded="true" signature="3137:3319" ph="..." />
<marker date="1539460834452" expanded="true" signature="3256:3257" ph="..." /> <marker date="1539549416716" expanded="true" signature="3351:3352" ph="..." />
<marker date="1539460834452" expanded="true" signature="3563:3564" ph="..." /> <marker date="1539549416716" expanded="true" signature="3658:3659" ph="..." />
<marker date="1539460834452" expanded="true" signature="3563:4290" ph="..." /> <marker date="1539549416716" expanded="true" signature="3658:4385" ph="..." />
<marker date="1539460834452" expanded="true" signature="3585:4196" ph="..." /> <marker date="1539549416716" expanded="true" signature="3680:4291" ph="..." />
<marker date="1539460834452" expanded="true" signature="4335:4339" ph="..." /> <marker date="1539549416716" expanded="true" signature="4430:4434" ph="..." />
<marker date="1539460834452" expanded="true" signature="5124:5129" ph="..." /> <marker date="1539549416716" expanded="true" signature="5219:6590" ph="..." />
<marker date="1539549416716" expanded="true" signature="5463:5468" ph="..." />
<marker date="1539549416716" expanded="true" signature="5489:5564" ph="..." />
<marker date="1539549416716" expanded="true" signature="6638:6639" ph="..." />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="193">
<caret line="40" lean-forward="true" selection-start-line="40" selection-end-line="40" />
<folding>
<element signature="e#643#675#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/YtManagerApp/templates/YtManagerApp/controls/folder_delete_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="105">
<caret line="7" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
<entry file="file://C:/Python36/Lib/site-packages/django/template/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="99">
<caret line="903" selection-start-line="903" selection-end-line="903" />
</state>
</provider>
</entry>
</component> </component>
</project> </project>

View File

@ -2,6 +2,7 @@ from YtManagerApp.models import SubscriptionFolder, Subscription
from typing import Callable, Union, Any, Optional from typing import Callable, Union, Any, Optional
from django.contrib.auth.models import User from django.contrib.auth.models import User
import logging import logging
from django.db.models.functions import Lower
def traverse_tree(root_folder_id: Optional[int], user: User, visit_func: Callable[[Union[SubscriptionFolder, Subscription]], Any]): def traverse_tree(root_folder_id: Optional[int], user: User, visit_func: Callable[[Union[SubscriptionFolder, Subscription]], Any]):
@ -27,11 +28,11 @@ def traverse_tree(root_folder_id: Optional[int], user: User, visit_func: Callabl
continue continue
visited.append(folder_id) visited.append(folder_id)
for folder in SubscriptionFolder.objects.filter(parent_id=folder_id, user=user).order_by('name'): for folder in SubscriptionFolder.objects.filter(parent_id=folder_id, user=user).order_by(Lower('name')):
collect(visit_func(folder)) collect(visit_func(folder))
queue.append(folder.id) queue.append(folder.id)
for subscription in Subscription.objects.filter(parent_folder_id=folder_id, user=user).order_by('name'): for subscription in Subscription.objects.filter(parent_folder_id=folder_id, user=user).order_by(Lower('name')):
collect(visit_func(subscription)) collect(visit_func(subscription))
return data_collected return data_collected

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.2 on 2018-10-14 14:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('YtManagerApp', '0003_auto_20181013_2018'),
]
operations = [
migrations.AlterField(
model_name='subscriptionfolder',
name='name',
field=models.CharField(max_length=250),
),
]

View File

@ -1,5 +1,6 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.functions import Lower
# help_text = user shown text # help_text = user shown text
# verbose_name = user shown name # verbose_name = user shown name
@ -69,12 +70,20 @@ class UserSettings(models.Model):
class SubscriptionFolder(models.Model): class SubscriptionFolder(models.Model):
name = models.TextField(null=False) name = models.CharField(null=False, max_length=250)
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True) parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False) user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self): def __str__(self):
return self.name s = ""
current = self
while current is not None:
s = current.name + " > " + s
current = current.parent
return s[:-3]
class Meta:
ordering = [Lower('parent__name'), Lower('name')]
class Channel(models.Model): class Channel(models.Model):

View File

@ -11,6 +11,13 @@
width: 64px; width: 64px;
height: 64px; } height: 64px; }
.loading-dual-ring-center-screen {
position: fixed;
top: 50%;
left: 50%;
margin-top: -32px;
margin-left: -32px; }
.loading-dual-ring:after { .loading-dual-ring:after {
content: " "; content: " ";
display: block; display: block;
@ -22,6 +29,26 @@
border-color: #007bff transparent #007bff transparent; border-color: #007bff transparent #007bff transparent;
animation: loading-dual-ring 1.2s linear infinite; } animation: loading-dual-ring 1.2s linear infinite; }
.black-overlay {
position: fixed;
/* Sit on top of the page content */
display: none;
/* Hidden by default */
width: 100%;
/* Full width (cover the whole page) */
height: 100%;
/* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
/* Black background with opacity */
z-index: 2;
/* Specify a stack order in case you're using a different order for other elements */
cursor: pointer;
/* Add a pointer on hover */ }
@keyframes loading-dual-ring { @keyframes loading-dual-ring {
0% { 0% {
transform: rotate(0deg); } transform: rotate(0deg); }
@ -58,4 +85,10 @@
.no-asterisk .asteriskField { .no-asterisk .asteriskField {
display: none; } display: none; }
.modal-field-error {
margin: 0.5rem 0;
padding: 0.5rem 0; }
.modal-field-error ul {
margin: 0; }
/*# sourceMappingURL=style.css.map */ /*# sourceMappingURL=style.css.map */

View File

@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "AAEA,gCAAgC;AAChC,wBAAyB;EACrB,OAAO,EAAE,OAAO;;AAGpB,wBAAyB;EACrB,OAAO,EAAE,OAAO;;AAGpB,uBAAuB;AACvB,kBAAmB;EACf,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAGhB,wBAAyB;EACrB,OAAO,EAAE,GAAG;EACZ,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,iBAAuB;EAC/B,YAAY,EAAE,uCAAmD;EACjE,SAAS,EAAE,sCAAsC;;AAGrD,4BAOC;EANG,EAAG;IACC,SAAS,EAAE,YAAY;EAE3B,IAAK;IACD,SAAS,EAAE,cAAc;AAK7B,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;AAKjC,8BAAgB;EACZ,KAAK,EAAE,OAAO;AAElB,6BAAe;EACX,KAAK,EAAE,OAAO;;AAItB,WAAY;EACR,SAAS,EAAE,KAAK;EAChB,MAAM,EAAE,MAAM;;AAId,2BAAe;EACX,OAAO,EAAE,IAAI", "mappings": "AAEA,gCAAgC;AAChC,wBAAyB;EACrB,OAAO,EAAE,OAAO;;AAGpB,wBAAyB;EACrB,OAAO,EAAE,OAAO;;AAGpB,uBAAuB;AACvB,kBAAmB;EACf,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAGhB,gCAAiC;EAC7B,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,GAAG;EACR,IAAI,EAAE,GAAG;EACT,UAAU,EAAE,KAAK;EACjB,WAAW,EAAE,KAAK;;AAGtB,wBAAyB;EACrB,OAAO,EAAE,GAAG;EACZ,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,iBAAuB;EAC/B,YAAY,EAAE,uCAAmD;EACjE,SAAS,EAAE,sCAAsC;;AAGrD,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;;AAGjD,4BAOC;EANG,EAAG;IACC,SAAS,EAAE,YAAY;EAE3B,IAAK;IACD,SAAS,EAAE,cAAc;AAK7B,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;AAKjC,8BAAgB;EACZ,KAAK,EAAE,OAAO;AAElB,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",
"sources": ["style.scss"], "sources": ["style.scss"],
"names": [], "names": [],
"file": "style.css" "file": "style.css"

View File

@ -16,6 +16,14 @@ $accent-color: #007bff;
height: 64px; height: 64px;
} }
.loading-dual-ring-center-screen {
position: fixed;
top: 50%;
left: 50%;
margin-top: -32px;
margin-left: -32px;
}
.loading-dual-ring:after { .loading-dual-ring:after {
content: " "; content: " ";
display: block; display: block;
@ -28,6 +36,20 @@ $accent-color: #007bff;
animation: loading-dual-ring 1.2s linear infinite; animation: loading-dual-ring 1.2s linear infinite;
} }
.black-overlay {
position: fixed; /* Sit on top of the page content */
display: none; /* Hidden by default */
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
z-index: 2; /* Specify a stack order in case you're using a different order for other elements */
cursor: pointer; /* Add a pointer on hover */
}
@keyframes loading-dual-ring { @keyframes loading-dual-ring {
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);
@ -88,3 +110,13 @@ $accent-color: #007bff;
display: none; display: none;
} }
} }
.modal-field-error {
margin: 0.5rem 0;
padding: 0.5rem 0;
ul {
margin: 0;
}
}

View File

@ -1,13 +0,0 @@
{% extends 'YtManagerApp/controls/modal.html' %}
{% load crispy_forms_tags %}
{% block modal_title %}
New folder
{% endblock modal_title %}
{% block modal_body %}
{% crispy form %}
{% endblock modal_body %}
{% block modal_footer_wrapper %}
{% endblock modal_footer_wrapper %}

View File

@ -0,0 +1,21 @@
{% extends 'YtManagerApp/controls/modal.html' %}
{% load crispy_forms_tags %}
{% block modal_title %}
New folder
{% endblock modal_title %}
{% block modal_content %}
<form action="{% url 'modal_create_folder' %}" method="post">
{{ block.super }}
</form>
{% endblock %}
{% block modal_body %}
{% crispy form %}
{% endblock modal_body %}
{% block modal_footer %}
<input class="btn btn-primary" type="submit" value="Create">
<input class="btn btn-secondary" type="button" value="Cancel" data-dismiss="modal" aria-label="Cancel">
{% endblock modal_footer %}

View File

@ -0,0 +1,21 @@
{% extends 'YtManagerApp/controls/modal.html' %}
{% load crispy_forms_tags %}
{% block modal_title %}
Delete folder
{% endblock modal_title %}
{% block modal_content %}
<form action="{% url 'modal_delete_folder' form.instance.pk %}" method="post">
{{ block.super }}
</form>
{% endblock %}
{% block modal_body %}
{% crispy form %}
{% endblock modal_body %}
{% block modal_footer %}
<input class="btn btn-danger" type="submit" value="Save" aria-label="Delete">
<input class="btn btn-secondary" type="button" value="Cancel" data-dismiss="modal" aria-label="Cancel">
{% endblock modal_footer %}

View File

@ -1,40 +0,0 @@
<div id="folderEditDialog" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 id="folderEditDialog_Title" class="modal-title">Edit folder</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div id="folderEditDialog_Loading" class="modal-body">
<div class="loading-dual-ring"></div>
</div>
<div id="folderEditDialog_Error">
</div>
<form id="folderEditDialog_Form" action="{% url 'ajax_edit_folder' %}" method="post">
<div class="modal-body">
{% csrf_token %}
<input type="hidden" id="folderEditDialog_Id" name="id" value="#">
<div class="form-group row">
<label class="col-sm-3" for="folderEditDialog_Name">Name</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="folderEditDialog_Name" name="name" placeholder="Folder name">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3" for="folderEditDialog_Parent">Parent folder</label>
<div class="col-sm-9">
<select class="form-control" id="folderEditDialog_Parent" name="parent">
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button id="folderEditDialog_Submit" type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,21 @@
{% extends 'YtManagerApp/controls/modal.html' %}
{% load crispy_forms_tags %}
{% block modal_title %}
Edit folder
{% endblock modal_title %}
{% block modal_content %}
<form action="{% url 'modal_update_folder' form.instance.pk %}" method="post">
{{ block.super }}
</form>
{% endblock %}
{% block modal_body %}
{% crispy form %}
{% endblock modal_body %}
{% block modal_footer %}
<input class="btn btn-primary" type="submit" value="Save" aria-label="Save">
<input class="btn btn-secondary" type="button" value="Cancel" data-dismiss="modal" aria-label="Cancel">
{% endblock modal_footer %}

View File

@ -11,14 +11,19 @@
<script> <script>
{% include 'YtManagerApp/js/subscription_tree.js' %} {% include 'YtManagerApp/js/subscription_tree.js' %}
</script> </script>
{% include 'YtManagerApp/controls/folder_edit_dialog.html' %}
{% include 'YtManagerApp/controls/subscription_edit_dialog.html' %}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div id="modal-wrapper">
<div id="modal-loading" class="black-overlay">
<div class="loading-dual-ring loading-dual-ring-center-screen"></div>
</div>
<div id="modal-wrapper">
</div>
</div>
<div class="row"> <div class="row">
<div class="col-3"> <div class="col-3">
@ -55,10 +60,10 @@
{% crispy filter_form %} {% crispy filter_form %}
</div> </div>
<div id="videos_wrapper"> <div id="videos-wrapper">
</div> </div>
<div id="videos_loading" style="display: none"> <div id="videos-loading" style="display: none">
<div class="d-flex"> <div class="d-flex">
<div class="loading-dual-ring mx-auto my-5"></div> <div class="loading-dual-ring mx-auto my-5"></div>
</div> </div>

View File

@ -43,3 +43,134 @@ class Dialog {
this.modal.modal('hide'); this.modal.modal('hide');
} }
} }
class AjaxModal
{
constructor(url)
{
this.wrapper = $("#modal-wrapper");
this.loading = $("#modal-loading");
this.url = url;
this.modal = null;
this.form = null;
this.submitCallback = null;
}
setSubmitCallback(callback) {
this.submitCallback = callback;
}
_showLoading() {
this.loading.fadeIn(500);
}
_hideLoading() {
this.loading.fadeOut(100);
}
_showModal() {
if (this.modal != null)
this.modal.modal();
}
_hideModal() {
if (this.modal != null)
this.modal.modal('hide');
}
_load(result) {
this.wrapper.html(result);
this.modal = this.wrapper.find('.modal');
this.form = this.wrapper.find('form');
let pThis = this;
this.form.submit(function(e) {
pThis._submit(e);
})
}
_loadFailed() {
this.wrapper.html('<div class="alert alert-danger">An error occurred while displaying the dialog!</div>');
}
_submit(e) {
let pThis = this;
let url = this.form.attr('action');
$.post(this.url, this.form.serialize())
.done(function(result) {
pThis._submitDone(result);
})
.fail(function() {
pThis._submitFailed();
});
e.preventDefault();
}
_submitDone(result) {
// Clear old errors first
this.form.find('.modal-field-error').remove();
if (result.success) {
this._hideModal();
if (this.submitCallback != null)
this.submitCallback();
}
else {
for (let field in result.errors)
if (result.errors.hasOwnProperty(field))
{
let errorsArray = result.errors[field];
let errorsConcat = "<div class=\"alert alert-danger modal-field-error\"><ul>";
for(let error of errorsArray) {
errorsConcat += `<li>${error.message}</li>`;
}
errorsConcat += '</ul></div>';
if (field === '__all__')
this.form.find('.modal-body').append(errorsConcat);
else
this.form.find(`[name='${field}']`).after(errorsConcat);
}
let errorsHtml = '';
let err = this.modal.find('#__modal_error');
if (err.length) {
err.html('An error occurred');
}
else {
this.modal.find('.modal-body').append(errorsHtml)
}
}
}
_submitFailed() {
// Clear old errors first
this.form.find('.modal-field-error').remove();
this.form.find('.modal-body')
.append(`<div class="alert alert-danger modal-field-error">An error occurred while processing request!</div>`);
}
loadAndShow()
{
let pThis = this;
this._showLoading();
$.get(this.url)
.done(function (result) {
pThis._load(result);
pThis._showModal();
})
.fail(function () {
pThis._loadFailed();
})
.always(function() {
pThis._hideLoading();
});
}
}

View File

@ -228,11 +228,19 @@ function treeNode_Edit()
if (selectedNodes.length === 1) if (selectedNodes.length === 1)
{ {
let node = selectedNodes[0]; let node = selectedNodes[0];
if (node.type === 'folder') { if (node.type === 'folder') {
folderEditDialog.showEdit(node); let id = node.id.replace('folder', '');
let modal = new AjaxModal("{% url 'modal_update_folder' 98765 %}".replace('98765', id));
modal.setSubmitCallback(tree_Refresh);
modal.loadAndShow();
} }
else { else {
subscriptionEditDialog.showEdit(node); //TODO:
//let id = node.id.replace('sub', '');
//let modal = new AjaxModal("{ url 'modal_update_subscription' 98765 }".replace('98765', id));
//modal.setSubmitCallback(tree_Refresh);
//modal.loadAndShow();
} }
} }
} }
@ -245,22 +253,17 @@ function treeNode_Delete()
let node = selectedNodes[0]; let node = selectedNodes[0];
if (node.type === 'folder') { if (node.type === 'folder') {
let folderId = node.id.toString().replace('folder', ''); let id = node.id.replace('folder', '');
if (confirm('Are you sure you want to delete folder "' + node.text + '" and all its descendants?\nNote: the subscriptions won\'t be deleted, they will only be moved outside.')) let modal = new AjaxModal("{% url 'modal_delete_folder' 98765 %}".replace('98765', id));
{ modal.setSubmitCallback(tree_Refresh);
$.post("{% url 'ajax_delete_folder' 99999 %}".replace('99999', folderId), { modal.loadAndShow();
csrfmiddlewaretoken: '{{ csrf_token }}'
}).done(tree_Refresh);
}
} }
else { else {
let subId = node.id.toString().replace('sub', ''); //TODO:
if (confirm('Are you sure you want to delete subscription "' + node.text + '"?')) //let id = node.id.replace('sub', '');
{ //let modal = new AjaxModal("{ url 'modal_delete_subscription' 98765 }".replace('98765', id));
$.post("{% url 'ajax_delete_subscription' 99999 %}".replace('99999', subId), { //modal.setSubmitCallback(tree_Refresh);
csrfmiddlewaretoken: '{{ csrf_token }}' //modal.loadAndShow();
}).done(tree_Refresh);
}
} }
} }
} }
@ -318,11 +321,14 @@ function tree_OnSelectionChanged(e, data)
let filterForm_folderId = filterForm.find('#form_video_filter_folder_id'); let filterForm_folderId = filterForm.find('#form_video_filter_folder_id');
let filterForm_subId = filterForm.find('#form_video_filter_subscription_id'); let filterForm_subId = filterForm.find('#form_video_filter_subscription_id');
let node = data.instance.get_selected(true)[0]; let node = data.instance.get_selected(true)[0];
// Fill folder/sub fields // Fill folder/sub fields
if (node.type === 'folder') { if (node == null) {
filterForm_folderId.val('');
filterForm_subId.val('');
}
else if (node.type === 'folder') {
let id = node.id.replace('folder', ''); let id = node.id.replace('folder', '');
filterForm_folderId.val(id); filterForm_folderId.val(id);
filterForm_subId.val(''); filterForm_subId.val('');
@ -340,16 +346,16 @@ function tree_OnSelectionChanged(e, data)
function videos_Reload() function videos_Reload()
{ {
let filterForm = $('#form_video_filter'); let filterForm = $('#form_video_filter');
let loadingDiv = $('#videos_loading'); let loadingDiv = $('#videos-loading');
loadingDiv.fadeIn(300); loadingDiv.fadeIn(300);
// Perform query // Perform query
$.post("{% url 'ajax_index_get_videos' %}", filterForm.serialize()) $.post("{% url 'ajax_index_get_videos' %}", filterForm.serialize())
.done(function (result) { .done(function (result) {
$("#videos_wrapper").html(result); $("#videos-wrapper").html(result);
}) })
.fail(function () { .fail(function () {
$("#videos_wrapper").html('<div class="alert alert-danger">An error occurred while retrieving the video list!</div>'); $("#videos-wrapper").html('<div class="alert alert-danger">An error occurred while retrieving the video list!</div>');
}) })
.always(function() { .always(function() {
loadingDiv.fadeOut(100); loadingDiv.fadeOut(100);
@ -387,8 +393,13 @@ $(document).ready(function ()
// folderEditDialog = new FolderEditDialog('#folderEditDialog'); // folderEditDialog = new FolderEditDialog('#folderEditDialog');
// subscriptionEditDialog = new SubscriptionEditDialog('#subscriptionEditDialog'); // subscriptionEditDialog = new SubscriptionEditDialog('#subscriptionEditDialog');
// //
// $("#btn_create_sub").on("click", function () { subscriptionEditDialog.showNew(); }); $("#btn_create_folder").on("click", function () {
let modal = new AjaxModal("{% url 'modal_create_folder' %}");
modal.setSubmitCallback(tree_Refresh);
modal.loadAndShow();
});
// $("#btn_create_folder").on("click", function () { folderEditDialog.showNew(); }); // $("#btn_create_folder").on("click", function () { folderEditDialog.showNew(); });
// $("#btn_edit_node").on("click", treeNode_Edit); $("#btn_edit_node").on("click", treeNode_Edit);
// $("#btn_delete_node").on("click", treeNode_Delete); $("#btn_delete_node").on("click", treeNode_Delete);
}); });

View File

@ -19,7 +19,7 @@ from django.conf.urls.static import static
from django.urls import path from django.urls import path
from .views.auth import ExtendedLoginView, RegisterView, RegisterDoneView from .views.auth import ExtendedLoginView, RegisterView, RegisterDoneView
from .views.index import index, ajax_get_tree, ajax_get_videos from .views.index import index, ajax_get_tree, ajax_get_videos, CreateFolderModal, UpdateFolderModal, DeleteFolderModal
from .views import old_views from .views import old_views
urlpatterns = [ urlpatterns = [
@ -29,10 +29,20 @@ urlpatterns = [
path('register_done/', RegisterDoneView.as_view(), name='register_done'), path('register_done/', RegisterDoneView.as_view(), name='register_done'),
path('', include('django.contrib.auth.urls')), path('', include('django.contrib.auth.urls')),
path('ajax/index_get_tree', ajax_get_tree, name='ajax_index_get_tree'), # Ajax
path('ajax/index_get_videos', ajax_get_videos, name='ajax_index_get_videos'), path('ajax/index_get_tree/', ajax_get_tree, name='ajax_index_get_tree'),
path('ajax/index_get_videos/', ajax_get_videos, name='ajax_index_get_videos'),
# Modals
path('modal/create_folder/', CreateFolderModal.as_view(), name='modal_create_folder'),
path('modal/create_folder/<int:parent_id>/', CreateFolderModal.as_view(), name='modal_create_folder'),
path('modal/update_folder/<int:pk>/', UpdateFolderModal.as_view(), name='modal_update_folder'),
path('modal/delete_folder/<int:pk>/', DeleteFolderModal.as_view(), name='modal_delete_folder'),
# Index
path('', index, name='home'), path('', index, name='home'),
# Old stuff # Old stuff
path('ajax/get_children', old_views.ajax_get_children, name='ajax_get_children'), 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/get_folders', old_views.ajax_get_folders, name='ajax_get_folders'),

View File

@ -1,8 +1,10 @@
from django.views.generic import TemplateView from django.views.generic.base import ContextMixin
from django.http import JsonResponse
class ModalView(TemplateView): class ModalMixin(ContextMixin):
template_name = 'YtManagerApp/controls/modal.html' template_name = 'YtManagerApp/controls/modal.html'
success_url = '/'
def __init__(self, modal_id='dialog', title='', fade=True, centered=True, small=False, large=False, *args, **kwargs): def __init__(self, modal_id='dialog', title='', fade=True, centered=True, small=False, large=False, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -32,3 +34,18 @@ class ModalView(TemplateView):
data['modal_title'] = self.title data['modal_title'] = self.title
return data return data
def modal_response(self, form, success=True):
result = {'success': success}
if not success:
result['errors'] = form.errors.get_json_data(escape_html=True)
return JsonResponse(result)
def form_valid(self, form):
super().form_valid(form)
return self.modal_response(form, success=True)
def form_invalid(self, form):
super().form_invalid(form)
return self.modal_response(form, success=False)

View File

@ -1,13 +1,15 @@
from django.http import HttpRequest, HttpResponseBadRequest, JsonResponse from django.http import HttpRequest, HttpResponseBadRequest, JsonResponse
from django.shortcuts import render from django.shortcuts import render
from django import forms from django import forms
from django.views.generic import CreateView from django.views.generic import CreateView, UpdateView, DeleteView
from YtManagerApp.management.folders import traverse_tree from YtManagerApp.management.folders import traverse_tree
from YtManagerApp.management.videos import get_videos from YtManagerApp.management.videos import get_videos
from YtManagerApp.models import Subscription, SubscriptionFolder from YtManagerApp.models import Subscription, SubscriptionFolder
from YtManagerApp.views.controls.modal import ModalView from YtManagerApp.views.controls.modal import ModalMixin
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field from crispy_forms.layout import Layout, Field
from crispy_forms.layout import Submit
from django.db.models import Q
class VideoFilterForm(forms.Form): class VideoFilterForm(forms.Form):
@ -162,8 +164,62 @@ def ajax_get_videos(request: HttpRequest):
return HttpResponseBadRequest() return HttpResponseBadRequest()
class CreateFolderForm(CreateView, ModalView): class SubscriptionFolderForm(forms.ModelForm):
class Meta:
model = SubscriptionFolder model = SubscriptionFolder
template_name = 'YtManagerApp/controls/folder_create_dialog.html'
fields = ['name', 'parent'] fields = ['name', 'parent']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
def clean_name(self):
name = self.cleaned_data['name']
return name.strip()
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name')
parent = cleaned_data.get('parent')
# Check name is unique in parent folder
args_id = []
if self.instance is not None:
args_id.append(~Q(id=self.instance.id))
if SubscriptionFolder.objects.filter(parent=parent, name__iexact=name, *args_id).count() > 0:
raise forms.ValidationError('A folder with the same name already exists in the given parent directory!', code='already_exists')
# Check for cycles
if self.instance is not None:
self.__test_cycles(parent)
def __test_cycles(self, new_parent):
visited = [self.instance.id]
current = new_parent
while current is not None:
if current.id in visited:
raise forms.ValidationError('Selected parent would create a parenting cycle!', code='parenting_cycle')
visited.append(current.id)
current = current.parent
class CreateFolderModal(ModalMixin, CreateView):
template_name = 'YtManagerApp/controls/folder_create_modal.html'
form_class = SubscriptionFolderForm
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
class UpdateFolderModal(ModalMixin, UpdateView):
template_name = 'YtManagerApp/controls/folder_update_modal.html'
model = SubscriptionFolder
form_class = SubscriptionFolderForm
class DeleteFolderModal(ModalMixin, DeleteView):
template_name = 'YtManagerApp/controls/folder_delete_modal.html'
model = SubscriptionFolder