Ejemplo n.º 1
0
    def generate_library_tags(self):
        db_library_directories = database.DatabaseFunctions(
            self.main_window.database_path).fetch_data(
                ('Path', 'Name', 'Tags'),
                'directories',  # This checks the directories table NOT the book one
                {'Path': ''},
                'LIKE')

        if db_library_directories:  # Empty database / table
            library_directories = {
                i[0]: (i[1], i[2]) for i in db_library_directories}

        else:
            db_library_directories = database.DatabaseFunctions(
                self.main_window.database_path).fetch_data(
                    ('Path',),
                    'books', # THIS CHECKS THE BOOKS TABLE
                    {'Path': ''},
                    'LIKE')

            library_directories = None
            if db_library_directories:
                library_directories = {
                    i[0]: (None, None) for i in db_library_directories}

        def get_tags(all_metadata):
            path = os.path.dirname(all_metadata['path'])
            path_ref = pathlib.Path(path)

            for i in library_directories:
                if i == path or pathlib.Path(i) in path_ref.parents:
                    directory_name = library_directories[i][0]
                    if directory_name:
                        directory_name = directory_name.lower()
                    else:
                        directory_name = i.rsplit(os.sep)[-1].lower()

                    directory_tags = library_directories[i][1]
                    if directory_tags:
                        directory_tags = directory_tags.lower()

                    return directory_name, directory_tags

            # A file is assigned a 'manually added' tag in case it isn't
            # in any designated library directory
            added_string = self._translate('Library', 'manually added')
            return added_string.lower(), None

        # Generate tags for the QStandardItemModel
        # This isn't triggered for an empty view model
        for i in range(self.libraryModel.rowCount()):
            this_item = self.libraryModel.item(i, 0)
            all_metadata = this_item.data(QtCore.Qt.UserRole + 3)
            directory_name, directory_tags = get_tags(all_metadata)

            this_item.setData(directory_name, QtCore.Qt.UserRole + 10)
            this_item.setData(directory_tags, QtCore.Qt.UserRole + 11)
Ejemplo n.º 2
0
    def start_library_scan(self):
        # TODO
        # return in case the treeView is not edited

        self.hide()

        data_pairs = []
        for i in self.filesystem_model.tag_data.items():
            data_pairs.append(
                [i[0], i[1]['name'], i[1]['tags'], i[1]['check_state']])

        database.DatabaseFunctions(
            self.database_path).set_library_paths(data_pairs)

        if not data_pairs:
            try:
                if self.sender().objectName() == 'reloadLibrary':
                    self.show()
            except AttributeError:
                pass

            self.parent.lib_ref.view_model.clear()
            self.parent.lib_ref.table_rows = []

            # TODO
            # Change this to no longer include files added manually

            database.DatabaseFunctions(
                self.database_path).delete_from_database('*', '*')

            return

        # Update the main window library filter menu
        self.parent.generate_library_filter_menu(data_pairs)
        self.parent.set_library_filter()

        # Disallow rechecking until the first check completes
        self.okButton.setEnabled(False)
        self.parent.reloadLibrary.setEnabled(False)
        self.okButton.setToolTip(
            self._translate('SettingsUI', 'Library scan in progress...'))

        # Traverse directories looking for files
        self.parent.statusMessage.setText(
            self._translate('SettingsUI', 'Checking library folders'))
        self.thread = BackGroundBookSearch(data_pairs, self)
        self.thread.finished.connect(self.finished_iterating)
        self.thread.start()
