def get_widgets(layout, placeholder, user=None, workspace=None, position=None, occupied_cells=[]): """ Gets widgets. In case if in restricted mode (``RESTRICT_PLUGIN_ACCESS`` is set to True), user argument should be provided. Based on it, the list of plugins is returned. Restrictions are bypassed in case if ``RESTRICT_PLUGIN_ACCESS`` is set to False or user given is a superuser. Placeholders are validated already. We don't need to have validation here. :param dash.base.BaseDashLayout layout: Layout object. :param string placeholder_uid: Placeholder uid. :param django.contrib.auth.models.User user: :param string workspace: Workspace slug. :param int position: Plugin position. :param list occupied_cells: List of already occupied cells. :return list: """ # We should get the layout, see loop through its' plugins and see which of those do have rendererrs. Then # we get all the plugins (based on whether they are restricted or not - get the list) and then filter # out those that do not have renderers. ensure_autodiscover() registered_widgets = {} plugin_widget_uids = plugin_widget_registry._registry.keys() if not RESTRICT_PLUGIN_ACCESS or getattr(user, 'is_superuser', False): for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the placeholder. plugin_widget_uid = PluginWidgetRegistry.namify(layout.uid, placeholder.uid, uid) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells(layout, placeholder, uid, position, check_boundaries=True) if plugin_widget_uid in plugin_widget_uids and widget_occupied_cells is not False and \ not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = {'placeholder_uid': placeholder.uid, 'plugin_uid': uid} if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = force_text(plugin.group) if not plugin_group in registered_widgets: registered_widgets[plugin_group] = [] if PY3: widget_name = force_text(plugin.name, encoding='utf-8') else: widget_name = force_text(plugin.name, encoding='utf-8').encode('utf-8') registered_widgets[plugin_group].append(( uid, '{0} ({1}x{2})'.format(widget_name, plugin_widget.cols, plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) )) else: allowed_plugin_uids = get_allowed_plugin_uids(user) for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the placeholder and user has access to the # widget desired. plugin_widget_uid = PluginWidgetRegistry.namify(layout.uid, placeholder.uid, uid) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells(layout, placeholder, uid, position, check_boundaries=True) if uid in allowed_plugin_uids and plugin_widget_uid in plugin_widget_uids and \ widget_occupied_cells is not False and not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = {'placeholder_uid': placeholder.uid, 'plugin_uid': uid} if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = force_text(plugin.group) if not plugin_group in registered_widgets: registered_widgets[plugin_group] = [] registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(force_text(plugin.name), plugin_widget.cols, plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) return registered_widgets
def get_occupied_cells(layout, placeholder, plugin_uid, position, check_boundaries=False, fail_silently=True): """ Get cells occupied by the given dashboard entry. :param dash.base.BaseDashboardLayout dashboard_entry: Instance of subclassed ``dash.base.BaseDashboardLayout`` object. :param dash.base.BaseDashboardPlaceholder placeholder: Instance of subclassed ``dash.base.BaseDashboardPlaceholder`` object. :param string plugin_uid: UID of the plugin to check against. :param int position: Position of the plugin to check against. :param bool check_boundaries: If set to True, boundaries of the placeholders are also considered. :param bool fail_silently: If set to True, no exceptions are raised. :return mixed: Returns a list (could be an empty list as well) if all goes well and returns boolean False if out of the placeholder boundaries. """ assert isinstance(layout, BaseDashboardLayout) #assert issubclass(placeholder, BaseDashboardPlaceholder) widget_cls = plugin_widget_registry.get( PluginWidgetRegistry.namify(layout.uid, placeholder.uid, plugin_uid) ) occupied_cells = [] placeholder_max_cell_num = placeholder.cols * placeholder.rows try: position = int(position) except Exception as e: if fail_silently: return False else: raise e if widget_cls: # First check the basic things. if check_boundaries: # Checking if widget isn't touching the boundaries. Checking the widget width. relative_col_num = position % placeholder.cols if 0 == relative_col_num: relative_col_num = placeholder.cols if (relative_col_num + widget_cls.cols - 1) > placeholder.cols: if fail_silently: return False else: raise PluginWidgetOutOfPlaceholderBoundaries("Widget is out of placeholder boundaries.") # Checking if widget isn't touching the boundaries. Checking the widget height. #relative_row_num = position % placeholder.rows #if 0 == relative_row_num: # relative_row_num = placeholder.rows #if (relative_row_num + widget_cls.rows - 1) > placeholder.rows: # if fail_silently: # return False # else: # raise PluginWidgetOutOfPlaceholderBoundaries("Widget is out of placeholder boundaries.") # Now check the collision with other plugin widgets. for row in range(0, widget_cls.rows): for col in range(0, widget_cls.cols): cell_num = position + col + (row * placeholder.cols) if check_boundaries and cell_num > placeholder_max_cell_num: if fail_silently: return False else: raise PluginWidgetOutOfPlaceholderBoundaries("Widget is out of placeholder boundaries.") occupied_cells.append(cell_num) return occupied_cells
def get_occupied_cells(layout, placeholder, plugin_uid, position, \ check_boundaries=False, fail_silently=True): """ Get cells occupied by the given dashboard entry. :param dash.base.BaseDashboardLayout dashboard_entry: Instance of subclassed ``dash.base.BaseDashboardLayout`` object. :param dash.base.BaseDashboardPlaceholder placeholder: Instance of subclassed ``dash.base.BaseDashboardPlaceholder`` object. :param string plugin_uid: UID of the plugin to check against. :param int position: Position of the plugin to check against. :param bool check_boundaries: If set to True, boundaries of the placeholders are also considered. :param bool fail_silently: If set to True, no exceptions are raised. :return mixed: Returns a list (could be an empty list as well) if all goes well and returns boolean False if out of the placeholder boundaries. """ assert isinstance(layout, BaseDashboardLayout) #assert issubclass(placeholder, BaseDashboardPlaceholder) widget_cls = plugin_widget_registry.get( PluginWidgetRegistry.namify(layout.uid, placeholder.uid, plugin_uid)) occupied_cells = [] placeholder_max_cell_num = placeholder.cols * placeholder.rows try: position = int(position) except Exception as e: if fail_silently: return False else: raise e if widget_cls: # First check the basic things. if check_boundaries: # Checking if widget isn't touching the boundaries. Checking the # widget width. relative_col_num = position % placeholder.cols if 0 == relative_col_num: relative_col_num = placeholder.cols if (relative_col_num + widget_cls.cols - 1) > placeholder.cols: if fail_silently: return False else: raise PluginWidgetOutOfPlaceholderBoundaries( "Widget is out of placeholder boundaries.") # Checking if widget isn't touching the boundaries. Checking the # widget height. #relative_row_num = position % placeholder.rows #if 0 == relative_row_num: # relative_row_num = placeholder.rows #if (relative_row_num + widget_cls.rows - 1) > placeholder.rows: # if fail_silently: # return False # else: # raise PluginWidgetOutOfPlaceholderBoundaries( # "Widget is out of placeholder boundaries." # ) # Now check the collision with other plugin widgets. for row in range(0, widget_cls.rows): for col in range(0, widget_cls.cols): cell_num = position + col + (row * placeholder.cols) if check_boundaries and cell_num > placeholder_max_cell_num: if fail_silently: return False else: raise PluginWidgetOutOfPlaceholderBoundaries( "Widget is out of placeholder boundaries.") occupied_cells.append(cell_num) return occupied_cells
def get_widgets(layout, placeholder, user=None, workspace=None, \ position=None, occupied_cells=[], sort_items=True): """ Gets widgets. In case if in restricted mode (``RESTRICT_PLUGIN_ACCESS`` is set to True), user argument should be provided. Based on it, the list of plugins is returned. Restrictions are bypassed in case if ``RESTRICT_PLUGIN_ACCESS`` is set to False or user given is a superuser. Placeholders are validated already. We don't need to have validation here. :param dash.base.BaseDashLayout layout: Layout object. :param string placeholder_uid: Placeholder uid. :param django.contrib.auth.models.User user: :param string workspace: Workspace slug. :param int position: Plugin position. :param list occupied_cells: List of already occupied cells. :param bool sort_items: If set to True, returned items are sorted. :return list: """ # We should get the layout, see loop through its' plugins and see which of # those do have rendererrs. Then we get all the plugins (based on whether # they are restricted or not - get the list) and then filter out those # that do not have renderers. ensure_autodiscover() registered_widgets = {} plugin_widget_uids = plugin_widget_registry._registry.keys() if not RESTRICT_PLUGIN_ACCESS or getattr(user, 'is_superuser', False): for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the # placeholder. plugin_widget_uid = PluginWidgetRegistry.namify( layout.uid, placeholder.uid, uid ) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells( layout, placeholder, uid, position, check_boundaries=True ) if plugin_widget_uid in plugin_widget_uids \ and widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = {'placeholder_uid': placeholder.uid, 'plugin_uid': uid} if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = safe_text(plugin.group) if plugin_group not in registered_widgets: registered_widgets[plugin_group] = [] widget_name = safe_text(plugin.name) registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(widget_name, \ plugin_widget.cols, \ plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) elif plugin_widget_uid in plugin_widget_uids and widget_occupied_cells is not False \ and lists_overlap(widget_occupied_cells, occupied_cells): workspace_id = None if workspace: workspace_id = DashboardWorkspace.objects.get(name=workspace).pk current_widget = DashboardEntry.objects.filter(position=int(position), layout_uid=layout.uid, workspace_id=workspace_id,)[0] pattern = re.compile(r'\d+x\d+') dimensions = pattern.search(str(current_widget.plugin_uid)) dimensions = (dimensions.group()).split('x') plugin_widget = plugin_widget_registry.get(plugin_widget_uid) if int(plugin_widget.cols) == int(dimensions[0]) and int(plugin_widget.rows) == int(dimensions[1]): kwargs = {'placeholder_uid': placeholder.uid, 'plugin_uid': uid} if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = safe_text(plugin.group) if plugin_group not in registered_widgets: registered_widgets[plugin_group] = [] widget_name = safe_text(plugin.name) registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(widget_name, \ plugin_widget.cols, \ plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) else: allowed_plugin_uids = get_allowed_plugin_uids(user) for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the # placeholder and user has access to the widget desired. plugin_widget_uid = PluginWidgetRegistry.namify( layout.uid, placeholder.uid, uid ) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells( layout, placeholder, uid, position, check_boundaries=True ) if uid in allowed_plugin_uids \ and plugin_widget_uid in plugin_widget_uids \ and widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = {'placeholder_uid': placeholder.uid, 'plugin_uid': uid} if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = safe_text(plugin.group) if not plugin_group in registered_widgets: registered_widgets[plugin_group] = [] registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(safe_text(plugin.name), \ plugin_widget.cols, \ plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) if sort_items: for key, prop in registered_widgets.items(): prop.sort() return registered_widgets
def get_widgets(layout, placeholder, user=None, workspace=None, \ position=None, occupied_cells=[], sort_items=True): """ Gets widgets. In case if in restricted mode (``RESTRICT_PLUGIN_ACCESS`` is set to True), user argument should be provided. Based on it, the list of plugins is returned. Restrictions are bypassed in case if ``RESTRICT_PLUGIN_ACCESS`` is set to False or user given is a superuser. Placeholders are validated already. We don't need to have validation here. :param dash.base.BaseDashLayout layout: Layout object. :param string placeholder_uid: Placeholder uid. :param django.contrib.auth.models.User user: :param string workspace: Workspace slug. :param int position: Plugin position. :param list occupied_cells: List of already occupied cells. :param bool sort_items: If set to True, returned items are sorted. :return list: """ # We should get the layout, see loop through its' plugins and see which of # those do have rendererrs. Then we get all the plugins (based on whether # they are restricted or not - get the list) and then filter out those # that do not have renderers. ensure_autodiscover() registered_widgets = {} plugin_widget_uids = plugin_widget_registry._registry.keys() if not RESTRICT_PLUGIN_ACCESS or getattr(user, 'is_superuser', False): for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the # placeholder. plugin_widget_uid = PluginWidgetRegistry.namify( layout.uid, placeholder.uid, uid) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells(layout, placeholder, uid, position, check_boundaries=True) if plugin_widget_uid in plugin_widget_uids \ and widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = { 'placeholder_uid': placeholder.uid, 'plugin_uid': uid } if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = safe_text(plugin.group) if not plugin_group in registered_widgets: registered_widgets[plugin_group] = [] widget_name = safe_text(plugin.name) registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(widget_name, \ plugin_widget.cols, \ plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) else: allowed_plugin_uids = get_allowed_plugin_uids(user) for uid, plugin in plugin_registry._registry.items(): # We should make sure that there are widgets available for the # placeholder and user has access to the widget desired. plugin_widget_uid = PluginWidgetRegistry.namify( layout.uid, placeholder.uid, uid) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells(layout, placeholder, uid, position, check_boundaries=True) if uid in allowed_plugin_uids \ and plugin_widget_uid in plugin_widget_uids \ and widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): plugin_widget = plugin_widget_registry.get(plugin_widget_uid) kwargs = { 'placeholder_uid': placeholder.uid, 'plugin_uid': uid } if workspace: kwargs.update({'workspace': workspace}) if position: kwargs.update({'position': position}) plugin_group = safe_text(plugin.group) if not plugin_group in registered_widgets: registered_widgets[plugin_group] = [] registered_widgets[plugin_group].append( ( uid, '{0} ({1}x{2})'.format(safe_text(plugin.name), \ plugin_widget.cols, \ plugin_widget.rows), reverse('dash.add_dashboard_entry', kwargs=kwargs) ) ) if sort_items: for key, prop in registered_widgets.items(): prop.sort() return registered_widgets