def __init__(self, main_window_builder, main_window):
        self.main_window: CozyUI = main_window
        self.main_window_builder = main_window_builder

        inject.configure_once(self.configure_inject)

        reporter.info("main", "startup")

        self.whats_new_window: WhatsNewWindow = WhatsNewWindow()

        self.library_view: LibraryView = LibraryView(main_window_builder)
        self.search_view: SearchView = SearchView(main_window_builder)
        self.book_detail_view: BookDetailView = BookDetailView(
            main_window_builder)

        self.library_view_model = inject.instance(LibraryViewModel)
        self.search_view_model = inject.instance(SearchViewModel)
        self.book_detail_view_model = inject.instance(BookDetailViewModel)

        self.search_view_model.add_listener(self._on_open_view)
        self.book_detail_view_model.add_listener(self._on_open_view)
        self.library_view_model.add_listener(self._on_open_view)
        self.library_view_model.add_listener(self._on_library_view_event)

        self.main_window.add_listener(self._on_main_window_event)
Exemple #2
0
    def __init__(self):
        super().__init__()
        self.ui = cozy.ui.main_view.CozyUI()

        from cozy.media.importer import Importer
        self._importer = inject.instance(Importer)

        self._importer.add_listener(self._on_importer_event)

        self.cache_dir = os.path.join(get_cache_dir(), "offline")
        if not os.path.exists(self.cache_dir):
            os.makedirs(self.cache_dir)

        self._start_processing()

        inject.instance(cozy.ui.settings.Settings).add_listener(self.__on_settings_changed)
Exemple #3
0
def report(component: str, type: LogLevel, message: str, exception: Exception):
    if ENABLE != 'true':
        return

    app_settings = inject.instance(ApplicationSettings)
    report_level = app_settings.report_level

    if report_level == 0:
        return

    curr_datetime = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
    curr_datetime = curr_datetime.isoformat('T')

    if not component or not type or not message:
        raise ValueError("component, type and message are mandatory")

    labels = __append_label("", "component", component)

    if exception:
        labels = __append_label(labels, "exception_type",
                                exception.__class__.__name__)

    labels = __append_label(labels, "app", "cozy")
    labels = __append_label(labels, "level", LOG_LEVEL_MAP[type])

    labels = __append_label(
        labels, "gtk_version", "{}.{}".format(Gtk.get_major_version(),
                                              Gtk.get_minor_version()))
    labels = __append_label(labels, "python_version",
                            platform.python_version())
    labels = __append_label(labels, "peewee_version", PeeweeVersion)
    labels = __append_label(labels, "mutagen_version", MutagenVersion)
    labels = __append_label(labels, "apsw_version", APSWVersion())
    labels = __append_label(labels, "version", CozyVersion)

    if report_level > 1:
        labels = __append_label(labels, "distro", distro.name())
        labels = __append_label(labels, "distro_version", distro.version())
        labels = __append_label(labels, "desktop_environment",
                                os.environ.get('DESKTOP_SESSION'))

    line = "[{}] {}".format(LOG_LEVEL_MAP[type], message)

    headers = {'Content-type': 'application/json'}
    payload = {
        'streams': [{
            'labels': "{{{}}}".format(labels),
            'entries': [{
                'ts': curr_datetime,
                'line': line
            }]
        }]
    }
    try:
        requests.post(URL, json=payload, headers=headers, timeout=10)
    except:
        pass
Exemple #4
0
def test_initializing_player_loads_last_book(mocker):
    from cozy.media.player import Player

    mocker.patch("cozy.media.player.Player._rewind_in_book")
    library = inject.instance(Library)
    library.last_played_book = library.books[0]

    player = Player()

    assert player._book == library.last_played_book
Exemple #5
0
def test_loading_new_chapter_loads_chapter(mocker):
    from cozy.media.player import Player

    mocker.patch("cozy.media.player.Player._rewind_in_book")
    library = inject.instance(Library)
    player = Player()

    book = library.books[0]
    player._load_chapter(book.current_chapter)

    assert player._book.current_chapter == book.current_chapter
