Ejemplo n.º 1
0
    def initialize(self, check_if_trusted: bool = False) -> None:
        super().initialize()

        preferences = Application.getInstance().getPreferences()
        if check_if_trusted:
            # Need to do this before the preferences are read for the first time, but after obj-creation, which is here.
            preferences.indicateUntrustedPreference("general", "theme",
                                                    lambda value: self._isPathSecure(Resources.getPath(Resources.Themes, value)))
            preferences.indicateUntrustedPreference("backend", "location",
                                                    lambda value: self._isPathSecure(os.path.abspath(value)))
        preferences.addPreference("view/force_empty_shader_cache", False)
        preferences.addPreference("view/opengl_version_detect", OpenGLContext.OpenGlVersionDetect.Autodetect)

        # Read preferences here (upgrade won't work) to get:
        #  - The language in use, so the splash window can be shown in the correct language.
        #  - The OpenGL 'force' parameters.
        try:
            self.readPreferencesFromConfiguration()
        except FileNotFoundError:
            Logger.log("i", "Preferences file not found, ignore and use default language '%s'", self._default_language)

        # Initialize the package manager to remove and install scheduled packages.
        self._package_manager = self._package_manager_class(self, parent = self)

        # If a plugin is removed, check if the matching package is also removed.
        self._plugin_registry.pluginRemoved.connect(lambda plugin_id: self._package_manager.removePackage(plugin_id))

        self._mesh_file_handler = MeshFileHandler(self) #type: MeshFileHandler
        self._workspace_file_handler = WorkspaceFileHandler(self) #type: WorkspaceFileHandler

        if preferences.getValue("view/force_empty_shader_cache"):
            self.setAttribute(Qt.ApplicationAttribute.AA_DisableShaderDiskCache)
        if preferences.getValue("view/opengl_version_detect") != OpenGLContext.OpenGlVersionDetect.ForceModern:
            major_version, minor_version, profile = OpenGLContext.detectBestOpenGLVersion(
                preferences.getValue("view/opengl_version_detect") == OpenGLContext.OpenGlVersionDetect.ForceLegacy)
        else:
            Logger.info("Force 'modern' OpenGL (4.1 core) -- overrides 'force legacy opengl' preference.")
            major_version, minor_version, profile = (4, 1, QSurfaceFormat.OpenGLContextProfile.CoreProfile)

        if major_version is None or minor_version is None or profile is None:
            Logger.log("e", "Startup failed because OpenGL version probing has failed: tried to create a 2.0 and 4.1 context. Exiting")
            if not self.getIsHeadLess():
                QMessageBox.critical(None, "Failed to probe OpenGL",
                                     "Could not probe OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers.")
            sys.exit(1)
        else:
            opengl_version_str = OpenGLContext.versionAsText(major_version, minor_version, profile)
            Logger.log("d", "Detected most suitable OpenGL context version: %s", opengl_version_str)
        if not self.getIsHeadLess():
            OpenGLContext.setDefaultFormat(major_version, minor_version, profile = profile)

        self._qml_import_paths.append(os.path.join(os.path.dirname(sys.executable), "qml"))
        self._qml_import_paths.append(os.path.join(self.getInstallPrefix(), "Resources", "qml"))

        Logger.log("i", "Initializing job queue ...")
        self._job_queue = JobQueue()
        self._job_queue.jobFinished.connect(self._onJobFinished)

        Logger.log("i", "Initializing version upgrade manager ...")
        self._version_upgrade_manager = VersionUpgradeManager(self)
Ejemplo n.º 2
0
 def wrapper(self, *args, **kwargs):
     try:
         return func(self, *args, **kwargs)
     except Exception as e:
         if isinstance(e, serial.serialutil.SerialException):
             self.disable_widgets()
             self.clear_servo()
             self.port_refresh_button_clicked(None)
             QMessageBox.critical(None, "Error", "Disconnected from device")
         else:
             QMessageBox.information(None, "Error", str(e))
Ejemplo n.º 3
0
 def checkCheck(self):
     if not fgoFunc.base.serialno:
         return QMessageBox.critical(self, '错误', '未连接设备')
     try:
         fgoFunc.Check().show()
     except Exception as e:
         logger.critical(e)
Ejemplo n.º 4
0
    def runFunc(self, func, *args, **kwargs):
        if not fgoFunc.base.serialno:
            return QMessageBox.critical(self, '错误', '未连接设备')

        def f():
            try:
                self.signalFuncBegin.emit()
                self.applyAll()
                func(*args, **kwargs)
            except fgoFunc.ScriptTerminate as e:
                logger.critical(e)
            except Exception as e:
                logger.exception(e)
            finally:
                self.signalFuncEnd.emit()
                fgoFunc.control.reset()
                fgoFunc.fuse.reset()
                QApplication.beep()

        self.thread = threading.Thread(
            target=f,
            name=
            f'{func.__qualname__}({",".join(repr(i)for i in args)}{","if kwargs else""}{",".join((i+"="+repr(j))for i,j in kwargs.items())})'
        )
        self.thread.start()
Ejemplo n.º 5
0
    def accept(self):
        """Accept the data provided through the dialog."""
        self.data = []
        for field in (self.nameField, self.jobField, self.emailField):
            if not field.text():
                QMessageBox.critical(
                    self,
                    "Error!",
                    f"You must provide a contact's{field.objectName()}",
                )
                self.data = None  # reset .data
                return

            self.data.append(field.text())

        if not self.data:
            return()

        super().accept()