Ejemplo n.º 3
0
    def prune_models(self, valid_paths):
        # To be executed when the library is updated by folder
        # All files in unselected directories will have to be removed
        # from both of the models
        # They will also have to be deleted from the library
        valid_paths = set(valid_paths)

        # Get all paths
        all_paths = set()
        for i in range(self.view_model.rowCount()):
            item = self.view_model.item(i, 0)
            item_metadata = item.data(QtCore.Qt.UserRole + 3)
            book_path = item_metadata['path']
            all_paths.add(book_path)

        invalid_paths = all_paths - valid_paths

        deletable_persistent_indexes = []
        for i in range(self.view_model.rowCount()):
            item = self.view_model.item(i)
            path = item.data(QtCore.Qt.UserRole + 3)['path']
            if path in invalid_paths:
                deletable_persistent_indexes.append(
                    QtCore.QPersistentModelIndex(item.index()))

        if deletable_persistent_indexes:
            for i in deletable_persistent_indexes:
                self.view_model.removeRow(i.row())

        # Remove invalid paths from the database as well
        database.DatabaseFunctions(
            self.parent.database_path).delete_from_database(
                'Path', invalid_paths)
Ejemplo n.º 4
0
    def prune_models(self, valid_paths):
        # To be executed when the library is updated by folder
        # All files in unselected directories will have to be removed
        # from both of the models
        # They will also have to be deleted from the library
        invalid_paths = []
        deletable_persistent_indexes = []

        for i in range(self.libraryModel.rowCount()):
            item = self.libraryModel.item(i)

            item_metadata = item.data(QtCore.Qt.UserRole + 3)
            book_path = item_metadata['path']
            try:
                addition_mode = item_metadata['addition_mode']
            except KeyError:
                addition_mode = 'automatic'
                print('Libary: Error setting addition mode for prune')

            if (book_path not in valid_paths
                    and (addition_mode != 'manual' or addition_mode is None)):

                invalid_paths.append(book_path)
                deletable_persistent_indexes.append(
                    QtCore.QPersistentModelIndex(item.index()))

        if deletable_persistent_indexes:
            for i in deletable_persistent_indexes:
                self.libraryModel.removeRow(i.row())

        # Remove invalid paths from the database as well
        database.DatabaseFunctions(
            self.main_window.database_path).delete_from_database(
                'Path', invalid_paths)
Ejemplo n.º 5
0
    def process_post_hoc_files(self, file_list, open_files_after_processing):
        # Takes care of both dragged and dropped files
        # As well as files sent as command line arguments

        file_list = [i for i in file_list if os.path.exists(i)]
        if not file_list:
            return

        books = sorter.BookSorter(file_list, ('addition', 'manual'),
                                  self.database_path,
                                  self.settings['auto_tags'],
                                  self.temp_dir.path())

        parsed_books = books.initiate_threads()
        if not parsed_books and not open_files_after_processing:
            return

        database.DatabaseFunctions(
            self.database_path).add_to_database(parsed_books)
        self.lib_ref.generate_model('addition', parsed_books, True)

        file_dict = {i: None for i in file_list}
        if open_files_after_processing:
            self.open_files(file_dict)

        self.move_on()
Ejemplo n.º 6
0
    def database_hashes(self):
        all_hashes_and_paths = database.DatabaseFunctions(
            self.database_path).fetch_data(('Hash', 'Path'), 'books',
                                           {'Hash': ''}, 'LIKE')

        if all_hashes_and_paths:
            self.hashes_and_paths = {i[0]: i[1] for i in all_hashes_and_paths}