Exemple #6
0
    def __init__(self):
        super().__init__()
        self.volume_monitor: Gio.VolumeMonitor = Gio.VolumeMonitor.get()
        self.volume_monitor.connect("mount-added", self.__on_mount_added)
        self.volume_monitor.connect("mount-removed", self.__on_mount_removed)

        self.init_offline_mode()

        from cozy.ui.settings import Settings as UISettings
        self._ui_settings = inject.instance(UISettings)
        self._ui_settings.add_listener(self.__on_settings_changed)
Exemple #7
0
def test_loading_new_book_emits_changed_event(mocker):
    from cozy.media.player import Player

    mocker.patch("cozy.media.player.Player._rewind_in_book")
    library = inject.instance(Library)
    player = Player()
    spy = mocker.spy(player, "emit_event_main_thread")

    book = library.books[2]
    player._continue_book(book)

    spy.assert_has_calls(calls=[call("chapter-changed", book)])
Exemple #8
0
    def __init__(self, main_window_builder, main_window):
        self.main_window: CozyUI = main_window
        self.main_window_builder = main_window_builder

        inject.configure_once(self.configure_inject)

        reporter.info("main", "startup")

        self.whats_new_window: WhatsNewWindow = WhatsNewWindow()

        self.library_view: LibraryView = LibraryView(main_window_builder)
        self.search_view: SearchView = SearchView()
        self.book_detail_view: BookDetailView = BookDetailView(
            main_window_builder)
        self.headerbar: Headerbar = Headerbar(main_window_builder)

        self.library_view_model = inject.instance(LibraryViewModel)
        self.search_view_model = inject.instance(SearchViewModel)
        self.book_detail_view_model = inject.instance(BookDetailViewModel)
        self.playback_control_view_model = inject.instance(
            PlaybackControlViewModel)
        self.sleep_timer_view_model = inject.instance(SleepTimerViewModel)
        self.player = inject.instance(Player)

        self._connect_popovers()

        self.search_view_model.add_listener(self._on_open_view)
        self.book_detail_view_model.add_listener(self._on_open_view)
        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.main_window.add_listener(self._on_main_window_event)
Exemple #9
0
def test_loading_new_chapter_sets_playback_speed(mocker):
    from cozy.media.player import Player

    mocker.patch("cozy.media.player.Player._rewind_in_book")
    library = inject.instance(Library)
    player = Player()

    book = library.books[0]
    book.playback_speed = 2.5
    player._load_chapter(book.current_chapter)
    print(player.playback_speed)

    assert player.playback_speed == book.playback_speed
Exemple #10
0
    def __init__(self, main_window_builder: Gtk.Builder):
        super().__init__()

        self._header_container: Gtk.Box = main_window_builder.get_object("header_container")
        self._header_container.add(self)

        self.sleep_timer: SleepTimer = SleepTimer(self.timer_image)
        self.volume_button.get_style_context().remove_class("flat")
        self.playback_speed_button.set_popover(PlaybackSpeedPopover())
        self.timer_button.set_popover(self.sleep_timer)

        self._playback_control_view_model: PlaybackControlViewModel = inject.instance(PlaybackControlViewModel)
        self._headerbar_view_model: HeaderbarViewModel = inject.instance(HeaderbarViewModel)
        self._artwork_cache: ArtworkCache = inject.instance(ArtworkCache)
        self._init_app_menu()
        self._connect_view_model()
        self._connect_widgets()

        self._on_book_changed()
        self._on_lock_ui_changed()
        self._on_length_changed()
        self._on_position_changed()
        self._on_volume_changed()
Exemple #11
0
Fichier : db.py Projet : leuc/cozy
def remove_invalid_entries(ui=None, refresh=False):
    """
    Remove track entries from db that no longer exist in the filesystem.
    """
    # remove entries from the db that are no longer existent

    from cozy.control.filesystem_monitor import FilesystemMonitor
    filesystem_monitor = inject.instance(FilesystemMonitor)
    for track in Track.select():
        if not os.path.isfile(
                track.file) and filesystem_monitor.is_track_online(track):
            track.delete_instance()

    clean_books()

    if refresh:
        Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, ui.refresh_content)
