lanscape 1.2.6a10__py3-none-any.whl → 1.2.6a12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lanscape/ui/static/css/style.css +715 -0
- lanscape/ui/static/img/ico/android-chrome-192x192.png +0 -0
- lanscape/ui/static/img/ico/android-chrome-512x512.png +0 -0
- lanscape/ui/static/img/ico/apple-touch-icon.png +0 -0
- lanscape/ui/static/img/ico/favicon-16x16.png +0 -0
- lanscape/ui/static/img/ico/favicon-32x32.png +0 -0
- lanscape/ui/static/img/ico/favicon.ico +0 -0
- lanscape/ui/static/img/ico/site.webmanifest +1 -0
- lanscape/ui/static/img/readme1.png +0 -0
- lanscape/ui/static/js/core.js +39 -0
- lanscape/ui/static/js/layout-sizing.js +31 -0
- lanscape/ui/static/js/main.js +208 -0
- lanscape/ui/static/js/quietReload.js +23 -0
- lanscape/ui/static/js/shutdown-server.js +17 -0
- lanscape/ui/static/js/subnet-info.js +19 -0
- lanscape/ui/static/js/subnet-selector.js +9 -0
- lanscape/ui/static/lanscape.webmanifest +19 -0
- lanscape/ui/templates/base.html +47 -0
- lanscape/ui/templates/core/head.html +10 -0
- lanscape/ui/templates/core/scripts.html +5 -0
- lanscape/ui/templates/error.html +35 -0
- lanscape/ui/templates/info.html +67 -0
- lanscape/ui/templates/main.html +89 -0
- lanscape/ui/templates/scan/export.html +27 -0
- lanscape/ui/templates/scan/ip-table-row.html +103 -0
- lanscape/ui/templates/scan/ip-table.html +26 -0
- lanscape/ui/templates/scan/overview.html +28 -0
- lanscape/ui/templates/scan/scan-error.html +33 -0
- lanscape/ui/templates/scan.html +14 -0
- lanscape/ui/templates/shutdown.html +23 -0
- {lanscape-1.2.6a10.dist-info → lanscape-1.2.6a12.dist-info}/METADATA +1 -1
- {lanscape-1.2.6a10.dist-info → lanscape-1.2.6a12.dist-info}/RECORD +35 -5
- {lanscape-1.2.6a10.dist-info → lanscape-1.2.6a12.dist-info}/LICENSE +0 -0
- {lanscape-1.2.6a10.dist-info → lanscape-1.2.6a12.dist-info}/WHEEL +0 -0
- {lanscape-1.2.6a10.dist-info → lanscape-1.2.6a12.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$(document).ready(function() {
|
|
2
|
+
rightSizeDocLayout(0,showFooter);
|
|
3
|
+
initTooltips();
|
|
4
|
+
})
|
|
5
|
+
|
|
6
|
+
$(window).on('resize', function() {
|
|
7
|
+
rightSizeDocLayout();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
function rightSizeDocLayout(delay=20,callback=null) {
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
const content = $('#content');
|
|
14
|
+
if (content) {
|
|
15
|
+
const headerHeight = $('#header').outerHeight();
|
|
16
|
+
const footerHeight = $('footer').outerHeight();
|
|
17
|
+
const viewportHeight = $(window).height();
|
|
18
|
+
|
|
19
|
+
const newHeight = viewportHeight - headerHeight - footerHeight;
|
|
20
|
+
content.height(newHeight);
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
if (callback) callback();
|
|
24
|
+
},delay);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function showFooter() {
|
|
28
|
+
const footer = $('footer');
|
|
29
|
+
footer.removeClass('div-hide');
|
|
30
|
+
setTimeout(() => {footer.css('transform','translateY(0px)')},1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
function initTooltips() {
|
|
35
|
+
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
|
36
|
+
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
37
|
+
return new bootstrap.Tooltip(tooltipTriggerEl)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
$(document).ready(function() {
|
|
2
|
+
rightSizeDocLayout(0,showFooter);
|
|
3
|
+
})
|
|
4
|
+
|
|
5
|
+
$(window).on('resize', function() {
|
|
6
|
+
rightSizeDocLayout();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
function rightSizeDocLayout(delay=20,callback=null) {
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
const content = $('#content');
|
|
13
|
+
if (content) {
|
|
14
|
+
const headerHeight = $('#header').outerHeight();
|
|
15
|
+
const footerHeight = $('footer').outerHeight();
|
|
16
|
+
const viewportHeight = $(window).height();
|
|
17
|
+
|
|
18
|
+
const newHeight = viewportHeight - headerHeight - footerHeight;
|
|
19
|
+
content.height(newHeight);
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
if (callback) callback();
|
|
23
|
+
},delay);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function showFooter() {
|
|
27
|
+
const footer = $('footer');
|
|
28
|
+
footer.removeClass('div-hide');
|
|
29
|
+
setTimeout(() => {footer.css('transform','translateY(0px)')},1);
|
|
30
|
+
}
|
|
31
|
+
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
$(document).ready(function() {
|
|
4
|
+
// Load port lists into the dropdown
|
|
5
|
+
getPortLists();
|
|
6
|
+
|
|
7
|
+
$('#parallelism').on('input', function() {
|
|
8
|
+
const val = $('#parallelism').val();
|
|
9
|
+
let ans = val;
|
|
10
|
+
|
|
11
|
+
if (parseFloat(val) > 1) {
|
|
12
|
+
ans += ' <span>Warning: Increased parallelism may have inaccurate results<span>'
|
|
13
|
+
}
|
|
14
|
+
$('#parallelism-value').html(ans);
|
|
15
|
+
});
|
|
16
|
+
const scanId = getActiveScanId();
|
|
17
|
+
if (scanId) {
|
|
18
|
+
showScan(scanId);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// Handle form submission
|
|
23
|
+
$('#scan-form').on('submit', function(event) {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
if ($('#scan-submit').text() == 'Scan') {
|
|
26
|
+
submitNewScan()
|
|
27
|
+
} else {
|
|
28
|
+
terminateScan();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Handle filter input
|
|
35
|
+
$('#filter').on('input', function() {
|
|
36
|
+
const filter = $(this).val();
|
|
37
|
+
const currentSrc = $('#ip-table-frame').attr('src');
|
|
38
|
+
const newSrc = currentSrc.split('?')[0] + '?filter=' + filter;
|
|
39
|
+
$('#ip-table-frame').attr('src', newSrc);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function submitNewScan() {
|
|
45
|
+
const formData = {
|
|
46
|
+
subnet: $('#subnet').val(),
|
|
47
|
+
port_list: $('#port-list').text(),
|
|
48
|
+
parallelism: $('#parallelism').val()
|
|
49
|
+
};
|
|
50
|
+
$.ajax('/api/scan', {
|
|
51
|
+
data : JSON.stringify(formData),
|
|
52
|
+
contentType : 'application/json',
|
|
53
|
+
type : 'POST',
|
|
54
|
+
success: function(response) {
|
|
55
|
+
if (response.status === 'running') {
|
|
56
|
+
showScan(response.scan_id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getActiveScanId() {
|
|
63
|
+
const url = new URL(window.location.href);
|
|
64
|
+
return url.searchParams.get('scan_id');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function showScan(scanId) {
|
|
68
|
+
pollScanSummary(scanId);
|
|
69
|
+
setScanState(false);
|
|
70
|
+
|
|
71
|
+
$('#no-scan').addClass('div-hide');
|
|
72
|
+
$('#scan-results').removeClass('div-hide');
|
|
73
|
+
|
|
74
|
+
$('#export-link').attr('href','/export/' + scanId);
|
|
75
|
+
//$('#overview-frame').attr('src', '/scan/' + scanId + '/overview');
|
|
76
|
+
$('#ip-table-frame').attr('src', '/scan/' + scanId + '/table');
|
|
77
|
+
|
|
78
|
+
// set url query string 'scan_id' to the scan_id
|
|
79
|
+
const url = new URL(window.location.href);
|
|
80
|
+
url.searchParams.set('scan_id', scanId);
|
|
81
|
+
// set url to the new url
|
|
82
|
+
window.history.pushState({}, '', url);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getPortLists() {
|
|
86
|
+
$.get('/api/port/list', function(data) {
|
|
87
|
+
const customSelect = $('#port-list');
|
|
88
|
+
const customSelectDropdown = $('#port-list-dropdown');
|
|
89
|
+
customSelectDropdown.empty();
|
|
90
|
+
|
|
91
|
+
// Populate the dropdown with the options
|
|
92
|
+
data.forEach(function(portList) {
|
|
93
|
+
customSelectDropdown.append('<div>' + portList + '</div>');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Handle dropdown click
|
|
97
|
+
customSelect.on('click', function() {
|
|
98
|
+
customSelectDropdown.toggleClass('open');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Handle option selection
|
|
102
|
+
customSelectDropdown.on('click', 'div', function() {
|
|
103
|
+
const selectedOption = $(this).text();
|
|
104
|
+
customSelect.text(selectedOption);
|
|
105
|
+
customSelectDropdown.removeClass('open');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
$(document).on('click', function(event) {
|
|
111
|
+
if (!$(event.target).closest('.port-list-wrapper').length) {
|
|
112
|
+
$('#port-list-dropdown').removeClass('open');
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
function setScanState(scanEnabled) {
|
|
117
|
+
const button = $('#scan-submit');
|
|
118
|
+
console.log('set scan state- scanning',scanEnabled)
|
|
119
|
+
|
|
120
|
+
if (scanEnabled) {
|
|
121
|
+
button.text("Scan");
|
|
122
|
+
button.removeClass('btn-danger').addClass('btn-primary');
|
|
123
|
+
} else {
|
|
124
|
+
button.text("Stop");
|
|
125
|
+
button.removeClass('btn-primary').addClass('btn-danger');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
function resizeIframe(iframe) {
|
|
131
|
+
// Adjust the height of the iframe to match the content
|
|
132
|
+
setTimeout( () => {
|
|
133
|
+
iframe.style.height = iframe.contentWindow.document.body.scrollHeight + 'px';
|
|
134
|
+
},100);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function observeIframeContent(iframe) {
|
|
138
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
|
139
|
+
|
|
140
|
+
// Use MutationObserver to observe changes within the iframe
|
|
141
|
+
const observer = new MutationObserver(() => {
|
|
142
|
+
resizeIframe(iframe);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Configure the observer to watch for changes in the subtree of the body
|
|
146
|
+
observer.observe(iframeDocument.body, {
|
|
147
|
+
childList: true,
|
|
148
|
+
subtree: true,
|
|
149
|
+
attributes: true, // In case styles/attributes change height
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function terminateScan() {
|
|
153
|
+
const button = $('#scan-submit');
|
|
154
|
+
button.prop('disabled', true);
|
|
155
|
+
const scanId = getActiveScanId();
|
|
156
|
+
$.get(`/api/scan/${scanId}/terminate`, function(ans) {
|
|
157
|
+
setScanState(true);
|
|
158
|
+
button.prop('disabled', false);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function pollScanSummary(id) {
|
|
162
|
+
$.get(`/api/scan/${id}/summary`, function(summary) {
|
|
163
|
+
let progress = $('#scan-progress-bar');
|
|
164
|
+
if (summary.running || summary.stage == 'terminating') {
|
|
165
|
+
progress.css('height','2px');
|
|
166
|
+
progress.css('width',`${summary.percent_complete}vw`);
|
|
167
|
+
// TODO: move overview here??
|
|
168
|
+
setTimeout(() => {pollScanSummary(id)},500);
|
|
169
|
+
} else {
|
|
170
|
+
progress.css('width','100vw');
|
|
171
|
+
progress.css('background-color','var(--success-accent)')
|
|
172
|
+
setTimeout(() => {progress.css('height','0px');},500);
|
|
173
|
+
setScanState(true);
|
|
174
|
+
|
|
175
|
+
// wait to make the width smaller for animation to be clean
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
progress.css('width','0vw');
|
|
178
|
+
progress.css('background-color','var(--primary-accent)')
|
|
179
|
+
},1000);
|
|
180
|
+
}
|
|
181
|
+
updateOverviewUI(summary);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function updateOverviewUI(summary) {
|
|
186
|
+
$('#scan-devices-alive').text(summary.devices.alive);
|
|
187
|
+
$('#scan-devices-scanned').text(summary.devices.scanned);
|
|
188
|
+
$('#scan-devices-total').text(summary.devices.total);
|
|
189
|
+
$('#scan-run-time').text(summary.runtime);
|
|
190
|
+
$('#scan-stage').text(summary.stage);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Bind the iframe's load event to initialize the observer
|
|
194
|
+
$('#ip-table-frame').on('load', function() {
|
|
195
|
+
resizeIframe(this); // Initial resizing after iframe loads
|
|
196
|
+
observeIframeContent(this); // Start observing for dynamic changes
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
$(window).on('resize', function() {
|
|
202
|
+
resizeIframe($('#ip-table-frame')[0]);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Reload the page gracefully every second
|
|
2
|
+
// Used in 'live' iframes
|
|
3
|
+
|
|
4
|
+
function quietReload() {
|
|
5
|
+
function run() {
|
|
6
|
+
$.get(document.location.href, function(data) {
|
|
7
|
+
// create a new document from the fetched data
|
|
8
|
+
var newDoc = new DOMParser().parseFromString(data, 'text/html');
|
|
9
|
+
// replace current body with the new body content
|
|
10
|
+
$('body').html($(newDoc.body).html());
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
setTimeout(function() {
|
|
14
|
+
// get current page via ajax, and replace the current page with the new one
|
|
15
|
+
try {
|
|
16
|
+
run();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.error(e);
|
|
19
|
+
quietReload();
|
|
20
|
+
}
|
|
21
|
+
}, 1000);
|
|
22
|
+
}
|
|
23
|
+
quietReload();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
$(document).ready(function() {
|
|
2
|
+
setTimeout(() => shutdownApp(), 2000);
|
|
3
|
+
});
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
function shutdownApp() {
|
|
8
|
+
// will term server before response
|
|
9
|
+
$.get('/shutdown').always(() => serverDown());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function serverDown() {
|
|
13
|
+
$('#shutdown-message').html('Server down.');
|
|
14
|
+
$('#shutdown-sub').html('You can close this browser window.');
|
|
15
|
+
$('#shutdown-sub-sub').html('(since your browser wont let me)');
|
|
16
|
+
setTimeout(() => window.close(),2500);
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Validation for subnet input
|
|
2
|
+
|
|
3
|
+
$(document).ready(function() {
|
|
4
|
+
$('#subnet').on('input', () => subnetUpdated($('#subnet').val()));
|
|
5
|
+
subnetUpdated($('#subnet').val());
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
function subnetUpdated(input) {
|
|
9
|
+
$.getJSON(`/api/tools/subnet/test?subnet=${input}`,(data) => {
|
|
10
|
+
setSubnetValidity(data.valid);
|
|
11
|
+
$('#subnet-info').html(data.msg);
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function setSubnetValidity(valid) { //boolean
|
|
16
|
+
if (valid) $('#scan-form').removeClass('error');
|
|
17
|
+
else $('#scan-form').addClass('error');
|
|
18
|
+
$("#scan-submit").attr("disabled",!valid);
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
$(document).ready(function () {
|
|
2
|
+
// Update input box when selecting a dropdown item
|
|
3
|
+
$('.dropdown-item').on('click', function (e) {
|
|
4
|
+
e.preventDefault();
|
|
5
|
+
let selectedSubnet = $(this).text();
|
|
6
|
+
$('#subnet').val(selectedSubnet); // Update input with selection
|
|
7
|
+
subnetUpdated(selectedSubnet); // from subnet-info.js
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "LANscape",
|
|
3
|
+
"short_name": "LANscape",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/static/img/ico/android-chrome-192x192.png",
|
|
7
|
+
"sizes": "192x192",
|
|
8
|
+
"type": "image/png"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "/static/img/ico/android-chrome-512x512.png",
|
|
12
|
+
"sizes": "512x512",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"theme_color": "#0856a9",
|
|
17
|
+
"background_color": "#1e1e1e",
|
|
18
|
+
"display": "standalone"
|
|
19
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
{% include 'core/head.html' %}
|
|
5
|
+
{% include 'core/scripts.html' %}
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
{% block content %}{% endblock %}
|
|
10
|
+
<footer class="div-hide">
|
|
11
|
+
<div class="version">
|
|
12
|
+
v{{app_version}}
|
|
13
|
+
{% if is_local %}
|
|
14
|
+
<span>(Local Run)</span>
|
|
15
|
+
{% elif update_available %}
|
|
16
|
+
<span>(Update Available)</span>
|
|
17
|
+
{% endif %}
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div id="app-actions">
|
|
21
|
+
<a href="/info">
|
|
22
|
+
<span
|
|
23
|
+
class="material-symbols-outlined"
|
|
24
|
+
data-bs-toggle="tooltip"
|
|
25
|
+
data-bs-placement="top"
|
|
26
|
+
title="App info">
|
|
27
|
+
info
|
|
28
|
+
</span>
|
|
29
|
+
</a>
|
|
30
|
+
|
|
31
|
+
{% if runtime_args.get('nogui') or runtime_args.get('headless') %}
|
|
32
|
+
<a href="/shutdown-ui">
|
|
33
|
+
<span
|
|
34
|
+
id="power-button"
|
|
35
|
+
class="material-symbols-outlined"
|
|
36
|
+
data-bs-toggle="tooltip"
|
|
37
|
+
data-bs-placement="top"
|
|
38
|
+
title="Shutdown App">
|
|
39
|
+
power_settings_new
|
|
40
|
+
</span>
|
|
41
|
+
</a>
|
|
42
|
+
{% endif %}
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
</footer>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<meta charset="UTF-8">
|
|
2
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3
|
+
<title>LANscape</title>
|
|
4
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
5
|
+
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
|
|
6
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
7
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/static/img/ico/apple-touch-icon.png">
|
|
8
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/static/img/ico/favicon-32x32.png">
|
|
9
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/static/img/ico/favicon-16x16.png">
|
|
10
|
+
<link rel="manifest" href="/static/lanscape.webmanifest">
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
|
|
2
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>
|
|
3
|
+
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
|
|
4
|
+
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
|
|
5
|
+
<script src="{{ url_for('static', filename='js/core.js') }}"></script>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
<div id="header">
|
|
5
|
+
<!-- Header and Scan Submission Inline -->
|
|
6
|
+
<div class="d-flex justify-content-start align-items-center">
|
|
7
|
+
<h1 class="title" onclick="location.href = '/'">
|
|
8
|
+
<span>LAN</span>scape
|
|
9
|
+
</h1>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="scroll-container" id="content">
|
|
13
|
+
<div class="container-fluid my-4">
|
|
14
|
+
<h3 class="text-danger">500 - Internal Server Error</h3>
|
|
15
|
+
<h5>{{ error or 'That was unexpected.' }}</h5>
|
|
16
|
+
|
|
17
|
+
{% if traceback %}
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Traceback:</summary>
|
|
20
|
+
<div class="error-container">
|
|
21
|
+
<pre>{{traceback}}</pre>
|
|
22
|
+
</div>
|
|
23
|
+
</details>
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
<button onclick="location.href='/'" class="btn btn-primary m-2">Home</button>
|
|
27
|
+
|
|
28
|
+
<a href="https://github.com/mdennis281/LANscape/issues" target="_blank">
|
|
29
|
+
<button class="btn btn-info m-2">Github issues</button>
|
|
30
|
+
</a>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
{% endblock %}
|
|
35
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
<div id="header">
|
|
5
|
+
<!-- Header and Scan Submission Inline -->
|
|
6
|
+
<div class="d-flex justify-content-start align-items-center">
|
|
7
|
+
<h1 class="title" onclick="location.href = '/'">
|
|
8
|
+
<span>LAN</span>scape
|
|
9
|
+
</h1>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="scroll-container" id="content">
|
|
13
|
+
{% if update_available %}
|
|
14
|
+
<div class="container-fluid my-4">
|
|
15
|
+
<h3>New version available!</h3>
|
|
16
|
+
<p>
|
|
17
|
+
A new version has been published to PyPi.
|
|
18
|
+
({{app_version}} -> {{latest_version}})
|
|
19
|
+
</p>
|
|
20
|
+
<input type="text" readonly class="form-control mb-3 mt-3" value="pip install --upgrade lanscape --no-cache"/>
|
|
21
|
+
<a href="https://pypi.org/project/lanscape/" target="_blank"></a>
|
|
22
|
+
<button class="btn btn-primary m-2">PyPi - Lanscape</button>
|
|
23
|
+
</a>
|
|
24
|
+
</div>
|
|
25
|
+
{% endif %}
|
|
26
|
+
<div class="container-fluid my-4">
|
|
27
|
+
<h3>About</h3>
|
|
28
|
+
<p>
|
|
29
|
+
LANscape was born from my frustration with existing local network scanning tools
|
|
30
|
+
alongside my desire to dive deeper into technologies like
|
|
31
|
+
Address Resolution Protocol (ARP), threadpooling, & Python packaging.
|
|
32
|
+
I set out to create something faster, lightweight, & easier to use.
|
|
33
|
+
This project has been a learning journey, & I hope it helps you
|
|
34
|
+
discover more about your network as well. Enjoy!
|
|
35
|
+
</p>
|
|
36
|
+
<a href="https://github.com/mdennis281/" target="_blank"></a>
|
|
37
|
+
<button class="btn btn-primary m-2">Github</button>
|
|
38
|
+
</a>
|
|
39
|
+
<a href="https://github.com/mdennis281/LANscape" target="_blank">
|
|
40
|
+
<button class="btn btn-secondary m-2">Project Repo</button>
|
|
41
|
+
</a>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="container-fluid my-4">
|
|
44
|
+
<h3>Runtime Arguments</h3>
|
|
45
|
+
<table class="table table-striped table-bordered">
|
|
46
|
+
<thead class="table-dark">
|
|
47
|
+
<tr>
|
|
48
|
+
<th>Key</th>
|
|
49
|
+
<th>Value</th>
|
|
50
|
+
</tr>
|
|
51
|
+
</thead>
|
|
52
|
+
<tbody>
|
|
53
|
+
{% for key, value in runtime_args.items() %}
|
|
54
|
+
<tr>
|
|
55
|
+
<td>{{ key }}</td>
|
|
56
|
+
<td>{{ value }}</td>
|
|
57
|
+
</tr>
|
|
58
|
+
{% endfor %}
|
|
59
|
+
</tbody>
|
|
60
|
+
</table>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
{% endblock %}
|
|
67
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
<div id="header">
|
|
5
|
+
<!-- Header and Scan Submission Inline -->
|
|
6
|
+
<div class="d-flex justify-content-between align-items-center flex-wrap">
|
|
7
|
+
<h1 class="title" onclick="location.reload()">
|
|
8
|
+
<span>LAN</span>scape
|
|
9
|
+
</h1>
|
|
10
|
+
<!-- Form -->
|
|
11
|
+
<form id="scan-form" class="d-flex align-items-end">
|
|
12
|
+
<div class="form-group me-2">
|
|
13
|
+
<div class="label-container">
|
|
14
|
+
<label for="subnet">Subnet:</label>
|
|
15
|
+
<div id="subnet-info"></div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="input-group">
|
|
18
|
+
<input type="text" id="subnet" name="subnet" class="form-control" value="{{ subnet }}" placeholder="Enter subnet">
|
|
19
|
+
<button class="btn btn-secondary dropdown-toggle" type="button" id="subnet-dropdown" data-bs-toggle="dropdown" aria-expanded="false"></button>
|
|
20
|
+
<ul class="dropdown-menu" aria-labelledby="subnet-dropdown" id="dropdown-list">
|
|
21
|
+
{% for subnet_option in alternate_subnets %}
|
|
22
|
+
<li><a class="dropdown-item" href="#">{{ subnet_option['subnet'] }}</a></li>
|
|
23
|
+
{% endfor %}
|
|
24
|
+
</ul>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<button type="submit" id="scan-submit" class="btn btn-primary mb-3">Scan</button>
|
|
28
|
+
</form>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Advanced Section -->
|
|
32
|
+
<details onclick="rightSizeDocLayout()">
|
|
33
|
+
<summary>Advanced</summary>
|
|
34
|
+
<div class="form-group mt-2">
|
|
35
|
+
<label for="port_list">Port List:</label>
|
|
36
|
+
<div class="port-list-wrapper">
|
|
37
|
+
<div id="port-list" class="port-list">{{port_list}}</div>
|
|
38
|
+
<div id="port-list-dropdown" class="port-list-dropdown"></div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="form-group mt-2">
|
|
43
|
+
<label for="parallelism">Parallelism:</label>
|
|
44
|
+
<input type="range" id="parallelism" name="parallelism" min="0.25" max="3" step="0.05" value="{{parallelism}}">
|
|
45
|
+
<output id="parallelism-value">{{parallelism}}</output>
|
|
46
|
+
</div>
|
|
47
|
+
</details>
|
|
48
|
+
<div id="scan-progress-bar"></div>
|
|
49
|
+
</div>
|
|
50
|
+
<div id="content">
|
|
51
|
+
<div class="container-fluid my-4">
|
|
52
|
+
<!-- Scan Results -->
|
|
53
|
+
<div id="scan-results" class="div-hide">
|
|
54
|
+
<div class="d-flex justify-content-between">
|
|
55
|
+
<h2>Scan Results</h2>
|
|
56
|
+
<div id="scan-actions">
|
|
57
|
+
<a href="" id="export-link">
|
|
58
|
+
<span
|
|
59
|
+
class="material-symbols-outlined secondary-icon-btn"
|
|
60
|
+
data-bs-toggle="tooltip"
|
|
61
|
+
data-bs-placement="top"
|
|
62
|
+
title="Export scan to json">
|
|
63
|
+
ios_share
|
|
64
|
+
</span>
|
|
65
|
+
</a>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{% include 'scan/overview.html' %}
|
|
70
|
+
<input type="text" id="filter" placeholder="Filter results" class="form-control mb-3 mt-3">
|
|
71
|
+
<div class="table-frame-container">
|
|
72
|
+
<iframe id="ip-table-frame" src=""></iframe>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
<div id="no-scan">
|
|
76
|
+
<h2>No results to show</h2>
|
|
77
|
+
<p>Submit a scan above</p>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
|
84
|
+
<script src="{{ url_for('static', filename='js/subnet-info.js') }}"></script>
|
|
85
|
+
<script src="{{ url_for('static', filename='js/subnet-selector.js') }}"></script>
|
|
86
|
+
{% endblock %}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
<div id="header">
|
|
5
|
+
<!-- Header and Scan Submission Inline -->
|
|
6
|
+
<div class="d-flex justify-content-start align-items-center">
|
|
7
|
+
<h1 class="title" onclick="location.href = '/'">
|
|
8
|
+
<span>LAN</span>scape
|
|
9
|
+
</h1>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="scroll-container" id="#content">
|
|
13
|
+
<div class="container-fluid my-4">
|
|
14
|
+
<h3>Json Export:</h3>
|
|
15
|
+
|
|
16
|
+
<details>
|
|
17
|
+
<summary>{{ scan.uid }}</summary>
|
|
18
|
+
<div class="error-container">
|
|
19
|
+
<pre>{{ export_json }}</pre>
|
|
20
|
+
</div>
|
|
21
|
+
</details>
|
|
22
|
+
<button onclick="location.href='/?scan_id={{scan.uid}}'" class="btn btn-primary m-2">Back</button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
{% endblock %}
|
|
27
|
+
|