def get_real_state_icon(self, services): """ Calculate real state and return QPixmap :param services: list of service dict :type services: list :return: QPixmap with right icon state :rtype: QPixmap """ if services: icon_names = [ 'all_services_ok', 'all_services_ok', 'all_services_ok', 'all_services_warning', 'all_services_critical' ] text_result = self.get_result_overall_state_id( icon_names, services) icon = QPixmap(get_image_path(text_result)) else: logger.warning( 'Services not found. Can\'t get real state icon for %s', self.host['name']) icon = QPixmap(get_image_path('all_services_none')) return icon
def initialize(self, service): """ TODO :return: """ self.aggregation = service['aggregation'] self.define_state_name(service) if not service['aggregation']: service['aggregation'] = 'Global' self.setText('%s is %s' % ( self.get_service_name(service).capitalize(), service['ls_state'], )) self.setToolTip(self.get_service_tooltip(service)) if service['ls_acknowledged']: img = get_image_path('services_acknowledge') elif service['ls_downtimed']: img = get_image_path('services_downtime') else: img = get_image_path('services_%s' % service['ls_state']) self.setIcon(QIcon(img))
def __init__(self, icon, parent=None): QSystemTrayIcon.__init__(self, icon, parent) self.menu = QMenu(parent) self.hosts_menu = QMenu(self.menu) self.hosts_menu.setIcon(QIcon(get_image_path('host'))) self.services_menu = QMenu(self.menu) self.services_menu.setIcon(QIcon(get_image_path('service'))) self.qaction_factory = QActionFactory() self.alignak_status = None self.app_about = None self.synthesis = None
def get_logo_widget(self, title): """ Return the logo QWidget :return: logo QWidget :rtype: QWidget """ logo_widget = QWidget() logo_widget.setFixedHeight(45) logo_widget.setObjectName('logo') logo_layout = QHBoxLayout() logo_widget.setLayout(logo_layout) logo_label = QLabel() logo_label.setPixmap(QPixmap(get_image_path('alignak'))) logo_label.setFixedSize(121, 35) logo_label.setScaledContents(True) logo_layout.addWidget(logo_label, 0) title_label = QLabel('<h3>%s</h3>' % title) title_label.setObjectName('title') title_label.setAttribute(Qt.WA_TransparentForMouseEvents) logo_layout.addWidget(title_label, 1) logo_layout.setAlignment(title_label, Qt.AlignHCenter) minimize_btn = QPushButton() minimize_btn.setIcon(QIcon(get_image_path('minimize'))) minimize_btn.setFixedSize(22, 22) minimize_btn.setObjectName('app_widget') minimize_btn.clicked.connect(self.minimize) logo_layout.addWidget(minimize_btn, 2) maximize_btn = QPushButton() maximize_btn.setIcon(QIcon(get_image_path('maximize'))) maximize_btn.setFixedSize(22, 22) maximize_btn.setObjectName('app_widget') maximize_btn.clicked.connect(self.minimize_maximize) logo_layout.addWidget(maximize_btn, 3) close_btn = QPushButton() close_btn.setIcon(QIcon(get_image_path('exit'))) close_btn.setFixedSize(22, 22) close_btn.setObjectName('app_widget') close_btn.clicked.connect(self.close) logo_layout.addWidget(close_btn, 4) return logo_widget
def get_stars_widget(stars_nb): """ Return QWidget with stars icons :param stars_nb: number of stars to display :type stars_nb: int :return: QWidget with stars :rtype: QWidget """ stars_widget = QWidget() layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) stars_widget.setLayout(layout) importance_label = QLabel('<b>Importance:</b>') layout.addWidget(importance_label) layout.setAlignment(importance_label, Qt.AlignLeft) for _ in range(int(get_app_config('Alignak', 'bi_less')), stars_nb): star_label = QLabel() star_label.setFixedSize(16, 16) star_label.setScaledContents(True) star_label.setPixmap(QPixmap(get_image_path('star'))) layout.addWidget(star_label) return stars_widget
def get_logo_widget(widget): """ Return the logo QWidget :param widget: widget parent, needed for action button :type widget: QWidget :return: logo QWidget :rtype: QWidget """ logo_widget = QWidget() logo_widget.setFixedHeight(45) logo_widget.setObjectName('title') logo_layout = QHBoxLayout() logo_widget.setLayout(logo_layout) logo_label = QLabel() logo_label.setPixmap(QPixmap(get_image_path('alignak'))) logo_label.setFixedSize(121, 35) logo_label.setScaledContents(True) logo_layout.addWidget(logo_label, 0) minimize_btn = QPushButton() minimize_btn.setIcon(QIcon(get_image_path('minimize'))) minimize_btn.setFixedSize(24, 24) minimize_btn.setObjectName('app_widget') minimize_btn.clicked.connect(widget.showMinimized) logo_layout.addStretch(widget.width()) logo_layout.addWidget(minimize_btn, 1) maximize_btn = QPushButton() maximize_btn.setIcon(QIcon(get_image_path('maximize'))) maximize_btn.setFixedSize(24, 24) maximize_btn.setObjectName('app_widget') maximize_btn.clicked.connect(widget.showMaximized) logo_layout.addWidget(maximize_btn, 2) close_btn = QPushButton() close_btn.setIcon(QIcon(get_image_path('exit'))) close_btn.setObjectName('app_widget') close_btn.setFixedSize(24, 24) close_btn.clicked.connect(widget.close) logo_layout.addWidget(close_btn, 3) return logo_widget
def update_states(self, state_name, nb_items, diff, percent): """ Update nb_items, diff and progress_bar value for the given "state_name" :param state_name: name of the state to be update :type state_name: str :param nb_items: state :type nb_items: str :param diff: str :type diff: str :param percent: value of progress bar :type percent: int """ # State number self.state_data[state_name]['state_number'].setText(str(nb_items)) # Icon if nb_items == 0 and 'downtime' not in state_name and 'acknowledge' not in state_name: if 'hosts' in state_name: self.state_data[state_name]['icon'].setPixmap( QPixmap(get_image_path('hosts_none'))) else: self.state_data[state_name]['icon'].setPixmap( QPixmap(get_image_path('services_none'))) else: self.state_data[state_name]['icon'].setPixmap( QPixmap(get_image_path(state_name))) # Diff between last check if diff != 0: self.state_data[state_name]['diff'].setText('<b>(%s)</b>' % "{0:+d}".format(diff)) else: self.state_data[state_name]['diff'].setText('') # ProgressBar if percent == 0.0: self.state_data[state_name]['progress_bar'].setFormat('-') self.state_data[state_name]['progress_bar'].setValue(0) else: self.state_data[state_name]['progress_bar'].setFormat('%.02f%%' % percent) self.state_data[state_name]['progress_bar'].setValue( float(percent))
def create(self, name, content, parent): """ Create QAction """ q_action = QAction(QIcon(get_image_path(name)), content, parent) self.add_action(name, q_action)
def test_get_image_path(self): """Get Right Image Path""" utils.init_config() expected_img = utils.get_main_folder() + '/images/icon.svg' under_test = utils.get_image_path('icon') self.assertEqual(under_test, expected_img)
def __init__(self, parent=None): super(Acknowledge, self).__init__(parent) self.setWindowTitle('Request an Acknowledge') self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(get_css()) self.setWindowIcon(QIcon(get_image_path('icon'))) self.setMinimumSize(360, 460) # Fields self.sticky = True self.notify = False self.ack_comment_edit = None
def __init__(self, parent=None): super(Downtime, self).__init__(parent) self.setWindowTitle('Request a Downtime') self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(get_css()) self.setWindowIcon(QIcon(get_image_path('icon'))) self.setMinimumSize(360, 460) # Fields self.fixed = True self.duration = QTimeEdit() self.start_time = QDateTimeEdit() self.end_time = QDateTimeEdit() self.comment_edit = QTextEdit()
def __init__(self, parent=None): super(AppLogin, self).__init__(parent) self.setWindowTitle('Login to Alignak') self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(get_css()) self.setWindowIcon(QIcon(get_image_path('icon'))) self.setFixedSize(300, 330) # Fields self.app_backend = AppBackend() self.backend_url = None self.username_line = None self.password_line = None self.offset = None
def create_buttons(self, host_layout, backend_data): """ Create QPushButtons for Acknowledge and Donwtime actions :param host_layout: layout of QWidget :type host_layout: QGridLayout :param backend_data: data of AppBackend :type backend_data: dict """ # ACK acknowledge_btn = QPushButton() acknowledge_btn.setObjectName( 'host:%s:%s' % (backend_data['host']['_id'], backend_data['host']['name'])) acknowledge_btn.setIcon(QIcon(get_image_path('hosts_acknowledge'))) acknowledge_btn.setFixedSize(32, 32) acknowledge_btn.setToolTip('Acknowledge this host') acknowledge_btn.clicked.connect(self.add_acknowledge) if 'UP' in backend_data['host']['ls_state'] \ or backend_data['host']['ls_acknowledged'] \ or backend_data['host']['_id'] in self.action_manager.acknowledged: acknowledge_btn.setEnabled(False) host_layout.addWidget(acknowledge_btn, 0, 1, 1, 1) # DOWN downtime_btn = QPushButton() downtime_btn.setObjectName( 'host:%s:%s' % (backend_data['host']['_id'], backend_data['host']['name'])) downtime_btn.setIcon(QIcon(get_image_path('hosts_downtime'))) downtime_btn.setFixedSize(32, 32) downtime_btn.setToolTip('Schedule a downtime for this host') downtime_btn.clicked.connect(self.add_downtime) if backend_data['host']['ls_downtimed'] or \ backend_data['host']['_id'] in self.action_manager.downtimed: downtime_btn.setEnabled(False) host_layout.addWidget(downtime_btn, 1, 1, 1, 1)
def create_state_labels(self, state_name): """ Generate 4 QLabel and 1 QProgressBar and store them in "state_data" QLabels are: state_icon | state_text | state_number | state_diff QProgressBar get value of percent. All are added on one row define by "row" value :param state_name: name of the state to be stored :type state_name: str """ # Icon icon = QPixmap(get_image_path(state_name)) state_icon = QLabel() state_icon.setFixedSize(16, 16) state_icon.setScaledContents(True) state_icon.setPixmap(icon) # Initialize Labels state_text = QLabel(self.define_label(state_name)) state_number = QLabel() state_diff = QLabel() # QProgressBar progress_bar = QProgressBar() progress_bar.setValue(0) progress_bar.setFixedHeight(20) progress_bar.setObjectName(state_name) # Layout self.main_layout.addWidget(state_icon, self.row, 0) self.main_layout.addWidget(state_text, self.row, 1) self.main_layout.addWidget(state_number, self.row, 2) self.main_layout.setAlignment(state_number, Qt.AlignCenter) self.main_layout.addWidget(state_diff, self.row, 3) self.main_layout.addWidget(progress_bar, self.row, 4) # Store state self.state_data[state_name] = { 'icon': state_icon, 'state_number': state_number, 'diff': state_diff, 'progress_bar': progress_bar } # Increment vertically position for next widget self.row += 1
def get_services_widget(self, backend_data): """ Return QWidget for services :param backend_data: data of AppBackend :type backend_data: dict :return: QWidget with Service in QStackedWidget :rtype: QWidget """ services_widget = QWidget() services_widget.setObjectName('services') services_layout = QGridLayout(services_widget) # Add aggregation filters and get current row row = self.add_aggregations_filters(services_layout, backend_data['services']) # Get number of each state for services services_stats = self.get_services_state_number( backend_data['services']) states = [ 'OK', 'UNKNOWN', 'WARNING', 'UNREACHABLE', 'CRITICAL', 'ACKNOWLEDGE', 'DOWNTIME' ] i_row = 1 for state in states: # Create states CheckBox self.check_boxes[state] = QCheckBox( '%s: %d (%.02f%%)' % (state, services_stats['nb'][state], services_stats['percent'][state])) self.check_boxes[state].setIcon( QIcon(get_image_path('services_%s' % state.lower()))) self.check_boxes[state].setObjectName(state) self.check_boxes[state].setChecked(True) self.check_boxes[state].stateChanged.connect(self.filter_services) services_layout.addWidget(self.check_boxes[state], row + i_row, 0, 1, 1) i_row += 1 row += 1 self.generate_services_qwidgets(row, services_layout, backend_data['services']) return services_widget
def add_aggregations_filters(self, services_layout, services_list): """ Add aggregations filter and return current row to maintain layout :param services_layout: layout of services :type services_layout: QGridLayout :param services_list: list of service dict :type services_list: list :return: current row :rtype: int """ col = 1 row = 0 aggregations = ['Global'] for service in services_list: if service['aggregation']: if service['aggregation'] not in aggregations: aggregations.append(service['aggregation']) for aggregation in aggregations: self.check_boxes[aggregation] = QCheckBox(aggregation) self.check_boxes[aggregation].setIcon(QIcon( get_image_path('tree'))) self.check_boxes[aggregation].setObjectName('aggregation') self.check_boxes[aggregation].setChecked(True) self.check_boxes[aggregation].stateChanged.connect( self.filter_services) services_layout.addWidget(self.check_boxes[aggregation], row, col, 1, 1) col += 1 if col == 6: row += 1 col = 1 # Filters title if row == 0: row = 1 filter_title = QLabel('States / Filters') services_layout.addWidget(filter_title, 0, 0, row, 1) services_layout.setAlignment(filter_title, Qt.AlignCenter | Qt.AlignBottom) return row
def run(self, app_backend=None): # pragma: no cover """ Start all Alignak-app processes and create AppBackend if connection by config file. :param app_backend: AppBackend object :type app_backend: alignak_app.core.backend.AppBackend | None """ # If not login form, app try anyway to connect by token if not app_backend: app_backend = AppBackend() connect = app_backend.login() if connect: username = app_backend.get_user(projection=['name'])['name'] send_banner('OK', 'Welcome %s, you are connected to Alignak Backend' % username) else: self.display_error_msg() if 'token' not in app_backend.user: app_backend.user['token'] = app_backend.backend.token # Dashboard self.dashboard = Dashboard() self.dashboard.initialize() # TrayIcon self.tray_icon = TrayIcon(QIcon(get_image_path('icon'))) self.tray_icon.build_menu(app_backend, self.dashboard) self.tray_icon.show() app_backend.app = self start = bool(app_backend.get_user(projection=['name'])) if start: # Notifier self.notifier = AppNotifier() self.notifier.initialize(app_backend, self.tray_icon, self.dashboard) self.notifier_timer.start(self.notifier.interval) self.notifier_timer.timeout.connect(self.notifier.check_data) self.reconnecting.connect(self.reconnect_to_backend) else: # In case of... self.display_error_msg()
def get_host_icon(host): """ Return QPixmap with the icon corresponding to the status. :param host: host data from AppBackend :type host: dict :return: QPixmap with image :rtype: QPixmap """ if host['ls_acknowledged']: icon_name = 'hosts_acknowledge' elif host['ls_downtimed']: icon_name = 'hosts_downtimed' else: icon_name = 'hosts_%s' % host['ls_state'].lower() icon = QPixmap(get_image_path(icon_name)) return icon
def get_service_icon(self, state): """ Return QPixmap with the icon corresponding to the status. :param state: state of the host. :type state: str :return: QPushButton with QIcon :rtype: QPushButton """ try: icon_name = self.state_model[state] except KeyError: state = 'ERROR' icon_name = self.state_model['DEFAULT'] icon = QPixmap(get_image_path(icon_name)) icon_label = QLabel() icon_label.setMaximumSize(32, 32) icon_label.setScaledContents(True) icon_label.setPixmap(icon) icon_label.setToolTip('Service is ' + state) return icon_label
def initialize(self, service): """ Inititialize Service QWidget :param service: service data :type service: dict """ layout = QGridLayout() self.setLayout(layout) layout.addWidget(self.get_service_icon(service['ls_state']), 0, 0, 2, 1) if service['display_name'] != '': service_name = service['display_name'] elif service['alias'] != '': service_name = service['alias'] else: service_name = service['name'] # Service name service_label = QLabel() if get_app_config('Alignak', 'webui'): service_label.setText( '<h3><a href="%s" style="color: black; text-decoration: none">%s</a></h3>' % (get_app_config('Alignak', 'webui') + '/service/' + service['_id'], service_name)) else: service_label.setText('<h3>%s</h3>' % service_name) service_label.setTextInteractionFlags(Qt.TextBrowserInteraction) service_label.setOpenExternalLinks(True) service_label.setToolTip('Service is %s. See in WebUI ?' % service['ls_state']) service_label.setObjectName(service['ls_state']) service_label.setMinimumWidth(200) service_label.setWordWrap(True) layout.addWidget(service_label, 0, 1, 2, 1) layout.setAlignment(service_label, Qt.AlignLeft) # Buttons self.acknowledge_btn = QPushButton() self.acknowledge_btn.setIcon( QIcon(get_image_path('services_acknowledge'))) self.acknowledge_btn.setFixedSize(25, 25) self.acknowledge_btn.setToolTip('Acknowledge this service') layout.addWidget(self.acknowledge_btn, 0, 2, 1, 1) self.downtime_btn = QPushButton() self.downtime_btn.setIcon(QIcon(get_image_path('services_downtime'))) self.downtime_btn.setFixedSize(25, 25) self.downtime_btn.setToolTip('Schedule a downtime for this service') layout.addWidget(self.downtime_btn, 1, 2, 1, 1) # Last check since_last_check = get_diff_since_last_check( service['ls_last_state_changed']) diff_last_check = get_diff_since_last_check(service['ls_last_check']) last_check = QLabel('<b>Since:</b> %s, <b>Last check:</b> %s' % (since_last_check, diff_last_check)) layout.addWidget(last_check, 0, 3, 1, 2) # Output date_output = get_date_from_timestamp(service['ls_last_check']) output = QTextEdit('<b>Output:</b> [%s] %s' % (date_output, service['ls_output'])) output.setObjectName('output') output.setToolTip(service['ls_output']) output.setTextInteractionFlags(Qt.TextSelectableByMouse) output.setFont(QFont('Times', 13)) layout.addWidget(output, 1, 3, 2, 4) # Service details business_impact = self.get_stars_widget(int( service['business_impact'])) layout.addWidget(business_impact, 2, 0, 1, 2) layout.setAlignment(business_impact, Qt.AlignLeft) self.add_services_details(service, layout)
def check_status(self): """ Check daemons states, update icons and display banner if changes. """ total_bad_daemons = 0 total_daemons = 0 arbiter_down = False daemon_msg = dict((element, '') for element in self.daemons) bad_daemons = dict((element, 0) for element in self.daemons) alignak_daemon = self.app_backend.get('alignakdaemon') if alignak_daemon: for daemon in alignak_daemon['_items']: if not daemon['alive']: bad_daemons[daemon['type']] += 1 total_bad_daemons += 1 daemon_msg[daemon['type']] += \ '<p>%s is not alive</p>' % daemon['name'].capitalize() if daemon == self.daemons[3]: arbiter_down = True if not bad_daemons[daemon['type']]: self.daemons_labels[daemon['type']]['icon'].setPixmap( QPixmap(get_image_path('valid'))) self.daemons_labels[daemon['type']]['icon'].setToolTip( 'All %ss are alive ' % daemon['type']) self.daemons_labels[daemon['type']]['label'].setToolTip( 'All %ss are alive ' % daemon['type']) else: self.daemons_labels[daemon['type']]['icon'].setPixmap( QPixmap(get_image_path('error'))) self.daemons_labels[daemon['type']]['icon'].setToolTip( daemon_msg[daemon['type']]) self.daemons_labels[daemon['type']]['label'].setToolTip( daemon_msg[daemon['type']]) total_daemons += 1 else: arbiter_down = True # Update text if not total_bad_daemons: self.info.setText('All daemons are alive.') self.info.setStyleSheet('color: #27ae60;') if self.first_start: self.first_start = False send_banner('INFO', 'All daemons are alive.') logger.info('All daemons are alive.') else: self.info.setText('%d on %d daemons are down !' % (total_bad_daemons, total_daemons)) self.info.setStyleSheet('color: #e74c3c;') logger.warning('%d on %d daemons are down !', total_bad_daemons, total_daemons) # Send Banners if sender is QTimer if not isinstance(self.sender(), QAction): if not total_bad_daemons and (self.old_bad_daemons != 0): send_banner('OK', 'All daemons are alive again.', duration=60000) if total_bad_daemons: send_banner('WARN', '%d on %d daemons are down !' % (total_bad_daemons, total_daemons), duration=60000) if arbiter_down: self.info.setText( 'Arbiter daemons are DOWN ! %d on %d daemons are down.' % (total_bad_daemons, total_daemons)) self.info.setStyleSheet('color: #e74c3c;') send_banner('ALERT', 'Arbiter daemons are down !', duration=60000) logger.critical('Arbiter daemons are down !') self.old_bad_daemons = total_bad_daemons
def create_widget(self): """ Create widget login """ # Main layout main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(self.get_logo_widget(self)) title = QLabel('Welcome to <b>Alignak-app</b>') title.setObjectName('title_login') main_layout.addWidget(title) main_layout.setAlignment(title, Qt.AlignCenter) version = QLabel('Version %s' % __version__) version.setObjectName('version_login') main_layout.addWidget(version) main_layout.setAlignment(version, Qt.AlignCenter | Qt.AlignTop) # Login QWidget login_widget = QWidget(self) login_widget.setObjectName('login') login_layout = QGridLayout(login_widget) # Configuration button refresh_conf_btn = QPushButton() refresh_conf_btn.clicked.connect(init_config) refresh_conf_btn.setFixedSize(25, 25) refresh_conf_btn.setIcon(QIcon(get_image_path('refresh'))) refresh_conf_btn.setToolTip('Reload configuration') login_layout.addWidget(refresh_conf_btn, 2, 1, 1, 1) # Server button server_btn = QPushButton() server_btn.clicked.connect(self.handle_server) server_btn.setFixedSize(25, 25) server_btn.setIcon(QIcon(get_image_path('host'))) server_btn.setToolTip('Modify Alignak Server') login_layout.addWidget(server_btn, 2, 2, 1, 1) # Welcome text login_label = QLabel('<b>Log-in</b> to use the application') login_layout.addWidget(login_label, 2, 0, 1, 1) login_layout.setAlignment(login_label, Qt.AlignCenter) # Username field self.username_line = QLineEdit(self) self.username_line.setPlaceholderText('Username') login_layout.addWidget(self.username_line, 3, 0, 1, 3) # Password field self.password_line = QLineEdit(self) self.password_line.setPlaceholderText('Password') self.password_line.setEchoMode(QLineEdit.Password) login_layout.addWidget(self.password_line, 4, 0, 1, 3) # Login button login_button = QPushButton('LOGIN', self) login_button.clicked.connect(self.handle_login) login_button.setObjectName('valid') login_button.setMinimumHeight(30) login_button.setDefault(True) login_layout.addWidget(login_button, 5, 0, 1, 3) main_layout.addWidget(login_widget) self.setLayout(main_layout) self.center(self)
def update_menu_actions(self, synthesis): """ Update items Menu, triggered by pyqtSignal :param synthesis: hosts and services synthesis :type synthesis: dict """ try: assert isinstance(synthesis, dict) except TypeError as e: logger.error('Bad object received: %s', e) logger.info('Update menus...') host_nb = synthesis['hosts']['up'] + \ synthesis['hosts']['down'] + \ synthesis['hosts']['unreachable'] + \ synthesis['hosts']['downtime'] + \ synthesis['hosts']['acknowledge'] services_nb = synthesis['services']['ok'] + \ synthesis['services']['warning'] + \ synthesis['services']['critical'] + \ synthesis['services']['unknown'] + \ synthesis['services']['unreachable'] + \ synthesis['services']['downtime'] + \ synthesis['services']['acknowledge'] if synthesis['hosts']['down'] != 0: self.hosts_menu.setIcon(QIcon(get_image_path('hosts_down'))) elif synthesis['hosts']['down'] == 0 and \ synthesis['hosts']['unreachable'] > synthesis['hosts']['up']: self.hosts_menu.setIcon(QIcon(get_image_path('hosts_unreachable'))) else: self.hosts_menu.setIcon(QIcon(get_image_path('hosts_up'))) self.hosts_menu.setTitle('Hosts (' + str(host_nb) + ')') if synthesis['services']['critical'] != 0 or synthesis['services'][ 'unreachable'] != 0: self.services_menu.setIcon( QIcon(get_image_path('services_critical'))) else: if synthesis['services']['unknown'] != 0 or synthesis['services'][ 'warning'] != 0: self.services_menu.setIcon( QIcon(get_image_path('services_warning'))) else: self.services_menu.setIcon(QIcon( get_image_path('services_ok'))) self.services_menu.setTitle('Services (' + str(services_nb) + ')') self.qaction_factory.get('hosts_up').setText( 'Hosts UP (' + str(synthesis['hosts']['up']) + ')') self.qaction_factory.get('hosts_down').setText( 'Hosts DOWN (' + str(synthesis['hosts']['down']) + ')') self.qaction_factory.get('hosts_unreachable').setText( 'Hosts UNREACHABLE (' + str(synthesis['hosts']['unreachable']) + ')') self.qaction_factory.get('hosts_acknowledge').setText( 'Hosts ACKNOWLEDGE (' + str(synthesis['hosts']['acknowledge']) + ')') self.qaction_factory.get('hosts_downtime').setText( 'Hosts DOWNTIME (' + str(synthesis['hosts']['downtime']) + ')') self.qaction_factory.get('services_ok').setText( 'Services OK (' + str(synthesis['services']['ok']) + ')') self.qaction_factory.get('services_critical').setText( 'Services CRITICAL (' + str(synthesis['services']['critical']) + ')') self.qaction_factory.get('services_warning').setText( 'Services WARNING (' + str(synthesis['services']['warning']) + ')') self.qaction_factory.get('services_unknown').setText( 'Services UNKNOWN (' + str(synthesis['services']['unknown']) + ')') self.qaction_factory.get('services_unreachable').setText( 'Services UNREACHABLE (' + str(synthesis['services']['unreachable']) + ')') self.qaction_factory.get('services_acknowledge').setText( 'Services ACKNOWLEDGE (' + str(synthesis['services']['acknowledge']) + ')') self.qaction_factory.get('services_downtime').setText( 'Services DOWNTIME (' + str(synthesis['services']['downtime']) + ')')
def create_banner(self, banner_type, message): """ Create banner QWidget and its QPropertyAnimation :param banner_type: defines type of banner: OK, INFO, WARN, or ALERT :type banner_type: str :param message: message to display in banner :type message: str """ layout = QHBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) event_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.setToolTip(event_date) if banner_type not in self.banner_type: banner_type = 'ERROR' self.setStyleSheet(get_css()) self.setObjectName('banner%s' % banner_type) valid_btn = QPushButton() valid_btn.setMaximumSize(self.banner_height, self.banner_height) valid_btn.setObjectName('banner') valid_btn.clicked.connect(self.close_banner) valid_btn.setIcon(QIcon(get_image_path(banner_type.lower()))) layout.addWidget(valid_btn) if len(message) > 170: message = message[:170] + '...' if get_app_config('Banners', 'title', boolean=True): banner_qlabel = QLabel('<b>%s</b>: %s' % (banner_type, message)) else: banner_qlabel = QLabel('%s' % message) banner_qlabel.setWordWrap(True) banner_qlabel.setObjectName('banner') layout.addWidget(banner_qlabel) # Animation banner_duration = int(get_app_config('Banners', 'animation')) if banner_duration < 0: logger.debug('Banner animation: %sms', str(banner_duration)) logger.error( '"animation" option must be equal or greater than 0. Replace by default: 1000ms' ) banner_duration = 1000 self.animation.setDuration(banner_duration) start_value = QPoint(0, 0) self.animation.setStartValue(start_value) screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos()) end_position = QApplication.desktop().screenGeometry(screen).topRight() end_value = QPoint(end_position.x() - self.width(), end_position.y()) self.animation.setEndValue(end_value)
def initialize(self, item_type, item_name, comment): """ Initialize Downtime QDialog :param item_type: type of item to acknowledge : host | service :type item_type: str :param item_name: name of the item to acknowledge :type item_name: str :param comment: the default comment of action :type comment: str """ # Main layout main_layout = QVBoxLayout(self) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(get_logo_widget(self)) downtime_widget = QWidget() downtime_widget.setObjectName('login') downtime_layout = QGridLayout(downtime_widget) ack_title = QLabel('<h2>Request a downtime</h2>') downtime_layout.addWidget(ack_title, 0, 0, 1, 3) host_label = QLabel('<h2>%s: %s</h2>' % (item_type.capitalize(), item_name)) downtime_layout.addWidget(host_label, 1, 0, 1, 1) options_label = QLabel('Downtime options:') options_label.setObjectName('actions') downtime_layout.addWidget(options_label, 2, 0, 1, 1) fixed_checkbox = QCheckBox() fixed_checkbox.setObjectName('actions') fixed_checkbox.setChecked(self.fixed) fixed_checkbox.setFixedSize(18, 18) downtime_layout.addWidget(fixed_checkbox, 2, 1, 1, 1) fixed_label = QLabel('Fixed') fixed_label.setObjectName('actions') downtime_layout.addWidget(fixed_label, 2, 2, 1, 1) fixed_info = QLabel( '<i>If checked, downtime will start and end at the times specified' ' by the “start time” and “end time” fields.</i>') fixed_info.setWordWrap(True) downtime_layout.addWidget(fixed_info, 3, 0, 1, 3) duration_label = QLabel('Duration') duration_label.setObjectName('actions') downtime_layout.addWidget(duration_label, 4, 0, 1, 1) duration_clock = QLabel() duration_clock.setPixmap(QPixmap(get_image_path('clock'))) downtime_layout.addWidget(duration_clock, 4, 1, 1, 1) duration_clock.setFixedSize(16, 16) duration_clock.setScaledContents(True) self.duration.setTime(QTime(4, 00)) self.duration.setDisplayFormat("HH'h'mm") downtime_layout.addWidget(self.duration, 4, 2, 1, 1) duration_info = QLabel( '<i>Sets the duration if it is a non-fixed downtime.</i>') downtime_layout.addWidget(duration_info, 5, 0, 1, 3) date_range_label = QLabel('Downtime date range') date_range_label.setObjectName('actions') downtime_layout.addWidget(date_range_label, 6, 0, 1, 1) calendar_label = QLabel() calendar_label.setPixmap(QPixmap(get_image_path('calendar'))) calendar_label.setFixedSize(16, 16) calendar_label.setScaledContents(True) downtime_layout.addWidget(calendar_label, 6, 1, 1, 1) start_time_label = QLabel('Start time:') downtime_layout.addWidget(start_time_label, 7, 0, 1, 1) self.start_time.setCalendarPopup(True) self.start_time.setDateTime(datetime.datetime.now()) self.start_time.setDisplayFormat("dd/MM/yyyy HH'h'mm") downtime_layout.addWidget(self.start_time, 7, 1, 1, 2) end_time_label = QLabel('End time:') downtime_layout.addWidget(end_time_label, 8, 0, 1, 1) self.end_time.setCalendarPopup(True) self.end_time.setDateTime(datetime.datetime.now() + datetime.timedelta(hours=2)) self.end_time.setDisplayFormat("dd/MM/yyyy HH'h'mm") downtime_layout.addWidget(self.end_time, 8, 1, 1, 2) self.comment_edit.setText(comment) self.comment_edit.setMaximumHeight(60) downtime_layout.addWidget(self.comment_edit, 9, 0, 1, 3) request_btn = QPushButton('REQUEST DOWNTIME', self) request_btn.clicked.connect(self.handle_accept) request_btn.setObjectName('valid') request_btn.setMinimumHeight(30) request_btn.setDefault(True) downtime_layout.addWidget(request_btn, 10, 0, 1, 3) main_layout.addWidget(downtime_widget)
def __init__(self, parent=None): super(AppQWidget, self).__init__(parent) self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowIcon(QIcon(get_image_path('icon'))) self.setStyleSheet(get_css()) self.offset = None
class TestAppNotifier(unittest2.TestCase): """ This file test the AppNotifier class. """ init_config() icon = QIcon(get_image_path('icon')) backend = AppBackend() backend.login() @classmethod def setUpClass(cls): """Create QApplication""" try: cls.app = QApplication(sys.argv) except: pass def test_other_objects_do_not_modify_notifier(self): """Other objects do not Modify Notifier""" # TrayIcon and Dashboard for notifier tray_icon = TrayIcon(self.icon) dashboard = Dashboard() dashboard.initialize() under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) self.assertIsNotNone(under_test.tray_icon) self.assertIsNotNone(under_test.app_backend) self.assertIsNotNone(under_test.dashboard) self.assertFalse(under_test.changes) tray_icon.build_menu(self.backend, dashboard) self.assertIsNotNone(under_test.tray_icon) self.assertIsNotNone(under_test.app_backend) self.assertIsNotNone(under_test.dashboard) self.assertFalse(under_test.changes) def test_check_data(self): """Check Data modify TrayIcon Actions""" # TrayIcon and Dashboard for notifier tray_icon = TrayIcon(self.icon) dashboard = Dashboard() dashboard.initialize() under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) tray_icon.build_menu(self.backend, dashboard) # Start notifier under_test.set_interval() # Check Actions are pending self.assertEqual( 'Hosts UP, Wait...', under_test.tray_icon.qaction_factory.get('hosts_up').text()) self.assertEqual( 'Services OK, Wait...', under_test.tray_icon.qaction_factory.get('services_ok').text()) # Check data... under_test.check_data() # ...so menu actions should be update self.assertNotEqual( 'Hosts UP, Wait...', under_test.tray_icon.qaction_factory.get('hosts_up').text()) self.assertNotEqual( 'Services OK, Wait...', under_test.tray_icon.qaction_factory.get('services_ok').text()) def test_states_change(self): """States and Notify Changes""" self.backend = AppBackend() self.backend.login() # TrayIcon and Dashboard for notifier dashboard = Dashboard() dashboard.initialize() tray_icon = TrayIcon(self.icon) tray_icon.build_menu(self.backend, dashboard) # Initialize Notifier under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) # Changes are True, first_start is True self.assertFalse(under_test.changes) self.assertTrue(under_test.first_start) self.assertIsNone(under_test.old_synthesis) def test_diff_last_state(self): """Diff Last Backend SState""" self.backend = AppBackend() self.backend.login() # TrayIcon and Dashboard for notifier tray_icon_test = TrayIcon(self.icon) dashboard_test = Dashboard() notifier_test = AppNotifier() notifier_test.app_backend = self.backend notifier_test.tray_icon = tray_icon_test notifier_test.dashboard = dashboard_test # Notifier check data to get first synthesys counts notifier_test.check_data() # Get synthesis test to test diff between check synthesis = self.backend.synthesis_count() under_test = notifier_test.diff_last_states(synthesis) fields_test = { 'hosts': { 'up': 0, 'downtime': 0, 'down': 0, 'acknowledge': 0, 'unreachable': 0 }, 'services': { 'ok': 0, 'acknowledge': 0, 'unknown': 0, 'critical': 0, 'downtime': 0, 'unreachable': 0, 'warning': 0 } } self.assertTrue(under_test) self.assertTrue('hosts' in under_test) self.assertTrue('services' in under_test) for state in fields_test['hosts']: self.assertTrue(state in under_test['hosts']) self.assertTrue(isinstance(under_test['hosts'][state], int)) for state in fields_test['services']: self.assertTrue(state in under_test['services']) self.assertTrue(isinstance(under_test['services'][state], int))
class TestTrayIcon(unittest2.TestCase): """ This file test the TrayIcon class. """ init_config() icon = QIcon(get_image_path('icon')) backend = AppBackend() backend.login() @classmethod def setUpClass(cls): """Create QApplication""" try: cls.app = QApplication(sys.argv) except: pass def test_tray_icon(self): """Init TrayIcon and QMenu""" under_test = TrayIcon(TestTrayIcon.icon) self.assertIsInstance(under_test.menu, QMenu) def test_host_actions(self): """Hosts QActions are created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_hosts_actions() self.assertIsInstance(under_test.qaction_factory.get('hosts_up'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_down'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_unreachable'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_acknowledge'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_downtime'), QAction) def test_services_actions(self): """Services QActions are created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_services_actions() self.assertIsInstance(under_test.qaction_factory.get('services_ok'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_warning'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_critical'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_unknown'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_acknowledge'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_downtime'), QAction) def test_about_action(self): """About QAction is created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_about_action() self.assertIsNotNone(under_test.qaction_factory) self.assertIsInstance(under_test.qaction_factory.get('about'), QAction) def test_quit_action(self): """Quit QAction is created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_quit_action() self.assertIsNotNone(under_test.qaction_factory.get('exit')) self.assertIsInstance(under_test.qaction_factory.get('exit'), QAction) def test_build_menu(self): """Build Menu add QActions""" under_test = TrayIcon(TestTrayIcon.icon) dashboard_test = Dashboard() # Assert no actions in Menu self.assertFalse(under_test.menu.actions()) self.assertIsNone(under_test.app_about) self.assertIsNone(under_test.synthesis) self.assertIsNone(under_test.alignak_status) self.assertIsNotNone(under_test.qaction_factory) under_test.build_menu(self.backend, dashboard_test) # Assert actions are added in Menu self.assertTrue(under_test.menu.actions()) self.assertIsNotNone(under_test.app_about) self.assertIsNotNone(under_test.synthesis) self.assertIsNotNone(under_test.alignak_status) self.assertIsNotNone(under_test.qaction_factory) def test_update_menus_actions(self): """Update Menu QActions""" under_test = TrayIcon(TestTrayIcon.icon) dashboard_test = Dashboard() under_test.build_menu(self.backend, dashboard_test) self.assertEqual('Hosts UP, Wait...', under_test.qaction_factory.get('hosts_up').text()) self.assertEqual('Hosts DOWN, Wait...', under_test.qaction_factory.get('hosts_down').text()) self.assertEqual('Hosts UNREACHABLE, Wait...', under_test.qaction_factory.get('hosts_unreachable').text()) self.assertEqual('Services OK, Wait...', under_test.qaction_factory.get('services_ok').text()) self.assertEqual('Services WARNING, Wait...', under_test.qaction_factory.get('services_warning').text()) self.assertEqual('Services CRITICAL, Wait...', under_test.qaction_factory.get('services_critical').text()) self.assertEqual('Services UNKNOWN, Wait...', under_test.qaction_factory.get('services_unknown').text()) synthesis = { 'hosts': { 'up': 1, 'down': 2, 'unreachable': 3, 'acknowledge': 4, 'downtime': 5, }, 'services': { 'ok': 4, 'warning': 5, 'critical': 6, 'unknown': 7, 'unreachable': 8, 'acknowledge': 9, 'downtime': 10, } } under_test.update_menu_actions(synthesis) self.assertEqual('Hosts UP (1)', under_test.qaction_factory.get('hosts_up').text()) self.assertEqual('Hosts DOWN (2)', under_test.qaction_factory.get('hosts_down').text()) self.assertEqual('Hosts UNREACHABLE (3)', under_test.qaction_factory.get('hosts_unreachable').text()) self.assertEqual('Hosts ACKNOWLEDGE (4)', under_test.qaction_factory.get('hosts_acknowledge').text()) self.assertEqual('Hosts DOWNTIME (5)', under_test.qaction_factory.get('hosts_downtime').text()) self.assertEqual('Services OK (4)', under_test.qaction_factory.get('services_ok').text()) self.assertEqual('Services WARNING (5)', under_test.qaction_factory.get('services_warning').text()) self.assertEqual('Services CRITICAL (6)', under_test.qaction_factory.get('services_critical').text()) self.assertEqual('Services UNKNOWN (7)', under_test.qaction_factory.get('services_unknown').text()) self.assertEqual('Services UNREACHABLE (8)', under_test.qaction_factory.get('services_unreachable').text()) self.assertEqual('Services ACKNOWLEDGE (9)', under_test.qaction_factory.get('services_acknowledge').text()) self.assertEqual('Services DOWNTIME (10)', under_test.qaction_factory.get('services_downtime').text())