Ejemplo n.º 7
0
    def start_library_scan(self):
        self.hide()

        data_pairs = []
        for i in self.filesystemModel.tag_data.items():
            data_pairs.append(
                [i[0], i[1]['name'], i[1]['tags'], i[1]['check_state']])

        database.DatabaseFunctions(
            self.database_path).set_library_paths(data_pairs)

        if not data_pairs:
            logger.error('Can\'t scan - No book paths saved')
            try:
                if self.sender().objectName() == 'reloadLibrary':
                    self.show()
                    treeViewIndex = self.listModel.index(0, 0)
                    self.listView.setCurrentIndex(treeViewIndex)
                    return
            except AttributeError:
                pass

            database.DatabaseFunctions(
                self.database_path).delete_from_database('*', '*')

            self.main_window.lib_ref.generate_model('build')
            self.main_window.lib_ref.generate_proxymodels()
            self.main_window.generate_library_filter_menu()

            return

        # Update the main window library filter menu
        self.main_window.generate_library_filter_menu(data_pairs)
        self.main_window.set_library_filter()

        # Disallow rechecking until the first check completes
        self.okButton.setEnabled(False)
        self.main_window.libraryToolBar.reloadLibraryButton.setEnabled(False)
        self.okButton.setToolTip(
            self._translate('SettingsUI', 'Library scan in progress...'))

        # Traverse directories looking for files
        self.main_window.statusMessage.setText(
            self._translate('SettingsUI', 'Checking library folders'))
        self.thread = BackGroundBookSearch(data_pairs)
        self.thread.finished.connect(self.finished_iterating)
        self.thread.start()
Ejemplo n.º 8
0
    def run(self):
        for i in self.all_metadata:
            book_hash = i['hash']
            database_dict = {
                'Position': i['position'],
                'LastAccessed': i['last_accessed'],
                'Bookmarks': i['bookmarks']}

            database.DatabaseFunctions(self.database_path).modify_metadata(
                database_dict, book_hash)
Ejemplo n.º 9
0
 def run(self):
     books = sorter.BookSorter(self.file_list, 'addition',
                               self.database_path,
                               self.parent.settings['auto_tags'],
                               self.parent.temp_dir.path())
     parsed_books = books.initiate_threads()
     self.parent.lib_ref.generate_model('addition', parsed_books, False)
     if self.prune_required:
         self.parent.lib_ref.prune_models(self.file_list)
     database.DatabaseFunctions(
         self.database_path).add_to_database(parsed_books)
Ejemplo n.º 10
0
    def cull_covers(self, event=None):
        blank_pixmap = QtGui.QPixmap()
        blank_pixmap.load(
            ':/images/blank.png')  # Keep this. Removing it causes the
        # listView to go blank on a resize

        all_indexes = set()
        for i in range(self.lib_ref.itemProxyModel.rowCount()):
            all_indexes.add(self.lib_ref.itemProxyModel.index(i, 0))

        y_range = list(range(0, self.listView.viewport().height(), 100))
        y_range.extend((-20, self.listView.viewport().height() + 20))
        x_range = range(0, self.listView.viewport().width(), 80)

        visible_indexes = set()
        for i in y_range:
            for j in x_range:
                this_index = self.listView.indexAt(QtCore.QPoint(j, i))
                visible_indexes.add(this_index)

        invisible_indexes = all_indexes - visible_indexes
        for i in invisible_indexes:
            model_index = self.lib_ref.itemProxyModel.mapToSource(i)
            this_item = self.lib_ref.libraryModel.item(model_index.row())

            if this_item:
                this_item.setIcon(QtGui.QIcon(blank_pixmap))
                this_item.setData(False, QtCore.Qt.UserRole + 8)

        hash_index_dict = {}
        hash_list = []
        for i in visible_indexes:
            model_index = self.lib_ref.itemProxyModel.mapToSource(i)

            book_hash = self.lib_ref.libraryModel.data(model_index,
                                                       QtCore.Qt.UserRole + 6)
            cover_displayed = self.lib_ref.libraryModel.data(
                model_index, QtCore.Qt.UserRole + 8)

            if book_hash and not cover_displayed:
                hash_list.append(book_hash)
                hash_index_dict[book_hash] = model_index

        all_covers = database.DatabaseFunctions(
            self.database_path).fetch_covers_only(hash_list)

        for i in all_covers:
            book_hash = i[0]
            cover = i[1]
            model_index = hash_index_dict[book_hash]

            book_item = self.lib_ref.libraryModel.item(model_index.row())
            self.cover_loader(book_item, cover)
