コード例 #1
0
from event_logger import EventLogger
from event_receiver_thread import EventReceiverThread
from command_thread import CommandThread
from command_tester import CommandTester

# def signal_handler(signal, frame):
#     print('You pressed Ctrl+Z!')

if __name__ == '__main__':
    # signal.signal(signal.SIGTSTP, signal_handler)

    outbound_queue = Queue()
    inbound_queue = Queue()
    command_thread = CommandThread(outbound_queue)
    command_thread.start()

    event_receiver_thread = EventReceiverThread(inbound_queue)
    event_receiver_thread.start()

    event_logger_thread = EventLogger(inbound_queue)
    event_logger_thread.start()

    command_tester = CommandTester(outbound_queue)
    command_tester.start()

    command_thread.join()
    event_receiver_thread.close()
    event_receiver_thread.join()
    event_logger_thread.join()
    command_tester.join()
コード例 #2
0
class ConfigSFTPDialog(QDialog, Ui_ConfigSFTPDialog):
    def __init__(self, window, just_save):
        QDialog.__init__(self)
        Ui_ConfigSFTPDialog.__init__(self)

        self.setupUi(self)
        self.window = window
        self.backup = None
        self.just_save = just_save

        if self.just_save:
            self.confirm_password_line_edit.hide()
            self.label_3.hide()

        self.browse_button.pressed.connect(self.browse)

    def browse(self):
        path, _ = QFileDialog.getOpenFileName()
        self.private_key_line_edit.setText(path)

    def command_done(self, res):
        self.setEnabled(True)

        ret, message = res
        if not ret:
            QMessageBox.warning(self.window, "Invalid details", message)
            return

        if self.just_save:
            Backups.save(self.backup)

        super().accept()

    def accept(self):
        name = self.name_line_edit.text().strip()
        password = self.password_line_edit.text()
        if self.just_save:
            confirm_password = password
        else:
            confirm_password = self.confirm_password_line_edit.text()
        private_key = self.private_key_line_edit.text()
        username = self.username_line_edit.text().strip()
        sftp_password = self.sftp_password_line_edit.text().strip()
        server = self.server_line_edit.text().strip()
        prefix = self.prefix_line_edit.text().strip()

        backup = Backup()
        backup.name = name
        backup.location = "SFTP"
        backup.password = password
        if len(private_key) is not 0:
            backup.sftp_private_key = private_key
        backup.sftp_username = username
        if len(sftp_password) is not 0:
            backup.sftp_password = sftp_password
        backup.sftp_server = server
        backup.cloud_prefix = prefix
        self.backup = backup

        fs = [
            Validator.validate_plan_name, Validator.validate_confirm_password,
            Validator.validate_non_empty, Validator.validate_non_empty,
            Validator.validate_non_empty, Validator.validate_no_space,
            Validator.validate_no_space, Validator.validate_no_space,
            Validator.validate_backend, Validator.validate_repo
        ]
        args = [(name, ), (password, confirm_password), ("Username", username),
                ("Server", server), ("Prefix", prefix), ("Server", server),
                ("Prefix", prefix), ("Username", username), (backup, ),
                (backup, self.just_save)]
        self.setEnabled(False)
        self.thread = CommandThread(config_worker, {"fs": fs, "args": args})
        self.thread.result.connect(self.command_done)
        self.thread.start()
コード例 #3
0
class ConfigAwsDialog(QDialog, Ui_ConfigAwsDialog):
    def __init__(self, window, just_save=False):
        QDialog.__init__(self)
        Ui_ConfigAwsDialog.__init__(self)

        self.setupUi(self)
        self.window = window
        self.backup = None
        self.just_save = just_save

        if self.just_save:
            self.confirm_password_line_edit.hide()
            self.label_3.hide()

    def command_done(self, res):
        self.setEnabled(True)

        ret, message = res
        if not ret:
            QMessageBox.warning(self.window, "Invalid details", message)
            return

        if self.just_save:
            Backups.save(self.backup)

        super().accept()

    def accept(self):
        name = self.name_line_edit.text().strip()
        password = self.password_line_edit.text()
        if self.just_save:
            confirm_password = password
        else:
            confirm_password = self.confirm_password_line_edit.text()
        key_id = self.key_id_line_edit.text().strip()
        key = self.key_line_edit.text().strip()
        bucket = self.bucket_line_edit.text().strip()
        prefix = self.prefix_line_edit.text().strip()

        backup = Backup()
        backup.name = name
        backup.location = "Amazon AWS"
        backup.password = password
        backup.aws_key_id = key_id
        backup.aws_key = key
        backup.aws_bucket = bucket
        backup.cloud_prefix = prefix
        self.backup = backup

        fs = [
            Validator.validate_plan_name, Validator.validate_confirm_password,
            Validator.validate_non_empty, Validator.validate_non_empty,
            Validator.validate_non_empty, Validator.validate_non_empty,
            Validator.validate_no_space, Validator.validate_no_space,
            Validator.validate_backend, Validator.validate_repo
        ]
        args = [(name, ), (password, confirm_password), ("AWS Key Id", key_id),
                ("AWS Key", key), ("Bucket", bucket), ("Prefix", prefix),
                ("Bucket", bucket), ("Prefix", prefix), (backup, ),
                (backup, self.just_save)]
        self.setEnabled(False)
        self.thread = CommandThread(config_worker, {"fs": fs, "args": args})
        self.thread.result.connect(self.command_done)
        self.thread.start()
