Beispiel #1
0
    def __init__(self, parent=None):

        super(StopTimer, self).__init__()

        self.main_context = True
        self.parent = parent
        self.setWindowIcon(self.parent.parent.icon)
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint
                            | QtCore.Qt.WindowMinimizeButtonHint)

        self._translate = QtCore.QCoreApplication.translate

        self.font = QtGui.QFont()
        self.font.setFamily("DejaVu Sans Condensed")
        self.font.setPointSize(9)
        self.font.setBold(True)
        self.font.setWeight(50)
        self.font.setKerning(True)

        self.resize(self.SIZE_W, self.SIZE_H)
        self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H))
        self.setMaximumSize(QtCore.QSize(self.SIZE_W + 100, self.SIZE_H + 100))
        self.setStyleSheet(style.load_stylesheet())

        self.setLayout(self._main())
        self.refresh_context()
        self.setWindowTitle('Pype - Stop Ftrack timer')
Beispiel #2
0
class LoginServerThread(QtCore.QThread):
    '''Login server thread.'''

    # Login signal.
    loginSignal = QtCore.Signal(object, object, object)

    def start(self, url):
        '''Start thread.'''
        self.url = url
        super(LoginServerThread, self).start()

    def _handle_login(self, api_user, api_key):
        '''Login to server with *api_user* and *api_key*.'''
        self.loginSignal.emit(self.url, api_user, api_key)

    def run(self):
        '''Listen for events.'''
        # self._server = BaseHTTPServer.HTTPServer(
        self._server = HTTPServer(('localhost', 0),
                                  functools.partial(LoginServerHandler,
                                                    self._handle_login))
        unformated_url = ('{0}/user/api_credentials?'
                          'redirect_url=http://localhost:{1}')
        webbrowser.open_new_tab(
            unformated_url.format(self.url, self._server.server_port))
        self._server.handle_request()
Beispiel #3
0
    def __init__(self, parent=None, is_event=False):

        super(Login_Dialog_ui, self).__init__()

        self.parent = parent
        self.is_event = is_event

        if hasattr(parent, 'icon'):
            self.setWindowIcon(self.parent.icon)
        elif hasattr(parent, 'parent') and hasattr(parent.parent, 'icon'):
            self.setWindowIcon(self.parent.parent.icon)
        else:
            pype_setup = os.getenv('PYPE_SETUP_ROOT')
            items = [pype_setup, "app", "resources", "icon.png"]
            fname = os.path.sep.join(items)
            icon = QtGui.QIcon(fname)
            self.setWindowIcon(icon)

        self.setWindowFlags(
            QtCore.Qt.WindowCloseButtonHint |
            QtCore.Qt.WindowMinimizeButtonHint
        )

        self.loginSignal.connect(self.loginWithCredentials)
        self._translate = QtCore.QCoreApplication.translate

        self.font = QtGui.QFont()
        self.font.setFamily("DejaVu Sans Condensed")
        self.font.setPointSize(9)
        self.font.setBold(True)
        self.font.setWeight(50)
        self.font.setKerning(True)

        self.resize(self.SIZE_W, self.SIZE_H)
        self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H))
        self.setMaximumSize(QtCore.QSize(self.SIZE_W+100, self.SIZE_H+100))
        self.setStyleSheet(style.load_stylesheet())

        self.setLayout(self._main())
        self.setWindowTitle('Pype - Ftrack Login')
Beispiel #4
0
class KeyboardThread(QtCore.QThread):
    signal_stop = QtCore.Signal()

    def __init__(self, parent):
        super(KeyboardThread, self).__init__()
        self.parent = parent
        self.signal_stop.connect(self.stop)
        self.k_listener = None

    def stop(self):
        if self.k_listener is not None:
            self.k_listener.stop()

    def on_press(self, key):
        self.parent.signal_reset_timer.emit()

    def run(self):
        self.k_listener = keyboard.Listener(on_press=self.on_press)
        self.k_listener.start()
Beispiel #5
0
class MouseThread(QtCore.QThread):
    signal_stop = QtCore.Signal()

    def __init__(self, parent):
        super(MouseThread, self).__init__()
        self.parent = parent
        self.signal_stop.connect(self.stop)
        self.m_listener = None

    def stop(self):
        if self.m_listener is not None:
            self.m_listener.stop()

    def on_move(self, posx, posy):
        self.parent.signal_reset_timer.emit()

    def run(self):
        self.m_listener = mouse.Listener(on_move=self.on_move)
        self.m_listener.start()