Ejemplo n.º 11
0
    def database_entry_for_book(self, file_hash):
        database_return = database.DatabaseFunctions(
            self.database_path).fetch_data(('Position', 'Bookmarks'), 'books',
                                           {'Hash': file_hash}, 'EQUALS')[0]

        book_data = []
        for i in database_return:
            # All of these values are pickled and stored
            if i:
                book_data.append(pickle.loads(i))
            else:
                book_data.append(None)
        return book_data
Ejemplo n.º 12
0
    def run(self):
        books = sorter.BookSorter(
            self.file_list,
            ('addition', self.addition_mode),
            self.database_path,
            self.main_window.settings,
            self.main_window.temp_dir.path())

        parsed_books, self.errors = books.initiate_threads()
        self.main_window.lib_ref.generate_model('addition', parsed_books, False)
        database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)

        if self.prune_required:
            self.main_window.lib_ref.prune_models(self.file_list)
Ejemplo n.º 13
0
    def generate_library_tags(self):
        db_library_directories = database.DatabaseFunctions(
            self.parent.database_path
        ).fetch_data(
            ('Path', 'Name', 'Tags'),
            'directories',  # This checks the directories table NOT the book one
            {'Path': ''},
            'LIKE')

        if not db_library_directories:  # Empty database / table
            return

        library_directories = {
            i[0]: (i[1], i[2])
            for i in db_library_directories
        }

        def get_tags(all_metadata):
            path = os.path.dirname(all_metadata['path'])
            path_ref = pathlib.Path(path)

            for i in library_directories:
                if i == path or pathlib.Path(i) in path_ref.parents:
                    directory_name = library_directories[i][0]
                    if directory_name:
                        directory_name = directory_name.lower()
                    else:
                        directory_name = i.rsplit(os.sep)[-1].lower()

                    directory_tags = library_directories[i][1]
                    if directory_tags:
                        directory_tags = directory_tags.lower()

                    return directory_name, directory_tags

            added_string = self._translate('Library', 'manually added')
            return added_string.lower(), None

        # Generate tags for the QStandardItemModel
        for i in range(self.view_model.rowCount()):
            this_item = self.view_model.item(i, 0)
            all_metadata = this_item.data(QtCore.Qt.UserRole + 3)
            directory_name, directory_tags = get_tags(all_metadata)

            this_item.setData(directory_name, QtCore.Qt.UserRole + 10)
            this_item.setData(directory_tags, QtCore.Qt.UserRole + 11)
Ejemplo n.º 14
0
    def database_entry_for_book(self, file_hash):
        database_return = database.DatabaseFunctions(
            self.database_path).fetch_data(
                ('Title', 'Author', 'Year', 'ISBN', 'Tags', 'Position',
                 'Bookmarks'), 'books', {'Hash': file_hash}, 'EQUALS')[0]

        book_data = []

        for count, i in enumerate(database_return):
            if count in (5, 6):
                if i:
                    book_data.append(pickle.loads(i))
                else:
                    book_data.append(None)
            else:
                book_data.append(i)

        return book_data
Ejemplo n.º 15
0
    def load_all_covers(self):
        all_covers_db = database.DatabaseFunctions(
            self.database_path).fetch_data((
                'Hash',
                'CoverImage',
            ), 'books', {'Hash': ''}, 'LIKE')

        all_covers = {i[0]: i[1] for i in all_covers_db}

        for i in range(self.lib_ref.view_model.rowCount()):
            this_item = self.lib_ref.view_model.item(i, 0)

            is_cover_already_displayed = this_item.data(QtCore.Qt.UserRole + 8)
            if is_cover_already_displayed:
                continue

            book_hash = this_item.data(QtCore.Qt.UserRole + 6)
            cover = all_covers[book_hash]
            self.cover_loader(this_item, cover)