Ejemplo n.º 6
0
    def save_to_file(self, configuration: Union[Dict[str, Any], None],
                     out_file_path: str) -> None:
        if configuration is None:
            return

        try:
            if not out_file_path:
                return

            file = open(out_file_path, 'w')
            json.dump(configuration, file, indent=4)
            file.close()

            QMessageBox.information(self, 'Success',
                                    'Configuration Saved Successfully!',
                                    QMessageBox.StandardButton.Ok,
                                    QMessageBox.StandardButton.Ok)
        except IOError:
            QMessageBox.critical(self, 'Failure', 'Unexpected Error Occurred',
                                 QMessageBox.StandardButton.Ok,
                                 QMessageBox.StandardButton.Ok)
Ejemplo n.º 7
0
 def start_errors_calculate(self):
     self.waiting_text_3.setText("Команда выполняется…")
     self.repaint()
     alpha = self.alpha_input.value()
     c = self.c_input.value()
     d = self.d_input.value()
     time = self.time_input.value()
     length = self.length_input.value()
     number = self.number_input_2.value()
     if 1 <= self.method_3 <= 2:
         hx_rate, ht_rate = 2, 4
     else:
         hx_rate, ht_rate = 2, 2
     norm_error = uniform_norm_error
     for j in range(self.tableWidget_error_rates.rowCount()):
         if not self.tableWidget_error_rates.item(
                 j, 0) or not self.tableWidget_error_rates.item(j, 1):
             QMessageBox.critical(
                 self, "Ошибка! ",
                 "Наличие пустых/полупустых строк в таблицах недопустимо!")
             break
         i = int(self.tableWidget_error_rates.item(j, 0).text())
         k = int(self.tableWidget_error_rates.item(j, 1).text())
         results = get_numerical_experiments(i, k, alpha, c, d, time,
                                             length, number, hx_rate,
                                             ht_rate,
                                             self.methods[self.method_3],
                                             norm_error)
         self.tableWidget_error_rates.setItem(
             j, 0, QTableWidgetItem(str(int(results[0]))))
         self.tableWidget_error_rates.setItem(
             j, 1, QTableWidgetItem(str(int(results[1]))))
         self.tableWidget_error_rates.setItem(
             j, 2, QTableWidgetItem(str("%.6e" % results[2])))
         self.tableWidget_error_rates.setItem(
             j, 3, QTableWidgetItem(str("%.6e" % results[3])))
         self.tableWidget_error_rates.setItem(
             j, 4, QTableWidgetItem(str("%.6f" % results[4])))
         self.repaint()
     self.waiting_text_3.setText("Нажмите «Старт» для начала работы.")
    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)
Ejemplo n.º 9
0
    def __init__(self) -> None:
        if OpenGL.__instance is not None:
            raise RuntimeError("Try to create singleton '%s' more than once" %
                               self.__class__.__name__)

        super().__init__()
        OpenGL.__instance = self

        profile = QOpenGLVersionProfile()
        profile.setVersion(OpenGLContext.major_version,
                           OpenGLContext.minor_version)
        profile.setProfile(OpenGLContext.profile)

        context = QOpenGLContext.currentContext()
        if not context:
            Logger.log(
                "e", "Startup failed due to OpenGL context creation failing")
            QOpenGLContext.currentContext()
            sys.exit(1)
        self._gl = QOpenGLVersionFunctionsFactory.get(profile, context)
        if not self._gl:
            Logger.log("e",
                       "Startup failed due to OpenGL initialization failing")
            QMessageBox.critical(
                QMessageBox.Icon.Critical, "Failed to Initialize OpenGL",
                i18n_catalog.i18nc(
                    "@message", "Failed to Initialize OpenGL",
                    "Could not initialize OpenGL. This program requires OpenGL 2.0 or higher. Please check your video card drivers."
                ))
            sys.exit(1)

        # It would be nice to be able to not necessarily need OpenGL FrameBuffer Object support, but
        # due to a limitation in PyQt, currently glReadPixels or similar methods are not available.
        # This means we can only get frame buffer contents through methods that indirectly call
        # those methods, in this case primarily QOpenGLFrameBufferObject::toImage(), making us
        # hard-depend on FrameBuffer Objects.
        if not self.hasFrameBufferObjects():
            Logger.log(
                "e",
                "Startup failed, OpenGL does not support Frame Buffer Objects")
            QMessageBox.critical(
                None,
                i18n_catalog.i18nc(
                    "Critical OpenGL Extensions Missing",
                    "Critical OpenGL extensions are missing. This program requires support for Framebuffer Objects. Please check your video card drivers."
                ))
            sys.exit(1)

        self._gl.initializeOpenGLFunctions()

        self._gpu_vendor = OpenGL.Vendor.Other  #type: int
        vendor_string = self._gl.glGetString(self._gl.GL_VENDOR)
        if vendor_string is None:
            vendor_string = "Unknown"
        vendor_string = vendor_string.lower()

        if "nvidia" in vendor_string:
            self._gpu_vendor = OpenGL.Vendor.NVidia
        elif "amd" in vendor_string or "ati" in vendor_string:
            self._gpu_vendor = OpenGL.Vendor.AMD
        elif "intel" in vendor_string:
            self._gpu_vendor = OpenGL.Vendor.Intel

        self._gpu_type = "Unknown"  # type: str
        # WORKAROUND: Cura/#1117 Cura-packaging/12
        # Some Intel GPU chipsets return a string, which is not undecodable via PyQt6.
        # This workaround makes the code fall back to a "Unknown" renderer in these cases.
        try:
            self._gpu_type = self._gl.glGetString(self._gl.GL_RENDERER)
        except UnicodeDecodeError:
            Logger.log(
                "e", "DecodeError while getting GL_RENDERER via glGetString!")

        self._opengl_version = self._gl.glGetString(
            self._gl.GL_VERSION)  #type: str
        short_versions = re.findall(
            r"(\d+.\d+(.\d+)?)", self._opengl_version
        )  # Find version numbers, either 2-component or 3-component.
        if short_versions:
            self._opengl_version_short = short_versions[0][
                0]  # First whole match (second [0] is to grab the first group which is the whole version number).
        else:
            self._opengl_version_short = "unknown"

        self._opengl_shading_language_version = Version("0.0")  # type: Version
        try:
            self._opengl_shading_language_version = Version(
                self._gl.glGetString(self._gl.GL_SHADING_LANGUAGE_VERSION))
        except:
            self._opengl_shading_language_version = Version("1.0")

        if not self.hasFrameBufferObjects():
            Logger.log(
                "w",
                "No frame buffer support, falling back to texture copies.")

        Logger.log("d", "Initialized OpenGL subsystems.")
        Logger.log("d", "OpenGL Version:  %s", self._opengl_version)
        Logger.log("d", "OpenGL Vendor:   %s",
                   self._gl.glGetString(self._gl.GL_VENDOR))
        Logger.log("d", "OpenGL Renderer: %s", self._gpu_type)
        Logger.log("d", "GLSL Version:    %s",
                   self._opengl_shading_language_version)
