def cut_dashboard_entry(request, entry_id): """ Cut the given dashboard entry. It's not possible to remove undeletable entries. :param django.http.HttpRequest request: :param int entry_id: ID of the DashboardEntry to cut to clipboard. :param str template_name: :return django.http.HttpResponse: """ dashboard_entry = DashboardEntry._default_manager \ .select_related('workspace') \ .get(pk=entry_id, user=request.user) workspace = dashboard_entry.workspace plugin = dashboard_entry.get_plugin() cut_entry_to_clipboard(request, dashboard_entry) messages.info(request, _('The dashboard function "{0}" was successfully ' 'cut and placed into the ' 'clipboard.').format(safe_text(plugin.name))) if workspace and workspace.slug: return redirect('dash.edit_dashboard', workspace=workspace.slug) else: return redirect('dash.edit_dashboard')
def copy_dashboard_entry(request, entry_id): """ Cut the given dashboard entry. It's not possible to remove undeletable entries. :param django.http.HttpRequest request: :param int entry_id: ID of the DashboardEntry to cut to clipboard. :param str template_name: :return django.http.HttpResponse: """ # Getting dashboard settings for the user. Then get users' layout. #dashboard_settings = get_or_create_dashboard_settings(request.user) #layout = get_layout( # layout_uid=dashboard_settings.layout_uid, as_instance=True # ) dashboard_entry = DashboardEntry._default_manager \ .select_related('workspace') \ .get(pk=entry_id, user=request.user) workspace = dashboard_entry.workspace plugin = dashboard_entry.get_plugin() copy_entry_to_clipboard(request, dashboard_entry) messages.info(request, _('The dashboard entry "{0}" was successfully ' 'copied and placed into the ' 'clipboard.').format(safe_text(plugin.name))) if workspace and workspace.slug: return redirect('dash.edit_dashboard', workspace=workspace.slug) else: return redirect('dash.edit_dashboard')
def paste_dashboard_entry(request, placeholder_uid, position, workspace=None): """ Pastes the dashboard entry from clipboard if any available. :param django.http.HttpRequest request: :param str placeholder: :param int position: :param str workspace: Workspace slug. :return django.http.HttpResponse: """ # Getting dashboard settings for the user. Then get users' layout. dashboard_settings = get_or_create_dashboard_settings(request.user) layout = get_layout( layout_uid=dashboard_settings.layout_uid, as_instance=True ) try: plugin_uid, success = paste_entry_from_clipboard( request, layout, placeholder_uid, position, workspace=workspace ) except Exception as e: plugin_uid, success = str(e), False if plugin_uid and success: plugin = plugin_registry.get(plugin_uid) messages.info( request, _('The dashboard function "{0}" was successfully pasted from ' 'clipboard.').format(safe_text(plugin.name)) ) else: # In case if not success, ``plugin_uid`` would be holding the error # message. messages.info( request, _('Problems occured while pasting from ' 'clipboard. {0}'.format(safe_text(plugin_uid))) ) if workspace: return redirect('dash.edit_dashboard', workspace=workspace) else: return redirect('dash.edit_dashboard')
def get_user_plugins(user): """ Gets a list of user plugins in a form if tuple (plugin name, plugin description). If not yet autodiscovered, autodiscovers them. :return list: """ ensure_autodiscover() if not RESTRICT_PLUGIN_ACCESS or getattr(user, 'is_superuser', False): return get_registered_plugins() registered_plugins = [] allowed_plugin_uids = get_allowed_plugin_uids(user) for uid, plugin in plugin_registry._registry.items(): if uid in allowed_plugin_uids: registered_plugins.append((uid, safe_text(plugin.name))) return registered_plugins
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
def paste_entry_from_clipboard(request, layout, placeholder_uid, position, \ workspace=None, entries=[], check_only=False, \ clear_clipboard=True): """ Pastes entry from clipboard to the given placeholder of a workspace selected. :param django.http.HttpRequest request: :param str layout_uid: Placeholder UID. :param str placeholder_uid: Placeholder UID. :param int position: Position. :param mixed workspace: Either str or ``dash.models.DashboardWorkspace`` instance. If str is given, a database hit occurs in order to obtain the ``dash.models.DashboardWorkspace`` instance. Thus, if you have the workspace instance already, provide it as is, in order to minify database hits. :param iterable entries: If given, entries are not fetched but the existing iterable is used. Each item in the iterable should be an instance of ``dash.models.DashboardEntry``. :param bool check_only: If set to True, it's only checked if it's possible to paste from clipboard (the ``dashboard_entry.save()`` part is skipped, which means that the entry is not saved in the database). :return tuple (str, bool): (Plugin name, boolean True) tuple on success and (error message, boolean False) on failure. """ clipboard_plugin_data = get_plugin_data_from_clipboard(request, layout.uid) if not clipboard_plugin_data: return (_("Clipboard is empty!"), False) if not validate_placeholder_uid(layout, placeholder_uid): return (_("Invalid placeholder `{0}`.").format(placeholder_uid), False) user_plugin_uids = get_user_plugin_uids(request.user) if isinstance(workspace, DashboardWorkspace): workspace_obj = workspace else: if workspace: try: workspace_obj = DashboardWorkspace._default_manager \ .get(slug=workspace) except ObjectDoesNotExist as e: workspace_obj = None else: workspace_obj = None dashboard_entry = DashboardEntry( user=request.user, workspace=workspace_obj, layout_uid=layout.uid, placeholder_uid=placeholder_uid, plugin_uid=clipboard_plugin_data['plugin_uid'], plugin_data=clipboard_plugin_data['plugin_data'], position=position) # We should now check if we have a space for pasting the plugin. For that # we should get the plugin and see if there's a space available for # the (workspace, placeholder, user) triple given. # Get the plugin. plugin = dashboard_entry.get_plugin() if not plugin.uid in user_plugin_uids: return (_("You're not allowed to " "use the {0} plugin.".format(safe_text(plugin.name))), False) # Getting occupied cells placeholder = layout.get_placeholder(placeholder_uid) occupied_cells = build_cells_matrix(request.user, layout, placeholder, workspace=workspace) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells(layout, placeholder, plugin.uid, position, check_boundaries=True) if widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): try: if not check_only: # Save data dashboard_entry.save() # Clear the clipboard clear_clipboard_data(request, layout.uid) return (plugin.uid, True) except Exception as e: return (str(e), False)
def paste_entry_from_clipboard(request, layout, placeholder_uid, position, \ workspace=None, entries=[], check_only=False, \ clear_clipboard=True): """ Pastes entry from clipboard to the given placeholder of a workspace selected. :param django.http.HttpRequest request: :param str layout_uid: Placeholder UID. :param str placeholder_uid: Placeholder UID. :param int position: Position. :param mixed workspace: Either str or ``dash.models.DashboardWorkspace`` instance. If str is given, a database hit occurs in order to obtain the ``dash.models.DashboardWorkspace`` instance. Thus, if you have the workspace instance already, provide it as is, in order to minify database hits. :param iterable entries: If given, entries are not fetched but the existing iterable is used. Each item in the iterable should be an instance of ``dash.models.DashboardEntry``. :param bool check_only: If set to True, it's only checked if it's possible to paste from clipboard (the ``dashboard_entry.save()`` part is skipped, which means that the entry is not saved in the database). :return tuple (str, bool): (Plugin name, boolean True) tuple on success and (error message, boolean False) on failure. """ clipboard_plugin_data = get_plugin_data_from_clipboard(request, layout.uid) if not clipboard_plugin_data: return (_("Clipboard is empty!"), False) if not validate_placeholder_uid(layout, placeholder_uid): return (_("Invalid placeholder `{0}`.").format(placeholder_uid), False) user_plugin_uids = get_user_plugin_uids(request.user) if isinstance(workspace, DashboardWorkspace): workspace_obj = workspace else: if workspace: try: workspace_obj = DashboardWorkspace._default_manager \ .get(slug=workspace) except ObjectDoesNotExist as e: workspace_obj = None else: workspace_obj = None dashboard_entry = DashboardEntry( user = request.user, workspace = workspace_obj, layout_uid = layout.uid, placeholder_uid = placeholder_uid, plugin_uid = clipboard_plugin_data['plugin_uid'], plugin_data = clipboard_plugin_data['plugin_data'], position = position ) # We should now check if we have a space for pasting the plugin. For that # we should get the plugin and see if there's a space available for # the (workspace, placeholder, user) triple given. # Get the plugin. plugin = dashboard_entry.get_plugin() if not plugin.uid in user_plugin_uids: return (_("You're not allowed to " "use the {0} plugin.".format(safe_text(plugin.name))), False) # Getting occupied cells placeholder = layout.get_placeholder(placeholder_uid) occupied_cells = build_cells_matrix( request.user, layout, placeholder, workspace = workspace ) # Get cells occupied by plugin widget. widget_occupied_cells = get_occupied_cells( layout, placeholder, plugin.uid, position, check_boundaries=True ) if widget_occupied_cells is not False \ and not lists_overlap(widget_occupied_cells, occupied_cells): try: if not check_only: # Save data dashboard_entry.save() # Clear the clipboard clear_clipboard_data(request, layout.uid) return (plugin.uid, True) except Exception as e: return (str(e), False)