class LoginWindow(QDialog): def __init__(self): """ Login Dialog """ super().__init__() self.initializeUI() def initializeUI(self): self.setWindowTitle("Login Window") self.setFixedSize(500, 200) self.setUpWindow() # Connect to database after setting up the login dialog self.connectToDatabase() self.show() def setUpWindow(self): """Set up the dialog's widgets and layout.""" header_label = QLabel("""<p style='color:#65888C'> Welcome to Database Manager</p>""") header_label.setFont(QFont("Arial", 24)) header_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.info_label = QLabel("""<p style='color:#65888C'> Sign into your account.</p>""") self.info_label.setAlignment(Qt.AlignmentFlag.AlignHCenter) username_label = QLabel("Username:"******"Password:"******"Log In", QDialogButtonBox.ButtonRole.AcceptRole) button_box.accepted.connect(self.clickedLogInButton) log_in_grid = QGridLayout() log_in_grid.addWidget(header_label, 0, 0, 1, 3, Qt.AlignmentFlag.AlignCenter) log_in_grid.addWidget(self.info_label, 1, 0, 1, 3, Qt.AlignmentFlag.AlignCenter) log_in_grid.addWidget(username_label, 2, 0) log_in_grid.addWidget(self.username_line, 2, 1) log_in_grid.addWidget(password_label, 3, 0) log_in_grid.addWidget(self.password_line, 3, 1) log_in_grid.addWidget(button_box, 4, 1) self.setLayout(log_in_grid) def connectToDatabase(self): """Create a QSqlDatabase object and connect to the database.""" database = QSqlDatabase.addDatabase("QSQLITE") database.setDatabaseName("data/inventory.db") database.setConnectOptions("QSQLITE_ENABLE_REGEXP") if not database.open(): error = database.lastError().text() QMessageBox.critical(QApplication.activeWindow(), "Connection Error", f"Something went wrong: {error}") sys.exit(1) # Handle if the database is missing and SQLite creates a new, # empty database tables_needed = { "Staff", "Customers", "Orders", "Products", "Categories" } no_tables = tables_needed - set(database.tables()) if no_tables: QMessageBox.critical(QApplication.activeWindow(), "Error", f'{no_tables} missing.') sys.exit(1) def replaceText(self, text): """Slot for resetting the information label's text.""" self.info_label.setText( "<p style='color:#65888C'>Sign into your account.</p>") def clickedLogInButton(self): """Check the user's username and password information from the database to determine if they are able to log in.""" username = self.username_line.text() password = self.password_line.text() query = QSqlQuery() query.exec("PRAGMA foreign_keys = ON") query.prepare("SELECT * FROM Staff WHERE username=:username") query.bindValue(":username", username) query.exec() # Open the main window or provide feedback if query.first(): # Retrieve the first matching username if query.value("password") == password: admin_or_not = query.value( "is_admin" ) # Retrieve the value for administrative privileges # Open the main window and close the login dialog self.main_window = MainWindow(admin_or_not) self.main_window.showMaximized() self.close() else: self.info_label.setText( "<p style='color:#F34B2C'>Incorrect password.</p>") else: self.info_label.setText( "<p style='color:#F34B2C'>Incorrect username.</p>")
class App(QWidget): def __init__(self): super().__init__() self.setWindowTitle('GitHub Abuz!') self.setWindowIcon(QIcon('icon.png')) layout = QGridLayout() vl = QVBoxLayout() hl = QHBoxLayout() hl2 = QHBoxLayout() hl3 = QHBoxLayout() self.y = QComboBox() self.name = QLineEdit() self.email = QLineEdit() self.passw = QLineEdit() self.repo = QLineEdit() self.type = QLineEdit() self.fonts = QComboBox() self.err = QMessageBox() self.nc = QSpinBox() lbl = QLabel('Commits/day:') prev = QPushButton('Translate') invert = QPushButton('Invert') leggo = QPushButton('Do it') invert.clicked.connect(self.invert) leggo.clicked.connect(self.doit) prev.clicked.connect(self.textCheck) self.name.textChanged[str].connect(self.rmph) self.email.textChanged[str].connect(self.rmph) self.passw.textChanged[str].connect(self.rmph) self.type.textChanged[str].connect(self.rmph) self.repo.textChanged[str].connect(self.rmph) self.y.addItem('Year (default: last 52 weeks)') for yr in range(datetime.datetime.now().year + 5, datetime.datetime.now().year - 20, -1): self.y.addItem(str(yr)) self.fonts.addItems(os.listdir('Fonts')) self.name.setPlaceholderText('Committer name') self.email.setPlaceholderText('Committer email') self.passw.setPlaceholderText('Password') self.passw.setEchoMode(QLineEdit.EchoMode.Password) self.repo.setPlaceholderText('Link to repo') self.type.setPlaceholderText('Translate text to tile art!') self.nc.setMinimum(1) self.nc.setValue(1) self.err.setWindowIcon(QIcon('icon.png')) self.err.setWindowTitle('Error!') hl.addWidget(self.name) hl.addWidget(self.email) hl.addWidget(self.passw) hl3.addWidget(self.repo) hl3.addWidget(self.y) hl3.addWidget(lbl) hl3.addWidget(self.nc) hl2.addWidget(self.type) hl2.addWidget(self.fonts) hl2.addWidget(prev) hl2.addWidget(invert) vl.addLayout(hl) vl.addLayout(hl3) vl.addLayout(layout) vl.addLayout(hl2) vl.addWidget(leggo) self.setLayout(vl) self.checkM = [list() for i in range(7)] for i in range(7): for j in range(52): m = QCheckBox() layout.addWidget(m, i, j) self.checkM[i].append(m) def rmph(self): self.setStyleSheet(''' QLineEdit[text=""]{ border: 1px #30363d; border-radius: 3px; padding: 1px 18px 1px 3px; background-color: #1c2128; color: #8b949e; } QLineEdit{ border: 1px #30363d; border-radius: 3px; padding: 1px 18px 1px 3px; background-color: #1c2128; color: #f0f6fc; } QLineEdit:hover { border: 0.5px solid #c9d1d9; } QLineEdit:focus { border: 1px solid #c9d1d9; }''') def getActiveDates(self, dates): ad = [] for i in range(7): for j in range(52): if self.checkM[i][j].isChecked(): ad.append(dates[i][j]) return ad def doit(self): try: year = int(self.y.currentText()) dates = self.getActiveDates(getDates(year)) except: dates = self.getActiveDates(getDates()) author = git.Actor(self.name.text(), self.email.text()) if not self.name.text() or not self.email.text(): self.err.setText('Did you enter your name and email? 🙄') self.err.exec() return repurl = "https://" + self.name.text() + ":" + self.passw.text( ) + "@" + self.repo.text()[8:] repname = repurl.split('/')[-1].split('.')[0] if not os.path.isdir(repname): try: git.cmd.Git().clone(repurl) except: self.err.setText( 'Could not clone the repo. Ensure that the remote repo exists and that you have access to it.' ) self.err.exec() return rep = git.Repo.init(repname) for date in dates: for n in range(self.nc.value()): rep.index.commit("committed for the lullzz!!", author=author, committer=author, author_date=date.isoformat()) try: rep.remotes.origin.set_url(repurl) except: rep.create_remote('origin', repurl) try: rep.remotes.origin.push() except: self.err.setText( 'Error pushing. Verify you have permissions to push to the repo and that the given credentials are correct' ) self.err.exec() return result = QMessageBox() text = f"Created {len(dates)*2} commits as {self.name.text()} <{self.email.text()}> in {repname} : {self.repo.text()}" result.setWindowIcon(QIcon('icon.png')) result.setWindowTitle('All Done!') result.setText(text) result.exec() os.remove(repname) def textCheck(self): for r in self.checkM: for m in r: m.setChecked(False) text_to_render = self.type.text() font = Font(os.path.join('Fonts', self.fonts.currentText()), 8) try: text = repr(font.render_text(text_to_render, 52, 7)) text_by_weekday = text.split('\n') for i in range(7): for j in range(51): if text_by_weekday[i][j] == '#': self.checkM[i][j].setChecked(True) except: self.err.setText('You typed too long :(') self.err.exec() def invert(self): for r in self.checkM: for m in r: if m.isChecked(): m.setChecked(False) else: m.setChecked(True)
class LoginDialog(QDialog): """登录对话框""" clicked_ok = pyqtSignal() def __init__(self, config): super().__init__() self._cwd = os.getcwd() self._config = config self._cookie_assister = 'login_assister.exe' self._user = "" self._pwd = "" self._cookie = {} self._del_user = "" self.initUI() self.setStyleSheet(dialog_qss_style) self.setMinimumWidth(560) self.name_ed.setFocus() # 信号 self.name_ed.textChanged.connect(self.set_user) self.pwd_ed.textChanged.connect(self.set_pwd) self.cookie_ed.textChanged.connect(self.set_cookie) def update_selection(self, user): """显示已经保存的登录用户信息""" user_info = self._config.get_user_info(user) if user_info: self._user = user_info[0] self._pwd = user_info[1] self._cookie = user_info[2] # 更新控件显示内容 self.name_ed.setText(self._user) self.pwd_ed.setText(self._pwd) try: text = ";".join([f'{k}={v}' for k, v in self._cookie.items()]) except: text = '' self.cookie_ed.setPlainText(text) def initUI(self): self.setWindowTitle("登录蓝奏云") self.setWindowIcon(QIcon(SRC_DIR + "login.ico")) logo = QLabel() logo.setPixmap(QPixmap(SRC_DIR + "logo3.gif")) logo.setStyleSheet("background-color:rgb(0,153,255);") logo.setAlignment(Qt.AlignmentFlag.AlignCenter) self.tabs = QTabWidget() self.auto_tab = QWidget() self.hand_tab = QWidget() # Add tabs self.tabs.addTab(self.auto_tab,"自动获取Cookie") self.tabs.addTab(self.hand_tab,"手动输入Cookie") self.auto_get_cookie_ok = AutoResizingTextEdit("🔶点击👇自动获取浏览器登录信息👇") self.auto_get_cookie_ok.setReadOnly(True) self.auto_get_cookie_btn = QPushButton("自动读取浏览器登录信息") auto_cookie_notice = '支持浏览器:Chrome, Chromium, Opera, Edge, Firefox' self.auto_get_cookie_btn.setToolTip(auto_cookie_notice) self.auto_get_cookie_btn.clicked.connect(self.call_auto_get_cookie) self.auto_get_cookie_btn.setStyleSheet("QPushButton {min-width: 210px;max-width: 210px;}") self.name_lb = QLabel("&U 用户") self.name_lb.setAlignment(Qt.AlignmentFlag.AlignCenter) self.name_ed = QLineEdit() self.name_lb.setBuddy(self.name_ed) self.pwd_lb = QLabel("&P 密码") self.pwd_lb.setAlignment(Qt.AlignmentFlag.AlignCenter) self.pwd_ed = QLineEdit() self.pwd_ed.setEchoMode(QLineEdit.EchoMode.Password) self.pwd_lb.setBuddy(self.pwd_ed) self.cookie_lb = QLabel("&Cookie") self.cookie_ed = QTextEdit() notice = "由于滑动验证的存在,需要输入cookie,cookie请使用浏览器获取\n" + \ "cookie会保存在本地,下次使用。其格式如下:\n ylogin=value1; phpdisk_info=value2" self.cookie_ed.setPlaceholderText(notice) self.cookie_lb.setBuddy(self.cookie_ed) self.show_input_cookie_btn = QPushButton("显示Cookie输入框") self.show_input_cookie_btn.setToolTip(notice) self.show_input_cookie_btn.setStyleSheet("QPushButton {min-width: 110px;max-width: 110px;}") self.show_input_cookie_btn.clicked.connect(self.change_show_input_cookie) self.ok_btn = QPushButton("登录") self.ok_btn.clicked.connect(self.change_ok_btn) self.cancel_btn = QPushButton("取消") self.cancel_btn.clicked.connect(self.change_cancel_btn) lb_line_1 = QLabel() lb_line_1.setText('<html><hr />切换用户</html>') lb_line_2 = QLabel() lb_line_2.setText('<html><hr /></html>') self.form = QFormLayout() self.form.setLabelAlignment(Qt.AlignmentFlag.AlignRight) self.form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow) # 覆盖MacOS的默认样式 self.form.addRow(self.name_lb, self.name_ed) self.form.addRow(self.pwd_lb, self.pwd_ed) if is_windows: def set_assister_path(): """设置辅助登录程序路径""" assister_path = QFileDialog.getOpenFileName(self, "选择辅助登录程序路径", self._cwd, "EXE Files (*.exe)") if not assister_path[0]: return None assister_path = os.path.normpath(assister_path[0]) # windows backslash if assister_path == self._cookie_assister: return None self.assister_ed.setText(assister_path) self._cookie_assister = assister_path self.assister_lb = QLabel("登录辅助程序") self.assister_lb.setAlignment(Qt.AlignmentFlag.AlignCenter) self.assister_ed = MyLineEdit(self) self.assister_ed.setText(self._cookie_assister) self.assister_ed.clicked.connect(set_assister_path) self.assister_lb.setBuddy(self.assister_ed) self.form.addRow(self.assister_lb, self.assister_ed) hbox = QHBoxLayout() hbox.addWidget(self.show_input_cookie_btn) hbox.addStretch(1) hbox.addWidget(self.ok_btn) hbox.addWidget(self.cancel_btn) user_box = QHBoxLayout() self.user_num = 0 self.user_btns = {} for user in self._config.users_name: user = str(user) # TODO: 可能需要删掉 self.user_btns[user] = QDoublePushButton(user) self.user_btns[user].setStyleSheet("QPushButton {border:none;}") if user == self._config.name: self.user_btns[user].setStyleSheet("QPushButton {background-color:rgb(0,153,2);}") self.tabs.setCurrentIndex(1) self.user_btns[user].setToolTip(f"点击选中,双击切换至用户:{user}") self.user_btns[user].doubleClicked.connect(self.choose_user) self.user_btns[user].clicked.connect(self.delete_chose_user) user_box.addWidget(self.user_btns[user]) self.user_num += 1 user_box.addStretch(1) self.layout = QVBoxLayout(self) self.layout.addWidget(logo) vbox = QVBoxLayout() if self._config.name: vbox.addWidget(lb_line_1) user_box.setAlignment(Qt.AlignmentFlag.AlignCenter) vbox.addLayout(user_box) vbox.addWidget(lb_line_2) if self.user_num > 1: self.del_user_btn = QPushButton("删除账户") self.del_user_btn.setIcon(QIcon(SRC_DIR + "delete.ico")) self.del_user_btn.setStyleSheet("QPushButton {min-width: 180px;max-width: 180px;}") self.del_user_btn.clicked.connect(self.call_del_chose_user) vbox.addWidget(self.del_user_btn) else: self.del_user_btn = None vbox.addStretch(1) vbox.addLayout(self.form) vbox.addStretch(1) vbox.addLayout(hbox) vbox.setAlignment(Qt.AlignmentFlag.AlignCenter) self.hand_tab.setLayout(vbox) auto_cookie_vbox = QVBoxLayout() auto_cookie_vbox.addWidget(self.auto_get_cookie_ok) auto_cookie_vbox.addWidget(self.auto_get_cookie_btn) auto_cookie_vbox.setAlignment(Qt.AlignmentFlag.AlignCenter) self.auto_tab.setLayout(auto_cookie_vbox) self.layout.addWidget(self.tabs) self.setLayout(self.layout) self.update_selection(self._config.name) def call_del_chose_user(self): if self._del_user: if self._del_user != self._config.name: self.user_num -= 1 self._config.del_user(self._del_user) self.user_btns[self._del_user].close() self._del_user = "" if self.user_num <= 1: self.del_user_btn.close() self.del_user_btn = None return else: title = '不能删除' msg = '不能删除当前登录账户,请先切换用户!' else: title = '请选择账户' msg = '请单击选择需要删除的账户\n\n注意不能删除当前账户(绿色)' message_box = QMessageBox(self) message_box.setIcon(QMessageBox.Icon.Critical) message_box.setStyleSheet(btn_style) message_box.setWindowTitle(title) message_box.setText(msg) message_box.setStandardButtons(QMessageBox.StandardButton.Close) buttonC = message_box.button(QMessageBox.StandardButton.Close) buttonC.setText('关闭') message_box.exec() def delete_chose_user(self): """更改单击选中需要删除的用户""" user = str(self.sender().text()) self._del_user = user if self.del_user_btn: self.del_user_btn.setText(f"删除 <{user}>") def choose_user(self): """切换用户""" user = self.sender().text() if user != self._config.name: self.ok_btn.setText("切换用户") else: self.ok_btn.setText("登录") self.update_selection(user) def change_show_input_cookie(self): row_c = 4 if is_windows else 3 if self.form.rowCount() < row_c: self.org_height = self.height() self.form.addRow(self.cookie_lb, self.cookie_ed) self.show_input_cookie_btn.setText("隐藏Cookie输入框") self.change_height = None self.adjustSize() else: if not self.change_height: self.change_height = self.height() if self.cookie_ed.isVisible(): self.cookie_lb.setVisible(False) self.cookie_ed.setVisible(False) self.show_input_cookie_btn.setText("显示Cookie输入框") start_height, end_height = self.change_height, self.org_height else: self.cookie_lb.setVisible(True) self.cookie_ed.setVisible(True) self.show_input_cookie_btn.setText("隐藏Cookie输入框") start_height, end_height = self.org_height, self.change_height gm = self.geometry() x, y = gm.x(), gm.y() wd = self.width() self.animation = QPropertyAnimation(self, b'geometry') self.animation.setDuration(400) self.animation.setStartValue(QRect(x, y, wd, start_height)) self.animation.setEndValue(QRect(x, y, wd, end_height)) self.animation.start() def set_user(self, user): self._user = user if not user: return None if user not in self._config.users_name: self.ok_btn.setText("添加用户") self.cookie_ed.setPlainText("") elif user != self._config.name: self.update_selection(user) self.ok_btn.setText("切换用户") else: self.update_selection(user) self.ok_btn.setText("登录") def set_pwd(self, pwd): if self._user in self._config.users_name: user_info = self._config.get_user_info(self._user) if pwd and pwd != user_info[1]: # 改变密码,cookie作废 self.cookie_ed.setPlainText("") self._cookie = None if not pwd: # 输入空密码,表示删除对pwd的存储,并使用以前的cookie self._cookie = user_info[2] try: text = ";".join([f'{k}={v}' for k, v in self._cookie.items()]) except: text = '' self.cookie_ed.setPlainText(text) self._pwd = pwd def set_cookie(self): cookies = self.cookie_ed.toPlainText() if cookies: try: self._cookie = {kv.split("=")[0].strip(" "): kv.split("=")[1].strip(" ") for kv in cookies.split(";") if kv.strip(" ") } except: self._cookie = None def change_cancel_btn(self): self.update_selection(self._config.name) self.close() def change_ok_btn(self): if self._user and self._pwd: if self._user not in self._config.users_name: self._cookie = None if self._cookie: up_info = {"name": self._user, "pwd": self._pwd, "cookie": self._cookie, "work_id": -1} if self.ok_btn.text() == "切换用户": self._config.change_user(self._user) else: self._config.set_infos(up_info) self.clicked_ok.emit() self.close() elif USE_WEB_ENG: self.web = LoginWindow(self._user, self._pwd) self.web.cookie.connect(self.get_cookie_by_web) self.web.setWindowModality(Qt.WindowModality.ApplicationModal) self.web.exec() elif os.path.isfile(self._cookie_assister): try: result = os.popen(f'{self._cookie_assister} {self._user} {self._pwd}') cookie = result.read() try: self._cookie = {kv.split("=")[0].strip(" "): kv.split("=")[1].strip(" ") for kv in cookie.split(";")} except: self._cookie = None if not self._cookie: return None up_info = {"name": self._user, "pwd": self._pwd, "cookie": self._cookie, "work_id": -1} self._config.set_infos(up_info) self.clicked_ok.emit() self.close() except: pass else: title = '请使用 Cookie 登录或是选择 登录辅助程序' msg = '没有输入 Cookie,或者没有找到登录辅助程序!\n\n' + \ '推荐使用浏览器获取 cookie 填入 cookie 输入框\n\n' + \ '如果不嫌文件体积大,请下载登录辅助程序:\n' + \ 'https://github.com/rachpt/lanzou-gui/releases' message_box = QMessageBox(self) message_box.setIcon(QMessageBox.Icon.Critical) message_box.setStyleSheet(btn_style) message_box.setWindowTitle(title) message_box.setText(msg) message_box.setStandardButtons(QMessageBox.StandardButton.Close) buttonC = message_box.button(QMessageBox.StandardButton.Close) buttonC.setText('关闭') message_box.exec() def get_cookie_by_web(self, cookie): """使用辅助登录程序槽函数""" self._cookie = cookie self._close_dialog() def call_auto_get_cookie(self): """自动读取浏览器cookie槽函数""" try: self._cookie = get_cookie_from_browser() except Exception as e: logger.error(f"Browser_cookie3 Error: {e}") self.auto_get_cookie_ok.setPlainText(f"❌获取失败,错误信息\n{e}") else: if self._cookie: self._user = self._pwd = '' self.auto_get_cookie_ok.setPlainText("✅获取成功即将登录……") QTimer.singleShot(2000, self._close_dialog) else: self.auto_get_cookie_ok.setPlainText("❌获取失败\n请提前使用支持的浏览器登录蓝奏云,读取前完全退出浏览器!\n支持的浏览器与顺序:\nchrome, chromium, opera, edge, firefox") def _close_dialog(self): """关闭对话框""" up_info = {"name": self._user, "pwd": self._pwd, "cookie": self._cookie} self._config.set_infos(up_info) self.clicked_ok.emit() self.close()