コード例 #4
0
def main(config, thread=False):
    """ 主函数 

    config: {'server': {host:, port:, db:}
            }
    """

    server = config['server']
    # 动态注册task
    for module in server['modules'].split():
        try:
            __import__(module)
        except ImportError:
            modules = module.split('.')
            __import__(modules[0], globals(), locals(), modules[1])

    # 连结服务器
    redis_host = server['host']
    redis_port = int(server['port'])
    redis_db = int(server['db'])
    ztq_core.setup_redis('default',
                         host=redis_host,
                         port=redis_port,
                         db=redis_db)

    # 开启一个命令线程
    alias = server.get('alias', '')
    if not alias:
        alias = get_ip()
        server['alias'] = alias

    command_thread = CommandThread(worker_name=alias)

    sys.stdout.write('Starting server in PID %s\n' % os.getpid())

    worker_state = ztq_core.get_worker_state()
    active_config = server.get('active_config', 'false')

    # 计算那些是需要根据线上配置启动的队列
    active_queue_config = {}
    if active_config.lower(
    ) == 'true' and command_thread.worker_name in worker_state:
        # 如果服务器有这个机器的配置信息,需要自动启动工作线程
        worker_config = ztq_core.get_worker_config()
        active_queue_config = worker_config.get(command_thread.worker_name, {})

    # 根据本地配置,启动的队列
    local_queue_config = {}
    if config['queues']:
        # 把worker监视队列的情况上报到服务器
        queue_config = ztq_core.get_queue_config()
        # 如果配置有queues,自动启动线程监视
        for queue_name, sleeps in config['queues'].items():
            # 线上配置稍后再设置
            if queue_name in active_queue_config: continue

            local_queue_config[queue_name] = [{
                'interval': int(sleep)
            } for sleep in sleeps.split(',')]
            if not queue_config.get(queue_name, []):
                queue_config[queue_name] = {
                    'name': queue_name,
                    'title': queue_name,
                    'widget': 5
                }

    # 合并线上和线下的配置
    active_queue_config.update(local_queue_config)
    init_job_threads(active_queue_config)

    loggers = config['log']
    initlog(
        loggers.get('key', 'ztq_worker'),
        loggers.get('handler_file'),
        loggers.get('level', 'ERROR'),
    )

    # 不是以线程启动
    if thread:
        command_thread.setDaemon(True)
        command_thread.start()
    else:
        command_thread.run()
コード例 #5
0
class ConfigGcpDialog(QDialog, Ui_ConfigGcpDialog):
    def __init__(self, window, just_save):
        QDialog.__init__(self)
        Ui_ConfigGcpDialog.__init__(self)

        self.setupUi(self)
        self.window = window
        self.backup = None
        self.just_save = just_save

        if self.just_save:
            self.confirm_password_line_edit.hide()
            self.label_3.hide()

        self.browse_button.pressed.connect(self.browse)

    def browse(self):
        path, _ = QFileDialog.getOpenFileName()
        self.cred_file_line_edit.setText(path)

    def command_done(self, res):
        self.setEnabled(True)

        ret, message = res 
        if not ret:
            QMessageBox.warning(self.window, "Invalid details", message)
            return

        if self.just_save:
            Backups.save(self.backup)

        super().accept()

    def accept(self):
        name = self.name_line_edit.text().strip()
        password = self.password_line_edit.text()
        if self.just_save:
            confirm_password = password
        else:
            confirm_password = self.confirm_password_line_edit.text()
        cred_file = self.cred_file_line_edit.text()
        project = self.project_line_edit.text().strip()
        bucket = self.bucket_line_edit.text().strip()
        prefix = self.prefix_line_edit.text().strip()

        backup = Backup()
        backup.name = name
        backup.location = "Google Cloud"
        backup.password = password
        backup.gcp_cred_file = cred_file
        backup.gcp_project = project
        backup.gcp_bucket = bucket
        backup.cloud_prefix = prefix
        self.backup = backup

        fs = [Validator.validate_plan_name, Validator.validate_confirm_password,
            Validator.validate_local_path, Validator.validate_non_empty,
            Validator.validate_non_empty, Validator.validate_non_empty,
            Validator.validate_no_space, Validator.validate_no_space,
            Validator.validate_backend, Validator.validate_repo]
        args = [(name, ), (password, confirm_password), (cred_file, ),
            ("Project", project), ("Bucket", bucket), ("Prefix", prefix),
            ("Bucket", bucket), ("Prefix", prefix), (backup, ),
            (backup, self.just_save)]
        self.setEnabled(False)
        self.thread = CommandThread(config_worker, {"fs": fs, "args": args})
        self.thread.result.connect(self.command_done)
        self.thread.start()
