From 2c93e50406baa49fc77bb269ed2073009213d9ac Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Sat, 29 Dec 2018 23:16:04 +0200 Subject: [PATCH] Fixed multiple problems related to migration to django-preferences. --- app/YtManager/settings.py | 19 +++++++++----- app/YtManagerApp/management/appconfig.py | 7 ++++++ .../migrations/0008_auto_20181229_2035.py | 25 +++++++++++++++++++ app/YtManagerApp/models.py | 22 ++++------------ .../templates/YtManagerApp/index.html | 2 +- app/YtManagerApp/tests.py | 2 -- app/YtManagerApp/utils/__init__.py | 4 +-- .../utils/subscription_file_parser.py | 8 +++--- app/YtManagerApp/utils/youtube.py | 4 +-- app/YtManagerApp/views/controls/modal.py | 4 +-- app/YtManagerApp/views/first_time.py | 6 ++++- app/YtManagerApp/views/index.py | 14 ++++++++--- 12 files changed, 77 insertions(+), 40 deletions(-) create mode 100644 app/YtManagerApp/migrations/0008_auto_20181229_2035.py diff --git a/app/YtManager/settings.py b/app/YtManager/settings.py index 52ee338..8fa0aad 100644 --- a/app/YtManager/settings.py +++ b/app/YtManager/settings.py @@ -153,17 +153,23 @@ _DEFAULT_DATABASE = { CONFIG_ERRORS = [] CONFIG_WARNINGS = [] +# These are just to make inspector happy, they will be set in the load_config_ini() method +DEBUG = None +SECRET_KEY = None +DATABASES = None +LOG_LEVEL = None # # Config parser options # CFG_PARSER_OPTS = { - 'PROJECT_ROOT' : PROJECT_ROOT, - 'BASE_DIR' : BASE_DIR, - 'CONFIG_DIR' : CONFIG_DIR, - 'DATA_DIR' : DATA_DIR, + 'PROJECT_ROOT': PROJECT_ROOT, + 'BASE_DIR': BASE_DIR, + 'CONFIG_DIR': CONFIG_DIR, + 'DATA_DIR': DATA_DIR, } + # # Load globals from config.ini # @@ -225,7 +231,7 @@ def load_config_ini(): logging.info(f"Using data directory {DATA_DIR}") except OSError as e: print(f'CRITICAL ERROR! Cannot create data directory {DATA_DIR}! {e}', file=sys.stderr) - return; + return cfg = ConfigParser(allow_no_value=True, interpolation=ExtendedInterpolatorWithEnv()) @@ -252,7 +258,8 @@ def load_config_ini(): } if cfg.has_option('global', 'DatabaseURL'): - DATABASES['default'] = dj_database_url.parse(cfg.get('global', 'DatabaseURL', vars=CFG_PARSER_OPTS), conn_max_age=600) + DATABASES['default'] = dj_database_url.parse(cfg.get('global', 'DatabaseURL', vars=CFG_PARSER_OPTS), + conn_max_age=600) else: DATABASES['default'] = { diff --git a/app/YtManagerApp/management/appconfig.py b/app/YtManagerApp/management/appconfig.py index 43e4137..46b6711 100644 --- a/app/YtManagerApp/management/appconfig.py +++ b/app/YtManagerApp/management/appconfig.py @@ -29,6 +29,13 @@ class AppConfig(object): else: super().__setattr__(key, value) + def for_sub(self, subscription, pref: str): + value = getattr(subscription, pref) + if value is None: + value = subscription.user.preferences[pref] + + return value + global_prefs = global_preferences_registry.manager() appconfig = AppConfig(global_prefs) diff --git a/app/YtManagerApp/migrations/0008_auto_20181229_2035.py b/app/YtManagerApp/migrations/0008_auto_20181229_2035.py new file mode 100644 index 0000000..42a413a --- /dev/null +++ b/app/YtManagerApp/migrations/0008_auto_20181229_2035.py @@ -0,0 +1,25 @@ +# Generated by Django 2.1.2 on 2018-12-29 20:35 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('YtManagerApp', '0007_auto_20181029_1638'), + ] + + operations = [ + migrations.RemoveField( + model_name='usersettings', + name='user', + ), + migrations.RenameField( + model_name='subscription', + old_name='delete_after_watched', + new_name='automatically_delete_watched', + ), + migrations.DeleteModel( + name='UserSettings', + ), + ] diff --git a/app/YtManagerApp/models.py b/app/YtManagerApp/models.py index 979bee2..53ea3a7 100644 --- a/app/YtManagerApp/models.py +++ b/app/YtManagerApp/models.py @@ -116,7 +116,7 @@ class Subscription(models.Model): null=True, blank=True, max_length=128, choices=VIDEO_ORDER_CHOICES) - delete_after_watched = models.BooleanField(null=True, blank=True) + automatically_delete_watched = models.BooleanField(null=True, blank=True) def __str__(self): return self.name @@ -161,18 +161,6 @@ class Subscription(models.Model): def delete_subscription(self, keep_downloaded_videos: bool): self.delete() - def get_overloads_dict(self) -> dict: - d = {} - if self.auto_download is not None: - d['AutoDownload'] = self.auto_download - if self.download_limit is not None: - d['DownloadSubscriptionLimit'] = self.download_limit - if self.download_order is not None: - d['DownloadOrder'] = self.download_order - if self.delete_after_watched is not None: - d['DeleteWatched'] = self.delete_after_watched - return d - class Video(models.Model): video_id = models.TextField(null=False) @@ -209,11 +197,11 @@ class Video(models.Model): self.watched = True self.save() if self.downloaded_path is not None: - from YtManagerApp.appconfig import settings + from YtManagerApp.management.appconfig import appconfig from YtManagerApp.management.jobs.delete_video import schedule_delete_video from YtManagerApp.management.jobs.synchronize import schedule_synchronize_now_subscription - if settings.getboolean_sub(self.subscription, 'user', 'DeleteWatched'): + if appconfig.for_sub(self.subscription, 'automatically_delete_watched'): schedule_delete_video(self) schedule_synchronize_now_subscription(self.subscription) @@ -233,13 +221,13 @@ class Video(models.Model): def delete_files(self): if self.downloaded_path is not None: from YtManagerApp.management.jobs.delete_video import schedule_delete_video - from YtManagerApp.appconfig import settings + from YtManagerApp.management.appconfig import appconfig from YtManagerApp.management.jobs.synchronize import schedule_synchronize_now_subscription schedule_delete_video(self) # Mark watched? - if settings.getboolean_sub(self, 'user', 'MarkDeletedAsWatched'): + if appconfig.mark_deleted_as_watched: self.watched = True schedule_synchronize_now_subscription(self.subscription) diff --git a/app/YtManagerApp/templates/YtManagerApp/index.html b/app/YtManagerApp/templates/YtManagerApp/index.html index ebe0609..ae9cf82 100644 --- a/app/YtManagerApp/templates/YtManagerApp/index.html +++ b/app/YtManagerApp/templates/YtManagerApp/index.html @@ -3,7 +3,7 @@ {% load crispy_forms_tags %} {% block stylesheets %} - + {% endblock %} {% block scripts %} diff --git a/app/YtManagerApp/tests.py b/app/YtManagerApp/tests.py index 7ce503c..a39b155 100644 --- a/app/YtManagerApp/tests.py +++ b/app/YtManagerApp/tests.py @@ -1,3 +1 @@ -from django.test import TestCase - # Create your tests here. diff --git a/app/YtManagerApp/utils/__init__.py b/app/YtManagerApp/utils/__init__.py index e198fb4..0862f1f 100644 --- a/app/YtManagerApp/utils/__init__.py +++ b/app/YtManagerApp/utils/__init__.py @@ -1,9 +1,9 @@ def first_non_null(*iterable): - ''' + """ Returns the first element from the iterable which is not None. If all the elements are 'None', 'None' is returned. :param iterable: Iterable containing list of elements. :return: First non-null element, or None if all elements are 'None'. - ''' + """ return next((item for item in iterable if item is not None), None) diff --git a/app/YtManagerApp/utils/subscription_file_parser.py b/app/YtManagerApp/utils/subscription_file_parser.py index 225c3bd..203d868 100644 --- a/app/YtManagerApp/utils/subscription_file_parser.py +++ b/app/YtManagerApp/utils/subscription_file_parser.py @@ -1,4 +1,4 @@ -from typing import Iterable +from typing import Iterable, Optional from xml.etree import ElementTree import re @@ -12,7 +12,7 @@ class SubFileParser(object): def probe(self, file_handle) -> bool: """ Tests if file matches file format. - :param file: File path + :param file_handle: File handle :return: True if file matches, false otherwise """ return False @@ -20,7 +20,7 @@ class SubFileParser(object): def parse(self, file_handle) -> Iterable[str]: """ Parses file and returns a list of subscription URLs. - :param file: + :param file_handle: :return: """ return [] @@ -63,7 +63,7 @@ class OPMLParser(SubFileParser): """ def __init__(self): self.__cached_file = None - self.__cached_tree: ElementTree.ElementTree = None + self.__cached_tree: Optional[ElementTree.ElementTree] = None def __parse(self, file_handle): if file_handle == self.__cached_file: diff --git a/app/YtManagerApp/utils/youtube.py b/app/YtManagerApp/utils/youtube.py index e2d7576..f8df22e 100644 --- a/app/YtManagerApp/utils/youtube.py +++ b/app/YtManagerApp/utils/youtube.py @@ -7,8 +7,8 @@ class YoutubeAPI(YouTube): @staticmethod def build_public() -> 'YoutubeAPI': - from YtManagerApp.management.appconfig import youtube_api_key - return YoutubeAPI(key=youtube_api_key) + from YtManagerApp.management.appconfig import appconfig + return YoutubeAPI(key=appconfig.youtube_api_key) # @staticmethod # def build_oauth() -> 'YoutubeAPI': diff --git a/app/YtManagerApp/views/controls/modal.py b/app/YtManagerApp/views/controls/modal.py index 448aef7..333071d 100644 --- a/app/YtManagerApp/views/controls/modal.py +++ b/app/YtManagerApp/views/controls/modal.py @@ -39,8 +39,8 @@ class ModalMixin(ContextMixin): result = {'success': success} if not success: result['errors'] = form.errors.get_json_data(escape_html=True) - if error_msg is not None: - result['errors']['__all__'] = [{'message': error_msg}] + if error_msg is not None: + result['errors']['__all__'] = [{'message': error_msg}] return JsonResponse(result) diff --git a/app/YtManagerApp/views/first_time.py b/app/YtManagerApp/views/first_time.py index e597f73..94aedc0 100644 --- a/app/YtManagerApp/views/first_time.py +++ b/app/YtManagerApp/views/first_time.py @@ -14,7 +14,11 @@ from YtManagerApp.views.forms.first_time import WelcomeForm, ApiKeyForm, PickAdm logger = logging.getLogger("FirstTimeWizard") -class WizardStepMixin(object): +class WizardStepMixin: + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + def get(self, request, *args, **kwargs): # Prevent access if application is already initialized diff --git a/app/YtManagerApp/views/index.py b/app/YtManagerApp/views/index.py index 49a2909..2b5b7df 100644 --- a/app/YtManagerApp/views/index.py +++ b/app/YtManagerApp/views/index.py @@ -227,6 +227,10 @@ class DeleteFolderModal(LoginRequiredMixin, ModalMixin, FormMixin, DeleteView): model = SubscriptionFolder form_class = DeleteFolderForm + def __init__(self, *args, **kwargs): + self.object = None + super().__init__(*args, **kwargs) + def delete(self, request, *args, **kwargs): self.object = self.get_object() form = self.get_form() @@ -246,7 +250,7 @@ class CreateSubscriptionForm(forms.ModelForm): class Meta: model = Subscription fields = ['parent_folder', 'auto_download', - 'download_limit', 'download_order', 'delete_after_watched'] + 'download_limit', 'download_order', "automatically_delete_watched"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -313,7 +317,7 @@ class UpdateSubscriptionForm(forms.ModelForm): class Meta: model = Subscription fields = ['name', 'parent_folder', 'auto_download', - 'download_limit', 'download_order', 'delete_after_watched'] + 'download_limit', 'download_order', "automatically_delete_watched"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -346,6 +350,10 @@ class DeleteSubscriptionModal(LoginRequiredMixin, ModalMixin, FormMixin, DeleteV model = Subscription form_class = DeleteSubscriptionForm + def __init__(self, *args, **kwargs): + self.object = None + super().__init__(*args, **kwargs) + def delete(self, request, *args, **kwargs): self.object = self.get_object() form = self.get_form() @@ -445,7 +453,7 @@ class ImportSubscriptionsModal(LoginRequiredMixin, ModalMixin, FormView): sub.auto_download = form.cleaned_data['auto_download'] sub.download_limit = form.cleaned_data['download_limit'] sub.download_order = form.cleaned_data['download_order'] - sub.delete_after_watched = form.cleaned_data['delete_after_watched'] + sub.automatically_delete_watched = form.cleaned_data["automatically_delete_watched"] try: sub.fetch_from_url(url, api) except Exception as e: