Exemple #1
0
    def __init__(self):
        super().__init__()

        self.setWindowTitle(WINDOW_TITLE)

        self.tree_games = QTreeWidget()

        self.line_edit_url = QLineEdit(DEFAULT_URL)
        self.button_refresh_by_url = QPushButton('&Refresh')
        self.button_refresh_by_url.clicked.connect(self.refresh_by_url)

        self.dock_widget_settings = QDockWidget('Settings')
        self.dock_widget_settings.setObjectName(self.dock_widget_settings.windowTitle())
        layout = QFormLayout()
        self.TEST_USING_FILE_GAMES = QCheckBox()
        self.PARSE_GAME_NAME_ON_SEQUENCE = QCheckBox()
        self.SORT_GAME = QCheckBox()
        self.SORT_REVERSE = QCheckBox()
        label_SORT_REVERSE = QLabel('SORT_REVERSE')
        self.SORT_GAME.toggled.connect(self.SORT_REVERSE.setVisible)
        self.SORT_GAME.toggled.connect(label_SORT_REVERSE.setVisible)
        self.DONT_SHOW_NUMBER_1_ON_GAME = QCheckBox()

        self.TEST_USING_FILE_GAMES.setChecked(True)
        self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
        self.SORT_GAME.setChecked(False)
        self.SORT_REVERSE.setChecked(False)
        self.DONT_SHOW_NUMBER_1_ON_GAME.setChecked(False)

        self.SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())
        label_SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())

        layout.addRow("TEST_USING_FILE_GAMES", self.TEST_USING_FILE_GAMES)
        layout.addRow("PARSE_GAME_NAME_ON_SEQUENCE", self.PARSE_GAME_NAME_ON_SEQUENCE)
        layout.addRow("SORT_GAME", self.SORT_GAME)
        layout.addRow(label_SORT_REVERSE, self.SORT_REVERSE)
        layout.addRow("DONT_SHOW_NUMBER_1_ON_GAME", self.DONT_SHOW_NUMBER_1_ON_GAME)

        # TODO: может в checkbox'ах показывать количество игр данных категорий
        self.check_FINISHED_GAME = QCheckBox(Parser.CategoryEnum.FINISHED_GAME.name)
        self.check_NOT_FINISHED_GAME = QCheckBox(Parser.CategoryEnum.NOT_FINISHED_GAME.name)
        self.check_FINISHED_WATCHED = QCheckBox(Parser.CategoryEnum.FINISHED_WATCHED.name)
        self.check_NOT_FINISHED_WATCHED = QCheckBox(Parser.CategoryEnum.NOT_FINISHED_WATCHED.name)
        self.check_OTHER = QCheckBox(Parser.CategoryEnum.OTHER.name)

        self.check_FINISHED_GAME.setChecked(True)
        self.check_NOT_FINISHED_GAME.setChecked(True)
        self.check_FINISHED_WATCHED.setChecked(True)
        self.check_NOT_FINISHED_WATCHED.setChecked(True)
        self.check_OTHER.setChecked(True)

        show_only_layout = QVBoxLayout()
        show_only_layout.addWidget(self.check_FINISHED_GAME)
        show_only_layout.addWidget(self.check_NOT_FINISHED_GAME)
        show_only_layout.addWidget(self.check_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_NOT_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_OTHER)

        show_only_group = QGroupBox('Show categories:')
        show_only_group.setLayout(show_only_layout)
        # show_only_group.setCheckable(True)
        # show_only_group.setChecked(True)
        # show_only_group.toggled.connect(lambda x:
        #                                 [i.setChecked(x)
        #                                  for i in show_only_group.findChildren(QCheckBox)])

        layout.addRow(show_only_group)

        widget = QWidget()
        widget.setLayout(layout)

        self.dock_widget_settings.setWidget(widget)
        self.dock_widget_settings.hide()
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget_settings)

        general_tool_bar = self.addToolBar('General')
        general_tool_bar.setObjectName(general_tool_bar.windowTitle())
        general_tool_bar.addAction(self.dock_widget_settings.toggleViewAction())

        # tool_bar_gist_url = self.addToolBar('Gist Url')
        # layout = QHBoxLayout()
        # layout.addWidget(self.line_edit_url)
        # layout.addWidget(self.button_refresh_by_url)
        # widget = QWidget()
        # widget.setLayout(layout)
        # tool_bar_gist_url.addWidget(widget)
        #
        # tool_bar_filter = self.addToolBar('Filter')
        # layout = QHBoxLayout()
        # self.line_edit_filter = QLineEdit()
        # self.line_edit_filter.setToolTip('Wildcard Filter')
        # self.line_edit_filter.textEdited.connect(self.load_tree)
        #
        # layout.addWidget(QLabel('Filter:'))
        # layout.addWidget(self.line_edit_filter)
        # widget = QWidget()
        # widget.setLayout(layout)
        # tool_bar_filter.addWidget(widget)

        layout = QHBoxLayout()
        layout.addWidget(self.line_edit_url)
        layout.addWidget(self.button_refresh_by_url)

        self.line_edit_filter = QLineEdit()
        self.line_edit_filter.setToolTip('Wildcard Filter')
        self.line_edit_filter.textEdited.connect(self.load_tree)

        filter_layout = QHBoxLayout()
        filter_layout.addWidget(QLabel('Filter:'))
        filter_layout.addWidget(self.line_edit_filter)

        main_layout = QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(filter_layout)
        main_layout.addWidget(self.tree_games)

        central_widget = QWidget()
        central_widget.setLayout(main_layout)

        self.setCentralWidget(central_widget)

        # # TODO: временно
        # # self.progress_bar = QProgressBar()
        # # self.statusBar().addWidget(self.progress_bar)
        # global PROGRESS_BAR
        # PROGRESS_BAR = QProgressBar()
        # self.statusBar().addWidget(PROGRESS_BAR)

        self.parser = Parser()
        self.parse_content = None

        self.update_header_tree_and_window_title()

        self.read_settings()
