Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize storage list #831

Merged
merged 22 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cozy/app_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from cozy.view_model.search_view_model import SearchViewModel
from cozy.view_model.settings_view_model import SettingsViewModel
from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel
from cozy.view_model.storages_view_model import StoragesViewModel


class AppController(metaclass=Singleton):
Expand Down Expand Up @@ -75,7 +76,7 @@ def __init__(self, gtk_app, main_window_builder, main_window):
self.library_view_model.add_listener(self._on_open_view)
self.library_view_model.add_listener(self._on_library_view_event)
self.playback_control_view_model.add_listener(self._on_open_view)
self.headerbar_view_model.add_listener(self._on_open_view)
self.headerbar_view_model.add_listener(self._on_working_event)
self.app_view_model.add_listener(self._on_app_view_event)

self.main_window.add_listener(self._on_main_window_event)
Expand Down Expand Up @@ -108,6 +109,7 @@ def configure_inject(self, binder):
binder.bind_to_constructor(ToastNotifier, lambda: ToastNotifier())
binder.bind_to_constructor(AppViewModel, lambda: AppViewModel())
binder.bind_to_constructor(SettingsViewModel, lambda: SettingsViewModel())
binder.bind_to_constructor(StoragesViewModel, lambda: StoragesViewModel())

def open_author(self, author: str):
self.library_view_model.library_view_mode = LibraryViewMode.AUTHOR
Expand Down Expand Up @@ -146,10 +148,12 @@ def _on_app_view_event(self, event: str, data):
if event == "view":
self.headerbar_view_model.set_view(data)

def _on_main_window_event(self, event: str, data):
def _on_working_event(self, event: str, data) -> None:
if event == "working":
self.book_detail_view_model.lock_ui = data
self.settings_view_model.lock_ui = data

def _on_main_window_event(self, event: str, data):
if event == "open_view":
self._on_open_view(data, None)

Expand Down
50 changes: 24 additions & 26 deletions cozy/model/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging
from typing import List, Optional

import peewee

Expand All @@ -16,7 +15,7 @@


class Settings:
_storages: List[Storage] = []
_storages: list[Storage] = []
_db = cache = inject.attr(SqliteDatabase)

def __init__(self):
Expand All @@ -27,19 +26,23 @@ def first_start(self) -> bool:
return self._db_object.first_start

@property
def last_played_book(self) -> Optional[Book]:
def last_played_book(self) -> Book | None:
try:
return self._db_object.last_played_book
except peewee.DoesNotExist:
log.warning("last_played_book references an non existent object. Setting last_played_book to None.")
reporter.warning("settings_model",
"last_played_book references an non existent object. Setting last_played_book to None.")
log.warning(
"last_played_book references an non existent object. Setting last_played_book to None."
)
reporter.warning(
"settings_model",
"last_played_book references an non existent object. Setting last_played_book to None.",
)

self.last_played_book = None
return None

@last_played_book.setter
def last_played_book(self, new_value):
def last_played_book(self, new_value) -> None:
if new_value:
self._db_object.last_played_book = new_value._db_object
else:
Expand All @@ -48,44 +51,39 @@ def last_played_book(self, new_value):
self._db_object.save(only=self._db_object.dirty_fields)

@property
def default_location(self):
return next(location
for location
in self.storage_locations
if location.default)
def default_location(self) -> Storage:
return next(location for location in self.storage_locations if location.default)

@property
def storage_locations(self):
def storage_locations(self) -> list[Storage]:
if not self._storages:
self._load_all_storage_locations()

return self._storages

@property
def external_storage_locations(self):
def external_storage_locations(self) -> list[Storage]:
if not self._storages:
self._load_all_storage_locations()

return [storage for storage in self._storages if storage.external]

def invalidate(self):
self._storages = []
def invalidate(self) -> None:
self._storages.clear()

def _load_all_storage_locations(self):
self._storages = []
def _load_all_storage_locations(self) -> None:
self.invalidate()

for storage_db_obj in StorageModel.select(StorageModel.id):
try:
self._storages.append(Storage(self._db, storage_db_obj.id))
except InvalidPath:
log.error("Invalid path found in database, skipping: {}".format(storage_db_obj.path))
log.error(
"Invalid path found in database, skipping: {}".format(storage_db_obj.path)
)

self._ensure_default_storage_present()
self._ensure_default_storage_is_present()

def _ensure_default_storage_present(self):
default_storage_present = any(storage.default
for storage
in self._storages)

if not default_storage_present and len(self._storages) > 0:
def _ensure_default_storage_is_present(self) -> None:
if self._storages and not any(storage.default for storage in self._storages):
self._storages[0].default = True
14 changes: 7 additions & 7 deletions cozy/model/storage.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os
from pathlib import Path

from peewee import SqliteDatabase

Expand All @@ -17,8 +17,8 @@ def __init__(self, db: SqliteDatabase, db_id: int):
self._get_db_object()

@staticmethod
def new(db: SqliteDatabase):
db_obj = StorageModel.create(path="")
def new(db: SqliteDatabase, path: str):
db_obj = StorageModel.create(path=path)
return Storage(db, db_obj.id)

def _get_db_object(self):
Expand All @@ -33,11 +33,11 @@ def path(self):
return self._db_object.path

@path.setter
def path(self, new_path: str):
if not os.path.isabs(new_path):
def path(self, path: str):
if not Path(path).is_absolute():
raise InvalidPath

self._db_object.path = new_path
self._db_object.path = path
self._db_object.save(only=self._db_object.dirty_fields)

@property
Expand Down Expand Up @@ -68,4 +68,4 @@ def external(self, new_external: bool):
self._db_object.save(only=self._db_object.dirty_fields)

def delete(self):
self._db_object.delete_instance(recursive=True, delete_nullable=False)
self._db_object.delete_instance(recursive=True, delete_nullable=False)
8 changes: 4 additions & 4 deletions cozy/ui/main_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from cozy.media.importer import Importer, ScanStatus
from cozy.media.player import Player
from cozy.model.settings import Settings as SettingsModel
from cozy.view_model.settings_view_model import SettingsViewModel
from cozy.view_model.storages_view_model import StoragesViewModel
from cozy.open_view import OpenView
from cozy.ui.library_view import LibraryView
from cozy.ui.preferences_view import PreferencesView
Expand All @@ -39,7 +39,7 @@ class CozyUI(EventSender, metaclass=Singleton):
_settings: SettingsModel = inject.attr(SettingsModel)
_files: Files = inject.attr(Files)
_player: Player = inject.attr(Player)
_settings_view_model: SettingsViewModel = inject.attr(SettingsViewModel)
_storages_view_model: StoragesViewModel = inject.attr(StoragesViewModel)

def __init__(self, pkgdatadir, app, version):
super().__init__()
Expand Down Expand Up @@ -258,9 +258,9 @@ def switch_to_playing(self):
self.block_ui_buttons(False, True)
else:
# we want to only block the player controls
# TODO: rework. this is messy
self.block_ui_buttons(False, True)
self.block_ui_buttons(True, False)
self.emit_event_main_thread("working", False)

def check_for_tracks(self):
"""
Expand Down Expand Up @@ -318,7 +318,7 @@ def _on_drag_data_received(self, widget, value, *_):
return True

def _set_audiobook_path(self, path):
self._settings_view_model.add_first_storage_location(path)
self._storages_view_model.add_first_storage_location(path)
self.main_stack.props.visible_child_name = "import"
self.scan(None, None)
self.fs_monitor.init_offline_mode()
Expand Down
Loading