Beispiel #6
0
class Login_Dialog_ui(QtWidgets.QWidget):

    SIZE_W = 300
    SIZE_H = 230

    loginSignal = QtCore.Signal(object, object, object)
    _login_server_thread = None
    inputs = []
    buttons = []
    labels = []

    def __init__(self, parent=None, is_event=False):

        super(Login_Dialog_ui, self).__init__()

        self.parent = parent
        self.is_event = is_event

        if hasattr(parent, 'icon'):
            self.setWindowIcon(self.parent.icon)
        elif hasattr(parent, 'parent') and hasattr(parent.parent, 'icon'):
            self.setWindowIcon(self.parent.parent.icon)
        else:
            pype_setup = os.getenv('PYPE_SETUP_ROOT')
            items = [pype_setup, "app", "resources", "icon.png"]
            fname = os.path.sep.join(items)
            icon = QtGui.QIcon(fname)
            self.setWindowIcon(icon)

        self.setWindowFlags(
            QtCore.Qt.WindowCloseButtonHint |
            QtCore.Qt.WindowMinimizeButtonHint
        )

        self.loginSignal.connect(self.loginWithCredentials)
        self._translate = QtCore.QCoreApplication.translate

        self.font = QtGui.QFont()
        self.font.setFamily("DejaVu Sans Condensed")
        self.font.setPointSize(9)
        self.font.setBold(True)
        self.font.setWeight(50)
        self.font.setKerning(True)

        self.resize(self.SIZE_W, self.SIZE_H)
        self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H))
        self.setMaximumSize(QtCore.QSize(self.SIZE_W+100, self.SIZE_H+100))
        self.setStyleSheet(style.load_stylesheet())

        self.setLayout(self._main())
        self.setWindowTitle('Pype - Ftrack Login')

    def _main(self):
        self.main = QtWidgets.QVBoxLayout()
        self.main.setObjectName("main")

        self.form = QtWidgets.QFormLayout()
        self.form.setContentsMargins(10, 15, 10, 5)
        self.form.setObjectName("form")

        self.ftsite_label = QtWidgets.QLabel("FTrack URL:")
        self.ftsite_label.setFont(self.font)
        self.ftsite_label.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.ftsite_label.setTextFormat(QtCore.Qt.RichText)
        self.ftsite_label.setObjectName("user_label")

        self.ftsite_input = QtWidgets.QLineEdit()
        self.ftsite_input.setEnabled(True)
        self.ftsite_input.setFrame(True)
        self.ftsite_input.setEnabled(False)
        self.ftsite_input.setReadOnly(True)
        self.ftsite_input.setObjectName("ftsite_input")

        self.user_label = QtWidgets.QLabel("Username:"******"user_label")

        self.user_input = QtWidgets.QLineEdit()
        self.user_input.setEnabled(True)
        self.user_input.setFrame(True)
        self.user_input.setObjectName("user_input")
        self.user_input.setPlaceholderText(
            self._translate("main", "user.name")
        )
        self.user_input.textChanged.connect(self._user_changed)

        self.api_label = QtWidgets.QLabel("API Key:")
        self.api_label.setFont(self.font)
        self.api_label.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.api_label.setTextFormat(QtCore.Qt.RichText)
        self.api_label.setObjectName("api_label")

        self.api_input = QtWidgets.QLineEdit()
        self.api_input.setEnabled(True)
        self.api_input.setFrame(True)
        self.api_input.setObjectName("api_input")
        self.api_input.setPlaceholderText(self._translate(
            "main", "e.g. xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        ))
        self.api_input.textChanged.connect(self._api_changed)

        self.error_label = QtWidgets.QLabel("")
        self.error_label.setFont(self.font)
        self.error_label.setTextFormat(QtCore.Qt.RichText)
        self.error_label.setObjectName("error_label")
        self.error_label.setWordWrap(True)
        self.error_label.hide()

        self.form.addRow(self.ftsite_label, self.ftsite_input)
        self.form.addRow(self.user_label, self.user_input)
        self.form.addRow(self.api_label, self.api_input)
        self.form.addRow(self.error_label)

        self.btnGroup = QtWidgets.QHBoxLayout()
        self.btnGroup.addStretch(1)
        self.btnGroup.setObjectName("btnGroup")

        self.btnEnter = QtWidgets.QPushButton("Login")
        self.btnEnter.setToolTip(
            'Set Username and API Key with entered values'
        )
        self.btnEnter.clicked.connect(self.enter_credentials)

        self.btnClose = QtWidgets.QPushButton("Close")
        self.btnClose.setToolTip('Close this window')
        self.btnClose.clicked.connect(self._close_widget)

        self.btnFtrack = QtWidgets.QPushButton("Ftrack")
        self.btnFtrack.setToolTip('Open browser for Login to Ftrack')
        self.btnFtrack.clicked.connect(self.open_ftrack)

        self.btnGroup.addWidget(self.btnFtrack)
        self.btnGroup.addWidget(self.btnEnter)
        self.btnGroup.addWidget(self.btnClose)

        self.main.addLayout(self.form)
        self.main.addLayout(self.btnGroup)

        self.inputs.append(self.api_input)
        self.inputs.append(self.user_input)
        self.inputs.append(self.ftsite_input)

        self.enter_site()
        return self.main

    def enter_site(self):
        try:
            url = os.getenv('FTRACK_SERVER')
            newurl = self.checkUrl(url)

            if newurl is None:
                self.btnEnter.setEnabled(False)
                self.btnFtrack.setEnabled(False)
                for input in self.inputs:
                    input.setEnabled(False)
                newurl = url

            self.ftsite_input.setText(newurl)

        except Exception:
            self.setError("FTRACK_SERVER is not set in templates")
            self.btnEnter.setEnabled(False)
            self.btnFtrack.setEnabled(False)
            for input in self.inputs:
                input.setEnabled(False)

    def setError(self, msg):
        self.error_label.setText(msg)
        self.error_label.show()

    def _user_changed(self):
        self.user_input.setStyleSheet("")

    def _api_changed(self):
        self.api_input.setStyleSheet("")

    def _invalid_input(self, entity):
        entity.setStyleSheet("border: 1px solid red;")

    def enter_credentials(self):
        username = self.user_input.text().strip()
        apiKey = self.api_input.text().strip()
        msg = "You didn't enter "
        missing = []
        if username == "":
            missing.append("Username")
            self._invalid_input(self.user_input)

        if apiKey == "":
            missing.append("API Key")
            self._invalid_input(self.api_input)

        if len(missing) > 0:
            self.setError("{0} {1}".format(msg, " and ".join(missing)))
            return

        verification = credentials._check_credentials(username, apiKey)

        if verification:
            credentials._save_credentials(username, apiKey, self.is_event)
            credentials._set_env(username, apiKey)
            if self.parent is not None:
                self.parent.loginChange()
            self._close_widget()
        else:
            self._invalid_input(self.user_input)
            self._invalid_input(self.api_input)
            self.setError(
                "We're unable to sign in to Ftrack with these credentials"
            )

    def open_ftrack(self):
        url = self.ftsite_input.text()
        self.loginWithCredentials(url, None, None)

    def checkUrl(self, url):
        url = url.strip('/ ')

        if not url:
            self.setError("There is no URL set in Templates")
            return

        if 'http' not in url:
            if url.endswith('ftrackapp.com'):
                url = 'https://' + url
            else:
                url = 'https://{0}.ftrackapp.com'.format(url)
        try:
            result = requests.get(
                url,
                # Old python API will not work with redirect.
                allow_redirects=False
            )
        except requests.exceptions.RequestException:
            self.setError(
                'The server URL set in Templates could not be reached.'
            )
            return

        if (
            result.status_code != 200 or 'FTRACK_VERSION' not in result.headers
        ):
            self.setError(
                'The server URL set in Templates is not a valid ftrack server.'
            )
            return
        return url

    def loginWithCredentials(self, url, username, apiKey):
        url = url.strip('/ ')

        if not url:
            self.setError(
                'You need to specify a valid server URL, '
                'for example https://server-name.ftrackapp.com'
            )
            return

        if 'http' not in url:
            if url.endswith('ftrackapp.com'):
                url = 'https://' + url
            else:
                url = 'https://{0}.ftrackapp.com'.format(url)
        try:
            result = requests.get(
                url,
                # Old python API will not work with redirect.
                allow_redirects=False
            )
        except requests.exceptions.RequestException:
            self.setError(
                'The server URL you provided could not be reached.'
            )
            return

        if (
            result.status_code != 200 or 'FTRACK_VERSION' not in result.headers
        ):
            self.setError(
                'The server URL you provided is not a valid ftrack server.'
            )
            return

        # If there is an existing server thread running we need to stop it.
        if self._login_server_thread:
            self._login_server_thread.quit()
            self._login_server_thread = None

        # If credentials are not properly set, try to get them using a http
        # server.
        if not username or not apiKey:
            self._login_server_thread = login_tools.LoginServerThread()
            self._login_server_thread.loginSignal.connect(self.loginSignal)
            self._login_server_thread.start(url)
            return

        verification = credentials._check_credentials(username, apiKey)

        if verification is True:
            credentials._save_credentials(username, apiKey, self.is_event)
            credentials._set_env(username, apiKey)
            if self.parent is not None:
                self.parent.loginChange()
            self._close_widget()

    def closeEvent(self, event):
        event.ignore()
        self._close_widget()

    def _close_widget(self):
        self.hide()
Beispiel #7
0
class CountdownThread(QtCore.QThread):
    # Senders
    signal_show_question = QtCore.Signal()
    signal_send_time = QtCore.Signal(object)
    signal_stop_timer = QtCore.Signal()
    signal_stop_countdown = QtCore.Signal()
    # Listeners
    signal_reset_timer = QtCore.Signal()
    signal_continue_timer = QtCore.Signal()

    def __init__(self, parent):
        super(CountdownThread, self).__init__()

        self.runs = True
        self.over_line = False
        config_data = self.load_timer_values()
        self.count_length = config_data['full_time'] * 60
        self.border_line = config_data['message_time'] * 60 + 1
        self.reset_count()
        self.signal_reset_timer.connect(self.reset_count)
        self.signal_continue_timer.connect(self.continue_timer)

    def continue_timer(self):
        self.over_line = False
        self.reset_count()

    def reset_count(self):
        if self.over_line is True:
            self.actual = self.border_line
        else:
            self.actual = self.count_length

    def stop(self):
        self.runs = False

    def run(self):
        thread_mouse = MouseThread(self)
        thread_mouse.start()
        thread_keyboard = KeyboardThread(self)
        thread_keyboard.start()
        while self.runs:
            if self.actual == self.border_line:
                self.signal_show_question.emit()
                self.over_line = True

            if self.actual <= self.border_line:
                self.signal_send_time.emit(self.actual)

            time.sleep(1)
            self.actual -= 1

            if self.actual == 0:
                self.runs = False
                self.signal_stop_timer.emit()

        thread_mouse.signal_stop.emit()
        thread_mouse.terminate()
        thread_mouse.wait()
        thread_keyboard.signal_stop.emit()
        thread_keyboard.terminate()
        thread_keyboard.wait()

    def load_timer_values(self):
        templates = os.environ['PYPE_STUDIO_TEMPLATES']
        path_items = [templates, 'presets', 'ftrack', 'ftrack_config.json']
        filepath = os.path.sep.join(path_items)
        data = dict()
        try:
            with open(filepath) as data_file:
                json_dict = json.load(data_file)
                data = json_dict['timer']
        except Exception as e:
            msg = ('Loading "Ftrack Config file" Failed.'
                   ' Please check log for more information.'
                   ' Times are set to default.')
            log.warning("{} - {}".format(msg, str(e)))

        data = self.validate_timer_values(data)

        return data

    def validate_timer_values(self, data):
        # default values
        if 'full_time' not in data:
            data['full_time'] = 15
        if 'message_time' not in data:
            data['message_time'] = 0.5

        # minimum values
        if data['full_time'] < 2:
            data['full_time'] = 2
        # message time is earlier that full time
        if data['message_time'] > data['full_time']:
            data['message_time'] = data['full_time'] - 0.5
        return data
Beispiel #8
0
class FtrackEventsThread(QtCore.QThread):
    # Senders
    signal_timer_started = QtCore.Signal()
    signal_timer_stopped = QtCore.Signal()
    # Listeners
    signal_stop_timer = QtCore.Signal()
    signal_restart_timer = QtCore.Signal()

    def __init__(self, parent):
        super(FtrackEventsThread, self).__init__()
        cred = credentials._get_credentials()
        self.username = cred['username']
        self.signal_stop_timer.connect(self.ftrack_stop_timer)
        self.signal_restart_timer.connect(self.ftrack_restart_timer)
        self.user = None
        self.last_task = None

    def run(self):
        self.timer_session = ftrack_api.Session(auto_connect_event_hub=True)
        self.timer_session.event_hub.subscribe(
            'topic=ftrack.update and source.user.username={}'.format(
                self.username), self.event_handler)

        user_query = 'User where username is "{}"'.format(self.username)
        self.user = self.timer_session.query(user_query).one()

        timer_query = 'Timer where user.username is "{}"'.format(self.username)
        timer = self.timer_session.query(timer_query).first()
        if timer is not None:
            self.last_task = timer['context']
            self.signal_timer_started.emit()

        self.timer_session.event_hub.wait()

    def event_handler(self, event):
        try:
            if event['data']['entities'][0]['objectTypeId'] != 'timer':
                return
        except Exception:
            return

        new = event['data']['entities'][0]['changes']['start']['new']
        old = event['data']['entities'][0]['changes']['start']['old']

        if old is None and new is None:
            return

        timer_query = 'Timer where user.username is "{}"'.format(self.username)
        timer = self.timer_session.query(timer_query).first()
        if timer is not None:
            self.last_task = timer['context']

        if old is None:
            self.signal_timer_started.emit()
        elif new is None:
            self.signal_timer_stopped.emit()

    def ftrack_stop_timer(self):
        try:
            self.user.stop_timer()
            self.timer_session.commit()
        except Exception as e:
            log.debug("Timer stop had issues: {}".format(e))

    def ftrack_restart_timer(self):
        try:
            if (self.last_task is not None) and (self.user is not None):
                self.user.start_timer(self.last_task)
                self.timer_session.commit()
        except Exception as e:
            log.debug("Timer stop had issues: {}".format(e))