Exemple #2
0
    def __init__(self):
        super().__init__()

        self.setWindowTitle(WINDOW_TITLE)

        self.tree_games = QTreeWidget()

        self.line_edit_url = QLineEdit(DEFAULT_URL)
        self.button_refresh_by_url = QPushButton('&Refresh')
        self.button_refresh_by_url.clicked.connect(self.refresh_by_url)

        self.dock_widget_settings = QDockWidget('Settings')
        self.dock_widget_settings.setObjectName(
            self.dock_widget_settings.windowTitle())
        layout = QFormLayout()
        self.TEST_USING_FILE_GAMES = QCheckBox()
        self.PARSE_GAME_NAME_ON_SEQUENCE = QCheckBox()
        self.SORT_GAME = QCheckBox()
        self.SORT_REVERSE = QCheckBox()
        label_SORT_REVERSE = QLabel('SORT_REVERSE')
        self.SORT_GAME.toggled.connect(self.SORT_REVERSE.setVisible)
        self.SORT_GAME.toggled.connect(label_SORT_REVERSE.setVisible)

        self.TEST_USING_FILE_GAMES.setChecked(True)
        self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
        self.SORT_GAME.setChecked(False)
        self.SORT_REVERSE.setChecked(False)

        self.SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())
        label_SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())

        layout.addRow("TEST_USING_FILE_GAMES", self.TEST_USING_FILE_GAMES)
        layout.addRow("PARSE_GAME_NAME_ON_SEQUENCE",
                      self.PARSE_GAME_NAME_ON_SEQUENCE)
        layout.addRow("SORT_GAME", self.SORT_GAME)
        layout.addRow(label_SORT_REVERSE, self.SORT_REVERSE)

        # TODO: может в checkbox'ах показывать количество игр данных категорий
        self.check_FINISHED_GAME = QCheckBox(
            Parser.CategoryEnum.FINISHED_GAME.name)
        self.check_NOT_FINISHED_GAME = QCheckBox(
            Parser.CategoryEnum.NOT_FINISHED_GAME.name)
        self.check_FINISHED_WATCHED = QCheckBox(
            Parser.CategoryEnum.FINISHED_WATCHED.name)
        self.check_NOT_FINISHED_WATCHED = QCheckBox(
            Parser.CategoryEnum.NOT_FINISHED_WATCHED.name)
        self.check_OTHER = QCheckBox(Parser.CategoryEnum.OTHER.name)

        self.check_FINISHED_GAME.setChecked(True)
        self.check_NOT_FINISHED_GAME.setChecked(True)
        self.check_FINISHED_WATCHED.setChecked(True)
        self.check_NOT_FINISHED_WATCHED.setChecked(True)
        self.check_OTHER.setChecked(True)

        show_only_layout = QVBoxLayout()
        show_only_layout.addWidget(self.check_FINISHED_GAME)
        show_only_layout.addWidget(self.check_NOT_FINISHED_GAME)
        show_only_layout.addWidget(self.check_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_NOT_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_OTHER)

        show_only_group = QGroupBox('Show categories:')
        show_only_group.setLayout(show_only_layout)
        layout.addRow(show_only_group)

        widget = QWidget()
        widget.setLayout(layout)

        self.dock_widget_settings.setWidget(widget)
        self.dock_widget_settings.hide()
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget_settings)

        general_tool_bar = self.addToolBar('General')
        general_tool_bar.setObjectName(general_tool_bar.windowTitle())
        general_tool_bar.addAction(
            self.dock_widget_settings.toggleViewAction())

        layout = QHBoxLayout()
        layout.addWidget(self.line_edit_url)
        layout.addWidget(self.button_refresh_by_url)

        self.line_edit_filter = QLineEdit()
        self.line_edit_filter.setToolTip('Wildcard Filter')
        self.line_edit_filter.textEdited.connect(self.load_tree)

        filter_layout = QHBoxLayout()
        filter_layout.addWidget(QLabel('Filter:'))
        filter_layout.addWidget(self.line_edit_filter)

        main_layout = QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(filter_layout)
        main_layout.addWidget(self.tree_games)

        central_widget = QWidget()
        central_widget.setLayout(main_layout)

        self.setCentralWidget(central_widget)

        self.parser = Parser()
        self.parse_content = None

        self.update_header_tree_and_window_title()

        self.read_settings()