Ejemplo n.º 10
0
 def add_x_value(self):
     if self.add_value(self.x_setted_list, self.x_input.value(),
                       self.length_input.value()) is False:
         QMessageBox.critical(self, "Ошибка! ",
                              "Выберите x меньше или равным длине трубки")
Ejemplo n.º 11
0
    def __init__(self, args):
        super(Application, self).__init__(args)
        QtWebEngineQuick.initialize()
        splash = QtWidgets.QSplashScreen(
            QtGui.QPixmap(resourcePath("vi/ui/res/logo_splash.png"))
        )
        splash.show()
        if version.SNAPSHOT:
            QMessageBox.critical(
                splash, "Snapshot", "This is a snapshot release... Use as you will...."
            )

        def change_splash_text(txt):
            if len(txt):
                splash.showMessage(
                    f"    {txt} ...",
                    QtCore.Qt.AlignmentFlag.AlignLeft,
                    QtGui.QColor(0x808000),
                )

        # Set up paths
        chat_log_directory = ""
        if len(sys.argv) > 1:
            chat_log_directory = sys.argv[1]

        if not os.path.exists(chat_log_directory):
            change_splash_text("Searching for EVE Logs")
            if sys.platform.startswith("darwin"):
                chat_log_directory = os.path.join(
                    os.path.expanduser("~"), "Documents", "EVE", "logs", "Chatlogs"
                )
                if not os.path.exists(chat_log_directory):
                    chat_log_directory = os.path.join(
                        os.path.expanduser("~"),
                        "Library",
                        "Application Support",
                        "Eve Online",
                        "p_drive",
                        "User",
                        "My Documents",
                        "EVE",
                        "logs",
                        "Chatlogs",
                    )
            elif sys.platform.startswith("linux"):
                chat_log_directory = os.path.join(
                    os.path.expanduser("~"), "Documents", "EVE", "logs", "Chatlogs"
                )
            elif sys.platform.startswith("win32") or sys.platform.startswith("cygwin"):
                import ctypes.wintypes

                buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
                ctypes.windll.shell32.SHGetFolderPathW(0, 0x05, 0, 0, buf)
                documents_path = buf.value

                chat_log_directory = os.path.join(
                    documents_path, "EVE", "logs", "Chatlogs"
                )
                # Now I need to just make sure... Some old pcs could still be on XP
                if not os.path.exists(chat_log_directory):
                    chat_log_directory = os.path.join(
                        os.path.expanduser("~"),
                        "My Documents",
                        "EVE",
                        "logs",
                        "Chatlogs",
                    )

        if not os.path.exists(chat_log_directory):
            chat_log_directory = QtWidgets.QFileDialog.getExistingDirectory(
                None,
                caption="Select EVE Online chat  logfiles directory",
                directory=chat_log_directory,
            )

        if not os.path.exists(chat_log_directory):
            # None of the paths for logs exist, bailing out
            QMessageBox.critical(
                splash,
                "No path to Logs",
                "No logs found at: " + chat_log_directory,
                QMessageBox.Close,
            )
            sys.exit(1)

        # Setting local directory for cache and logging
        change_splash_text("Setting Spyglass Directories")
        spyglass_dir = os.path.join(
            os.path.dirname(os.path.dirname(chat_log_directory)), "spyglass"
        )
        if not os.path.exists(spyglass_dir):
            os.mkdir(spyglass_dir)
        cache.Cache.PATH_TO_CACHE = os.path.join(spyglass_dir, "cache-2.sqlite3")

        spyglass_log_directory = os.path.join(spyglass_dir, "logs")
        if not os.path.exists(spyglass_log_directory):
            os.mkdir(spyglass_log_directory)

        change_splash_text("Connecting to Cache")
        spyglass_cache = Cache()
        log_level = spyglass_cache.getFromCache("logging_level")
        if not log_level:
            log_level = logging.WARN
        if version.SNAPSHOT:
            log_level = logging.DEBUG  # For Testing
        BACKGROUND_COLOR = spyglass_cache.getFromCache("background_color")

        if BACKGROUND_COLOR:
            self.setStyleSheet(f"background-color: {BACKGROUND_COLOR};")
        css = Styles().getStyle()
        self.setStyleSheet(css)
        del css

        # Setup logging for console and rotated log files
        formatter = logging.Formatter(
            "%(asctime)s| %(message)s", datefmt="%m/%d %I:%M:%S"
        )
        root_logger = logging.getLogger()
        root_logger.setLevel(level=log_level)

        log_filename = spyglass_log_directory + "/output.log"

        file_handler = RotatingFileHandler(
            maxBytes=(1048576 * 5), backupCount=7, filename=log_filename, mode="a"
        )
        file_handler.setFormatter(formatter)
        root_logger.addHandler(file_handler)

        console_handler = StreamHandler()
        console_handler.setFormatter(formatter)
        root_logger.addHandler(console_handler)

        logging.critical("")
        logging.critical(
            "------------------- Spyglass %s starting up -------------------",
            version.VERSION,
        )
        logging.critical("")
        logging.critical(" Looking for chat logs at: %s", chat_log_directory)
        logging.critical(
            " Cache maintained here: %s", cache.Cache.PATH_TO_CACHE
        )
        logging.critical(" Writing logs to: %s", spyglass_log_directory)
        tray_icon = systemtray.TrayIcon(self)
        tray_icon.show()

        self.main_window = viui.MainWindow(
            chat_log_directory, tray_icon, change_splash_text
        )
        self.main_window.show()
        self.main_window.raise_()
