Skip to content

Commit

Permalink
v1.4.4 Use middleware to inject, add opendelay
Browse files Browse the repository at this point in the history
  • Loading branch information
PieterL75 committed Jun 11, 2024
1 parent 2b5c643 commit 21309cb
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 85 deletions.
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
recursive-include netbox_contextmenus/templates *.html
recursive-include netbox_contextmenus/static *.js
recursive-include netbox_contextmenus/templates *.js
recursive-include netbox_contextmenus/templates *.css
33 changes: 29 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,36 @@ Add context buttons to the links, making navigating in netbox less clicky

The menu items can easliy be personalised

## Installation:
## INSTALLATION

- install as a any regular plugin. See [https://docs.netbox.dev/en/stable/plugins/installation/](https://docs.netbox.dev/en/stable/plugins/installation/)
- PyPi Packagename is 'netbox-contextmenus'.
- NetBox packagenam is 'netbox_contextmenus'.
- Remove (delete, remark) BANNER_BOTTOM from the configuration file. If you need to set a bottom banner, then use the ConfigurationRevisions of NetBox [https://docs.netbox.dev/en/stable/configuration/#dynamic-configuration-parameters](https://docs.netbox.dev/en/stable/configuration/#dynamic-configuration-parameters)
- run a collect static `/opt/netbox/venv/bin/python3 manage.py collectstatic --no-input`
- NetBox packagename is 'netbox_contextmenus'.
- restart the netbox service

NBCM is compatible with NetBox v3 and v4.0

---
### IMPORTANT NOTE !
NBCM version <= 1.4.3 used the 'BOTTOM_BANNER' variable to inject the javascript.

As of v1.4.4, the javascript is injected using django middleware.
Make sure to remove the setting from the ConfigRevision BOTTOM_BANNER or from your configuration.py
The nbcm.js file located in /opt/netbox/netbox/netbox/scripts can be removed.

This is a preparation to create a GUI to modifiy the Contect Menu items

---

## CONFIGURATION
These settings can be customized using the PLUGINS_CONFIG variable in 'configuration.py'
```
PLUGINS_CONFIG = {
'netbox_contextmenus': {
'nbcmopendelay': 150
}
}
```
| variable | default | function |
| --- | --- | --- |
| nbcmopendelay | 150 | Time in milliseconds that the opening of the contextmenu will be delayed |
50 changes: 6 additions & 44 deletions netbox_contextmenus/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import logging

from django_redis.exceptions import ConnectionInterrupted
from redis.exceptions import ConnectionError

from netbox.settings import VERSION
from netbox.settings import VERSION # type: ignore
if VERSION.startswith("3."):
from extras.plugins import PluginConfig
from extras.plugins import PluginConfig # type: ignore
else:
from netbox.plugins import PluginConfig
from netbox.plugins import PluginConfig # type: ignore

from .pluginvars import (
__version__,
Expand All @@ -27,43 +22,10 @@ class NetboxContextMenusConfig(PluginConfig):
author_email = __author_email__
required_settings = []
default_settings = {
"nbcmjs": '<script src="/static/netbox_contextmenus/nbcm.js"></script>'
'nbcmjspath': '/plugins/netbox_contextmenus/nbcmrender/',
'nbcmopendelay': 150
}
baseurl = "netbox_contextmenus"

def ready(self):
try:
import netbox_contextmenus.signals

super().ready()

from core.models import ConfigRevision
from netbox.config import get_config
from django.core.cache import cache

NBCM_JS = self.default_settings["nbcmjs"]

cache.clear()
nb_config = get_config()
nb_config._populate_from_db()
ConfigRevisions = ConfigRevision.objects.all()
if not ConfigRevisions:
DefaultConfigRevisionParams = get_config().config
ConfigRevisionItem = ConfigRevision.objects.create(
data=DefaultConfigRevisionParams
)
ConfigRevisionItem.save()
else:
for ConfigRevisionItem in ConfigRevisions:
if ConfigRevisionItem.is_active:
if NBCM_JS not in getattr(
ConfigRevisionItem, "BANNER_BOTTOM", ""
):
ConfigRevisionItem.save()
except (ConnectionInterrupted, ConnectionError) as e:
logger = logging.getLogger("netbox.netbox_contextmenus")
logger.error("Redis connection is not ready")
logger.debug(e)

middleware = ["netbox_contextmenus.middleware.ContextMenusMiddleware"]

config = NetboxContextMenusConfig
34 changes: 34 additions & 0 deletions netbox_contextmenus/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from netbox.settings import VERSION # type: ignore
if VERSION.startswith("3."):
from extras.plugins import get_plugin_config # type: ignore
else:
from netbox.plugins import get_plugin_config # type: ignore

import re


class ContextMenusMiddleware:

def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
response = self.get_response(request)
request_path = request.get_full_path()
NBCM_JSPATH = get_plugin_config('netbox_contextmenus', 'nbcmjspath')

if request_path.startswith('/api/'):
return response
if NBCM_JSPATH == request.get_full_path():
return response

NBCM_JS = '<script src="'+NBCM_JSPATH+'" defer></script>'
content = str(response.content)
if not NBCM_JS in content:
response.content=re.sub(
b'</head>',
bytes(NBCM_JS, response.charset) + b'\n </head>',
response.content,
flags=re.IGNORECASE
)
return response
2 changes: 1 addition & 1 deletion netbox_contextmenus/pluginvars.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__name__ = 'netbox_contextmenus'
__version__ = '1.4.3'
__version__ = '1.4.4'
__description__ = 'Add context menu to links in NetBox'
__author__ = 'Pieter Lambrecht'
__author_email__ = '[email protected]'
Expand Down
27 changes: 0 additions & 27 deletions netbox_contextmenus/signals.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const nbcm_opendelay = 300; // Menu opening delay in milliseconds
const nbcm_opendelay = {{ opendelay }}; // Menu opening delay in milliseconds
const nbcm_views_all = { // Menu items shown on all models
'pre': {
'View': ['', 'mdi-share'],
Expand Down Expand Up @@ -96,6 +96,7 @@ const nbcm_views = { // Menu items per model. The model has to be present
},
};

var nbcmopentimeout;

function nbcmHideBox() {
document.getElementById("nbcmboxmenu").style.display = "none"
Expand Down Expand Up @@ -176,8 +177,6 @@ function nbcmShowbox(currentTarget, relatedTarget) {
function nbcm_add_burgers() {
'use strict';

var nbcmopentimeout;

var css=[
'.nbcm-box { white-space: nowrap; display: inline-flex; }',
'.nbcm-icon { padding:.1rem .1rem; margin-left: .2rem; white-space: nowrap; opacity: 20%; line-height: 0 !important; }',
Expand All @@ -192,7 +191,7 @@ function nbcm_add_burgers() {
var head = document.getElementsByTagName('head')[0];
if (head) {
var style = document.createElement('style');
style.type = 'text/css';
//style.type = 'text/css';
style.appendChild(document.createTextNode(css.join("\r\n")));
head.appendChild(style);
}
Expand All @@ -205,7 +204,7 @@ function nbcm_add_burgers() {
nbcmboxmenuul.className="list-group nbcm-menu";
document.body.appendChild(nbcmboxmenu);
nbcmboxmenu.addEventListener('mouseleave', function (e) {
clearTimeout(nbcmopentimeout);
clearTimeout(globalThis.nbcmopentimeout);
nbcmHideBox(e)
}, false);

Expand Down Expand Up @@ -252,14 +251,14 @@ function nbcm_add_burgers() {
var currentTarget = e.currentTarget;
var relatedTarget = e.relatedTarget;

clearTimeout(nbcmopentimeout);
nbcmopentimeout = setTimeout(function() {
clearTimeout(globalThis.nbcmopentimeout);
globalThis.nbcmopentimeout = setTimeout(function() {
nbcmShowbox(currentTarget, relatedTarget)
}, nbcm_opendelay);
}, false);

nbcmbox.addEventListener('mouseleave', function (e) {
clearTimeout(nbcmopentimeout);
clearTimeout(globalThis.nbcmopentimeout);
}, false);

nbcmbox.url = link.href;
Expand Down
6 changes: 6 additions & 0 deletions netbox_contextmenus/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.urls import path
from .views import ContextMenuRenderView

urlpatterns = [
path('nbcmrender/', ContextMenuRenderView.as_view(), name='nbcmrender'),
]
17 changes: 17 additions & 0 deletions netbox_contextmenus/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.shortcuts import render
from django.views.generic import View

from netbox.settings import VERSION # type: ignore
if VERSION.startswith("3."):
from extras.plugins import get_plugin_config # type: ignore
else:
from netbox.plugins import get_plugin_config # type: ignore

class ContextMenuRenderView(View):
def get(self, request):
return render(
request,
'netbox_contextmenus/nbcm.js',
{ 'opendelay' : get_plugin_config('netbox_contextmenus', 'nbcmopendelay') },
content_type='application/javascript'
)

0 comments on commit 21309cb

Please sign in to comment.