コード例 #6
0
ファイル: main_qt.py プロジェクト: tyallen22/PyHand_Earth
class MainWindow(QMainWindow):
    """
    This is a class that creates a PyQt5 window containing start, stop, and exit buttons as
    well as gesture icons. The window is the main window for our program.

    Attributes:
        commands: KeyboardCommand class object
        capture: QtCapture class object
        camera: OpenCV camera object
        command_thread: CommandThread class object
        google_earth: GoogleEarth class object
        popup_window: QMessageBox object
        popup_title (string) : Pop up window title
        popup_text (string) : Pop up window body text
        desktop : Available screen geometry based on current screen resolution
        screen : Total screen geometry based on current screen resolution
        qt_window_height (int) : Calculated value for gesture icon window size
        layout : Instantiate QVBoxLayout or QHBoxLayout classes, used for aligning images and
            buttons
        label_dict (dict) : Contains labels that are used to display gesture icon images
        image_list (list) : Contains names of image files for gesture icon images
        title_list (list) : Contains names of titles for corresponding gesture images
        state_machine: Instantiate QStateMachine class, used to control state of program buttons
        label : Instantiate QLabel class, labels used to hold gesture icon images and text
        button : Instantiate QPushButton class, buttons used to start, stop, and exit program
        widget : Insantiate QWidget class, contains and displays labels and buttons

    Args:
        earth : GoogleEarth class object
        desk_geo: Available screen geometry
        screen_geo: Total screen geometry
    """
    # Signals for updating state of state machine
    onSignal = pyqtSignal()
    offSignal = pyqtSignal()

    def __init__(self, earth, desk_geo, screen_geo, *args, **kwargs):
        """
        Please see help(MainWindow) for more info.
        """
        super(MainWindow, self).__init__(*args, **kwargs)
        # Instantiate KeyboardCommands class
        self.commands = KeyboardCommands()
        # Will hold hand_recognition QtCapture class
        self.capture = None
        # Will hold camera object for OpenCV
        self.camera = None
        # Will hold thread for issuing GE commands
        self.command_thread = None
        # Make Qt gesture icon window frameless
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        # Get resolution, window size, and offsets for positioning
        self.google_earth = earth
        # Variables for popup windows
        self.popup_window = None
        self.popup_title = ""
        self.popup_text = ""
        # Available screen geometry
        self.desktop = desk_geo
        # Total screen geometry
        self.screen = screen_geo
        # Sets gesture icon window to be 1/4 of available screen space
        self.qt_window_height = int(self.desktop.height() * 1 / 4)
        # Set geometry of Qt gesture icon window
        self.setGeometry(
            QtWidgets.QStyle.alignedRect(
                QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
                QtCore.QSize(self.desktop.width(), self.qt_window_height),
                self.desktop))
        # Create layouts for organizing Qt gesture icon window
        self.layout = QVBoxLayout()
        self.layout1 = QHBoxLayout()
        self.layout2 = QHBoxLayout()
        self.layout3 = QHBoxLayout()
        # Dictionary to hold labels once they are created
        self.label_dict = dict()
        # Lists hold gesture icon file names and gesture icon titles
        self.image_list = [
            'images/index_up.png', 'images/v_sign.png',
            'images/thumb_left.png', 'images/thumb_right.png',
            'images/fist.png', 'images/five_wide.png', 'images/palm.png',
            'images/shaka.png'
        ]
        self.title_list = [
            'Move Up', 'Move Down', 'Move Left', 'Move Right', 'Zoom In',
            'Zoom Out', 'Tilt Up', 'Tilt Down'
        ]
        # Create and add 6 labels containing hand gesture image to layout2 and 6
        # labels with the gesture descriptions to layout1
        for num in range(0, 8):
            # Each label is created to hold gesture icon image
            self.label = QLabel(self)
            # Pixmap is created with the current gesture icon image
            self.pixmap = QPixmap(self.image_list[num])
            # Breakpoints to scale size of gesture icons for different resolutions
            if self.screen.width() >= 2560:
                self.pixmap = self.pixmap.scaledToWidth(225)
            elif self.screen.width() >= 1920:
                self.pixmap = self.pixmap.scaledToWidth(185)
            elif self.screen.width() > 1280 and self.screen.height() >= 1200:
                self.pixmap = self.pixmap.scaledToWidth(175)
            elif self.screen.width() > 800 and self.screen.height() >= 1024:
                self.pixmap = self.pixmap.scaledToWidth(125)
            elif self.screen.width() > 800:
                self.pixmap = self.pixmap.scaledToWidth(100)
            else:
                self.pixmap = self.pixmap.scaledToWidth(50)
            # Assigns gesture icon image to the current label
            self.label.setPixmap(self.pixmap)
            # Create gesture title label for the image
            self.label_title = QLabel(self.title_list[num])
            # Store current icon image label in dictionary
            self.label_dict[num] = self.label
            # Place current icon image label in layout
            self.layout2.addWidget(self.label_dict[num],
                                   alignment=QtCore.Qt.AlignCenter)
            # Place current icon image title label in layout
            self.layout1.addWidget(self.label_title,
                                   alignment=QtCore.Qt.AlignCenter)

        # Create state machine to reliably handle state changes during threading
        self.state_machine = QStateMachine()
        # Create button to handle state changes when pressed
        self.state_button = QPushButton(self)
        self.state_button.setStyleSheet("background-color: silver")
        # Connect button released signal to check_state slot
        self.state_button.released.connect(self.check_state)
        # Create on state for state machine
        self.on = QState()
        # Create off state for state machine
        self.off = QState()
        # Add transition for on state to off state when offSignal is emitted
        self.on.addTransition(self.offSignal, self.off)
        # Add transition for on state to on state when state_button clicked signal emitted
        self.on.addTransition(self.state_button.clicked, self.on)
        # Add transition for off state to on state when onSignal is emitted
        self.off.addTransition(self.onSignal, self.on)
        # Assign text property to state_button in on state
        self.on.assignProperty(self.state_button, "text",
                               "Start Gesture Navigation")
        # Assign text property to state_button in off state
        self.off.assignProperty(self.state_button, "text",
                                "Stop Gesture Navigation")
        # Add off state to state machine
        self.state_machine.addState(self.off)
        # Add on state to state machine
        self.state_machine.addState(self.on)
        # Set state machine initial state to on
        self.state_machine.setInitialState(self.on)
        # State state machine
        self.state_machine.start()
        # Create gesture tips button and connect it to start_gesture_tips slot
        self.tips_button = QPushButton("Gesture Navigation Tips")
        self.tips_button.setStyleSheet("background-color: silver")
        self.tips_button.pressed.connect(self.start_gesture_tips)
        # Create exit button and connect it to exit slot
        self.exit_button = QPushButton("Exit Program")
        self.exit_button.setStyleSheet("background-color: silver")
        self.exit_button.pressed.connect(self.exit)
        # Add tips, state, and exit button to layout 3
        self.layout3.addWidget(self.tips_button)
        self.layout3.addWidget(self.state_button)
        self.layout3.addWidget(self.exit_button)
        # Add layout 1, 2, and 3 to layout
        self.layout.addLayout(self.layout1)
        self.layout.addLayout(self.layout2)
        self.layout.addLayout(self.layout3)
        # Create widget to hold layout, add layout to widget
        self.widget = QWidget()
        self.widget.setLayout(self.layout)
        # Set widget with layouts as central widget
        self.setCentralWidget(self.widget)

    # Function to display pop up windows and block GUI loop until closed
    def show_popup(self, title, message, icon):
        """
        Function to create a pop up window that blocks the event loop until it is closed.
        Used to send info or warning messages.

        Parameters:
            title (string) : Title of pop up window
            message (string) : Body text of pop up window
            icon : QMessageBox icon to be displayed
        """
        # Create QMessageBox for pop up message
        self.popup_window = QMessageBox()
        # Set pop up title to passed in title
        self.popup_window.setWindowTitle(title)
        # Set pop up body text to passed in message
        self.popup_window.setText(message)
        # Set pop up icon to passed in icon
        self.popup_window.setIcon(icon)
        # Set pop up window to use Ok close button
        self.popup_window.setStandardButtons(QMessageBox.Ok)
        # Execute pop up window so that it blocks GUI loop until closed
        self.popup_window.exec()

    # Check state of state machine, take actions based on current state
    def check_state(self):
        """
        Function to check the current state of the state machine. Calls check_earth_tips
        if in on state, calls stop_opencv if in off state.
        """
        current_state = self.state_machine.configuration()

        if self.on in current_state:
            self.check_earth_tips()
        elif self.off in current_state:
            self.stop_opencv()

    def start_gesture_tips(self):
        """
        Function to create PyHand Earth gesture navigation tips window.
        """
        # Sets title of pop up window
        self.popup_title = "Welcome to PyHand Earth!"
        # Sets body text of pop up window
        self.popup_text = """\nThis program allows you to navigate the Google Earth Pro desktop application using only your Webcam and eight hand gestures.
                             \n\t       Instructions and Tips 
                             \n\nFor the best experience, please read the instructions below and then close this window: 
                             \n\n1. Position your webcam so that you have a blank, light-colored background behind you. 
                             \n\n2. Position your right hand and desired gesture in front of the webcam so that it fills a good portion of the orange bounding rectangle in the live video window once it opens. 
                             \n\n3. If the prediction is stuck on the wrong gesture, just shake your hand a little and let it reset. 
                             \n\n4. If you remove your hand completely and have a blank background, navigation should halt. 
                             \n\n5. Happy navigating! """
        # Calls show_popup to create pop up window
        self.show_popup(self.popup_title, self.popup_text,
                        QMessageBox.Information)

    def check_earth_tips(self):
        """
        Called by check_state when state machine is in on state. Checks to see if Google Earth
        Start-up Tips window is open, and asks user to close the window with a pop up window
        message. If Google Earth Start-up Tips window is closed, calls open_camera.
        """
        # Checks if Google Earth start-up tips window is open
        if self.google_earth.start_up_tips():
            # Sets title of pop up window
            self.popup_title = "Gesture Navigation Warning Message"
            # Sets body text of pop up window
            self.popup_text = "Please make sure the Start-up Tips window is closed before " + \
                              "starting gesture navigation"
            # Calls show_popup to create pop up window
            self.show_popup(self.popup_title, self.popup_text,
                            QMessageBox.Warning)
        else:
            # If Google Earth start-up tips window now open, calls open_camera
            self.open_camera()

    def open_camera(self):
        """
        Function to create OpenCV VideoCapture object. If camera is not found, creates pop up window
        message to warn user and ask them to connect a camera. If camera is found, calls
        start_opencv.
        """
        # Creates cv2 VideoCapture object, passing in -1 to find first active camera
        self.camera = cv2.VideoCapture(-1)
        # If camera is not found, create pop up window to warn the user
        if self.camera is None or not self.camera.isOpened():
            # Sets title of pop up window
            self.popup_title = "No Camera Found Warning Message"
            # Sets body text of pop up window
            self.popup_text = "No camera has been detected. \n\nPlease connect a camera before " + \
                              "starting gesture navigation.\n"
            # Calls show_popup to create pop up window
            self.show_popup(self.popup_title, self.popup_text,
                            QMessageBox.Warning)
        else:
            # If camera is found, calls start_opencv
            self.start_opencv()

    def start_opencv(self):
        """
        Function to start the OpenCV gesture navigation window. Repositions the Google Earth window
        to take up half of the screen, then calls create_opencv to instantiate QtCapture window. The
        CommandThread class object is then instantiated to begin sending commands generated in the
        CaptureThread class to Google Earth. The QtCapture window is then displayed. Finally, the
        offSignal is emitted to change the state machine to the off state and the tips_button is
        disabled to prevent tips from being shown while gesture navigation is active.
        """
        # Repositions Google Earth to take up one half of the available screen size
        self.google_earth.reposition_earth_small()
        # If opencv window not created, create it
        if not self.capture:
            self.create_opencv()
        else:
            self.capture = None
            self.create_opencv()
        # If command thread exists, remove it
        if self.command_thread:
            self.command_thread = None
        # Start command thread for sending commands to GE
        self.command_thread = CommandThread(self.capture, self.commands)
        self.command_thread.start()
        # Show opencv window
        self.capture.show()
        # Emits offSignal to ensure button in correct state
        self.offSignal.emit()
        # Disable tips button while gesture navigation is active
        self.tips_button.setEnabled(False)

    def create_opencv(self):
        """
        Creates QtCapture window to display the OpenCV window frames. Resizes and repositions
        the QtCapture window based on current monitor resolution.
        """
        # Create QtCapture window for rendering opencv window
        self.capture = QtCapture(self.desktop, self.screen, self.camera)
        self.capture.setParent(self.widget)
        self.capture.setWindowFlags(QtCore.Qt.Tool)
        self.capture.setWindowTitle("OpenCV Recording Window")
        # Get new height based on available screen space minus an offset for the window title
        new_height = int((self.desktop.height() * 3 / 4) - 35)
        # Get width that is half of the available screen space
        half_width = int(self.desktop.width() / 2)
        # Breakpoints to resize and reposition QtCapture window based on current monitor resolution
        if self.screen.width() > 1280:
            window_x = int(self.desktop.width() / 2) + (self.screen.width() -
                                                        self.desktop.width())
            self.capture.setGeometry(window_x, 0, half_width, new_height)
        elif self.screen.width() > 1152:
            new_width = int((self.desktop.width() * 29 / 64) + 3)
            window_x = int(half_width + (half_width - new_width) +
                           (self.screen.width() - self.desktop.width()))
            self.capture.setGeometry(window_x, 0, new_width, new_height)
        elif self.screen.width() > 1024:
            new_width = int((self.desktop.width() * 25 / 64))
            window_x = int(half_width + (half_width - new_width) +
                           (self.screen.width() - self.desktop.width()))
            self.capture.setGeometry(window_x, 0, new_width, new_height)
        else:
            new_width = int((self.desktop.width() * 20 / 64) - 3)
            window_x = int(half_width + (half_width - new_width) +
                           (self.screen.width() - self.desktop.width()))
            self.capture.setGeometry(window_x, 0, new_width, new_height)

    def stop_opencv(self):
        """
        Function to close the QtCapture OpenCV window and stop commands being sent to Google
        Earth.
        """
        # Sends request to end the Google Earth command thread
        self.command_thread.end_thread()
        time.sleep(1)

        # If capture object exists, end thread, release camera, and close window
        if self.capture:
            self.capture.stop_thread()
            time.sleep(1)
            self.capture.delete()
            self.capture.setParent(None)
        # Repositions Google Earth to take up full width of available screen space
        self.google_earth.reposition_earth_large()
        # Emits onSignal to ensure button in correct state
        self.onSignal.emit()
        # Enable tips when gesture navigation is not active
        self.tips_button.setEnabled(True)

    def exit(self):
        """
        Slot function for exit button signal. Stops commands being sent to Google Earth,
        ends the OpenCV window thread if running, closes Google Earth, and exits the Qt
        application.
        """
        # If the command thread is running, request thread end
        if self.command_thread:
            self.command_thread.end_thread()
            time.sleep(1)

        # If the capture thread is running, request thread end
        if self.capture:
            self.capture.stop_thread()
            time.sleep(1)
        # Close the Google Earth window
        self.google_earth.close_earth()
        # Quit the Qt application, returning to main
        QtCore.QCoreApplication.instance().quit()