Exemple #12
0
def test_play_pause_chapter_does_not_trigger_chapter_or_book_reload_when_book_has_been_played_before(
        mocker):
    from cozy.media.player import Player

    mocker.patch("cozy.media.player.Player._load_last_book")
    player = Player()

    library = inject.instance(Library)
    book = library.books[0]
    chapter = book.chapters[0]

    # Start Playback
    player.play_pause_chapter(book, chapter)

    spy_book = mocker.spy(player, "_load_book")
    spy_chapter = mocker.spy(player, "_load_chapter")

    # Pause Playback. Spies should not record any book or chapter reload
    player.play_pause_chapter(book, chapter)

    spy_book.assert_not_called()
    spy_chapter.assert_not_called()
Exemple #13
0
    def __init__(self):
        super().__init__()
        from cozy.control.artwork_cache import ArtworkCache
        self._artwork_cache: ArtworkCache = inject.instance(ArtworkCache)

        self.view_model = SettingsViewModel()

        self.ui = cozy.ui.main_view.CozyUI()
        self.builder = Gtk.Builder.new_from_resource(
            "/com/github/geigi/cozy/settings.ui")

        # get settings window
        self.window = self.builder.get_object("settings_window")
        self.window.set_transient_for(self.ui.window)
        self.window.connect("delete-event", self.ui.hide_window)

        self.add_storage_button = self.builder.get_object("add_location_button")
        self.add_storage_button.connect("clicked", self.__on_add_storage_clicked)
        self.remove_storage_button = self.builder.get_object("remove_location_button")
        self.remove_storage_button.connect("clicked", self.__on_remove_storage_clicked)
        self.external_button = self.builder.get_object("external_button")
        self.external_button_handle_id = self.external_button.connect("clicked", self.__on_external_clicked)
        self.default_storage_button = self.builder.get_object("default_location_button")
        self.default_storage_button.connect("clicked", self.__on_default_storage_clicked)
        self.storage_list_box = self.builder.get_object("storage_list_box")
        self.storage_list_box.connect("row-activated", self.__on_storage_box_changed)

        self.remove_blacklist_button = self.builder.get_object("remove_blacklist_button")
        self.remove_blacklist_button.connect("clicked", self.__on_remove_blacklist_clicked)
        # self.remove_blacklist_button.set_sensitive(False)
        self.blacklist_tree_view = self.builder.get_object("blacklist_tree_view")
        self.blacklist_model = self.builder.get_object("blacklist_store")
        self.blacklist_tree_view.get_selection().connect("changed", self.__on_blacklist_selection_changed)

        self.sleep_fadeout_switch = self.builder.get_object("sleep_fadeout_switch")
        self.sleep_fadeout_switch.connect("notify::active", self.__on_fadeout_switch_changed)

        self.external_cover_switch = self.builder.get_object("external_cover_switch")
        self.external_cover_switch.connect("state-set", self.__on_external_cover_switch_changed)

        self.fadeout_duration_label = self.builder.get_object("fadeout_duration_label")
        self.fadeout_duration_row = self.builder.get_object("fadeout_duration_row")

        self.fadeout_duration_adjustment = self.builder.get_object("fadeout_duration_adjustment")
        self.fadeout_duration_adjustment.connect("value-changed", self.__on_fadeout_adjustment_changed)
        self.__on_fadeout_adjustment_changed(self.fadeout_duration_adjustment)

        self.force_refresh_button = self.builder.get_object("force_refresh_button")
        self.force_refresh_button.connect("clicked", self.__on_force_refresh_clicked)

        self.settings_stack: Gtk.Stack = self.builder.get_object("settings_stack")
        self.settings_stack.connect("notify::visible-child", self._on_settings_stack_changed)

        from cozy.ui.widgets.error_reporting import ErrorReporting
        self.settings_stack.add_titled(ScrollWrapper(ErrorReporting()), "feedback", _("Feedback"))

        self._init_storage()
        self._init_blacklist()
        self.__init_bindings()
        self.__on_storage_box_changed(None, None)

        self.set_darkmode()
Exemple #14
0
 def __init__(self):
     _importer = inject.instance(Importer)
     _importer.add_listener(self._on_importer_event)