Ejemplo n.º 12
0
class YTdownloader(QWidget):
    def __init__(self):
        super().__init__()
        # setup some flags
        self.isFetching = False
        self.isDownloading = False

        # default output path
        self.outputPath = f'{QDir.homePath()}/videos'

        # setup some window specific things
        self.setWindowTitle('YouTube Downloader')
        self.setWindowIcon(QIcon('assets/yt-icon.ico'))
        self.setFixedSize(705, 343)

        # parent layout
        layout = QVBoxLayout()
        layout.setContentsMargins(15, 15, 15, 10)
        self.setLayout(layout)

        # top bar layout
        topBar = QHBoxLayout()

        # detail section
        detailSec = QHBoxLayout()
        metaSec = QVBoxLayout()

        # download section
        downloadSec = QHBoxLayout()
        downloadBtn = QVBoxLayout()

        # output path link button
        self.outputBtn = QPushButton('📂  Output Path')
        self.outputBtn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.outputBtn.setToolTip(self.outputPath)
        self.outputBtn.clicked.connect(self.setOutputPath)

        # status bar
        self.statusBar = QStatusBar()

        # message box
        self.message = QMessageBox()

        # setting up widgets
        self.urlBox = QLineEdit()
        self.urlBox.setFocusPolicy(Qt.FocusPolicy.ClickFocus or Qt.FocusPolicy.NoFocus)
        self.urlBox.setPlaceholderText('🔍 Enter or paste video URL...')
        self.button = QPushButton('Get')
        self.button.setDefault(True)
        self.button.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.button.clicked.connect(self.getDetails)

        # thumbnail
        pixmap = QPixmap('assets\placeholder.jpg')
        self.thumb = QLabel()
        self.thumb.setFixedSize(250, 141)
        self.thumb.setScaledContents(True)
        self.thumb.setPixmap(pixmap)

        # detail widgets
        self.title = QLabel('Title: ')
        self.author = QLabel('Author: ')
        self.length = QLabel('Duration: ')
        self.publish_date = QLabel('Published: ')

        # progress bar
        self.progress_bar = QProgressBar()
        
        # download options
        self.download = QComboBox()
        self.download.setPlaceholderText('Download Video')
        self.download.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.download.activated.connect(lambda: self.getContent(0))
        self.download.setEnabled(False)

        # download audio button
        self.download_audio = QPushButton('Download Audio')
        self.download_audio.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.download_audio.clicked.connect(lambda: self.getContent(1))
        self.download_audio.setEnabled(False)

        # add widgets and layouts
        topBar.addWidget(self.urlBox)
        topBar.addWidget(self.button)

        # detail section
        metaSec.addWidget(self.title)
        metaSec.addWidget(self.author)
        metaSec.addWidget(self.length)
        metaSec.addWidget(self.publish_date)
        detailSec.addWidget(self.thumb)
        detailSec.addSpacing(20)
        detailSec.addLayout(metaSec)

        # download section
        downloadBtn.addWidget(self.download)
        downloadBtn.addWidget(self.download_audio)
        downloadSec.addWidget(self.progress_bar)
        downloadSec.addSpacing(10)
        downloadSec.addLayout(downloadBtn)

        # status bar
        self.statusBar.setSizeGripEnabled(False)
        self.statusBar.addPermanentWidget(self.outputBtn)

        # add content to parent layout
        layout.addLayout(topBar)
        layout.addSpacing(20)
        layout.addLayout(detailSec)
        layout.addSpacing(5)
        layout.addLayout(downloadSec)
        layout.addWidget(self.statusBar)

        # setup a connection thread to keep checking internet connectivity
        self.connection = ConnectionThread()
        self.connection.start()

        # catch the connection response signal
        self.connection.con_response.connect(self.connection_slot)

    # connection slot
    def connection_slot(self, status):
        curMsg = self.statusBar.currentMessage()
        # connection succeeded
        if status:
            if curMsg == '🔴  Disconnected':
                self.statusBar.showMessage('🟢  Connection restored!', 3000)
            elif curMsg != '🟢  Connected':
                self.statusBar.showMessage('🟢  Connected')
        # connection failed
        elif curMsg == '🟢  Connected':
            self.statusBar.showMessage('🔴  Connection interrupted!', 3000)
        elif curMsg != '🔴  Disconnected': 
            self.statusBar.showMessage('🔴  Disconnected')

    # set output path slot
    def setOutputPath(self):
        # update the output path
        path = str(QFileDialog.getExistingDirectory(self, "Select Output Directory"))
        if path:
            self.outputPath = path
            # update tooltip
            self.outputBtn.setToolTip(path)

    # get button slot
    def getDetails(self):
        curMsg = self.statusBar.currentMessage()
        if curMsg == '🔴  Disconnected' or curMsg == '🔴  Connection interrupted!':
            self.message.critical(
                self,
                'Error',
                'Connection failed!\nAre you sure you\'re connected to the internet ? '
            )
        elif self.button.text() == 'Get':
            self.button.setText('Stop')
            # indicate progress bar as busy
            self.progress_bar.setRange(0, 0)
            # set fetching flag
            self.isFetching = True
            # setup a worker thread to keep UI responsive
            self.worker = WorkerThread(self.urlBox.text())
            self.worker.start()
            # catch the finished signal
            self.worker.finished.connect(self.finished_slot)
            # catch the response signal
            self.worker.worker_response.connect(self.response_slot)
            # catch the error signal
            self.worker.worker_err_response.connect(self.err_slot)
        elif self.button.text() == 'Stop':
            if self.isFetching:
                # stop worker thread
                self.worker.terminate()
                # set back the button text
                self.button.setText('Get')
            elif self.isDownloading:
                # stop download thread
                self.download_thread.terminate()
                # show the warning message
                self.message.information(
                    self,
                    'Interrupted',
                    'Download interrupted!\nThe process was aborted while the file was being downloaded... '
                )
                # reset pogress bar
                self.progress_bar.reset()

    # download options slot
    def getContent(self, id):
        if self.isFetching:
            # show the warning message
            self.message.warning(
                self,
                'Warning',
                'Please wait!\nWait while the details are being fetched... '
            )
        else:
            # disable the download options
            self.download.setDisabled(True)
            self.download_audio.setDisabled(True)
            # set downloading flag
            self.isDownloading = True
            # set button to stop 
            self.button.setText('Stop')
            # setup download thread
            if id == 0:
                self.download_thread = DownloadThread(self.yt, self.download.currentText()[:4], self.outputPath)
            else:
                self.download_thread = DownloadThread(self.yt, 'audio', self.outputPath)
            # start the thread
            self.download_thread.start()
            # catch the finished signal
            self.download_thread.finished.connect(self.download_finished_slot)
            # catch the response signal
            self.download_thread.download_response.connect(self.download_response_slot)
            # catch the complete signal
            self.download_thread.download_complete.connect(self.download_complete_slot)
            # catch the error signal
            self.download_thread.download_err.connect(self.download_err_slot)

    # finished slot
    def finished_slot(self):
        # remove progress bar busy indication
        self.progress_bar.setRange(0, 100)
        # unset fetching flag
        self.isFetching = False

    # response slot
    def response_slot(self, res):
        # set back the button text
        self.button.setText('Get')
        # save the yt object for speeding up download
        self.yt = res[0]
        # set the actual thumbnail of requested video
        self.thumb.setPixmap(res[1])
        # slice the title if it is more than the limit
        if len(res[2]) > 50:
            self.title.setText(f'Title:  {res[2][:50]}...')
        else:
            self.title.setText(f'Title:  {res[2]}')
        # set leftover details
        self.author.setText(f'Author:  {res[3]}')
        self.length.setText(f'Duration:  {timedelta(seconds=res[4])}')
        self.publish_date.setText(f'Published:  {res[5].strftime("%d/%m/%Y")}')
        # clear any previous items if any
        self.download.clear()
        # add resolutions as items to the download button and enable them
        self.download.addItems([item for item in res[6]])
        self.download.setDisabled(False)
        self.download_audio.setDisabled(False)

    # error slot
    def err_slot(self):
        # show the warning message
        self.message.warning(
            self,
            'Warning',
            'Something went wrong!\nProbably a broken link or some restricted content... '
        )
        # set back the button text
        self.button.setText('Get')

    # download finished slot
    def download_finished_slot(self):
        # set back the button text
        self.button.setText('Get')
        # now enable the download options
        self.download.setDisabled(False)
        self.download_audio.setDisabled(False)
        # unset downloading flag
        self.isDownloading = False
        # reset pogress bar
        self.progress_bar.reset()

    # download response slot
    def download_response_slot(self, per):
        # update progress bar
        self.progress_bar.setValue(per)
        # adjust the font color to maintain the contrast
        if per > 52:
            self.progress_bar.setStyleSheet('QProgressBar { color: #fff }')
        else:
            self.progress_bar.setStyleSheet('QProgressBar { color: #000 }')
    
    # download complete slot
    def download_complete_slot(self, location):
        # use native separators
        location = QDir.toNativeSeparators(location)
        # show the success message
        if self.message.information(
            self,
            'Downloaded',
            f'Download complete!\nFile was successfully downloaded to :\n{location}\n\nOpen the downloaded file now ?',
            QMessageBox.StandardButtons.Open,
            QMessageBox.StandardButtons.Cancel
        ) is QMessageBox.StandardButtons.Open: subprocess.Popen(f'explorer /select,{location}')

    # download error slot
    def download_err_slot(self):
        # show the error message
        self.message.critical(
            self,
            'Error',
            'Error!\nSomething unusual happened and was unable to download...'
        )