コード例 #7
0
ファイル: main.py プロジェクト: arw180/firebase-example
from event_receiver_thread import EventReceiverThread
from command_thread import CommandThread
from command_tester import CommandTester


# def signal_handler(signal, frame):
#     print('You pressed Ctrl+Z!')


if __name__ == '__main__':
    # signal.signal(signal.SIGTSTP, signal_handler)

    outbound_queue = Queue()
    inbound_queue = Queue()
    command_thread = CommandThread(outbound_queue)
    command_thread.start()

    event_receiver_thread = EventReceiverThread(inbound_queue)
    event_receiver_thread.start()

    event_logger_thread = EventLogger(inbound_queue)
    event_logger_thread.start()

    command_tester = CommandTester(outbound_queue)
    command_tester.start()

    command_thread.join()
    event_receiver_thread.close()
    event_receiver_thread.join()
    event_logger_thread.join()
    command_tester.join()
コード例 #8
0
ファイル: main.py プロジェクト: everydo/ztq
def main(config, thread=False):
    """ 主函数 

    config: {'server': {host:, port:, db:}
            }
    """

    server = config["server"]
    # 动态注册task
    for module in server["modules"].split():
        try:
            __import__(module)
        except ImportError:
            modules = module.split(".")
            __import__(modules[0], globals(), locals(), modules[1])

    # 连结服务器
    redis_host = server["host"]
    redis_port = int(server["port"])
    redis_db = int(server["db"])
    ztq_core.setup_redis("default", host=redis_host, port=redis_port, db=redis_db)

    # 开启一个命令线程
    alias = server.get("alias", "")
    if not alias:
        alias = get_ip()
        server["alias"] = alias

    command_thread = CommandThread(worker_name=alias)

    sys.stdout.write("Starting server in PID %s\n" % os.getpid())

    worker_state = ztq_core.get_worker_state()
    active_config = server.get("active_config", "false")

    # 计算那些是需要根据线上配置启动的队列
    active_queue_config = {}
    if active_config.lower() == "true" and command_thread.worker_name in worker_state:
        # 如果服务器有这个机器的配置信息,需要自动启动工作线程
        worker_config = ztq_core.get_worker_config()
        active_queue_config = worker_config.get(command_thread.worker_name, {})

    # 根据本地配置,启动的队列
    local_queue_config = {}
    if config["queues"]:
        # 把worker监视队列的情况上报到服务器
        queue_config = ztq_core.get_queue_config()
        # 如果配置有queues,自动启动线程监视
        for queue_name, sleeps in config["queues"].items():
            # 线上配置稍后再设置
            if queue_name in active_queue_config:
                continue

            local_queue_config[queue_name] = [{"interval": int(sleep)} for sleep in sleeps.split(",")]
            if not queue_config.get(queue_name, []):
                queue_config[queue_name] = {"name": queue_name, "title": queue_name, "widget": 5}

    # 合并线上和线下的配置
    active_queue_config.update(local_queue_config)
    init_job_threads(active_queue_config)

    loggers = config["log"]
    initlog(loggers.get("key", "ztq_worker"), loggers.get("handler_file"), loggers.get("level", "ERROR"))

    # 不是以线程启动
    if thread:
        command_thread.setDaemon(True)
        command_thread.start()
    else:
        command_thread.run()
