def event_type_filter(event_types, is_method=False): """ A decorator to filter a signal handler by the specified event types. Using this will ensure that the decorated function is only called for the specified event types and not others which may have been subscribed to elsewhere in the application. :param event_types: A single event type as a string or a list of event type strings. :type event_types: list, str :param bool is_method: Whether or not the function being decorated is a class method. """ utilities.assert_arg_type(event_types, (list, set, str, tuple)) if isinstance(event_types, str): event_types = (event_types,) def decorator(function): @functools.wraps(function) def wrapper(*args): if is_method: _, _, event_type, _ = args else: _, event_type, _ = args if event_type in event_types: function(*args) return return wrapper return decorator
def safe_send(signal, logger, *args, **kwargs): """ Send a signal and catch any exception which may be raised during it's emission. Details regarding the error that occurs (including a stack trace) are logged to the specified *logger*. This is suitable for allowing signals to be emitted in critical code paths without interrupting the emitter. :param str signal: The name of the signal to send safely. :param logger: The logger to use for logging exceptions. :type logger: :py:class:`logging.Logger` :param args: The arguments to be forwarded to the signal as it is sent. :param kwargs: The key word arguments to be forward to the signal as it is sent. """ utilities.assert_arg_type(signal, str, 1) utilities.assert_arg_type(logger, (logging.Logger, logging.LoggerAdapter), 2) try: blinker.signal(signal).send(*args, **kwargs) except Exception: calling_frame = inspect.stack()[1] logger.error( "an error occurred while emitting signal '{0}' from {1}:{2}". format(signal, calling_frame[1], calling_frame[2]), exc_info=True) return
def event_type_filter(event_types, is_method=False): """ A decorator to filter a signal handler by the specified event types. Using this will ensure that the decorated function is only called for the specified event types and not others which may have been subscribed to elsewhere in the application. :param event_types: A single event type as a string or a list of event type strings. :type event_types: list, str :param bool is_method: Whether or not the function being decorated is a class method. """ utilities.assert_arg_type(event_types, (list, set, str, tuple)) if isinstance(event_types, str): event_types = (event_types, ) def decorator(function): @functools.wraps(function) def wrapper(*args): if is_method: _, _, event_type, _ = args else: _, event_type, _ = args if event_type in event_types: function(*args) return return wrapper return decorator
def from_db_authenticated_session(cls, stored_session): utilities.assert_arg_type(stored_session, db_models.AuthenticatedSession) session = cls(stored_session.user_id) session.created = stored_session.created session.last_seen = stored_session.last_seen return session
def test_assert_arg_type(self): with self.assertRaisesRegex(TypeError, r'test_assert_arg_type\(\) argument 1 must be str, not int'): utilities.assert_arg_type(0, str) try: utilities.assert_arg_type('', str) except TypeError: self.fail('assert_arg_type raised a TypeError when it should not have')
def add(self, web_socket): """ Add a connected web socket to the manager. :param web_socket: The connected web socket. :type web_socket: :py:class:`advancedhttpserver.WebSocketHandler` """ utilities.assert_arg_type(web_socket, advancedhttpserver.WebSocketHandler) self.web_sockets.append(web_socket)
def __init__(self, title, parent, **kwargs): """ :param str title: The title for the file chooser dialog. :param parent: The parent window for the dialog. :type parent: :py:class:`Gtk.Window` """ utilities.assert_arg_type(parent, Gtk.Window, arg_pos=2) super(FileChooserDialog, self).__init__(title, parent, **kwargs) self.parent = self.get_parent_window()
def __init__(self, children=None, top_level=None, name=None): children = children or () utilities.assert_arg_type(children, tuple, 1) self.children = children """A tuple of string names or :py:class:`.GladeProxy` instances listing the children widgets to load from the parent.""" self.top_level = top_level """A tuple of string names listing additional top level widgets to load such as images.""" self.name = name """The string of the name of the top level parent widget to load."""
def test_assert_arg_type(self): with self.assertRaisesRegex( TypeError, r'test_assert_arg_type\(\) argument 1 must be str, not int'): utilities.assert_arg_type(0, str) try: utilities.assert_arg_type('', str) except TypeError: self.fail( 'assert_arg_type raised a TypeError when it should not have')
def __init__(self, widget, method, args=None, kwargs=None): utilities.assert_arg_type(widget, str, 1) utilities.assert_arg_type(method, str, 2) self.widget = widget """The name of the parent widget for this proxied child.""" self.method = method """The method of the parent widget that should be called to add the proxied child.""" self.args = args or () """Arguments to append after the proxied child instance when calling :py:attr:`~.GladeProxyDestination.method`.""" self.kwargs = kwargs or {} """Key word arguments to append after the proxied child instance when calling :py:attr:`~.GladeProxyDestination.method`."""
def from_db_authenticated_session(cls, stored_session): """ Load an instance from a record stored in the database. :param stored_session: The authenticated session from the database to load. :return: A new :py:class:`.AuthenticatedSession` instance. """ utilities.assert_arg_type(stored_session, db_models.AuthenticatedSession) session = cls(stored_session.user) session.created = stored_session.created session.last_seen = stored_session.last_seen return session
def from_db_authenticated_session(cls, stored_session): """ Load an instance from a record stored in the database. :param stored_session: The authenticated session from the database to load. :return: A new :py:class:`.AuthenticatedSession` instance. """ utilities.assert_arg_type(stored_session, db_models.AuthenticatedSession) session = cls(stored_session.user_id) session.created = stored_session.created session.last_seen = stored_session.last_seen return session
def send_safe_iter(signal, logger, sender, **kwargs): utilities.assert_arg_type(signal, str, 1) utilities.assert_arg_type(logger, (logging.Logger, logging.LoggerAdapter), 2) signal = blinker.signal(signal) for receiver in signal.receivers_for(sender): try: result = receiver(sender, **kwargs) except Exception: calling_frame = inspect.stack()[1] logger.error("an error occurred while emitting signal '{0}' from {1}:{2}".format(signal, calling_frame[1], calling_frame[2]), exc_info=True) else: yield (receiver, result) return
def liststore_to_xlsx_worksheet(store, worksheet, columns): """ Write the contents of a :py:class:`Gtk.ListStore` to an XLSX workseet. :param store: The store to export the information from. :type store: :py:class:`Gtk.ListStore` :param worksheet: The destination sheet for the store's data. :type worksheet: :py:class:`xlsxwriter.worksheet.Worksheet` :param dict columns: A dictionary mapping store column ids to the value names. :return: The number of rows that were written. :rtype: int """ utilities.assert_arg_type(worksheet, xlsxwriter.worksheet.Worksheet, 2) return liststore_export(store, columns, _xlsx_write, worksheet)
def verify_dict(self, data, signature_encoding='base64'): """ Verify a signed dictionary object. The dictionary must have a 'signature' key as added by the :py:meth:`.SigningKey.sign_dict` method. To serialize the dictionary to data suitable for the operation the :py:func:`json.dumps` function is used and the resulting data is then UTF-8 encoded. :param dict data: The dictionary of data to verify. :param str signature_encoding: The encoding name of the signature data. """ utilities.assert_arg_type(data, dict, arg_pos=1) data = copy.copy(data) signature = _decode_data(data.pop('signature'), encoding=signature_encoding) data = json.dumps(data, sort_keys=True).encode('utf-8') return self.verify(signature, data)
def gtk_combobox_set_entry_completion(combobox): """ Add completion for a :py:class:`Gtk.ComboBox` widget which contains an entry. They combobox's ``entry-text-column`` property it used to determine which column in its model contains the strings to suggest for completion. .. versionadded:: 1.14.0 :param combobox: The combobox to add completion for. :type: :py:class:`Gtk.ComboBox` """ utilities.assert_arg_type(combobox, Gtk.ComboBox) completion = Gtk.EntryCompletion() completion.set_model(combobox.get_model()) completion.set_text_column(combobox.get_entry_text_column()) entry = combobox.get_child() entry.set_completion(completion)
def sign_dict(self, data, signature_encoding='base64'): """ Sign a dictionary object. The dictionary will have a 'signature' key added is required by the :py:meth:`.VerifyingKey.verify_dict` method. To serialize the dictionary to data suitable for the operation the :py:func:`json.dumps` function is used and the resulting data is then UTF-8 encoded. :param dict data: The dictionary of data to sign. :param str signature_encoding: The encoding name of the signature data. """ utilities.assert_arg_type(data, dict, arg_pos=1) data = copy.copy(data) json_data = json.dumps(data, sort_keys=True).encode('utf-8') data['signature'] = _encoding_data(self.sign(json_data), encoding=signature_encoding) return data
def __init__(self, application, window): utilities.assert_arg_type(application, Gtk.Application, arg_pos=1) utilities.assert_arg_type(window, MainAppWindow, arg_pos=2) super(MainMenuBar, self).__init__(application) self.window = weakref.proxy(window) self._add_accelerators() graphs_menu_item = self.gtk_builder_get('menuitem_tools_create_graph') if graphs.has_matplotlib: graphs_submenu = Gtk.Menu.new() for graph_name in graphs.get_graphs(): graph = graphs.get_graph(graph_name) menu_item = Gtk.MenuItem.new_with_label(graph.name_human) menu_item.connect('activate', self.signal_activate_tools_show_campaign_graph, graph_name) graphs_submenu.append(menu_item) graphs_menu_item.set_submenu(graphs_submenu) graphs_menu_item.show_all() else: graphs_menu_item.set_sensitive(False)
def send_safe_iter(signal, logger, sender, **kwargs): utilities.assert_arg_type(signal, str, 1) utilities.assert_arg_type(logger, (logging.Logger, logging.LoggerAdapter), 2) signal = blinker.signal(signal) for receiver in signal.receivers_for(sender): try: result = receiver(sender, **kwargs) except Exception: calling_frame = inspect.stack()[1] logger.error( "an error occurred while emitting signal '{0}' from {1}:{2}". format(signal, calling_frame[1], calling_frame[2]), exc_info=True) else: yield (receiver, result) return
def __init__(self, glade_gobject, widget_type, group_name): """ :param glade_gobject: The gobject which has the radio buttons set. :type glade_gobject: :py:class:`.GladeGObject` :param str group_name: The name of the group of buttons. """ utilities.assert_arg_type(glade_gobject, gui_utilities.GladeGObject) self.group_name = group_name name_prefix = widget_type + '_' + self.group_name + '_' self.buttons = utilities.FreezableDict() for gobj_name in glade_gobject.dependencies.children: if not gobj_name.startswith(name_prefix): continue button_name = gobj_name[len(name_prefix):] self.buttons[button_name] = glade_gobject.gobjects[gobj_name] if not len(self.buttons): raise ValueError('found no ' + widget_type + ' of group: ' + self.group_name) self.buttons.freeze()
def add_reference(self, ref_object): """ Add *ref_object* to the :py:attr:`.references` so the object won't be garbage collected. The object must either be a :py:class:`.GladeGObject` or :py:class:`Gtk.Widget` instance so a cleanup function can be attached to a ``destroy`` signal to remove the reference automatically. :param ref_object: The object to store a reference to. :type ref_object: :py:class:`.GladeGObject`, :py:class:`Gtk.Widget` """ utilities.assert_arg_type(ref_object, (gui_utilities.GladeGObject, Gtk.Widget)) self.references.append(ref_object) if isinstance(ref_object, gui_utilities.GladeGObject): widget = getattr(ref_object, ref_object.top_gobject) else: widget = ref_object widget.connect('destroy', self.signal_multi_destroy_remove_reference, ref_object)
def remote_row_resolve(self, row): """ Take a :py:class:`~.RemoteRow` instance and load all fields which are :py:data:`~.UNRESOLVED`. If all fields are present, no modifications are made. :param row: The row who's data is to be resolved. :rtype: :py:class:`~.RemoteRow` :return: The row with all of it's fields fully resolved. :rtype: :py:class:`~.RemoteRow` """ utilities.assert_arg_type(row, RemoteRow) slots = getattr(row, '__slots__')[1:] if not any(prop for prop in slots if getattr(row, prop) is UNRESOLVED): return row for key, value in self.call('db/table/get', getattr(row, '__table__'), row.id).items(): setattr(row, key, value) return row
def sign_dict(self, data, signature_encoding='base64'): """ Sign a dictionary object. The dictionary will have a 'signature' key added is required by the :py:meth:`.VerifyingKey.verify_dict` method. To serialize the dictionary to data suitable for the operation the :py:func:`json.dumps` function is used and the resulting data is then UTF-8 encoded. :param dict data: The dictionary of data to sign. :param str signature_encoding: The encoding name of the signature data. :return: The dictionary object is returned with the 'signature' key added. """ utilities.assert_arg_type(data, dict, arg_pos=1) data = copy.copy(data) data.pop('signature', None) # remove a pre-existing signature json_data = json.dumps(data, sort_keys=True).encode('utf-8') data['signature'] = _encoding_data(self.sign(json_data), encoding=signature_encoding) return data
def __init__(self, glade_gobject, button_group_name): """ :param glade_gobject: The gobject which has the radio buttons set. :type glade_gobject: :py:class:`.GladeGObject` :param str button_group_name: The name of the group of buttons. """ utilities.assert_arg_type(glade_gobject, gui_utilities.GladeGObject) self.group_name = button_group_name name_prefix = 'radiobutton_' + self.group_name + '_' self.buttons = utilities.FreezableDict() for gobj_name in glade_gobject.dependencies.children: if not gobj_name.startswith(name_prefix): continue button_name = gobj_name[len(name_prefix):] self.buttons[button_name] = glade_gobject.gobjects[gobj_name] if not len(self.buttons): raise ValueError('found no radiobuttons of group: ' + self.group_name) self.buttons.freeze()
def __init__(self, application): """ :param application: The parent application for this object. :type application: :py:class:`Gtk.Application` """ utilities.assert_arg_type(application, Gtk.Application, arg_pos=1) self.config = application.config """A reference to the King Phisher client configuration.""" self.application = application """The parent :py:class:`Gtk.Application` instance.""" self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) builder = Gtk.Builder() self.gtk_builder = builder """A :py:class:`Gtk.Builder` instance used to load Glade data with.""" top_level_dependencies = [ gobject.name for gobject in self.dependencies.children if isinstance(gobject, GladeProxy) ] top_level_dependencies.append(self.dependencies.name) if self.dependencies.top_level is not None: top_level_dependencies.extend(self.dependencies.top_level) builder.add_objects_from_file(which_glade(), top_level_dependencies) builder.connect_signals(self) gobject = builder.get_object(self.dependencies.name) setattr(self, self.top_gobject, gobject) if isinstance(gobject, Gtk.Window): gobject.set_transient_for(self.application.get_active_window()) self.application.add_reference(self) if isinstance(gobject, Gtk.ApplicationWindow): application.add_window(gobject) if isinstance(gobject, Gtk.Dialog): gobject.set_modal(True) self.gobjects = utilities.FreezableDict() """A :py:class:`~king_phisher.utilities.FreezableDict` which maps gobjects to their unique GTK Builder id.""" self._load_child_dependencies(self.dependencies) self.gobjects.freeze() self._load_child_proxies() if self.objects_persist: self.objects_load_from_config()
def liststore_to_xlsx_worksheet(store, worksheet, columns, title_format, xlsx_options=None): """ Write the contents of a :py:class:`Gtk.ListStore` to an XLSX workseet. :param store: The store to export the information from. :type store: :py:class:`Gtk.ListStore` :param worksheet: The destination sheet for the store's data. :type worksheet: :py:class:`xlsxwriter.worksheet.Worksheet` :param dict columns: A dictionary mapping store column ids to the value names. :param xlsx_options: A collection of additional options for formatting the Excel Worksheet. :type xlsx_options: :py:class:`.XLSXWorksheetOptions` :return: The number of rows that were written. :rtype: int """ utilities.assert_arg_type(worksheet, xlsxwriter.worksheet.Worksheet, 2) utilities.assert_arg_type(columns, dict, 3) utilities.assert_arg_type(title_format, xlsxwriter.format.Format, 4) utilities.assert_arg_type(xlsx_options, XLSXWorksheetOptions, 5) if xlsx_options is None: worksheet.set_column(0, len(columns), 30) else: for column, width in enumerate(xlsx_options.column_widths): worksheet.set_column(column, column, width) column_names, _ = _split_columns(columns) if xlsx_options is None: start_row = 0 else: start_row = 2 worksheet.merge_range(0, 0, 0, len(column_names) - 1, xlsx_options.title, title_format) row_count = liststore_export(store, columns, _xlsx_write, (worksheet, ), row_offset=start_row, write_columns=False) options = { 'columns': list({'header': column_name} for column_name in column_names), 'style': 'Table Style Medium 1' } worksheet.add_table(start_row, 0, row_count + start_row, len(column_names) - 1, options=options) worksheet.freeze_panes(1 + start_row, 0) return row_count
def __init__(self, method, widget=None, args=None, kwargs=None): """ :param str method: The method of the container *widget* to use to add the proxied widget. :param str widget: The widget name to add the proxied widget to. If this value is ``None``, the proxied widget is added to the top level widget. :param tuple args: Position arguments to provide when calling *method*. :param dict kwargs: Key word arguments to provide when calling *method*. """ utilities.assert_arg_type(method, str, 1) utilities.assert_arg_type(widget, (type(None), str), 2) self.widget = widget """The name of the parent widget for this proxied child.""" self.method = method """The method of the parent widget that should be called to add the proxied child.""" self.args = args or () """Arguments to append after the proxied child instance when calling :py:attr:`~.GladeProxyDestination.method`.""" self.kwargs = kwargs or {} """Key word arguments to append after the proxied child instance when calling :py:attr:`~.GladeProxyDestination.method`."""
def safe_send(signal, logger, *args, **kwargs): """ Send a signal and catch any exception which may be raised during it's emission. Details regarding the error that occurs (including a stack trace) are logged to the specified *logger*. This is suitable for allowing signals to be emitted in critical code paths without interrupting the emitter. :param str signal: The name of the signal to send safely. :param logger: The logger to use for logging exceptions. :type logger: :py:class:`logging.Logger` :param args: The arguments to be forwarded to the signal as it is sent. :param kwargs: The key word arguments to be forward to the signal as it is sent. """ utilities.assert_arg_type(signal, str, 1) utilities.assert_arg_type(logger, logging.Logger, 2) try: blinker.signal(signal).send(*args, **kwargs) except Exception: calling_frame = inspect.stack()[1] logger.error("an error occurred while emitting signal '{0}' from {1}:{2}".format(signal, calling_frame[1], calling_frame[2]), exc_info=True) return
def liststore_to_xlsx_worksheet(store, worksheet, columns, title_format): """ Write the contents of a :py:class:`Gtk.ListStore` to an XLSX workseet. :param store: The store to export the information from. :type store: :py:class:`Gtk.ListStore` :param worksheet: The destination sheet for the store's data. :type worksheet: :py:class:`xlsxwriter.worksheet.Worksheet` :param dict columns: A dictionary mapping store column ids to the value names. :param title_format: The formatting to use for the title row. :type title_format: :py:class:`xlsxwriter.format.Format` :return: The number of rows that were written. :rtype: int """ utilities.assert_arg_type(worksheet, xlsxwriter.worksheet.Worksheet, 2) utilities.assert_arg_type(columns, dict, 3) utilities.assert_arg_type(title_format, xlsxwriter.format.Format, 4) worksheet.set_column(0, len(columns), 30) column_names, _ = _split_columns(columns) _xlsx_write(0, column_names, worksheet, title_format) worksheet.freeze_panes(1, 0) return liststore_export(store, columns, _xlsx_write, (worksheet, ), write_columns=False)
def subscribe(self, event_id, event_types, attributes): """ Subscribe the client to the specified event published by the server. When the event is published the specified *attributes* of it and it's corresponding id and type information will be sent to the client. :param str event_id: The identifier of the event to subscribe to. :param list event_types: A list of sub-types for the corresponding event. :param list attributes: A list of attributes of the event object to be sent to the client. """ utilities.assert_arg_type(event_id, str, arg_pos=1) utilities.assert_arg_type(event_types, (list, set, tuple), arg_pos=2) utilities.assert_arg_type(event_types, (list, set, tuple), arg_pos=3) new_event_types = set(event_types) new_attributes = set(attributes) subscription_table = self._subscriptions[event_id] for subscription in itertools.product(event_types, attributes): subscription = _SubscriptionStub(*subscription) subscription_table[subscription] += 1 if subscription_table[subscription] > 1: new_event_types.discard(subscription.event_type) new_attributes.discard(subscription.attribute) if new_event_types or new_attributes: self._subscribe(event_id, event_types, attributes)
def unsubscribe(self, event_id, event_types=None, attributes=None): """ Unsubscribe from an event published by the server that the client previously subscribed to. :param str event_id: The identifier of the event to subscribe to. :param list event_types: A list of sub-types for the corresponding event. :param list attributes: A list of attributes of the event object to be sent to the client. """ utilities.assert_arg_type(event_id, str, arg_pos=1) utilities.assert_arg_type(event_types, (type(None), list, set, tuple), arg_pos=2) utilities.assert_arg_type(event_types, (type(None), list, set, tuple), arg_pos=3) subscription = self._subscriptions.get(event_id) if subscription is None: return if event_types is not None: for event_type in event_types: subscription.event_types.discard(event_type) if attributes is not None: for attribute in attributes: subscription.attributes.discard(attribute) if not subscription.event_types and not subscription.attributes: del self._subscriptions[event_id]
def subscribe(self, event_id, event_types=None, attributes=None): """ Subscribe the client to the specified event published by the server. When the event is published the specified *attributes* of it and it's corresponding id and type information will be sent to the client. :param str event_id: The identifier of the event to subscribe to. :param list event_types: A list of sub-types for the corresponding event. :param list attributes: A list of attributes of the event object to be sent to the client. """ utilities.assert_arg_type(event_id, str, arg_pos=1) utilities.assert_arg_type(event_types, (type(None), list, set, tuple), arg_pos=2) utilities.assert_arg_type(event_types, (type(None), list, set, tuple), arg_pos=3) subscription = self._subscriptions.get(event_id) if subscription is None: subscription = EventSubscription(attributes=set(), event_types=set()) if event_types is not None: subscription.event_types.update(event_types) if attributes is not None: subscription.attributes.update(attributes) self._subscriptions[event_id] = subscription
def __init__(self, application): """ :param application: The parent application for this object. :type application: :py:class:`Gtk.Application` """ utilities.assert_arg_type(application, Gtk.Application, arg_pos=1) self.config = application.config """A reference to the King Phisher client configuration.""" self.application = application """The parent :py:class:`Gtk.Application` instance.""" self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) builder = Gtk.Builder() self.gtk_builder = builder """A :py:class:`Gtk.Builder` instance used to load Glade data with.""" top_level_dependencies = [gobject.name for gobject in self.dependencies.children if isinstance(gobject, GladeProxy)] top_level_dependencies.append(self.dependencies.name) if self.dependencies.top_level is not None: top_level_dependencies.extend(self.dependencies.top_level) builder.add_objects_from_file(which_glade(), top_level_dependencies) builder.connect_signals(self) gobject = builder.get_object(self.dependencies.name) setattr(self, self.top_gobject, gobject) if isinstance(gobject, Gtk.Window): gobject.set_transient_for(self.application.get_active_window()) self.application.add_reference(self) if isinstance(gobject, Gtk.ApplicationWindow): application.add_window(gobject) if isinstance(gobject, Gtk.Dialog): gobject.set_modal(True) self.gobjects = utilities.FreezableDict() """A :py:class:`~king_phisher.utilities.FreezableDict` which maps gobjects to their unique GTK Builder id.""" self._load_child_dependencies(self.dependencies) self.gobjects.freeze() self._load_child_proxies() if self.objects_persist: self.objects_load_from_config()
def unsubscribe(self, event_id, event_types, attributes): """ Unsubscribe from an event published by the server that the client previously subscribed to. :param str event_id: The identifier of the event to subscribe to. :param list event_types: A list of sub-types for the corresponding event. :param list attributes: A list of attributes of the event object to be sent to the client. """ utilities.assert_arg_type(event_id, str, arg_pos=1) utilities.assert_arg_type(event_types, (list, set, tuple), arg_pos=2) utilities.assert_arg_type(event_types, (list, set, tuple), arg_pos=3) event_types = set(event_types) attributes = set(attributes) freeable_subsriptions = collections.deque() subscription_table = self._subscriptions[event_id] for subscription in itertools.product(event_types, attributes): subscription = _SubscriptionStub(*subscription) subscription_table[subscription] -= 1 if subscription_table[subscription] < 1: freeable_subsriptions.append(subscription) for subscription in freeable_subsriptions: del subscription_table[subscription] # to do, delete the subscription table from _subscriptions if it's empty remaining_event_types = [sub.event_type for sub in subscription_table] remaining_attributes = [sub.attribute for sub in subscription_table] freeable_event_types = [sub.event_type for sub in freeable_subsriptions if not sub.event_type in remaining_event_types] freeable_attributes = [sub.attribute for sub in freeable_subsriptions if not sub.attribute in remaining_attributes] if freeable_event_types or freeable_attributes: self._unsubscribe(event_id, freeable_event_types, freeable_attributes)
def liststore_to_xlsx_worksheet(store, worksheet, columns, title_format, xlsx_options=None): """ Write the contents of a :py:class:`Gtk.ListStore` to an XLSX workseet. :param store: The store to export the information from. :type store: :py:class:`Gtk.ListStore` :param worksheet: The destination sheet for the store's data. :type worksheet: :py:class:`xlsxwriter.worksheet.Worksheet` :param dict columns: A dictionary mapping store column ids to the value names. :param xlsx_options: A collection of additional options for formatting the Excel Worksheet. :type xlsx_options: :py:class:`.XLSXWorksheetOptions` :return: The number of rows that were written. :rtype: int """ utilities.assert_arg_type(worksheet, xlsxwriter.worksheet.Worksheet, 2) utilities.assert_arg_type(columns, dict, 3) utilities.assert_arg_type(title_format, xlsxwriter.format.Format, 4) utilities.assert_arg_type(xlsx_options, (type(None), XLSXWorksheetOptions), 5) if xlsx_options is None: worksheet.set_column(0, len(columns), 30) else: for column, width in enumerate(xlsx_options.column_widths): worksheet.set_column(column, column, width) column_names, _ = _split_columns(columns) if xlsx_options is None: start_row = 0 else: start_row = 2 worksheet.merge_range(0, 0, 0, len(column_names) - 1, xlsx_options.title, title_format) row_count = liststore_export(store, columns, _xlsx_write, (worksheet,), row_offset=start_row, write_columns=False) if not row_count: column_ = 0 for column_name in column_names: worksheet.write(start_row, column_, column_name) column_ += 1 return row_count options = { 'columns': list({'header': column_name} for column_name in column_names), 'style': 'Table Style Medium 1' } worksheet.add_table(start_row, 0, row_count + start_row, len(column_names) - 1, options=options) worksheet.freeze_panes(1 + start_row, 0) return row_count
def gtk_menu_insert_by_path(menu, menu_path, menu_item): """ Add a new menu item into the existing menu at the path specified in *menu_path*. :param menu: The existing menu to add the new item to. :type menu: :py:class:`Gtk.Menu` :py:class:`Gtk.MenuBar` :param list menu_path: The labels of submenus to traverse to insert the new item. :param menu_item: The new menu item to insert. :type menu_item: :py:class:`Gtk.MenuItem` """ utilities.assert_arg_type(menu, (Gtk.Menu, Gtk.MenuBar), 1) utilities.assert_arg_type(menu_path, list, 2) utilities.assert_arg_type(menu_item, Gtk.MenuItem, 3) while len(menu_path): label = menu_path.pop(0) menu_cursor = gtk_menu_get_item_by_label(menu, label) if menu_cursor is None: raise ValueError('missing node labeled: ' + label) menu = menu_cursor.get_submenu() menu.append(menu_item)
def liststore_to_xlsx_worksheet(store, worksheet, columns, title_format): """ Write the contents of a :py:class:`Gtk.ListStore` to an XLSX workseet. :param store: The store to export the information from. :type store: :py:class:`Gtk.ListStore` :param worksheet: The destination sheet for the store's data. :type worksheet: :py:class:`xlsxwriter.worksheet.Worksheet` :param dict columns: A dictionary mapping store column ids to the value names. :param title_format: The formatting to use for the title row. :type title_format: :py:class:`xlsxwriter.format.Format` :return: The number of rows that were written. :rtype: int """ utilities.assert_arg_type(worksheet, xlsxwriter.worksheet.Worksheet, 2) utilities.assert_arg_type(columns, dict, 3) utilities.assert_arg_type(title_format, xlsxwriter.format.Format, 4) worksheet.set_column(0, len(columns), 30) column_names, _ = _split_columns(columns) _xlsx_write(0, column_names, worksheet, title_format) worksheet.freeze_panes(1, 0) return liststore_export(store, columns, _xlsx_write, (worksheet,), write_columns=False)
def __init__(self, config, application): """ :param dict config: The main King Phisher client configuration. :param application: The application instance to which this window belongs. :type application: :py:class:`.KingPhisherClientApplication` """ utilities.assert_arg_type(application, Gtk.Application, arg_pos=2) super(MainAppWindow, self).__init__(application=application) self.application = application self.logger = logging.getLogger('KingPhisher.Client.MainWindow') self.config = config """The main King Phisher client configuration.""" self.set_property('title', 'King Phisher') vbox = Gtk.Box() vbox.set_property('orientation', Gtk.Orientation.VERTICAL) vbox.show() self.add(vbox) default_icon_file = find.data_file('king-phisher-icon.svg') if default_icon_file: icon_pixbuf = GdkPixbuf.Pixbuf.new_from_file(default_icon_file) self.set_default_icon(icon_pixbuf) self.accel_group = Gtk.AccelGroup() self.add_accel_group(self.accel_group) self.menu_bar = MainMenuBar(application, self) vbox.pack_start(self.menu_bar.menubar, False, False, 0) # create notebook and tabs self.notebook = Gtk.Notebook() """The primary :py:class:`Gtk.Notebook` that holds the top level taps of the client GUI.""" self.notebook.connect('switch-page', self.signal_notebook_switch_page) self.notebook.set_scrollable(True) vbox.pack_start(self.notebook, True, True, 0) self.tabs = {} current_page = self.notebook.get_current_page() self.last_page_id = current_page mailer_tab = MailSenderTab(self, self.application) self.tabs['mailer'] = mailer_tab self.notebook.insert_page(mailer_tab.box, mailer_tab.label, current_page + 1) self.notebook.set_current_page(current_page + 1) campaign_tab = CampaignViewTab(self, self.application) campaign_tab.box.show() self.tabs['campaign'] = campaign_tab self.notebook.insert_page(campaign_tab.box, campaign_tab.label, current_page + 2) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_size_request(800, 600) self.connect('delete-event', self.signal_delete_event) self.notebook.show() self.show() self.rpc = None # needs to be initialized last """The :py:class:`.KingPhisherRPCClient` instance.""" self.application.connect('server-connected', self.signal_kp_server_connected) self.login_dialog = dialogs.LoginDialog(self.application) self.login_dialog.dialog.connect('response', self.signal_login_dialog_response) self.login_dialog.show()
def __init__(self, destination): utilities.assert_arg_type(destination, GladeProxyDestination, 1) self.destination = destination """A :py:class:`.GladeProxyDestination` instance describing how this proxied widget should be added to the parent."""
def __init__(self, application): """ :param application: The application instance to which this window belongs. :type application: :py:class:`.KingPhisherClientApplication` """ utilities.assert_arg_type(application, Gtk.Application, arg_pos=1) self.application = application self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) if not has_vte: gui_utilities.show_dialog_error('RPC Terminal Is Unavailable', self.application.get_active_window(), 'VTE is not installed') return config = application.config self.terminal = Vte.Terminal() self.rpc_window = RPCTerminalAppWindow(self.terminal, self.application) rpc = self.application.rpc config = { 'campaign_id': config['campaign_id'], 'campaign_name': config['campaign_name'], 'rpc_data': { 'address': (rpc.host, rpc.port), 'use_ssl': rpc.use_ssl, 'username': rpc.username, 'uri_base': rpc.uri_base, 'headers': rpc.headers } } module_path = os.path.dirname(client_rpc.__file__) + ((os.path.sep + '..') * client_rpc.__name__.count('.')) module_path = os.path.normpath(module_path) python_command = [ "import {0}".format(client_rpc.__name__), "{0}.vte_child_routine('{1}')".format(client_rpc.__name__, json_ex.dumps(config, pretty=False)) ] python_command = '; '.join(python_command) if hasattr(self.terminal, 'pty_new_sync'): # Vte._version >= 2.91 vte_pty = self.terminal.pty_new_sync(Vte.PtyFlags.DEFAULT) self.terminal.set_pty(vte_pty) self.terminal.connect('child-exited', lambda vt, status: self.rpc_window.window.destroy()) else: # Vte._version <= 2.90 vte_pty = self.terminal.pty_new(Vte.PtyFlags.DEFAULT) self.terminal.set_pty_object(vte_pty) self.terminal.connect('child-exited', lambda vt: self.rpc_window.window.destroy()) child_pid, _, _, _ = GLib.spawn_async( working_directory=os.getcwd(), argv=[sys.executable, '-c', python_command], envp=[ 'PATH=' + os.environ['PATH'], 'PYTHONPATH=' + module_path, find.ENV_VAR + '=' + os.environ[find.ENV_VAR] ], flags=(GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD), child_setup=self._child_setup, user_data=vte_pty ) self.logger.info("vte spawned child process with pid: {0}".format(child_pid)) self.child_pid = child_pid self.terminal.watch_child(child_pid) GLib.spawn_close_pid(child_pid) self.rpc_window.window.show_all() self.rpc_window.child_pid = child_pid return
def __init__(self, organizer_email, start, summary, organizer_cn=None, description=None, duration='1h', location=None): """ :param str organizer_email: The email of the event organizer. :param start: The start time for the event. :type start: :py:class:`datetime.datetime` :param str summary: A short summary of the event. :param str organizer_cn: The name of the event organizer. :param str description: A more complete description of the event than what is provided by the *summary* parameter. :param duration: The events scheduled duration. :type duration: int, str, :py:class:`~datetime.timedelta`, :py:class:`.DurationAllDay` :param str location: The location for the event. """ utilities.assert_arg_type(start, datetime.datetime, 2) super(Calendar, self).__init__() if start.tzinfo is None: start = start.replace(tzinfo=dateutil.tz.tzlocal()) start = start.astimezone(dateutil.tz.tzutc()) for case in utilities.switch(duration, comp=isinstance): if case(str): duration = smoke_zephyr.utilities.parse_timespan(duration) duration = datetime.timedelta(seconds=duration) break if case(int): duration = datetime.timedelta(seconds=duration) break if case(datetime.timedelta): break if case(DurationAllDay): break else: raise TypeError('unknown duration type') self.add('method', 'REQUEST') self.add('prodid', 'Microsoft Exchange Server 2010') self.add('version', '2.0') self._event = icalendar.Event() event = self._event self.add_component(event) self.add_component(Timezone()) organizer = icalendar.vCalAddress('MAILTO:' + organizer_email) organizer.params['cn'] = icalendar.vText(organizer_cn or organizer_email) event['organizer'] = organizer event.add('description', description or summary) event.add('uid', str(uuid.uuid4())) event.add('summary', summary) if isinstance(duration, DurationAllDay): event.add('dtstart', start.date()) event.add('dtend', (start + datetime.timedelta(days=duration.days)).date()) else: event.add('dtstart', start) event.add('dtend', start + duration) event.add('class', 'PUBLIC') event.add('priority', 5) event.add('dtstamp', datetime.datetime.now(dateutil.tz.tzutc())) event.add('transp', 'OPAQUE') event.add('status', 'CONFIRMED') event.add('sequence', 0) if location: event.add('location', icalendar.vText(location)) alarm = icalendar.Alarm() alarm.add('description', 'REMINDER') alarm.add('trigger;related=start', '-PT1H') alarm.add('action', 'DISPLAY') event.add_component(alarm)
def __init__(self, application): """ :param application: The application instance to which this window belongs. :type application: :py:class:`.KingPhisherClientApplication` """ utilities.assert_arg_type(application, Gtk.Application, arg_pos=1) self.application = application self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) if not has_vte: gui_utilities.show_dialog_error( 'RPC Terminal Is Unavailable', self.application.get_active_window(), 'VTE is not installed') return config = application.config self.terminal = Vte.Terminal() self.rpc_window = RPCTerminalAppWindow(self.terminal, self.application) rpc = self.application.rpc config = { 'campaign_id': config['campaign_id'], 'campaign_name': config['campaign_name'], 'rpc_data': { 'address': (rpc.host, rpc.port), 'use_ssl': rpc.use_ssl, 'username': rpc.username, 'uri_base': rpc.uri_base, 'headers': rpc.headers } } module_path = os.path.dirname(client_rpc.__file__) + ( (os.path.sep + '..') * client_rpc.__name__.count('.')) module_path = os.path.normpath(module_path) python_command = [ "import {0}".format(client_rpc.__name__), "{0}.vte_child_routine('{1}')".format( client_rpc.__name__, serializers.JSON.dumps(config, pretty=False)) ] python_command = '; '.join(python_command) if hasattr(self.terminal, 'pty_new_sync'): # Vte._version >= 2.91 vte_pty = self.terminal.pty_new_sync(Vte.PtyFlags.DEFAULT) self.terminal.set_pty(vte_pty) self.terminal.connect( 'child-exited', lambda vt, status: self.rpc_window.window.destroy()) else: # Vte._version <= 2.90 vte_pty = self.terminal.pty_new(Vte.PtyFlags.DEFAULT) self.terminal.set_pty_object(vte_pty) self.terminal.connect('child-exited', lambda vt: self.rpc_window.window.destroy()) child_pid, _, _, _ = GLib.spawn_async( working_directory=os.getcwd(), argv=[sys.executable, '-c', python_command], envp=[ 'DISPLAY=' + os.environ['DISPLAY'], 'PATH=' + os.environ['PATH'], 'PYTHONPATH=' + module_path, find.ENV_VAR + '=' + os.environ[find.ENV_VAR] ], flags=(GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD), child_setup=self._child_setup, user_data=vte_pty) self.logger.info( "vte spawned child process with pid: {0}".format(child_pid)) self.child_pid = child_pid self.terminal.watch_child(child_pid) GLib.spawn_close_pid(child_pid) self.rpc_window.window.show_all() self.rpc_window.child_pid = child_pid return