Ejemplo n.º 13
0
class B23Download(QWidget):
    def __init__(self):
        super(B23Download, self).__init__()
        # setup some flags
        self.is_fetching = False
        self.is_downloading = False

        # default output path
        basepath = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(basepath, "videos")
        self.output_path = path

        # setup some window specific things
        self.setWindowTitle("Bilibili Favorite Downloader")
        self.setWindowIcon(QIcon("images/icon_bilibili.ico"))
        self.setFixedSize(705, 343)

        # parent layout
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(15, 15, 15, 10)
        self.setLayout(main_layout)

        # top bar layout
        top_layout = QHBoxLayout()

        # detail section
        mid_main_layout = QHBoxLayout()
        mid_right_layout = QVBoxLayout()

        # download section
        bottom_main_layout = QHBoxLayout()
        bottom_right_layout = QVBoxLayout()

        # output path link button
        self.output_btn = QPushButton("📂  Output Path")
        self.output_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.output_btn.setToolTip(self.output_path)
        self.output_btn.clicked.connect(self.set_output_path)

        # status bar
        self.status_bar = QStatusBar()

        # message box
        self.message_box = QMessageBox()

        # setting up widgets
        self.url_edit = QLineEdit()
        self.url_edit.setPlaceholderText("🔍 Enter or paste favorite URL...")
        self.get_btn = QPushButton("Get")
        self.get_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.get_btn.clicked.connect(self.get_details)

        # thumbnail
        pixmap = QPixmap("images/placeholder.png")
        self.thumb = QLabel()
        self.thumb.setFixedSize(250, 141)
        self.thumb.setScaledContents(True)
        self.thumb.setPixmap(pixmap)

        # detail widgets
        self.title = QLabel("Title: ")
        self.author = QLabel("Author: ")
        self.length = QLabel("Videos: ")
        self.publish_date = QLabel("Published: ")

        # progress bar
        self.progress_bar = QProgressBar()

        # download options
        self.download_btn = QPushButton(" Download Videos ")
        self.download_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self.download_btn.clicked.connect(self.get_content)
        self.download_btn.setEnabled(False)
        self.download_btn.setShortcut("Ctrl+Return")
        self.download_btn.setMinimumWidth(200)

        # add widgets and layouts
        top_layout.addWidget(self.url_edit)
        top_layout.addWidget(self.get_btn)

        # detail section
        mid_right_layout.addWidget(self.title)
        mid_right_layout.addWidget(self.author)
        mid_right_layout.addWidget(self.length)
        mid_right_layout.addWidget(self.publish_date)
        mid_main_layout.addWidget(self.thumb)
        mid_main_layout.addSpacing(20)
        mid_main_layout.addLayout(mid_right_layout)

        # download section
        bottom_right_layout.addWidget(self.download_btn)
        bottom_main_layout.addWidget(self.progress_bar)
        bottom_main_layout.addSpacing(10)
        bottom_main_layout.addLayout(bottom_right_layout)

        # status bar
        self.status_bar.setSizeGripEnabled(False)
        self.status_bar.addPermanentWidget(self.output_btn)

        # add content to parent layout
        main_layout.addLayout(top_layout)
        main_layout.addSpacing(20)
        main_layout.addLayout(mid_main_layout)
        main_layout.addSpacing(5)
        main_layout.addLayout(bottom_main_layout)
        main_layout.addWidget(self.status_bar)

    # set output path slot
    def set_output_path(self):
        # update the output path
        path = str(
            QFileDialog.getExistingDirectory(self, "Select Output Directory"))
        if path:
            self.output_path = path
            # update tooltip
            self.output_btn.setToolTip(path)

    # get button slot
    def get_details(self):
        text = self.url_edit.text().strip()

        if not text:
            return

        if text.find("fid") < 0:
            self.message_box.warning(
                self,
                "Error",
                ("Input a correct favorite URL!\n"
                 "For example: https://space.bilibili.com/xxx/favlist?fid=xxx..."
                 ),
            )
            return

        if self.get_btn.text() == "Get":
            self.get_btn.setText("Stop")
            # indicate progress bar as busy
            self.progress_bar.setRange(0, 0)
            # set fetching flag
            self.is_fetching = True
            # setup a worker thread to keep UI responsive
            self.media_id = text.split("fid=")[-1].split("&")[0]
            self.worker = WorkerThread(self.media_id)
            self.worker.start()
            # catch the finished signal
            self.worker.finished.connect(self.finished_slot)
            # catch the response signal
            self.worker.worker_response.connect(self.response_slot)
            # catch the error signal
            self.worker.worker_err_response.connect(self.err_slot)
        elif self.get_btn.text() == "Stop":
            if self.is_fetching:
                # stop worker thread
                self.worker.terminate()
                # set back the get_btn text
                self.get_btn.setText("Get")
            elif self.is_downloading:
                # stop download thread
                self.download_thread.terminate()
                # show the warning message_box
                self.message_box.information(
                    self,
                    "Interrupted",
                    "Download interrupted!\nThe process was aborted while the file was being downloaded... ",
                )
                # reset progress bar
                self.progress_bar.reset()

    # download options slot
    def get_content(self):
        if self.is_fetching:
            # show the warning message
            self.message_box.critical(
                self,
                "Error",
                "Please wait!\nWait while the details are being fetched... ",
            )
        else:
            # disable the download options
            self.download_btn.setDisabled(True)
            # set downloading flag
            self.is_downloading = True
            # set button to stop
            self.get_btn.setText("Stop")
            self.download_thread = DownloadThread(
                self.media_id,
                self.media_counts,
                self.first_page_medias,
                self.output_path,
            )
            # start the thread
            self.download_thread.start()
            # catch the finished signal
            self.download_thread.finished.connect(self.download_finished_slot)
            # catch the response signal
            self.download_thread.download_response.connect(
                self.download_response_slot)
            # catch the complete signal
            self.download_thread.download_complete.connect(
                self.download_complete_slot)
            # catch the error signal
            self.download_thread.download_err.connect(self.download_err_slot)

    # handling enter key for get/stop button
    def keyPressEvent(self, event):
        self.url_edit.setFocus()
        if (event.key() == Qt.Key.Key_Enter.value
                or event.key() == Qt.Key.Key_Return.value):
            self.get_details()

    # finished slot
    def finished_slot(self):
        # remove progress bar busy indication
        self.progress_bar.setRange(0, 100)
        # unset fetching flag
        self.is_fetching = False

    # response slot
    def response_slot(self, res):
        # set back the button text
        self.get_btn.setText("Get")
        # set the actual thumbnail of requested video
        self.thumb.setPixmap(res.thumb_img)
        # slice the title if it is more than the limit
        if len(res.title) > 50:
            self.title.setText(f"Title: {res.title[:50]}...")
        else:
            self.title.setText(f"Title: {res.title}")
        # cache first page medias
        self.first_page_medias = res.medias
        self.media_counts = res.media_counts
        # set leftover details
        self.author.setText(f"Author: {res.author}")
        self.length.setText(f"Videos: {res.media_counts}")
        self.publish_date.setText(
            f'Published: {time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(res.publish_date))}'
        )
        self.download_btn.setDisabled(False)

    # error slot
    def err_slot(self):
        # show the warning message
        self.message_box.warning(
            self,
            "Warning",
            "Something went wrong!\nProbably a broken link or some restricted content... ",
        )
        # set back the button text
        self.get_btn.setText("Get")

    # download finished slot
    def download_finished_slot(self):
        # set back the button text
        self.get_btn.setText("Get")
        # now enable the download options
        self.download_btn.setDisabled(False)
        # unset downloading flag
        self.is_downloading = False
        # reset pogress bar
        self.progress_bar.reset()

    # download response slot
    def download_response_slot(self, per):
        # update progress bar
        self.progress_bar.setValue(per)
        # adjust the font color to maintain the contrast
        if per > 52:
            self.progress_bar.setStyleSheet("QProgressBar { color: #fff }")
        else:
            self.progress_bar.setStyleSheet("QProgressBar { color: #000 }")

    # download complete slot
    def download_complete_slot(self, location):
        # use native separators
        location = QDir.toNativeSeparators(location)
        # show the success message
        if (self.message_box.information(
                self,
                "Downloaded",
                f"Download complete!\nFile was successfully downloaded to :\n{location}\n\nOpen the downloaded file now ?",
                QMessageBox.StandardButtons.Open,
                QMessageBox.StandardButtons.Cancel,
        ) is QMessageBox.StandardButtons.Open):
            subprocess.Popen(f"explorer /select,{location}")

    # download error slot
    def download_err_slot(self):
        # show the error message
        self.message_box.critical(
            self,
            "Error",
            "Error!\nSomething unusual happened and was unable to download...",
        )