コード例 #9
0
class ConfigLocalDialog(QDialog, Ui_ConfigLocalDialog):
    def __init__(self, window, just_save=False):
        QDialog.__init__(self)
        Ui_ConfigLocalDialog.__init__(self)

        self.setupUi(self)
        self.window = window
        self.backup = None

        self.just_save = just_save

        if self.just_save:
            self.confirm_password_line_edit.hide()
            self.label_3.hide()

        self.browse_button.pressed.connect(self.browse)

    def browse(self):
        directory = QFileDialog.getExistingDirectory()
        self.local_directory_line_edit.setText(directory)

    def command_done(self, res):
        self.setEnabled(True)

        ret, message = res
        if not ret:
            QMessageBox.warning(self.window, "Invalid details", message)
            return

        if self.just_save:
            Backups.save(self.backup)

        super().accept()

    def accept(self):
        name = self.name_line_edit.text().strip()
        password = self.password_line_edit.text()
        if self.just_save:
            confirm_password = password
        else:
            confirm_password = self.confirm_password_line_edit.text()
        directory = self.local_directory_line_edit.text()

        backup = Backup()
        backup.name = name
        backup.location = "Local Directory"
        backup.password = password
        backup.local_directory = directory
        self.backup = backup

        fs = [
            Validator.validate_plan_name, Validator.validate_confirm_password,
            Validator.validate_local_path, Validator.validate_backend,
            Validator.validate_repo
        ]
        args = [(name, ), (password, confirm_password), (directory, ),
                (backup, ), (backup, self.just_save)]
        self.setEnabled(False)
        self.thread = CommandThread(config_worker, {"fs": fs, "args": args})
        self.thread.result.connect(self.command_done)
        self.thread.start()