Ejemplo n.º 16
0
    def ok_pressed(self, event=None):
        book_item = self.parent.lib_ref.libraryModel.item(
            self.book_index.row())

        title = self.titleLine.text()
        author = self.authorLine.text()
        tags = self.tagsLine.text()

        try:
            year = int(self.yearLine.text())
        except ValueError:
            year = self.book_year

        author_string = self._translate('MetadataUI', 'Author')
        year_string = self._translate('MetadataUI', 'Year')
        tooltip_string = f'{title} \n{author_string}: {author} \n{year_string}: {str(year)}'

        book_item.setData(title, QtCore.Qt.UserRole)
        book_item.setData(author, QtCore.Qt.UserRole + 1)
        book_item.setData(year, QtCore.Qt.UserRole + 2)
        book_item.setData(tags, QtCore.Qt.UserRole + 4)
        book_item.setToolTip(tooltip_string)

        book_hash = book_item.data(QtCore.Qt.UserRole + 6)
        database_dict = {
            'Title': title,
            'Author': author,
            'Year': year,
            'Tags': tags
        }

        if self.cover_for_database:
            database_dict['CoverImage'] = self.cover_for_database
            self.parent.cover_functions.cover_loader(book_item,
                                                     self.cover_for_database)

        self.parent.lib_ref.update_proxymodels()
        self.hide()

        database.DatabaseFunctions(self.database_path).modify_metadata(
            database_dict, book_hash)
Ejemplo n.º 17
0
    def open_books_at_startup(self):
        # Last open books and command line books aren't being opened together
        # so that command line books are processed last and therefore retain focus

        # Open last... open books.
        # Then set the value to None for the next run
        if self.settings['last_open_books']:
            files_to_open = {i: None for i in self.settings['last_open_books']}
            self.open_files(files_to_open)
        else:
            self.settings['last_open_tab'] = None

        # Open input files if specified
        cl_parser = QtCore.QCommandLineParser()
        cl_parser.process(QtWidgets.qApp)
        my_args = cl_parser.positionalArguments()
        if my_args:
            file_list = [
                QtCore.QFileInfo(i).absoluteFilePath() for i in my_args
            ]
            books = sorter.BookSorter(file_list, ('addition', 'manual'),
                                      self.database_path,
                                      self.settings['auto_tags'],
                                      self.temp_dir.path())

            parsed_books = books.initiate_threads()
            if not parsed_books:
                return

            database.DatabaseFunctions(
                self.database_path).add_to_database(parsed_books)
            self.lib_ref.generate_model('addition', parsed_books, True)

            file_dict = {
                QtCore.QFileInfo(i).absoluteFilePath(): None
                for i in my_args
            }
            self.open_files(file_dict)

            self.move_on()
Ejemplo n.º 18
0
    def ok_pressed(self, event):
        book_item = self.parent.lib_ref.view_model.item(self.book_index.row())

        title = self.titleLine.text()
        author = self.authorLine.text()
        tags = self.tagsLine.text()

        try:
            year = int(self.yearLine.text())
        except ValueError:
            year = self.book_year

        tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)

        book_item.setData(title, QtCore.Qt.UserRole)
        book_item.setData(author, QtCore.Qt.UserRole + 1)
        book_item.setData(year, QtCore.Qt.UserRole + 2)
        book_item.setData(tags, QtCore.Qt.UserRole + 4)
        book_item.setToolTip(tooltip_string)

        book_hash = book_item.data(QtCore.Qt.UserRole + 6)
        database_dict = {
            'Title': title,
            'Author': author,
            'Year': year,
            'Tags': tags}

        if self.cover_for_database:
            database_dict['CoverImage'] = self.cover_for_database
            self.parent.cover_loader(
                book_item, self.cover_for_database)

        self.parent.lib_ref.update_proxymodels()
        self.hide()

        database.DatabaseFunctions(self.database_path).modify_metadata(
            database_dict, book_hash)
Ejemplo n.º 19
0
 def run(self):
     database.DatabaseFunctions(self.database_path).delete_from_database(
         'Hash', self.hash_list)