Ejemplo n.º 14
0
 def isDeviceAvailable(self):
     if not fgoKernel.device.available:
         self.LBL_DEVICE.clear()
         QMessageBox.critical(self, 'FGO-py', '未连接设备')
         return False
     return True
Ejemplo n.º 15
0
 def add_t_value(self):
     if self.add_value(self.t_setted_list, self.t_input.value(),
                       self.time_input.value()) is False:
         QMessageBox.critical(
             self, "Ошибка! ",
             "Выберите t меньше или равным времени наблюдения")
Ejemplo n.º 16
0
 def start_convergences_calculate(self):
     self.waiting_text_2.setText("Команда выполняется…")
     self.repaint()
     alpha = self.alpha_input.value()
     c = self.c_input.value()
     d = self.d_input.value()
     number = self.number_input_2.value()
     x_input = self.x_input_2.value()
     t_input = self.t_input_2.value()
     x_array = np.empty((self.tableWidget_by_t.rowCount() + 1),
                        dtype=object)
     x_functions = np.empty((self.tableWidget_by_t.rowCount() + 1),
                            dtype=object)
     x_labels = np.array([])
     t_labels = np.array([])
     t_array = np.empty((self.tableWidget_by_x.rowCount() + 1),
                        dtype=object)
     t_functions = np.empty((self.tableWidget_by_x.rowCount() + 1),
                            dtype=object)
     status_ok = True
     for i in range(self.tableWidget_by_t.rowCount()):
         if not self.tableWidget_by_t.item(
                 i, 0) or not self.tableWidget_by_t.item(i, 1):
             QMessageBox.critical(
                 self, "Ошибка! ",
                 "Наличие пустых/полупустых строк в таблицах недопустимо!")
             status_ok = False
             break
         x = linspace(0, self.length_input.value(),
                      int(self.tableWidget_by_t.item(i, 0).text()))
         t = linspace(0, self.time_input.value(),
                      int(self.tableWidget_by_t.item(i, 1).text()))
         field = self.methods[self.method_2](x, t, alpha, c, d, number)
         index, = np.where(x >= x_input)
         x_array[i] = t
         x_functions[i] = field[index[0]]
         x_labels = np.append(
             x_labels, "I=" + self.tableWidget_by_t.item(i, 0).text() +
             " K=" + self.tableWidget_by_t.item(i, 1).text())
     for i in range(self.tableWidget_by_x.rowCount()):
         if not self.tableWidget_by_x.item(
                 i, 0) or not self.tableWidget_by_x.item(i, 1):
             QMessageBox.critical(
                 self, "Ошибка! ",
                 "Наличие пустых/полупустых строк в таблицах недопустимо!")
             status_ok = False
             break
         x = linspace(0, self.length_input.value(),
                      int(self.tableWidget_by_x.item(i, 0).text()))
         t = linspace(0, self.time_input.value(),
                      int(self.tableWidget_by_x.item(i, 1).text()))
         field = self.methods[self.method_2](x, t, alpha, c, d, number)
         index, = np.where(t >= t_input)
         t_array[i] = x
         t_functions[i] = field.T[index[0]]
         t_labels = np.append(
             t_labels, "I=" + self.tableWidget_by_x.item(i, 0).text() +
             " K=" + self.tableWidget_by_x.item(i, 1).text())
     if status_ok:
         x = linspace(0, self.length_input.value(),
                      self.i_input_2.value())  # разбиение интервала длины
         t = linspace(0, self.time_input.value(),
                      self.k_input_2.value())  # разбиение интервала времени
         field = analytical_solution(x, t, alpha, c, d, number)
         index, = np.where(x >= x_input)
         x_array[-1] = t
         x_functions[-1] = field[index[0]]
         x_labels = np.append(x_labels, "Аналитическое решение")
         index, = np.where(t >= t_input)
         t_array[-1] = x
         t_functions[-1] = field.T[index[0]]
         t_labels = np.append(t_labels, "Аналитическое решение")
         x_labels = np.append(x_labels, " ")
         t_labels = np.append(t_labels, " ")
         plot(x_array, x_functions, x_labels, "t, с",
              "Сходимость решения u(x,t) к точному, x = " + str(x_input))
         plot(t_array, t_functions, t_labels, "x, см",
              "Сходимость решения u(x, t) к точному, t = " + str(t_input))
     self.waiting_text_2.setText("Нажмите «Старт» для начала работы.")
