class SyncWidget(QWidget): def __init__(self, gui, do_user_config, selected_book_ids, is_sync_selected): QWidget.__init__(self, gui) api.build_request('/limits') self.logger = Logger( path.join(gui.current_db.library_path, 'bookfusion_sync.log')) self.logger.info( 'Open sync dialog: selected_book_ids={}; is_sync_selected={}'. format(selected_book_ids, is_sync_selected)) if len(selected_book_ids) == 0: is_sync_selected = False self.worker_thread = None self.do_user_config = do_user_config self.db = gui.current_db.new_api self.selected_book_ids = selected_book_ids self.l = QVBoxLayout() self.l.setContentsMargins(0, 0, 0, 0) self.setLayout(self.l) self.radio_layout = QVBoxLayout() self.l.addLayout(self.radio_layout) self.sync_all_radio = QRadioButton('Sync all books') self.sync_all_radio.setChecked(not is_sync_selected) self.radio_layout.addWidget(self.sync_all_radio) sync_selected_radio_label = 'Sync selected books' if len(selected_book_ids) > 0: sync_selected_radio_label = 'Sync {} selected {}'.format( len(selected_book_ids), 'book' if len(selected_book_ids) == 1 else 'books') self.sync_selected_radio = QRadioButton(sync_selected_radio_label) self.sync_selected_radio.toggled.connect(self.toggle_sync_selected) self.sync_selected_radio.setChecked(is_sync_selected) self.sync_selected_radio.setEnabled(len(selected_book_ids) > 0) self.radio_layout.addWidget(self.sync_selected_radio) self.reupload_possible = len(selected_book_ids) > 0 and len( selected_book_ids) <= 100 if self.reupload_possible: for book_id in selected_book_ids: identifiers = self.db.get_proxy_metadata(book_id).identifiers if not identifiers.get('bookfusion'): self.reupload_possible = False self.reupload_checkbox = QCheckBox('Re-upload book files', self) self.reupload_checkbox.setVisible(is_sync_selected and self.reupload_possible) self.radio_layout.addWidget(self.reupload_checkbox) self.btn_layout = QHBoxLayout() self.l.addLayout(self.btn_layout) self.config_btn = QPushButton('Configure') self.config_btn.clicked.connect(self.config) self.btn_layout.addWidget(self.config_btn) self.btn_layout.addStretch() self.start_btn = QPushButton('Start') self.start_btn.clicked.connect(self.start) self.btn_layout.addWidget(self.start_btn) self.cancel_btn = QPushButton('Cancel') self.cancel_btn.clicked.connect(self.cancel) self.cancel_btn.hide() self.btn_layout.addWidget(self.cancel_btn) self.info = QHBoxLayout() self.info.setContentsMargins(0, 0, 0, 0) self.l.addLayout(self.info) self.msg = QLabel() self.info.addWidget(self.msg) self.info.addStretch() self.log_btn = QLabel('<a href="#">Log</a>') self.log_btn.linkActivated.connect(self.toggle_log) self.log_btn.hide() self.info.addWidget(self.log_btn) self.log = QTableWidget(0, 2) self.log.setHorizontalHeaderLabels(['Book', 'Message']) self.log.horizontalHeader().setStretchLastSection(True) self.log.hide() self.l.addWidget(self.log) self.apply_config() def __del__(self): if self.worker_thread: self.worker_thread.quit() self.worker_thread.terminate() def config(self): self.do_user_config(parent=self) self.apply_config() def apply_config(self): configured = bool(prefs['api_key']) self.start_btn.setEnabled(configured) def toggle_sync_selected(self, is_sync_selected): if hasattr(self, 'reupload_checkbox'): self.reupload_checkbox.setVisible(is_sync_selected and self.reupload_possible) def start(self): if self.sync_selected_radio.isChecked( ) and self.reupload_checkbox.isChecked(): reply = QMessageBox.question( self, 'BookFusion Sync', 'Re-uploading book files can potentially result in previous highlights or bookmarks no longer working.\n\nPreviously uploaded files will be overwritten. Are you sure you want to re-upload?', QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes) if reply != QMessageBox.Yes: return self.worker = None self.valid_book_ids = None self.book_log_map = {} self.book_progress_map = {} if self.sync_selected_radio.isChecked(): book_ids = list(self.selected_book_ids) else: book_ids = list(self.db.all_book_ids()) self.logger.info('Start sync: sync_selected={}; book_ids={}'.format( self.sync_selected_radio.isChecked(), book_ids)) self.in_progress = True self.total = len(book_ids) self.update_progress(None) self.start_btn.hide() self.cancel_btn.show() self.config_btn.setEnabled(False) self.sync_all_radio.setEnabled(False) self.sync_selected_radio.setEnabled(False) self.worker_thread = QThread(self) self.worker = CheckWorker(self.db, self.logger, book_ids) self.worker.finished.connect(self.finish_check) self.worker.finished.connect(self.worker_thread.quit) self.worker.progress.connect(self.update_progress) self.worker.limitsAvailable.connect(self.apply_limits) self.worker.resultsAvailable.connect(self.apply_results) self.worker.aborted.connect(self.abort) self.worker.moveToThread(self.worker_thread) self.worker_thread.started.connect(self.worker.start) self.worker_thread.start() def apply_limits(self, limits): self.logger.info('Limits: {}'.format(limits)) self.limits = limits def apply_results(self, books_count, valid_ids): self.logger.info('Check results: books_count={}; valid_ids={}'.format( books_count, valid_ids)) self.valid_book_ids = valid_ids self.books_count = books_count def finish_check(self): if self.valid_book_ids: is_filesize_exceeded = len(self.valid_book_ids) < self.books_count is_total_books_exceeded = self.limits[ 'total_books'] and self.books_count > self.limits['total_books'] if is_filesize_exceeded or is_total_books_exceeded: if self.limits['message']: msg_box = QMessageBox(self) msg_box.setWindowTitle('BookFusion Sync') msg_box.addButton(QMessageBox.No) msg_box.addButton(QMessageBox.Yes) msg_box.setText(self.limits['message']) msg_box.setDefaultButton(QMessageBox.Yes) reply = msg_box.exec_() if reply == QMessageBox.Yes: self.start_sync() else: self.in_progress = False self.msg.setText('Canceled.') self.finish_sync() else: self.start_sync() else: self.start_sync() else: if self.in_progress: self.in_progress = False self.msg.setText('No supported books selected.') self.finish_sync() def start_sync(self): self.log_btn.show() self.log.setRowCount(0) self.log.show() self.worker_thread = QThread(self) book_ids = self.valid_book_ids if self.limits['total_books']: book_ids = book_ids[:self.limits['total_books']] self.total = len(book_ids) self.worker = UploadManager( self.db, self.logger, book_ids, self.sync_selected_radio.isChecked() and self.reupload_checkbox.isChecked()) self.worker.finished.connect(self.finish_sync) self.worker.finished.connect(self.worker_thread.quit) self.worker.progress.connect(self.update_progress) self.worker.uploadProgress.connect(self.update_upload_progress) self.worker.started.connect(self.log_start) self.worker.skipped.connect(self.log_skip) self.worker.failed.connect(self.log_fail) self.worker.uploaded.connect(self.log_upload) self.worker.updated.connect(self.log_update) self.worker.aborted.connect(self.abort) self.worker.moveToThread(self.worker_thread) self.worker_thread.started.connect(self.worker.start) self.worker_thread.start() def finish_sync(self): if self.in_progress: self.msg.setText('Done.') self.cancel_btn.hide() self.cancel_btn.setEnabled(True) self.start_btn.show() self.config_btn.setEnabled(True) self.sync_all_radio.setEnabled(True) self.sync_selected_radio.setEnabled(len(self.selected_book_ids) > 0) def abort(self, error): self.in_progress = False self.msg.setText(error) def cancel(self): self.in_progress = False self.msg.setText('Canceled.') self.cancel_btn.setEnabled(False) self.worker.cancel() def update_progress(self, progress): if self.in_progress: if isinstance(self.worker, UploadManager): msg = 'Synchronizing...' else: msg = 'Preparing...' if progress: msg += ' {} of {}'.format(progress + 1, self.total) self.msg.setText(msg) def update_upload_progress(self, book_id, sent, total): if not book_id in self.book_progress_map: return progress = self.book_progress_map[book_id] if sent < total: progress.setValue(sent) progress.setMaximum(total) else: progress.setMaximum(0) def log_start(self, book_id): self.update_log(book_id, None) def log_fail(self, book_id, msg): self.update_log(book_id, msg) def log_skip(self, book_id): self.update_log(book_id, 'skipped') def log_upload(self, book_id): self.update_log(book_id, 'uploaded') def log_update(self, book_id): self.update_log(book_id, 'updated') def toggle_log(self, _): self.log.setVisible(not self.log.isVisible()) def update_log(self, book_id, msg): if book_id in self.book_log_map: index = self.book_log_map[book_id] else: index = self.log.rowCount() self.book_log_map[book_id] = index self.log.insertRow(index) title = self.db.get_proxy_metadata(book_id).title title_item = QTableWidgetItem(title) title_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemNeverHasChildren) self.log.setItem(index, 0, title_item) progress = QProgressBar() progress.setMaximum(0) self.log.setCellWidget(index, 1, progress) self.book_progress_map[book_id] = progress if not msg is None: del (self.book_progress_map[book_id]) self.log.setCellWidget(index, 1, None) msg_item = QTableWidgetItem(msg) msg_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemNeverHasChildren) self.log.setItem(index, 1, msg_item) def maybe_cancel(self): if self.worker_thread and self.worker_thread.isRunning(): reply = QMessageBox.question( self, 'BookFusion Sync', 'Are you sure you want to cancel the currently running process?', QMessageBox.No | QMessageBox.Yes, QMessageBox.Yes) if reply == QMessageBox.Yes: self.cancel() else: return False return True
class Game(QWidget): def __init__(self): super().__init__() self._flag_1 = False self.media = QtCore.QUrl.fromLocalFile("MP3/music.mp3") content = QtMultimedia.QMediaContent(self.media) self.player = QtMultimedia.QMediaPlayer() self.player.setMedia(content) self.player.setVolume(50) self.initUI() def initUI(self): self.file_number = 2 self._score = 0 self.setMouseTracking(True) self.resize(500, 500) self.center() self.setWindowTitle('Игра') self.main_pic = QLabel(self) self.main_pic.setPixmap( QPixmap(resource_path("PIC/running_rabbit.jpg"))) self.main_pic.resize(500, 500) self.button_start_game = QPushButton("НАЧАТЬ ИГРУ", self) self.button_start_game.resize(140, 50) self.button_start_game.move(70, 300) self.button_start_game.clicked.connect(self.start_game) self.button_edit_map = QPushButton("СОЗДАТЬ КАРТУ", self) self.button_edit_map.resize(140, 50) self.button_edit_map.move(70, 360) self.button_edit_map.clicked.connect(self.edit_map_menu) self.button_exit = QPushButton("ЗАКОНЧИТЬ СЕАНС", self) self.button_exit.resize(140, 50) self.button_exit.move(70, 420) self.button_exit.clicked.connect(self.exit) self.timer_game = QTimer() self.timer_game.timeout.connect(self.updateValues) self.timer_game.start(200) self.setFocusPolicy(Qt.StrongFocus) self.lable_score = QLabel(self) self.lable_score.resize(200, 35) self.lable_score.setFont( QFont("RetroComputer[RUS by Daymarius]", 26, QFont.Bold)) self.lable_score.setVisible(False) self.button_menu = QPushButton("НАЗАД", self) self.button_menu.resize(120, 40) self.button_menu.clicked.connect(self.show_menu) self.button_menu.setVisible(False) self.lable_name = QLabel("ВВЕДИТЕ ВАШЕ ИМЯ:", self) self.lable_name.sizeHint() self.lable_name.setFont( QFont("RetroComputer[RUS by Daymarius]", 10, QFont.Bold)) self.lable_name.move(230, 300) self.input_name = QLineEdit("Без имени", self) self.input_name.resize(200, 20) self.input_name.move(230, 325) self.table_score = QTableWidget(self) self.table_score.resize(200, 120) self.table_score.move(230, 350) def bd_score(self): con = sqlite3.connect(resource_path("DB/score.db")) # Создание курсора cur = con.cursor() # Выполнение запроса и получение всех результатов result = cur.execute( "SELECT * FROM main ORDER BY score DESC;").fetchmany(5) cur.execute("DROP TABLE main") cur.execute("CREATE TABLE main (name STRING, score INTEGER)") for item in result: cur.execute("INSERT INTO main VALUES(?, ?)", (item[0], item[1])) con.commit() # Вывод результатов на экран if result != []: self.table_score.setColumnCount(len(result[0])) self.table_score.setRowCount(0) for i, row in enumerate(result): self.table_score.setRowCount(self.table_score.rowCount() + 1) for j, elem in enumerate(row): item = QTableWidgetItem(str(elem)) self.table_score.setItem(i, j, item) item.setFlags(QtCore.Qt.ItemIsEnabled) self.table_score.setHorizontalHeaderItem( 0, QTableWidgetItem("Имя игрока")) self.table_score.setHorizontalHeaderItem(1, QTableWidgetItem("Счет")) self.table_score.setColumnWidth(0, 127) self.table_score.setColumnWidth(1, 20) con.close() def append_bd_score_and_name(self): con = sqlite3.connect("DB/score.db") # Создание курсора cur = con.cursor() cur.execute("INSERT INTO main VALUES(?, ?)", (self.input_name.text(), self.get_score())) con.commit() self.bd_score() con.close() def get_score(self): return self._score def set_score(self, score): self._score = score def keyPressEvent(self, event): if event.key() == Qt.Key_Right: self.hero.go_right() elif event.key() == Qt.Key_Left: self.hero.go_left() elif event.key() == Qt.Key_Up: self.hero.go_up() elif event.key() == Qt.Key_Down: self.hero.go_down() elif event.key() == Qt.Key_Space: self.hero.go_dig() def keyReleaseEvent(self, QKeyEvent): if self._flag_1 and not QKeyEvent.isAutoRepeat(): self.hero.stop() def edit_map_menu(self): game.setVisible(False) edit_map.create_map() edit_map.show() def exit(self): sys.exit(app.exec()) def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def reload_game(self): score = self.get_score() lifes = self.hero.get_lifes() self.start_game() self.set_score(score) self.hero.set_lifes(lifes) def start_game(self): self.player.play() self.set_score(0) self.map = Map(resource_path("MAP/" + str(self.file_number) + ".map")) for enemy in self.enemies: enemy.create_labirint() self.button_menu.setVisible(True) self.button_menu.setFocusPolicy(False) self.lable_score.setVisible(True) self.lable_score.move(0, 0) self.button_menu.move(self.map.get_col() * 40 - 120, 0) self.lable_score.setText("00000") sp_0_1 = [] for j in range(self.map.get_row()): for i in range(self.map.get_col()): if type(self.map.get_elem_xy(i, j)) == Empty and ( self.map.get_row() - 1 == j or type(self.map.get_elem_xy( i, j + 1)) in [Stairs, Brick]): sp_0_1.append((i, j)) zerro = Zerro() one = One() for i in range(int(round(len(sp_0_1) * 0.2))): t = randrange(0, len(sp_0_1)) x, y = sp_0_1[t] self.map.set_elem_xy(x, y, choice([zerro, one])) del sp_0_1[t] self.hide_menu() def show_menu(self): self.append_bd_score_and_name() game.player.pause() self.hero.timer.stop() for enemy in self.enemies: enemy.timer.stop() self.timer_game.stop() self.main_pic.show() self.table_score.show() self.input_name.show() self.lable_name.show() self.button_menu.setVisible(False) self.lable_score.setVisible(False) self.button_edit_map.setVisible(True) self.button_exit.setVisible(True) self.button_start_game.setVisible(True) self.resize(500, 500) self.center() self._flag_1 = False def hide_menu(self): game.player.play() self.hero.timer.start(200) for enemy in self.enemies: enemy.timer.start(200) game.timer_game.start(200) self.main_pic.hide() self.table_score.hide() self.input_name.hide() self.lable_name.hide() self.button_menu.setVisible(True) self.lable_score.setVisible(True) self.button_edit_map.setVisible(False) self.button_exit.setVisible(False) self.button_start_game.setVisible(False) self.resize(self.map.get_col() * 40, self.map.get_row() * 40 + 40) self.center() self._flag_1 = True def paintEvent(self, event): qp = QPainter() qp.begin(self) if self._flag_1: for i in range(self.map.get_col()): for j in range(self.map.get_row()): qp.drawPixmap( i * 40, j * 40 + 40, self.map.get_elem_xy( i, j).get_pic()) # рисуем картинками из elem_map qp.drawPixmap(self.hero.get_x() * 40, self.hero.get_y() * 40 + 40, self.hero.get_pic()) for enemy in self.enemies: qp.drawPixmap(enemy.get_x() * 40, enemy.get_y() * 40 + 40, enemy.get_pic()) for i in range(game.hero.get_lifes()): qp.drawPixmap(280 + i * 40, 0, self.hero._pic[self.hero._STOP][0]) txt = "00000" + str(self._score) self.lable_score.setText(txt[len(txt) - 5:len(txt)]) qp.end() def updateValues(self): self.update() def you_lose(self): self.player.pause() self.hero.timer.stop() for enemy in self.enemies: enemy.timer.stop() self.timer_game.stop() if self.hero.get_lifes() > 1: game.player.pause() buttonReply = QMessageBox.question( self, 'ВЫ ПРОИГРАЛИ', "Продолжить игру?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if buttonReply == QMessageBox.Yes: self.hero.set_lifes(self.hero.get_lifes() - 1) self.reload_game() self.timer_game.start(200) else: self.set_score(0) self.show_menu() else: game.player.pause() buttonReply = QMessageBox.information(self, 'ИГРА ОКОНЧЕНА', "Вы проиграли.") self.append_bd_score_and_name() self.show_menu()