Ejemplo n.º 20
0
    def generate_model(self, mode, parsed_books=None, is_database_ready=True):
        if mode == 'build':
            self.libraryModel = QtGui.QStandardItemModel()
            self.libraryModel.setColumnCount(10)

            books = database.DatabaseFunctions(
                self.main_window.database_path).fetch_data(
                    ('Title', 'Author', 'Year', 'DateAdded', 'Path',
                     'Position', 'ISBN', 'Tags', 'Hash', 'LastAccessed',
                     'Addition'), 'books', {'Title': ''}, 'LIKE')

            if not books:
                print('Database returned nothing')
                return

        elif mode == 'addition':
            # Assumes self.libraryModel already exists and may be extended
            # Because any additional books have already been added to the
            # database using background threads

            books = []
            current_qdatetime = QtCore.QDateTime().currentDateTime()
            for i in parsed_books.items():
                _tags = i[1]['tags']
                if _tags:
                    _tags = ', '.join([j for j in _tags if j])

                books.append([
                    i[1]['title'], i[1]['author'], i[1]['year'],
                    current_qdatetime, i[1]['path'], None, i[1]['isbn'], _tags,
                    i[0], None, i[1]['addition_mode']
                ])

        else:
            return

        for i in books:
            # The database query returns (or the extension data is)
            # an iterable with the following indices:
            title = i[0]
            author = i[1]
            year = i[2]
            path = i[4]
            addition_mode = i[10]

            last_accessed = i[9]
            if last_accessed and not isinstance(last_accessed,
                                                QtCore.QDateTime):
                last_accessed = pickle.loads(last_accessed)

            tags = i[7]
            if isinstance(tags,
                          list):  # When files are added for the first time
                if tags:
                    tags = ', '.join(str(this_tag) for this_tag in tags)
                else:
                    tags = None

            try:
                date_added = pickle.loads(i[3])
            except TypeError:  # Because of datetime.datetime.now() above
                date_added = i[3]

            position_perc = None
            position = i[5]
            if position:
                position = pickle.loads(position)
                if position['is_read']:
                    position_perc = 1
                else:
                    try:
                        position_perc = (position['current_block'] /
                                         position['total_blocks'])
                    except (KeyError, ZeroDivisionError):
                        try:
                            position_perc = (position['current_chapter'] /
                                             position['total_chapters'])
                        except KeyError:
                            position_perc = None

            try:
                file_exists = os.path.exists(path)
            except UnicodeEncodeError:
                print('Library: Unicode encoding error')

            all_metadata = {
                'title': title,
                'author': author,
                'year': year,
                'date_added': date_added,
                'path': path,
                'position': position,
                'isbn': i[6],
                'tags': tags,
                'hash': i[8],
                'last_accessed': last_accessed,
                'addition_mode': addition_mode,
                'file_exists': file_exists
            }

            author_string = self._translate('Library', 'Author')
            year_string = self._translate('Library', 'Year')
            tooltip_string = f'{title} \n{author_string}: {author} \n{year_string}: {str(year)}'

            # Additional data can be set using an incrementing
            # QtCore.Qt.UserRole
            # QtCore.Qt.DisplayRole is the same as item.setText()
            # The model is a single row and has no columns

            # No covers are set at this time
            # That is to be achieved by way of the culling function
            img_pixmap = QtGui.QPixmap()
            img_pixmap.load(':/images/blank.png')
            img_pixmap = img_pixmap.scaled(420, 600,
                                           QtCore.Qt.IgnoreAspectRatio)
            item = QtGui.QStandardItem()
            item.setToolTip(tooltip_string)

            # Just keep the following order. It's way too much trouble otherwise
            item.setData(title, QtCore.Qt.UserRole)
            item.setData(author, QtCore.Qt.UserRole + 1)
            item.setData(year, QtCore.Qt.UserRole + 2)
            item.setData(all_metadata, QtCore.Qt.UserRole + 3)
            item.setData(tags, QtCore.Qt.UserRole + 4)
            item.setData(file_exists, QtCore.Qt.UserRole + 5)
            item.setData(i[8], QtCore.Qt.UserRole + 6)  # File hash
            item.setData(position_perc, QtCore.Qt.UserRole + 7)
            item.setData(False, QtCore.Qt.UserRole +
                         8)  # Is the cover being displayed?
            item.setData(date_added, QtCore.Qt.UserRole + 9)
            item.setData(last_accessed, QtCore.Qt.UserRole + 12)
            item.setIcon(QtGui.QIcon(img_pixmap))

            self.libraryModel.appendRow(item)

        # The is_database_ready boolean is required when a new thread sends
        # books here for model generation.
        if not self.main_window.settings[
                'perform_culling'] and is_database_ready:
            self.main_window.cover_functions.load_all_covers()