Ejemplo n.º 17
0
    def get_current_configuration(self) -> Union[Dict[str, Any], None]:
        if len(self.header_name_input.text()) == 0:
            QMessageBox.critical(self, "Input Data Error",
                                 "Header Name cannot be Empty!",
                                 QMessageBox.StandardButton.Ok,
                                 QMessageBox.StandardButton.Ok)
            return None

        if len(self.header_output_path_input.text()) == 0:
            QMessageBox.critical(self, "Input Data Error",
                                 "Header Output Path cannot be Empty!",
                                 QMessageBox.StandardButton.Ok,
                                 QMessageBox.StandardButton.Ok)
            return None

        if self.header_name_input.text()[self.header_name_input.text().find('.'):].lower() \
                not in ['.h', '.hh', '.hpp']:
            # noinspection PyTypeChecker

            if QMessageBox.StandardButton.Yes != QMessageBox.warning(
                    self, "Header Extension Unknown", """Header extension is
            not .h, .hpp or .hh, continue?""", QMessageBox.StandardButton.Yes
                    | QMessageBox.StandardButton.No,
                    QMessageBox.StandardButton.No):
                return None

        name_violations: [int] = []

        for i in range(len(self.warnings)):
            if not self.warnings[i]['Name']:
                name_violations.append(i)

        if name_violations:
            as_string = ''
            for i in name_violations:
                as_string += '  ' + str(i + 1) + '\n'
            if as_string:
                as_string = as_string[:-1]
            QMessageBox.critical(
                self, "Unnamed Warning Suppression",
                "The items at the following rows are not named:\n" + as_string,
                QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.Ok)

            return None

        type_violations: Dict[str, ([str], str)] = {}
        final_values: List[Dict[str, Union[str, int]]] = []

        for platform in self.platforms:
            for i in range(len(self.warnings)):
                while i >= len(final_values):
                    final_values.append({'Name': self.warnings[i]['Name']})

                if platform.warning_type.value == Platform.WarningType.INTEGER:
                    try:
                        if len(self.warnings[i][platform.platform_name]) == 0:
                            continue

                        final_values[i][platform.platform_name] = int(
                            self.warnings[i][platform.platform_name])
                    except ValueError:
                        if platform.platform_name not in type_violations.keys(
                        ):
                            type_violations[platform.platform_name] = (
                                [], 'Integer')

                        type_violations[platform.platform_name][0].append(
                            self.warnings[i]['Name'])

                if platform.warning_type.value == Platform.WarningType.COMMENT:
                    try:
                        if len(self.warnings[i][platform.platform_name]) == 0:
                            continue

                        final_values[i][platform.platform_name] = str(
                            self.warnings[i][platform.platform_name])
                    except ValueError:
                        if platform.platform_name not in type_violations.keys(
                        ):
                            type_violations[platform.platform_name] = (
                                [], 'Comment')

                        type_violations[platform.platform_name][0].append(
                            self.warnings[i]['Name'])

        if type_violations.keys():
            all_str: str = ''

            for key in type_violations.keys():
                current_str = f"{len(type_violations[key][0])} '{key}' platform violations, of type" \
                              f" '{type_violations[key][1]}':\n"

                for name in type_violations[key][0]:
                    current_str += f'  {name}\n'

                all_str += current_str + '\n'

            QMessageBox.critical(
                self, "Type Validation Error",
                "The following Warning Suppression Fields have type "
                "validation errors:\n" + all_str,
                QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.Ok)

            return None

        return self.get_current_configuration_from_values(final_values)
Ejemplo n.º 18
0
 def mapKey(self, x):
     if x and not fgoFunc.base.serialno:
         self.ui.MENU_CONTROL_MAPKEY.setChecked(False)
         return QMessageBox.critical(self, '错误', '未连接设备')