コード例 #10
0
class BackupSettings(QDialog, Ui_BackupSettingsDialog):
    def __init__(self, backup, window, edit=False):
        QDialog.__init__(self)
        Ui_BackupSettingsDialog.__init__(self)

        self.setupUi(self)
        self.backup = backup
        self.window = window
        self.edit = edit
        self.paths = set()
        self.exclude_rules = set()

        self.map = {
            "mon": self.mon_checkbox,
            "tue": self.tue_checkbox,
            "wed": self.wed_checkbox,
            "thu": self.thu_checkbox,
            "fri": self.fri_checkbox,
            "sat": self.sat_checkbox,
            "sun": self.sun_checkbox
        }
        self.days_checked = set()

        prefix = self.backup.cloud_prefix if self.backup.cloud_prefix is not None else self.backup.local_directory
        window_title = f"{self.backup.location} ({prefix})"

        # Hiding unsupported add file button for now
        self.add_file_button.hide()

        self.add_button.pressed.connect(self.add_folder)
        self.add_file_button.pressed.connect(self.add_file)
        self.remove_button.pressed.connect(self.remove_folder)

        self.add_exclude_rule.pressed.connect(self.add_rule)
        self.remove_exclude_rule.pressed.connect(self.remove_rule)

        self.group_schedule = QButtonGroup()
        self.group_schedule.addButton(self.manual_radio_button)
        self.group_schedule.addButton(self.backup_every_radio_button)
        self.group_schedule.addButton(self.daily_radio_button)

        self.group_retention = QButtonGroup()
        self.group_retention.addButton(self.forever_radio_button)
        self.group_retention.addButton(self.keep_last_radio_button)

        self.forever_radio_button.setChecked(True)
        self.manual_radio_button.setChecked(True)

        self.daily_radio_button.pressed.connect(self.daily_radio_pressed)
        self.backup_every_radio_button.pressed.connect(
            self.backup_every_pressed)
        self.manual_radio_button.pressed.connect(self.manual_radio_pressed)

        self.forever_radio_button.pressed.connect(
            lambda: self.days_spin_box.setEnabled(False))
        self.keep_last_radio_button.pressed.connect(
            lambda: self.days_spin_box.setEnabled(True))

        self.mon_checkbox.clicked.connect(
            lambda: self.state_changed("mon", self.mon_checkbox))
        self.tue_checkbox.clicked.connect(
            lambda: self.state_changed("tue", self.tue_checkbox))
        self.wed_checkbox.clicked.connect(
            lambda: self.state_changed("wed", self.wed_checkbox))
        self.thu_checkbox.clicked.connect(
            lambda: self.state_changed("thu", self.thu_checkbox))
        self.fri_checkbox.clicked.connect(
            lambda: self.state_changed("fri", self.fri_checkbox))
        self.sat_checkbox.clicked.connect(
            lambda: self.state_changed("sat", self.sat_checkbox))
        self.sun_checkbox.clicked.connect(
            lambda: self.state_changed("sun", self.sun_checkbox))

        self.activation_label.hide()
        self.setWindowTitle(window_title)

        self.thread_count_spin_box.setValue(DEFAULT_THREAD_COUNT)
        self.compression_level_spin_box.setValue(DEFAULT_COMPRESSION_LEVEL)

        self.populate()

    def daily_radio_pressed(self):
        self.set_days(True)
        self.set_every(False)

    def backup_every_pressed(self):
        self.set_every(True)
        self.set_days(False)

    def manual_radio_pressed(self):
        self.set_days(False)
        self.set_every(False)

    def state_changed(self, day, checkbox):
        if checkbox.isChecked():
            self.days_checked.add(day)
        else:
            self.days_checked.remove(day)

    def set_every(self, status):
        self.hourly_spinbox.setEnabled(status)
        self.mins_spinbox.setEnabled(status)
        self.label_2.setEnabled(status)
        self.label_3.setEnabled(status)

    def set_days(self, status):
        self.schedule_time_edit.setEnabled(status)
        self.mon_checkbox.setEnabled(status)
        self.tue_checkbox.setEnabled(status)
        self.wed_checkbox.setEnabled(status)
        self.thu_checkbox.setEnabled(status)
        self.fri_checkbox.setEnabled(status)
        self.sat_checkbox.setEnabled(status)
        self.sun_checkbox.setEnabled(status)

    def populate(self):
        if self.backup.paths is not None:
            self.paths = self.backup.paths
        self.reload_paths()

        if self.backup.exclude_rules is not None:
            self.exclude_rules = self.backup.exclude_rules
        self.reload_exclude_rules()

        self.set_days(False)
        if self.backup.backup_daily_time is not None:
            self.set_days(True)
            self.daily_radio_button.setChecked(True)
            self.schedule_time_edit.setTime(self.backup.backup_daily_time)

        self.set_every(False)
        if self.backup.every_hour is not None and self.backup.every_min is not None:
            self.set_every(True)
            self.backup_every_radio_button.setChecked(True)
            self.hourly_spinbox.setValue(self.backup.every_hour)
            self.mins_spinbox.setValue(self.backup.every_min)

        self.days_spin_box.setEnabled(False)
        if self.backup.retention is not None:
            self.days_spin_box.setEnabled(True)
            self.keep_last_radio_button.setChecked(True)
            self.days_spin_box.setValue(self.backup.retention)

        if self.backup.backup_days is not None:
            days = self.backup.backup_days.split(",")
            for checkbox in self.map.values():
                checkbox.setChecked(False)
            for day in days:
                self.days_checked.add(day)
                self.map[day].setChecked(True)

        self.thread_count_spin_box.setValue(self.backup.thread_count)
        self.compression_level_spin_box.setValue(self.backup.compression_level)

    def reload_exclude_rules(self):
        self.exclude_rules_list_widget.clear()
        for rule in self.exclude_rules:
            self.exclude_rules_list_widget.addItem(rule)

    def reload_paths(self):
        self.paths_list_widget.clear()
        for path in self.paths:
            self.paths_list_widget.addItem(path)

    def add_rule(self):
        input = QInputDialog(self.window)
        input.setWindowTitle("Add exclude rule")
        input.setLabelText("Exclude rule (eg: C:\\Users\\*\\Volumes\\*.iso)")
        if input.exec_():
            exclude_rule = input.textValue()
            exclude_rule = exclude_rule.replace(os.sep, "/")
            self.exclude_rules.add(exclude_rule)
            self.reload_exclude_rules()

    def remove_rule(self):
        selected_item = self.exclude_rules_list_widget.currentItem()
        if selected_item is None:
            return
        rule = selected_item.text()
        self.exclude_rules.remove(rule)
        self.reload_exclude_rules()

    def add_file(self):
        path, _ = QFileDialog.getOpenFileName(self,
                                              dir=os.path.expanduser("~"))
        if len(path) is 0:
            return
        self.paths.add(path)
        self.reload_paths()

    def add_folder(self):
        path = QFileDialog.getExistingDirectory(self,
                                                dir=os.path.expanduser("~"))
        if len(path) is 0:
            return
        self.paths.add(path)
        self.reload_paths()

    def remove_folder(self):
        selected_item = self.paths_list_widget.currentItem()
        if selected_item is None:
            return
        path = selected_item.text()
        self.paths.remove(path)
        self.reload_paths()

    def worker(self, args):
        is_initialized = Repo(Utils.get_backend(self.backup)).is_initialized()
        if self.edit:
            if not is_initialized:
                return False
        else:
            Repo(Utils.get_backend(self.backup)).init(
                self.backup.password.encode())
        return True

    def command_done(self, ret):
        self.setEnabled(True)
        if not ret:
            QMessageBox.warning(
                self.window, "Invalid details",
                f"Backup {self.backup.name} has not been initialized")
            return
        Backups.save(self.backup)

        self.window.app.scheduler.reload()

        super().accept()

    def accept(self):
        self.backup.paths = self.paths
        self.backup.exclude_rules = self.exclude_rules
        self.backup.retention = None if self.forever_radio_button.isChecked(
        ) else self.days_spin_box.value()
        self.backup.backup_daily_time = None if not self.daily_radio_button.isChecked(
        ) else self.schedule_time_edit.time()
        self.backup.backup_days = None if not self.daily_radio_button.isChecked(
        ) else ",".join(self.days_checked)
        self.backup.every_hour = None if not self.backup_every_radio_button.isChecked(
        ) else self.hourly_spinbox.value()
        self.backup.every_min = None if not self.backup_every_radio_button.isChecked(
        ) else self.mins_spinbox.value()
        self.backup.thread_count = self.thread_count_spin_box.value()
        self.backup.compression_level = self.compression_level_spin_box.value()

        if self.backup.backup_days == "":
            QMessageBox.warning(self.window, "Invalid details",
                                "Please select some days of the week")
            return

        self.setEnabled(False)
        self.thread = CommandThread(self.worker, {})
        self.thread.result.connect(self.command_done)
        self.thread.start()