Ejemplo n.º 21
0
    def generate_library_context_menu(self, position):
        index = self.sender().indexAt(position)
        if not index.isValid():
            return

        # It's worth remembering that these are indexes of the libraryModel
        # and NOT of the proxy models
        selected_indexes = self.get_selection(self.sender())

        context_menu = QtWidgets.QMenu()

        openAction = context_menu.addAction(
            self.QImageFactory.get_image('view-readermode'),
            self._translate('Main_UI', 'Start reading'))

        editAction = None
        if len(selected_indexes) == 1:
            editAction = context_menu.addAction(
                self.QImageFactory.get_image('edit-rename'),
                self._translate('Main_UI', 'Edit'))

        deleteAction = context_menu.addAction(
            self.QImageFactory.get_image('trash-empty'),
            self._translate('Main_UI', 'Delete'))
        readAction = context_menu.addAction(
            QtGui.QIcon(':/images/checkmark.svg'),
            self._translate('Main_UI', 'Mark read'))
        unreadAction = context_menu.addAction(
            QtGui.QIcon(':/images/xmark.svg'),
            self._translate('Main_UI', 'Mark unread'))

        action = context_menu.exec_(self.sender().mapToGlobal(position))

        if action == openAction:
            books_to_open = {}
            for i in selected_indexes:
                metadata = self.lib_ref.libraryModel.data(
                    i, QtCore.Qt.UserRole + 3)
                books_to_open[metadata['path']] = metadata['hash']

            self.open_files(books_to_open)

        if action == editAction:
            edit_book = selected_indexes[0]
            is_cover_loaded = self.lib_ref.libraryModel.data(
                edit_book, QtCore.Qt.UserRole + 8)

            # Loads a cover in case culling is enabled and the table view is visible
            if not is_cover_loaded:
                book_hash = self.lib_ref.libraryModel.data(
                    edit_book, QtCore.Qt.UserRole + 6)
                book_item = self.lib_ref.libraryModel.item(edit_book.row())
                book_cover = database.DatabaseFunctions(
                    self.database_path).fetch_covers_only([book_hash])[0][1]
                self.cover_functions.cover_loader(book_item, book_cover)

            cover = self.lib_ref.libraryModel.item(edit_book.row()).icon()
            title = self.lib_ref.libraryModel.data(edit_book,
                                                   QtCore.Qt.UserRole)
            author = self.lib_ref.libraryModel.data(edit_book,
                                                    QtCore.Qt.UserRole + 1)
            year = str(
                self.lib_ref.libraryModel.data(edit_book, QtCore.Qt.UserRole +
                                               2))  # Text cannot be int
            tags = self.lib_ref.libraryModel.data(edit_book,
                                                  QtCore.Qt.UserRole + 4)

            self.metadataDialog.load_book(cover, title, author, year, tags,
                                          edit_book)
            self.metadataDialog.show()

        if action == deleteAction:
            self.delete_books(selected_indexes)

        if action == readAction or action == unreadAction:
            for i in selected_indexes:
                metadata = self.lib_ref.libraryModel.data(
                    i, QtCore.Qt.UserRole + 3)
                book_hash = self.lib_ref.libraryModel.data(
                    i, QtCore.Qt.UserRole + 6)
                position = metadata['position']

                if position:
                    if action == readAction:
                        position['is_read'] = True
                        position['scroll_value'] = 1
                    elif action == unreadAction:
                        position['is_read'] = False
                        position['current_chapter'] = 1
                        position['scroll_value'] = 0
                else:
                    position = {}
                    if action == readAction:
                        position['is_read'] = True

                metadata['position'] = position

                position_perc = None
                last_accessed_time = None
                if action == readAction:
                    last_accessed_time = QtCore.QDateTime().currentDateTime()
                    position_perc = 1

                self.lib_ref.libraryModel.setData(i, metadata,
                                                  QtCore.Qt.UserRole + 3)
                self.lib_ref.libraryModel.setData(i, position_perc,
                                                  QtCore.Qt.UserRole + 7)
                self.lib_ref.libraryModel.setData(i, last_accessed_time,
                                                  QtCore.Qt.UserRole + 12)
                self.lib_ref.update_proxymodels()

                database_dict = {
                    'Position': position,
                    'LastAccessed': last_accessed_time
                }

                database.DatabaseFunctions(self.database_path).modify_metadata(
                    database_dict, book_hash)