Exemple #3
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle(WINDOW_TITLE)

        self.tree_games = QTreeWidget()

        self.line_edit_url = QLineEdit(DEFAULT_URL)
        self.button_refresh_by_url = QPushButton('&Refresh')
        self.button_refresh_by_url.clicked.connect(self.refresh_by_url)

        self.dock_widget_settings = QDockWidget('Settings')
        self.dock_widget_settings.setObjectName(self.dock_widget_settings.windowTitle())
        layout = QFormLayout()
        self.TEST_USING_FILE_GAMES = QCheckBox()
        self.PARSE_GAME_NAME_ON_SEQUENCE = QCheckBox()
        self.SORT_GAME = QCheckBox()
        self.SORT_REVERSE = QCheckBox()
        label_SORT_REVERSE = QLabel('SORT_REVERSE')
        self.SORT_GAME.toggled.connect(self.SORT_REVERSE.setVisible)
        self.SORT_GAME.toggled.connect(label_SORT_REVERSE.setVisible)
        self.DONT_SHOW_NUMBER_1_ON_GAME = QCheckBox()

        self.TEST_USING_FILE_GAMES.setChecked(True)
        self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
        self.SORT_GAME.setChecked(False)
        self.SORT_REVERSE.setChecked(False)
        self.DONT_SHOW_NUMBER_1_ON_GAME.setChecked(False)

        self.SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())
        label_SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())

        layout.addRow("TEST_USING_FILE_GAMES", self.TEST_USING_FILE_GAMES)
        layout.addRow("PARSE_GAME_NAME_ON_SEQUENCE", self.PARSE_GAME_NAME_ON_SEQUENCE)
        layout.addRow("SORT_GAME", self.SORT_GAME)
        layout.addRow(label_SORT_REVERSE, self.SORT_REVERSE)
        layout.addRow("DONT_SHOW_NUMBER_1_ON_GAME", self.DONT_SHOW_NUMBER_1_ON_GAME)

        # TODO: может в checkbox'ах показывать количество игр данных категорий
        self.check_FINISHED_GAME = QCheckBox(Parser.CategoryEnum.FINISHED_GAME.name)
        self.check_NOT_FINISHED_GAME = QCheckBox(Parser.CategoryEnum.NOT_FINISHED_GAME.name)
        self.check_FINISHED_WATCHED = QCheckBox(Parser.CategoryEnum.FINISHED_WATCHED.name)
        self.check_NOT_FINISHED_WATCHED = QCheckBox(Parser.CategoryEnum.NOT_FINISHED_WATCHED.name)
        self.check_OTHER = QCheckBox(Parser.CategoryEnum.OTHER.name)

        self.check_FINISHED_GAME.setChecked(True)
        self.check_NOT_FINISHED_GAME.setChecked(True)
        self.check_FINISHED_WATCHED.setChecked(True)
        self.check_NOT_FINISHED_WATCHED.setChecked(True)
        self.check_OTHER.setChecked(True)

        show_only_layout = QVBoxLayout()
        show_only_layout.addWidget(self.check_FINISHED_GAME)
        show_only_layout.addWidget(self.check_NOT_FINISHED_GAME)
        show_only_layout.addWidget(self.check_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_NOT_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_OTHER)

        show_only_group = QGroupBox('Show categories:')
        show_only_group.setLayout(show_only_layout)
        # show_only_group.setCheckable(True)
        # show_only_group.setChecked(True)
        # show_only_group.toggled.connect(lambda x:
        #                                 [i.setChecked(x)
        #                                  for i in show_only_group.findChildren(QCheckBox)])

        layout.addRow(show_only_group)

        widget = QWidget()
        widget.setLayout(layout)

        self.dock_widget_settings.setWidget(widget)
        self.dock_widget_settings.hide()
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget_settings)

        general_tool_bar = self.addToolBar('General')
        general_tool_bar.setObjectName(general_tool_bar.windowTitle())
        general_tool_bar.addAction(self.dock_widget_settings.toggleViewAction())

        # tool_bar_gist_url = self.addToolBar('Gist Url')
        # layout = QHBoxLayout()
        # layout.addWidget(self.line_edit_url)
        # layout.addWidget(self.button_refresh_by_url)
        # widget = QWidget()
        # widget.setLayout(layout)
        # tool_bar_gist_url.addWidget(widget)
        #
        # tool_bar_filter = self.addToolBar('Filter')
        # layout = QHBoxLayout()
        # self.line_edit_filter = QLineEdit()
        # self.line_edit_filter.setToolTip('Wildcard Filter')
        # self.line_edit_filter.textEdited.connect(self.load_tree)
        #
        # layout.addWidget(QLabel('Filter:'))
        # layout.addWidget(self.line_edit_filter)
        # widget = QWidget()
        # widget.setLayout(layout)
        # tool_bar_filter.addWidget(widget)

        layout = QHBoxLayout()
        layout.addWidget(self.line_edit_url)
        layout.addWidget(self.button_refresh_by_url)

        self.line_edit_filter = QLineEdit()
        self.line_edit_filter.setToolTip('Wildcard Filter')
        self.line_edit_filter.textEdited.connect(self.load_tree)

        filter_layout = QHBoxLayout()
        filter_layout.addWidget(QLabel('Filter:'))
        filter_layout.addWidget(self.line_edit_filter)

        main_layout = QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(filter_layout)
        main_layout.addWidget(self.tree_games)

        central_widget = QWidget()
        central_widget.setLayout(main_layout)

        self.setCentralWidget(central_widget)

        # # TODO: временно
        # # self.progress_bar = QProgressBar()
        # # self.statusBar().addWidget(self.progress_bar)
        # global PROGRESS_BAR
        # PROGRESS_BAR = QProgressBar()
        # self.statusBar().addWidget(PROGRESS_BAR)

        self.parser = Parser()
        self.parse_content = None

        self.update_header_tree_and_window_title()

        self.read_settings()

    # TODO: выполнить функцию в другом потоке
    # def download(self, url):
    #     logger.debug('Download {} start.'.format(url))
    #     local_filename, headers = urlretrieve(url, reporthook=reporthook)
    #     logger.debug('Download finish:\nlocal_filename: {}\n\nHeaders:\n{}'.format(local_filename, headers))
    #
    #     logger.debug('Read from file start: ' + local_filename)
    #     with open(local_filename, encoding='utf-8') as f:
    #         content_file = f.read()
    #
    #     logger.debug('Read from file finish.')
    #
    #     logger.debug('Load tree start.')
    #     self.load_tree(content_file)
    #     logger.debug('Load tree finish.')
    #
    #     self.tree_games.expandAll()

    def refresh_by_url(self):
        # TODO: выполнить функцию в другом потоке
        # TODO: после окончания рабоыт потока генерировать сигнал
        # и в нем вернуть путь к файлу
        # import threading
        #
        # thread = threading.Thread(target=self.download, args=(self.line_edit_url.text(),))
        # thread.start()
        # thread.join()

        logger.debug('TEST_USING_FILE_GAMES = {}.'.format(self.TEST_USING_FILE_GAMES.isChecked()))

        if self.TEST_USING_FILE_GAMES.isChecked():
            # TODO: для тестирования интерфейса
            test_file_name = 'gistfile1.txt'

            logger.debug('Open and read {} start.'.format(test_file_name))
            with open(test_file_name, 'r', encoding='utf8') as f:
                content_file = f.read()
            logger.debug('Finish open and read. Content file length = {}.'.format(len(content_file)))
        else:
            # PROGRESS_BAR.show()
            # PROGRESS_BAR.setValue(-1)

            url = self.line_edit_url.text()

            # Теперь нужно получить url файла с последней ревизией
            logger.debug('Get url file last revision start.')
            t = time.clock()

            with urlopen(url) as f:
                context = f.read().decode()

                parser = etree.HTMLParser()
                tree = etree.parse(StringIO(context), parser)

                # Ищем первый файл с кнопкой Raw
                rel_url = tree.xpath('//*[@class="btn btn-sm "]/@href')[0]
                logger.debug('Relative url = {}.'.format(rel_url))

                url = urljoin(url, str(rel_url))
                logger.debug('Full url = {}.'.format(url))

            logger.debug('Get url file last revision finish. Elapsed time: {:.3f} sec.'.format(time.clock() - t))

            logger.debug('Download {} start.'.format(url))
            t = time.clock()
            local_filename, headers = urlretrieve(url, reporthook=reporthook)
            logger.debug('Download finish. Elapsed time: {:.3f} sec.'.format(time.clock() - t))

            # # Через 3 секунды прячем прогресс бар
            # QTimer.singleShot(5000, PROGRESS_BAR.hide)

            logger.debug('Read from file start: ' + local_filename)
            with open(local_filename, encoding='utf-8') as f:
                content_file = f.read()

        logger.debug('Read from file finish.')

        self.parse_content = content_file
        self.load_tree()

    def load_tree(self):
        logger.debug('Start build tree.')

        show_only_categories = list()
        if self.check_FINISHED_GAME.isChecked():
            show_only_categories.append(Parser.CategoryEnum.FINISHED_GAME)

        if self.check_NOT_FINISHED_GAME.isChecked():
            show_only_categories.append(Parser.CategoryEnum.NOT_FINISHED_GAME)

        if self.check_FINISHED_WATCHED.isChecked():
            show_only_categories.append(Parser.CategoryEnum.FINISHED_WATCHED)

        if self.check_NOT_FINISHED_WATCHED.isChecked():
            show_only_categories.append(Parser.CategoryEnum.NOT_FINISHED_WATCHED)

        if self.check_OTHER.isChecked():
            show_only_categories.append(Parser.CategoryEnum.OTHER)

        self.parser.parse(self.parse_content,
                          self.line_edit_filter.text(),
                          self.PARSE_GAME_NAME_ON_SEQUENCE.isChecked(),
                          self.SORT_GAME.isChecked(),
                          self.SORT_REVERSE.isChecked(),
                          self.DONT_SHOW_NUMBER_1_ON_GAME.isChecked(),
                          show_only_categories)
        self.tree_games.clear()

        for k, v in self.parser.sorted_platforms:
            platform_item = add_tree_widget_item_platform(v)
            self.tree_games.addTopLevelItem(platform_item)

            for kind in SEQ_ADDED_CATEGORIES:
                if kind not in v.categories:
                    continue

                category = v.categories[kind]
                category_item = add_tree_widget_item_category(category)
                platform_item.addChild(category_item)

                for game in category:
                    game_item = add_tree_widget_item_game(game)
                    category_item.addChild(game_item)

        if self.parser.other.count_games > 0:
            other_item = QTreeWidgetItem(['{} ({}):'.format(OTHER_GAME_TITLE, self.parser.other.count_games)])
            self.tree_games.addTopLevelItem(other_item)

            for k, v in self.parser.other.platforms.items():
                platform_item = add_tree_widget_item_platform(v)
                other_item.addChild(platform_item)

                for category in v.categories.values():
                    for game in category:
                        game_item = add_tree_widget_item_game(game)
                        platform_item.addChild(game_item)

        self.tree_games.expandAll()
        self.update_header_tree_and_window_title()

    def update_header_tree_and_window_title(self):
        # Указываем в заголовке общее количество игр и при фильтр, количество игр, оставшихся после фильтрации
        self.tree_games.setHeaderLabel('{} ({})'.format(TREE_HEADER, self.parser.count_games))

        # Обновление заголовка окна
        self.setWindowTitle('{}. Platforms: {}. Games: {}'.format(WINDOW_TITLE,
                                                                  self.parser.count_platforms,
                                                                  self.parser.count_games))

    def read_settings(self):
        logger.debug('Start read_settings. CONFIG_FILE={}.'.format(CONFIG_FILE))

        try:
            with open(CONFIG_FILE, encoding='utf-8') as f:
                settings = json.load(f)

                self.TEST_USING_FILE_GAMES.setChecked(settings['TEST_USING_FILE_GAMES'])
                self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(settings['PARSE_GAME_NAME_ON_SEQUENCE'])
                self.SORT_GAME.setChecked(settings['SORT_GAME'])
                self.SORT_REVERSE.setChecked(settings['SORT_REVERSE'])
                self.DONT_SHOW_NUMBER_1_ON_GAME.setChecked(settings['DONT_SHOW_NUMBER_1_ON_GAME'])

                self.check_FINISHED_GAME.setChecked(settings['check_FINISHED_GAME'])
                self.check_NOT_FINISHED_GAME.setChecked(settings['check_NOT_FINISHED_GAME'])
                self.check_FINISHED_WATCHED.setChecked(settings['check_FINISHED_WATCHED'])
                self.check_NOT_FINISHED_WATCHED.setChecked(settings['check_NOT_FINISHED_WATCHED'])
                self.check_OTHER.setChecked(settings['check_OTHER'])

                state = QByteArray.fromBase64(settings['MainWindow_State'])
                self.restoreState(state)

                geometry = QByteArray.fromBase64(settings['MainWindow_Geometry'])
                self.restoreGeometry(geometry)

        except Exception as e:
            logger.warning(e)
            logger.debug("Заполняю значения по умолчанию.")

            self.TEST_USING_FILE_GAMES.setChecked(True)
            self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
            self.SORT_GAME.setChecked(False)
            self.SORT_REVERSE.setChecked(False)
            self.DONT_SHOW_NUMBER_1_ON_GAME.setChecked(False)

            self.check_FINISHED_GAME.setChecked(True)
            self.check_NOT_FINISHED_GAME.setChecked(True)
            self.check_FINISHED_WATCHED.setChecked(True)
            self.check_NOT_FINISHED_WATCHED.setChecked(True)
            self.check_OTHER.setChecked(True)

        logger.debug('Finish read_settings.')

    def write_settings(self):
        logger.debug('Start write_settings. CONFIG_FILE={}.'.format(CONFIG_FILE))
        logger.debug('Build dict.')

        settings = {
            'TEST_USING_FILE_GAMES': self.TEST_USING_FILE_GAMES.isChecked(),
            'PARSE_GAME_NAME_ON_SEQUENCE': self.PARSE_GAME_NAME_ON_SEQUENCE.isChecked(),
            'SORT_GAME': self.SORT_GAME.isChecked(),
            'SORT_REVERSE': self.SORT_REVERSE.isChecked(),
            'DONT_SHOW_NUMBER_1_ON_GAME': self.DONT_SHOW_NUMBER_1_ON_GAME.isChecked(),

            'check_FINISHED_GAME': self.check_FINISHED_GAME.isChecked(),
            'check_NOT_FINISHED_GAME': self.check_NOT_FINISHED_GAME.isChecked(),
            'check_FINISHED_WATCHED': self.check_FINISHED_WATCHED.isChecked(),
            'check_NOT_FINISHED_WATCHED': self.check_NOT_FINISHED_WATCHED.isChecked(),
            'check_OTHER': self.check_OTHER.isChecked(),

            'MainWindow_State': str(self.saveState().toBase64()),
            'MainWindow_Geometry': str(self.saveGeometry().toBase64()),
        }

        logger.debug('Write config.')

        with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
            str_json_obj = json.dumps(settings, sort_keys=True, indent=4)
            f.write(str_json_obj)

        logger.debug('Finish write_settings.')

    def closeEvent(self, event):
        self.write_settings()
        quit()