コード例 #11
0
class ConfigAzureDialog(QDialog, Ui_ConfigAzureDialog):
    def __init__(self, window, just_save):
        QDialog.__init__(self)
        Ui_ConfigAzureDialog.__init__(self)

        self.setupUi(self)
        self.window = window
        self.backup = None
        self.just_save = just_save

        if self.just_save:
            self.confirm_password_line_edit.hide()
            self.label_3.hide()

    def command_done(self, res):
        self.setEnabled(True)

        ret, message = res
        if not ret:
            QMessageBox.warning(self.window, "Invalid details", message)
            return

        if self.just_save:
            Backups.save(self.backup)

        super().accept()

    def accept(self):
        name = self.name_line_edit.text().strip()
        password = self.password_line_edit.text()
        if self.just_save:
            confirm_password = password
        else:
            confirm_password = self.confirm_password_line_edit.text()
        connection = self.connection_line_edit.text().strip()
        container = self.container_line_edit.text().strip()
        prefix = self.prefix_line_edit.text().strip()

        backup = Backup()
        backup.name = name
        backup.location = "Microsoft Azure"
        backup.password = password
        backup.azure_conn_str = connection
        backup.azure_container = container
        backup.cloud_prefix = prefix
        self.backup = backup

        fs = [
            Validator.validate_plan_name, Validator.validate_confirm_password,
            Validator.validate_non_empty, Validator.validate_non_empty,
            Validator.validate_non_empty, Validator.validate_no_space,
            Validator.validate_no_space, Validator.validate_backend,
            Validator.validate_repo
        ]
        args = [(name, ), (password, confirm_password),
                ("Connection String", connection), ("Container", container),
                ("Prefix", prefix), ("Container", container),
                ("Prefix", prefix), (backup, ), (backup, self.just_save)]
        self.setEnabled(False)
        self.thread = CommandThread(config_worker, {"fs": fs, "args": args})
        self.thread.result.connect(self.command_done)
        self.thread.start()