Ejemplo n.º 22
0
 def database_care(self):
     database.DatabaseFunctions(self.database_path).vacuum_database()
     QtWidgets.qApp.exit()
Ejemplo n.º 23
0
    def generate_tree(self):
        # Fetch all directories in the database
        paths = database.DatabaseFunctions(
            self.database_path).fetch_data(
                ('Path', 'Name', 'Tags', 'CheckState'),
                'directories',
                {'Path': ''},
                'LIKE')

        self.parent.generate_library_filter_menu(paths)
        directory_data = {}
        if not paths:
            print('Database: No paths for settings...')
        else:
            # Convert to the dictionary format that is
            # to be fed into the QFileSystemModel
            for i in paths:
                directory_data[i[0]] = {
                    'name': i[1],
                    'tags': i[2],
                    'check_state': i[3]}

        self.filesystem_model = MostExcellentFileSystemModel(directory_data)
        self.filesystem_model.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Dirs)
        self.treeView.setModel(self.filesystem_model)

        # TODO
        # This here might break on them pestilent non unixy OSes
        # Check and see

        root_directory = QtCore.QDir().rootPath()
        self.treeView.setRootIndex(
            self.filesystem_model.setRootPath(root_directory))

        # Set the treeView and QFileSystemModel to its desired state
        selected_paths = [
            i for i in directory_data if directory_data[i]['check_state'] == QtCore.Qt.Checked]
        expand_paths = set()
        for i in selected_paths:

            # Recursively grind down parent paths for expansion
            this_path = i
            while True:
                parent_path = os.path.dirname(this_path)
                if parent_path == this_path:
                    break
                expand_paths.add(parent_path)
                this_path = parent_path

        # Expand all the parent paths derived from the selected path
        if root_directory in expand_paths:
            expand_paths.remove(root_directory)

        for i in expand_paths:
            this_index = self.filesystem_model.index(i)
            self.treeView.expand(this_index)

        header_sizes = self.parent.settings['settings_dialog_headers']
        if header_sizes:
            for count, i in enumerate((0, 4)):
                self.treeView.setColumnWidth(i, int(header_sizes[count]))

        # TODO
        # Set a QSortFilterProxy model on top of the existing QFileSystem model
        # self.filesystem_proxy_model = FileSystemProxyModel()
        # self.filesystem_proxy_model.setSourceModel(self.filesystem_model)
        # self.treeView.setModel(self.filesystem_proxy_model)

        for i in range(1, 4):
            self.treeView.hideColumn(i)