Exemple #4
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle(WINDOW_TITLE)

        self.tree_games = QTreeWidget()

        self.line_edit_url = QLineEdit(DEFAULT_URL)
        self.button_refresh_by_url = QPushButton('&Refresh')
        self.button_refresh_by_url.clicked.connect(self.refresh_by_url)

        self.dock_widget_settings = QDockWidget('Settings')
        self.dock_widget_settings.setObjectName(
            self.dock_widget_settings.windowTitle())
        layout = QFormLayout()
        self.TEST_USING_FILE_GAMES = QCheckBox()
        self.PARSE_GAME_NAME_ON_SEQUENCE = QCheckBox()
        self.SORT_GAME = QCheckBox()
        self.SORT_REVERSE = QCheckBox()
        label_SORT_REVERSE = QLabel('SORT_REVERSE')
        self.SORT_GAME.toggled.connect(self.SORT_REVERSE.setVisible)
        self.SORT_GAME.toggled.connect(label_SORT_REVERSE.setVisible)

        self.TEST_USING_FILE_GAMES.setChecked(True)
        self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
        self.SORT_GAME.setChecked(False)
        self.SORT_REVERSE.setChecked(False)

        self.SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())
        label_SORT_REVERSE.setVisible(self.SORT_GAME.isChecked())

        layout.addRow("TEST_USING_FILE_GAMES", self.TEST_USING_FILE_GAMES)
        layout.addRow("PARSE_GAME_NAME_ON_SEQUENCE",
                      self.PARSE_GAME_NAME_ON_SEQUENCE)
        layout.addRow("SORT_GAME", self.SORT_GAME)
        layout.addRow(label_SORT_REVERSE, self.SORT_REVERSE)

        # TODO: может в checkbox'ах показывать количество игр данных категорий
        self.check_FINISHED_GAME = QCheckBox(
            Parser.CategoryEnum.FINISHED_GAME.name)
        self.check_NOT_FINISHED_GAME = QCheckBox(
            Parser.CategoryEnum.NOT_FINISHED_GAME.name)
        self.check_FINISHED_WATCHED = QCheckBox(
            Parser.CategoryEnum.FINISHED_WATCHED.name)
        self.check_NOT_FINISHED_WATCHED = QCheckBox(
            Parser.CategoryEnum.NOT_FINISHED_WATCHED.name)
        self.check_OTHER = QCheckBox(Parser.CategoryEnum.OTHER.name)

        self.check_FINISHED_GAME.setChecked(True)
        self.check_NOT_FINISHED_GAME.setChecked(True)
        self.check_FINISHED_WATCHED.setChecked(True)
        self.check_NOT_FINISHED_WATCHED.setChecked(True)
        self.check_OTHER.setChecked(True)

        show_only_layout = QVBoxLayout()
        show_only_layout.addWidget(self.check_FINISHED_GAME)
        show_only_layout.addWidget(self.check_NOT_FINISHED_GAME)
        show_only_layout.addWidget(self.check_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_NOT_FINISHED_WATCHED)
        show_only_layout.addWidget(self.check_OTHER)

        show_only_group = QGroupBox('Show categories:')
        show_only_group.setLayout(show_only_layout)
        layout.addRow(show_only_group)

        widget = QWidget()
        widget.setLayout(layout)

        self.dock_widget_settings.setWidget(widget)
        self.dock_widget_settings.hide()
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget_settings)

        general_tool_bar = self.addToolBar('General')
        general_tool_bar.setObjectName(general_tool_bar.windowTitle())
        general_tool_bar.addAction(
            self.dock_widget_settings.toggleViewAction())

        layout = QHBoxLayout()
        layout.addWidget(self.line_edit_url)
        layout.addWidget(self.button_refresh_by_url)

        self.line_edit_filter = QLineEdit()
        self.line_edit_filter.setToolTip('Wildcard Filter')
        self.line_edit_filter.textEdited.connect(self.load_tree)

        filter_layout = QHBoxLayout()
        filter_layout.addWidget(QLabel('Filter:'))
        filter_layout.addWidget(self.line_edit_filter)

        main_layout = QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(filter_layout)
        main_layout.addWidget(self.tree_games)

        central_widget = QWidget()
        central_widget.setLayout(main_layout)

        self.setCentralWidget(central_widget)

        self.parser = Parser()
        self.parse_content = None

        self.update_header_tree_and_window_title()

        self.read_settings()

    def refresh_by_url(self):
        logger.debug('TEST_USING_FILE_GAMES = {}.'.format(
            self.TEST_USING_FILE_GAMES.isChecked()))

        if self.TEST_USING_FILE_GAMES.isChecked():
            # TODO: для тестирования интерфейса
            test_file_name = 'gistfile1.txt'

            logger.debug('Open and read {} start.'.format(test_file_name))
            with open(test_file_name, 'r', encoding='utf8') as f:
                content_file = f.read()
            logger.debug(
                'Finish open and read. Content file length = {}.'.format(
                    len(content_file)))
        else:
            url = self.line_edit_url.text()

            # Проверяем, что если прописан путь до файла на компе, то его открываем, иначе считаем ссылкой и качаем
            import os
            if os.path.exists(url):
                with open(url, encoding='utf-8') as f:
                    content_file = f.read()

            else:
                # Теперь нужно получить url файла с последней ревизией
                logger.debug('Get url file last revision start.')
                t = time.clock()

                try:
                    with urlopen(url) as f:
                        context = f.read().decode()

                        parser = etree.HTMLParser()
                        tree = etree.parse(StringIO(context), parser)

                        # Ищем первый файл с кнопкой Raw
                        rel_url = tree.xpath(
                            '//*[@class="btn btn-sm "]/@href')[0]
                        logger.debug('Relative url = {}.'.format(rel_url))

                        url = urljoin(url, str(rel_url))
                        logger.debug('Full url = {}.'.format(url))

                    logger.debug(
                        'Get url file last revision finish. Elapsed time: {:.3f} sec.'
                        .format(time.clock() - t))

                    with urlopen(url) as f:
                        content_file = f.read().decode()

                except Exception as e:
                    import traceback
                    text = ''.join(traceback.format_exc())

                    logger.error(text)
                    QMessageBox.critical(None, 'Error', text)

                    content_file = ""

        logger.debug('Read last content finish.')

        self.parse_content = content_file
        self.load_tree()

    def load_tree(self):
        logger.debug('Start build tree.')

        show_only_categories = list()
        if self.check_FINISHED_GAME.isChecked():
            show_only_categories.append(Parser.CategoryEnum.FINISHED_GAME)

        if self.check_NOT_FINISHED_GAME.isChecked():
            show_only_categories.append(Parser.CategoryEnum.NOT_FINISHED_GAME)

        if self.check_FINISHED_WATCHED.isChecked():
            show_only_categories.append(Parser.CategoryEnum.FINISHED_WATCHED)

        if self.check_NOT_FINISHED_WATCHED.isChecked():
            show_only_categories.append(
                Parser.CategoryEnum.NOT_FINISHED_WATCHED)

        if self.check_OTHER.isChecked():
            show_only_categories.append(Parser.CategoryEnum.OTHER)

        self.parser.parse(self.parse_content, self.line_edit_filter.text(),
                          self.PARSE_GAME_NAME_ON_SEQUENCE.isChecked(),
                          self.SORT_GAME.isChecked(),
                          self.SORT_REVERSE.isChecked(), show_only_categories)
        self.tree_games.clear()

        for k, v in self.parser.sorted_platforms:
            platform_item = add_tree_widget_item_platform(v)
            self.tree_games.addTopLevelItem(platform_item)

            for kind in SEQ_ADDED_CATEGORIES:
                if kind not in v.categories:
                    continue

                category = v.categories[kind]
                category_item = add_tree_widget_item_category(category)
                platform_item.addChild(category_item)

                for game in category:
                    game_item = add_tree_widget_item_game(game)
                    category_item.addChild(game_item)

        if self.parser.other.count_games > 0:
            other_item = QTreeWidgetItem([
                '{} ({}):'.format(OTHER_GAME_TITLE,
                                  self.parser.other.count_games)
            ])
            self.tree_games.addTopLevelItem(other_item)

            for k, v in self.parser.other.platforms.items():
                platform_item = add_tree_widget_item_platform(v)
                other_item.addChild(platform_item)

                for category in v.categories.values():
                    for game in category:
                        game_item = add_tree_widget_item_game(game)
                        platform_item.addChild(game_item)

        self.tree_games.expandAll()
        self.update_header_tree_and_window_title()

    def update_header_tree_and_window_title(self):
        # Указываем в заголовке общее количество игр и при фильтр, количество игр, оставшихся после фильтрации
        self.tree_games.setHeaderLabel('{} ({})'.format(
            TREE_HEADER, self.parser.count_games))

        # Обновление заголовка окна
        self.setWindowTitle('{}. Platforms: {}. Games: {}'.format(
            WINDOW_TITLE, self.parser.count_platforms,
            self.parser.count_games))

    def read_settings(self):
        logger.debug(
            'Start read_settings. CONFIG_FILE={}.'.format(CONFIG_FILE))

        try:
            with open(CONFIG_FILE, encoding='utf-8') as f:
                settings = json.load(f)

                self.TEST_USING_FILE_GAMES.setChecked(
                    settings['TEST_USING_FILE_GAMES'])
                self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(
                    settings['PARSE_GAME_NAME_ON_SEQUENCE'])
                self.SORT_GAME.setChecked(settings['SORT_GAME'])
                self.SORT_REVERSE.setChecked(settings['SORT_REVERSE'])

                self.check_FINISHED_GAME.setChecked(
                    settings['check_FINISHED_GAME'])
                self.check_NOT_FINISHED_GAME.setChecked(
                    settings['check_NOT_FINISHED_GAME'])
                self.check_FINISHED_WATCHED.setChecked(
                    settings['check_FINISHED_WATCHED'])
                self.check_NOT_FINISHED_WATCHED.setChecked(
                    settings['check_NOT_FINISHED_WATCHED'])
                self.check_OTHER.setChecked(settings['check_OTHER'])

                base64_state = settings['MainWindow_State']
                state = QByteArray.fromBase64(base64_state.encode())
                self.restoreState(state)

                base64_geometry = settings['MainWindow_Geometry']
                geometry = QByteArray.fromBase64(base64_geometry.encode())
                self.restoreGeometry(geometry)

        except Exception as e:
            logger.exception(e)
            logger.debug("Заполняю значения по умолчанию.")

            self.TEST_USING_FILE_GAMES.setChecked(True)
            self.PARSE_GAME_NAME_ON_SEQUENCE.setChecked(True)
            self.SORT_GAME.setChecked(False)
            self.SORT_REVERSE.setChecked(False)

            self.check_FINISHED_GAME.setChecked(True)
            self.check_NOT_FINISHED_GAME.setChecked(True)
            self.check_FINISHED_WATCHED.setChecked(True)
            self.check_NOT_FINISHED_WATCHED.setChecked(True)
            self.check_OTHER.setChecked(True)

        logger.debug('Finish read_settings.')

    def write_settings(self):
        logger.debug(
            'Start write_settings. CONFIG_FILE={}.'.format(CONFIG_FILE))
        logger.debug('Build dict.')

        settings = {
            'TEST_USING_FILE_GAMES':
            self.TEST_USING_FILE_GAMES.isChecked(),
            'PARSE_GAME_NAME_ON_SEQUENCE':
            self.PARSE_GAME_NAME_ON_SEQUENCE.isChecked(),
            'SORT_GAME':
            self.SORT_GAME.isChecked(),
            'SORT_REVERSE':
            self.SORT_REVERSE.isChecked(),
            'check_FINISHED_GAME':
            self.check_FINISHED_GAME.isChecked(),
            'check_NOT_FINISHED_GAME':
            self.check_NOT_FINISHED_GAME.isChecked(),
            'check_FINISHED_WATCHED':
            self.check_FINISHED_WATCHED.isChecked(),
            'check_NOT_FINISHED_WATCHED':
            self.check_NOT_FINISHED_WATCHED.isChecked(),
            'check_OTHER':
            self.check_OTHER.isChecked(),
            'MainWindow_State':
            bytes(self.saveState().toBase64()).decode(),
            'MainWindow_Geometry':
            bytes(self.saveGeometry().toBase64()).decode(),
        }

        logger.debug('Write config.')

        with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
            str_json_obj = json.dumps(settings, sort_keys=True, indent=4)
            f.write(str_json_obj)

        logger.debug('Finish write_settings.')

    def closeEvent(self, event):
        self.write_settings()
        quit()