Compare commits

..
Author SHA1 Message Date
mattieserver daf35c097d bump version (#334) 2023-06-22 09:19:26 +02:00
Mario 63b9775218 Merge pull request #323 from dreng/247_base_path_broken_images
Fixes #247: Using BASE_PATH results in broken image URLs
2023-06-04 19:38:59 +02:00
dreng 69cd2c431c add newline to end of images.html 2023-06-04 12:06:26 +02:00
dreng 873c757606 fixed xml-export path construction 2023-06-04 08:52:17 +02:00
dreng 8f520f9a6a fixed image path construction 2023-06-03 23:04:47 +02:00
14 changed files with 32 additions and 23 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ class TopologyViewsConfig(PluginConfig):
name = "netbox_topology_views"
verbose_name = "Topology views"
description = "An plugin to render topology maps"
version = "3.6.0-beta.1"
version = "3.6.0-beta.2"
author = "Mattijs Vanhaverbeke"
author_email = "author@example.com"
base_url = "netbox_topology_views"
+5 -2
View File
@@ -142,9 +142,12 @@ class SaveRoleImageViewSet(PermissionRequiredMixin, ReadOnlyModelViewSet):
{"status": "Missing or malformed request body"}, status=400
)
device_roles = {k: v for k, v in request.data.items() if k.isnumeric()}
device_roles = {
k: v.removeprefix(settings.STATIC_URL)
for k, v in request.data.items()
if k.isnumeric()}
content_type_ids = {
k[2:]: v
k[2:]: v.removeprefix(settings.STATIC_URL)
for k, v in request.data.items()
if k.startswith("ct") and k[2:].isnumeric()
}
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
(()=>{var l=(e,t,o)=>new Promise((n,r)=>{var c=s=>{try{i(o.next(s))}catch(a){r(a)}},m=s=>{try{i(o.throw(s))}catch(a){r(a)}},i=s=>s.done?n(s.value):Promise.resolve(s.value).then(c,m);i((o=o.apply(e,t)).next())});var d=e=>{if(!document.cookie)return;let t=null,o=document.cookie.split(";");for(let n=0;n<o.length;n++){let r=o[n].trim();if(r.substring(0,e.length+1)===e+"="){t=decodeURIComponent(r.substring(e.length+1));break}}return t};var u={success:e=>{let t=document.querySelector("#topology-plugin-success-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()},error:e=>{let t=document.querySelector("#topology-plugin-error-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()}};var g={},p=d("csrftoken");document.querySelector("form#images").addEventListener("submit",e=>l(void 0,null,function*(){e.preventDefault();try{let t=yield fetch("/api/plugins/netbox_topology_views/images/save/",{method:"POST",body:JSON.stringify(g),headers:{"X-CSRFToken":p,"Content-Type":"application/json"}});if(!t.ok)throw new Error(yield t.text());u.success("Saved settings")}catch(t){console.dir(t),u.error(t.message)}}));document.querySelectorAll("form#images .dropdown-menu img").forEach(e=>{e.addEventListener("click",t=>{var c;if(!(t.currentTarget instanceof HTMLElement))return;let{dataset:{role:o,image:n}}=t.currentTarget;g[o]=n;let r=(c=t.currentTarget.closest(".dropdown"))==null?void 0:c.querySelector(`#dropdownMenuButton${o}`);r&&(r.innerHTML=`<img src="${n}" />`)})});})();
(()=>{var l=(e,t,o)=>new Promise((n,r)=>{var c=s=>{try{i(o.next(s))}catch(a){r(a)}},m=s=>{try{i(o.throw(s))}catch(a){r(a)}},i=s=>s.done?n(s.value):Promise.resolve(s.value).then(c,m);i((o=o.apply(e,t)).next())});var d=e=>{if(!document.cookie)return;let t=null,o=document.cookie.split(";");for(let n=0;n<o.length;n++){let r=o[n].trim();if(r.substring(0,e.length+1)===e+"="){t=decodeURIComponent(r.substring(e.length+1));break}}return t};var u={success:e=>{let t=document.querySelector("#topology-plugin-success-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()},error:e=>{let t=document.querySelector("#topology-plugin-error-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()}};var g={},p=d("csrftoken");document.querySelector("form#images").addEventListener("submit",e=>l(void 0,null,function*(){e.preventDefault();try{let t=yield fetch("/"+basePath+"api/plugins/netbox_topology_views/images/save/",{method:"POST",body:JSON.stringify(g),headers:{"X-CSRFToken":p,"Content-Type":"application/json"}});if(!t.ok)throw new Error(yield t.text());u.success("Saved settings")}catch(t){console.dir(t),u.error(t.message)}}));document.querySelectorAll("form#images .dropdown-menu img").forEach(e=>{e.addEventListener("click",t=>{var c;if(!(t.currentTarget instanceof HTMLElement))return;let{dataset:{role:o,image:n}}=t.currentTarget;g[o]=n;let r=(c=t.currentTarget.closest(".dropdown"))==null?void 0:c.querySelector(`#dropdownMenuButton${o}`);r&&(r.innerHTML=`<img src="${n}" />`)})});})();
@@ -1,6 +1,6 @@
{
"version": 3,
"sources": ["../../../static_dev/js/csrftoken.js", "../../../static_dev/js/toast.js", "../../../static_dev/js/images.js"],
"mappings": "mNAAO,GAAM,GAAY,AAAC,GAAS,CAC/B,GAAI,CAAC,SAAS,OAAQ,OAEtB,GAAI,GAAc,KACZ,EAAU,SAAS,OAAO,MAAM,KAEtC,OAAS,GAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACrC,GAAM,GAAS,EAAQ,GAAG,OAE1B,GAAI,EAAO,UAAU,EAAG,EAAK,OAAS,KAAO,EAAO,IAAK,CACrD,EAAc,mBAAmB,EAAO,UAAU,EAAK,OAAS,IAChE,OAIR,MAAO,ICfJ,GAAM,GAAQ,CACjB,QAAS,AAAC,GAAY,CAClB,GAAM,GAAK,SAAS,cAAc,kCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,QAEV,MAAO,AAAC,GAAY,CAChB,GAAM,GAAK,SAAS,cAAc,gCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,SCZd,GAAM,GAAU,GACV,EAAY,EAAU,aAE5B,SAAS,cAAc,eAAe,iBAAiB,SAAU,AAAO,GAAM,0BAC1E,EAAE,iBACF,GAAI,CACA,GAAM,GAAM,KAAM,OAAM,kDAAmD,CACvE,OAAQ,OACR,KAAM,KAAK,UAAU,GACrB,QAAS,CACL,cAAe,EACf,eAAgB,sBAIxB,GAAI,CAAC,EAAI,GAAI,KAAM,IAAI,OAAM,KAAM,GAAI,QACvC,EAAM,QAAQ,wBACT,EAAP,CACE,QAAQ,IAAI,GACZ,EAAM,MAAM,EAAI,aAIxB,SAAS,iBAAiB,kCAAkC,QAAQ,AAAC,GAAO,CACxE,EAAG,iBAAiB,QAAS,AAAC,GAAM,CA3BxC,MA4BQ,GAAI,CAAE,GAAE,wBAAyB,cAAc,OAC/C,GAAM,CACF,QAAS,CAAE,OAAM,UACjB,EAAE,cAEN,EAAQ,GAAQ,EAEhB,GAAM,GAAS,KAAE,cACZ,QAAQ,eADE,cAET,cAAc,sBAAsB,KAC1C,AAAI,GAAQ,GAAO,UAAY,aAAa",
"mappings": "mNAAO,GAAM,GAAY,AAAC,GAAS,CAC/B,GAAI,CAAC,SAAS,OAAQ,OAEtB,GAAI,GAAc,KACZ,EAAU,SAAS,OAAO,MAAM,KAEtC,OAAS,GAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACrC,GAAM,GAAS,EAAQ,GAAG,OAE1B,GAAI,EAAO,UAAU,EAAG,EAAK,OAAS,KAAO,EAAO,IAAK,CACrD,EAAc,mBAAmB,EAAO,UAAU,EAAK,OAAS,IAChE,OAIR,MAAO,ICfJ,GAAM,GAAQ,CACjB,QAAS,AAAC,GAAY,CAClB,GAAM,GAAK,SAAS,cAAc,kCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,QAEV,MAAO,AAAC,GAAY,CAChB,GAAM,GAAK,SAAS,cAAc,gCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,SCZd,GAAM,GAAU,GACV,EAAY,EAAU,aAE5B,SAAS,cAAc,eAAe,iBAAiB,SAAU,AAAO,GAAM,0BAC1E,EAAE,iBACF,GAAI,CACA,GAAM,GAAM,KAAM,OAAM,IAAM,SAAW,iDAAkD,CACvF,OAAQ,OACR,KAAM,KAAK,UAAU,GACrB,QAAS,CACL,cAAe,EACf,eAAgB,sBAIxB,GAAI,CAAC,EAAI,GAAI,KAAM,IAAI,OAAM,KAAM,GAAI,QACvC,EAAM,QAAQ,wBACT,EAAP,CACE,QAAQ,IAAI,GACZ,EAAM,MAAM,EAAI,aAIxB,SAAS,iBAAiB,kCAAkC,QAAQ,AAAC,GAAO,CACxE,EAAG,iBAAiB,QAAS,AAAC,GAAM,CA3BxC,MA4BQ,GAAI,CAAE,GAAE,wBAAyB,cAAc,OAC/C,GAAM,CACF,QAAS,CAAE,OAAM,UACjB,EAAE,cAEN,EAAQ,GAAQ,EAEhB,GAAM,GAAS,KAAE,cACZ,QAAQ,eADE,cAET,cAAc,sBAAsB,KAC1C,AAAI,GAAQ,GAAO,UAAY,aAAa",
"names": []
}
+2 -2
View File
@@ -81,7 +81,7 @@ const coordSaveCheckbox = document.querySelector('#id_save_coords')
async ([nodeId, nodePosition]) => {
window.nodes.update({id: parseInt(nodeId), physics: false, x: nodePosition.x, y: nodePosition.y});
const res = await fetch(
'/api/plugins/netbox_topology_views/save-coords/save_coords/',
'/' + basePath + 'api/plugins/netbox_topology_views/save-coords/save_coords/',
{
method: 'PATCH',
headers: {
@@ -171,7 +171,7 @@ function performXmlDownload() {
fetch('/api/plugins/netbox_topology_views/xml-export/?' + xml_search_options).then(response => response.text())
fetch('/' + basePath + 'api/plugins/netbox_topology_views/xml-export/?' + xml_search_options).then(response => response.text())
.then(data => {
var blob = new Blob([data ], { type: "text/plain" });
@@ -6,8 +6,8 @@ const csrftoken = getCookie('csrftoken')
document.querySelector('form#images').addEventListener('submit', async (e) => {
e.preventDefault()
try {
const res = await fetch('/api/plugins/netbox_topology_views/images/save/', {
try {
const res = await fetch('/' + basePath + 'api/plugins/netbox_topology_views/images/save/', {
method: 'POST',
body: JSON.stringify(mapping),
headers: {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "netbox_topology_views",
"version": "3.6.0-beta.1",
"version": "3.6.0-beta.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1,7 +1,7 @@
{
"private": true,
"name": "netbox_topology_views",
"version": "3.6.0-beta.1",
"version": "3.6.0-beta.2",
"scripts": {
"bundle": "node bundle.js",
"bundle:styles": "node bundle.js --styles",
@@ -42,5 +42,8 @@
{% endblock content-wrapper %}
{% block javascript %}
<script src="{% static 'netbox_topology_views/js/images.js' %}" defer></script>
{% endblock javascript %}
<script type="text/javascript">
const basePath = '{{ basepath }}';
</script>
<script src="{% static 'netbox_topology_views/js/images.js' %}" defer></script>
{% endblock javascript %}
@@ -77,6 +77,7 @@
<script type="text/javascript">
const brokenImage = '{{ broken_image }}';
const topologyData = {{ topology_data | safe }};
const basePath = '{{ basepath }}';
</script>
<script src="{% static 'netbox_topology_views/js/app.js' %}" defer></script>
{% endblock javascript %}
+5 -6
View File
@@ -29,18 +29,17 @@ else:
def image_static_url(path: Path) -> str:
return settings.BASE_PATH + static(
return static(
f"/{path.relative_to(Path(settings.STATIC_ROOT))}"
)
def get_image_from_url(url: str) -> str:
url_path = settings.BASE_PATH + settings.STATIC_URL
if sys.version_info >= (3,9,0):
return url.removeprefix(url_path)
return url.removeprefix(settings.STATIC_URL)
else:
if url.startswith(url_path):
url_new = url[len(url_path):]
if url.startswith(settings.STATIC_URL):
url_new = url[len(settings.STATIC_URL):]
return url_new
else:
return url
@@ -250,7 +249,7 @@ def export_data_to_xml(data: dict):
noPositionX = 0
noPositionY = 1000
for node in data['nodes']:
with open(str(Path(settings.BASE_DIR)) + node['image'], "rb") as img:
with open(settings.STATIC_ROOT + '/' + get_image_from_url(node['image']), "rb") as img:
svg = base64.b64encode(img.read()).decode('utf-8')
mxcell = doc.createElement('mxCell')
mxcell.setAttribute('id', 'node_' + str(node['id']))
+5 -2
View File
@@ -723,7 +723,8 @@ class TopologyHomeView(PermissionRequiredMixin, View):
"filter_form": DeviceFilterForm(request.GET, label_suffix=""),
"topology_data": json.dumps(topo_data),
"broken_image": find_image_url("role-unknown"),
"epoch": int(time.time())
"epoch": int(time.time()),
"basepath": settings.BASE_PATH,
},
)
@@ -734,7 +735,8 @@ class TopologyHomeView(PermissionRequiredMixin, View):
"filter_form": DeviceFilterForm(request.GET, label_suffix=""),
"topology_data": json.dumps(topo_data),
"broken_image": find_image_url("role-unknown"),
"model": self.model
"model": self.model,
"basepath": settings.BASE_PATH,
},
)
@@ -793,6 +795,7 @@ class TopologyImagesView(PermissionRequiredMixin, View):
{
"roles": sorted(list(roles.values()), key=lambda r: r["name"]),
"images": images,
"basepath": settings.BASE_PATH,
},
)
+1 -1
View File
@@ -7,7 +7,7 @@ long_description = readme.read_text()
setup(
name="netbox-topology-views",
version="3.6.0-beta.1",
version="3.6.0-beta.2",
description="An NetBox plugin to create Topology maps",
long_description=long_description,
long_description_content_type="text/markdown",