portune 0.1.3__py3-none-any.whl → 0.1.5__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.
Potentially problematic release.
This version of portune might be problematic. Click here for more details.
- portune/portune.py +71 -30
- portune/version.py +2 -2
- {portune-0.1.3.dist-info → portune-0.1.5.dist-info}/METADATA +8 -2
- portune-0.1.5.dist-info/RECORD +9 -0
- portune-0.1.3.dist-info/RECORD +0 -9
- {portune-0.1.3.dist-info → portune-0.1.5.dist-info}/WHEEL +0 -0
- {portune-0.1.3.dist-info → portune-0.1.5.dist-info}/entry_points.txt +0 -0
- {portune-0.1.3.dist-info → portune-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {portune-0.1.3.dist-info → portune-0.1.5.dist-info}/top_level.txt +0 -0
portune/portune.py
CHANGED
|
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
# Standard library imports
|
|
17
17
|
import os
|
|
18
18
|
import sys
|
|
19
|
+
import platform
|
|
19
20
|
import argparse
|
|
20
21
|
import socket
|
|
21
22
|
import threading
|
|
@@ -32,13 +33,16 @@ from typing import List, Dict, Tuple, Any, Optional, Union
|
|
|
32
33
|
|
|
33
34
|
# Constants and global variables
|
|
34
35
|
ICON = "data:image/svg+xml,%3Csvg height='200px' width='200px' version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 508 508' xml:space='preserve' fill='%23000000'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ccircle style='fill:%23ffbb06;' cx='254' cy='254' r='254'%3E%3C/circle%3E%3Cg%3E%3Ccircle style='fill:%234c4c4c;' cx='399.6' cy='252' r='55.2'%3E%3C/circle%3E%3Ccircle style='fill:%234c4c4c;' cx='150' cy='356' r='55.2'%3E%3C/circle%3E%3Ccircle style='fill:%234c4c4c;' cx='178.4' cy='127.2' r='55.2'%3E%3C/circle%3E%3C/g%3E%3Cpath style='fill:%23000000;' d='M301.2,282.4l15.6,1.2l6.4-19.2l-13.2-8c0.4-5.6,0-11.2-1.2-16.4l12-10l-9.2-18l-15.2,3.6 c-3.6-4-7.6-8-12.4-10.8l1.2-15.6l-19.2-6.4l-8,13.2c-5.6-0.4-11.2,0-16.4,1.2l-10-12l-18,8.8l3.6,15.2c-4,3.6-8,7.6-10.8,12.4 l-15.6-1.2l-6.4,19.2l13.2,8.4c-0.4,5.6,0,11.2,1.2,16.4l-12,10l9.2,18l15.2-3.6c3.6,4,7.6,8,12.4,10.8l-1.6,15.2l19.2,6.4l8.4-13.2 c5.6,0.4,11.2,0,16.4-1.2l10,12l18-8.8l-3.6-15.2C294.4,291.2,298.4,287.2,301.2,282.4z M242.4,286c-18.8-6.4-28.8-26.4-22.8-45.2 c6.4-18.8,26.8-29.2,45.6-22.8c18.8,6.4,28.8,26.4,22.8,45.2C281.6,282,261.2,292.4,242.4,286z'%3E%3C/path%3E%3Cpath style='fill:%23324A5E;' d='M380.4,304c-20.4,50-69.6,85.2-126.8,85.2c-18.8,0-36.8-4-53.6-10.8c-2.4,5.6-5.6,10.4-9.6,14.8 c19.2,8.8,40.8,13.6,63.2,13.6c65.6,0,122-41.2,144.4-99.2C392,307.2,386,306,380.4,304z M132,157.2c-20.4,26-32.8,59.2-32.8,94.8 c0,22.4,4.8,43.6,13.6,62.8c4.4-4,9.2-7.2,14.8-9.6c-6.8-16.4-10.8-34.4-10.8-53.2c0-30.4,10-58.8,27.2-81.6 C139.2,166.8,135.2,162.4,132,157.2z M253.6,97.6c-9.2,0-18.4,0.8-27.6,2.4c2.8,5.2,5.2,10.8,6.4,16.8c6.8-1.2,14-1.6,21.2-1.6 c57.2,0,106.4,35.2,126.8,85.2c5.6-2,11.2-3.2,17.2-3.2C375.6,138.8,319.6,97.6,253.6,97.6z'%3E%3C/path%3E%3Cg%3E%3Ccircle style='fill:%23FF7058;' cx='399.6' cy='252' r='28.4'%3E%3C/circle%3E%3Ccircle style='fill:%23FF7058;' cx='150' cy='356' r='28.4'%3E%3C/circle%3E%3Ccircle style='fill:%23FF7058;' cx='178.4' cy='127.2' r='28.4'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E"
|
|
36
|
+
XL='data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M12.5535 16.5061C12.4114 16.6615 12.2106 16.75 12 16.75C11.7894 16.75 11.5886 16.6615 11.4465 16.5061L7.44648 12.1311C7.16698 11.8254 7.18822 11.351 7.49392 11.0715C7.79963 10.792 8.27402 10.8132 8.55352 11.1189L11.25 14.0682V3C11.25 2.58579 11.5858 2.25 12 2.25C12.4142 2.25 12.75 2.58579 12.75 3V14.0682L15.4465 11.1189C15.726 10.8132 16.2004 10.792 16.5061 11.0715C16.8118 11.351 16.833 11.8254 16.5535 12.1311L12.5535 16.5061Z" fill="%23eee"></path><path d="M3.75 15C3.75 14.5858 3.41422 14.25 3 14.25C2.58579 14.25 2.25 14.5858 2.25 15V15.0549C2.24998 16.4225 2.24996 17.5248 2.36652 18.3918C2.48754 19.2919 2.74643 20.0497 3.34835 20.6516C3.95027 21.2536 4.70814 21.5125 5.60825 21.6335C6.47522 21.75 7.57754 21.75 8.94513 21.75H15.0549C16.4225 21.75 17.5248 21.75 18.3918 21.6335C19.2919 21.5125 20.0497 21.2536 20.6517 20.6516C21.2536 20.0497 21.5125 19.2919 21.6335 18.3918C21.75 17.5248 21.75 16.4225 21.75 15.0549V15C21.75 14.5858 21.4142 14.25 21 14.25C20.5858 14.25 20.25 14.5858 20.25 15C20.25 16.4354 20.2484 17.4365 20.1469 18.1919C20.0482 18.9257 19.8678 19.3142 19.591 19.591C19.3142 19.8678 18.9257 20.0482 18.1919 20.1469C17.4365 20.2484 16.4354 20.25 15 20.25H9C7.56459 20.25 6.56347 20.2484 5.80812 20.1469C5.07435 20.0482 4.68577 19.8678 4.40901 19.591C4.13225 19.3142 3.9518 18.9257 3.85315 18.1919C3.75159 17.4365 3.75 16.4354 3.75 15Z" fill="%23eee"></path></g></svg>'
|
|
35
37
|
CSS="""
|
|
36
38
|
<style>
|
|
37
39
|
body {
|
|
38
40
|
font-family: Arial, sans-serif;
|
|
39
41
|
overflow: auto;
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
.hidden {
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
42
46
|
.icon {
|
|
43
47
|
border-radius: 25px;
|
|
44
48
|
background-color: #444;
|
|
@@ -80,7 +84,7 @@ div {
|
|
|
80
84
|
}
|
|
81
85
|
.desc {
|
|
82
86
|
text-overflow: ellipsis;
|
|
83
|
-
max-width:
|
|
87
|
+
max-width: 200px;
|
|
84
88
|
white-space: nowrap;
|
|
85
89
|
overflow: hidden;
|
|
86
90
|
}
|
|
@@ -134,7 +138,7 @@ th {
|
|
|
134
138
|
}
|
|
135
139
|
.sort-btn {
|
|
136
140
|
color: #aaa;
|
|
137
|
-
font-size:
|
|
141
|
+
font-size: 10px;
|
|
138
142
|
user-select: none;
|
|
139
143
|
display: inline-block;
|
|
140
144
|
width: 7px;
|
|
@@ -216,13 +220,18 @@ th {
|
|
|
216
220
|
border-radius: 17px;
|
|
217
221
|
/* min-width: 17px; */
|
|
218
222
|
text-align: center;
|
|
219
|
-
|
|
223
|
+
/* text-indent: 14px;*/
|
|
224
|
+
padding: 0px 18px 0px 4px;
|
|
220
225
|
margin-left: auto;
|
|
221
226
|
cursor: pointer;
|
|
227
|
+
background-image: url('{XL}');
|
|
228
|
+
background-repeat: no-repeat;
|
|
229
|
+
background-position: right 4px center;
|
|
230
|
+
background-size: 12px 12px;
|
|
222
231
|
}
|
|
223
232
|
|
|
224
233
|
</style>
|
|
225
|
-
""".replace("{ICON}", ICON)
|
|
234
|
+
""".replace("{ICON}", ICON).replace("{XL}", XL)
|
|
226
235
|
JS="""
|
|
227
236
|
<script src=https://unpkg.com/exceljs@4.1.1/dist/exceljs.min.js></script>
|
|
228
237
|
<script>
|
|
@@ -236,18 +245,25 @@ function initTableFilters(table) {
|
|
|
236
245
|
// Add sort button first
|
|
237
246
|
const sortBtn = document.createElement('span');
|
|
238
247
|
sortBtn.className = 'sort-btn';
|
|
239
|
-
sortBtn.innerHTML = '⬆'; // Unicode for sort icon
|
|
248
|
+
sortBtn.innerHTML = '▲' //'⬆'; // Unicode for sort icon ▼
|
|
240
249
|
sortBtn.style.cursor = 'pointer';
|
|
241
250
|
sortBtn.setAttribute('data-sort-order', '');
|
|
242
251
|
sortBtn.onclick = () => toggleSort(table, index, sortBtn);
|
|
243
|
-
|
|
252
|
+
|
|
253
|
+
const titleSpan = document.createElement('span');
|
|
254
|
+
titleSpan.className = 'th-title';
|
|
255
|
+
titleSpan.innerHTML = header.innerHTML;
|
|
256
|
+
|
|
244
257
|
// Move existing elements into the content span
|
|
245
|
-
while (header.firstChild) {
|
|
246
|
-
|
|
247
|
-
}
|
|
258
|
+
//while (header.firstChild) {
|
|
259
|
+
// contentSpan.appendChild(header.firstChild);
|
|
260
|
+
//}
|
|
248
261
|
|
|
249
262
|
// Add sort button at the beginning
|
|
250
|
-
contentSpan.
|
|
263
|
+
contentSpan.appendChild(sortBtn);
|
|
264
|
+
contentSpan.appendChild(titleSpan);
|
|
265
|
+
|
|
266
|
+
//contentSpan.insertBefore(sortBtn, contentSpan.firstChild);
|
|
251
267
|
|
|
252
268
|
// Add export button and row counter for last column
|
|
253
269
|
if (index === headers.length - 1) {
|
|
@@ -259,6 +275,7 @@ function initTableFilters(table) {
|
|
|
259
275
|
contentSpan.appendChild(rowCount);
|
|
260
276
|
}
|
|
261
277
|
|
|
278
|
+
header.innerHTML = '';
|
|
262
279
|
header.appendChild(contentSpan);
|
|
263
280
|
|
|
264
281
|
// Add filter input
|
|
@@ -277,7 +294,7 @@ function initTableFilters(table) {
|
|
|
277
294
|
function updateRowCount(table, count) {
|
|
278
295
|
const rowCount = table.querySelector('.row-count');
|
|
279
296
|
if (rowCount) {
|
|
280
|
-
rowCount.innerHTML =
|
|
297
|
+
rowCount.innerHTML = ` ${count}`; // 🡇🡇 not working macOS
|
|
281
298
|
}
|
|
282
299
|
}
|
|
283
300
|
|
|
@@ -286,7 +303,7 @@ function toggleSort(table, colIndex, sortBtn) {
|
|
|
286
303
|
table.querySelectorAll('.sort-btn').forEach(btn => {
|
|
287
304
|
if (btn !== sortBtn) {
|
|
288
305
|
btn.setAttribute('data-sort-order', '');
|
|
289
|
-
btn.innerHTML = '⬆';
|
|
306
|
+
btn.innerHTML = '▲'; //'⬆';
|
|
290
307
|
}
|
|
291
308
|
});
|
|
292
309
|
|
|
@@ -295,12 +312,12 @@ function toggleSort(table, colIndex, sortBtn) {
|
|
|
295
312
|
let newOrder = 'asc';
|
|
296
313
|
if (currentOrder === 'asc') {
|
|
297
314
|
newOrder = 'desc';
|
|
298
|
-
sortBtn.innerHTML = '⬇';
|
|
315
|
+
sortBtn.innerHTML = '▼'; //'⬇';
|
|
299
316
|
} else if (currentOrder === 'desc') {
|
|
300
317
|
newOrder = '';
|
|
301
|
-
sortBtn.innerHTML = '⬆';
|
|
318
|
+
sortBtn.innerHTML = '▲'; //'⬆';
|
|
302
319
|
} else {
|
|
303
|
-
sortBtn.innerHTML = '⬆';
|
|
320
|
+
sortBtn.innerHTML = '▲'; //'⬆';
|
|
304
321
|
}
|
|
305
322
|
sortBtn.setAttribute('data-sort-order', newOrder);
|
|
306
323
|
sortBtn.setAttribute('data-col-index', colIndex); // Store column index on the button
|
|
@@ -308,6 +325,7 @@ function toggleSort(table, colIndex, sortBtn) {
|
|
|
308
325
|
}
|
|
309
326
|
|
|
310
327
|
function applyFilters(table) {
|
|
328
|
+
table.classList.add('hidden');
|
|
311
329
|
const rows = Array.from(table.querySelectorAll('tbody tr'));
|
|
312
330
|
const filters = Array.from(table.querySelectorAll('.column-filter'))
|
|
313
331
|
.map(filter => ({
|
|
@@ -322,10 +340,10 @@ function applyFilters(table) {
|
|
|
322
340
|
// First apply filters
|
|
323
341
|
const filteredRows = rows.filter(row => {
|
|
324
342
|
// If no filters are active, show all rows
|
|
325
|
-
if (filters.every(f => !f.value)) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
343
|
+
//if (filters.every(f => !f.value)) {
|
|
344
|
+
// row.classList.remove('hidden');
|
|
345
|
+
// return true;
|
|
346
|
+
//}
|
|
329
347
|
const cells = row.cells;
|
|
330
348
|
const shouldShow = !filters.some(filter => {
|
|
331
349
|
if (!filter.value) return false;
|
|
@@ -333,7 +351,11 @@ function applyFilters(table) {
|
|
|
333
351
|
if (filter.regexp) return !filter.regexp.test(cellText);
|
|
334
352
|
return !cellText.toLowerCase().includes(filter.value);
|
|
335
353
|
});
|
|
336
|
-
|
|
354
|
+
if (shouldShow) {
|
|
355
|
+
row.classList.remove('hidden');
|
|
356
|
+
} else {
|
|
357
|
+
row.classList.add('hidden');
|
|
358
|
+
}
|
|
337
359
|
return shouldShow;
|
|
338
360
|
});
|
|
339
361
|
|
|
@@ -371,6 +393,7 @@ function applyFilters(table) {
|
|
|
371
393
|
const tbody = table.querySelector('tbody');
|
|
372
394
|
filteredRows.forEach(row => tbody.appendChild(row));
|
|
373
395
|
}
|
|
396
|
+
table.classList.remove('hidden');
|
|
374
397
|
}
|
|
375
398
|
|
|
376
399
|
function processHtmlContent(element) {
|
|
@@ -425,7 +448,7 @@ function exportToExcel(table, fileNamePrefix = 'export') {
|
|
|
425
448
|
|
|
426
449
|
// Get headers and data
|
|
427
450
|
const headers = Array.from(table.querySelectorAll('thead th'))
|
|
428
|
-
.map(th => th.querySelector('.th-
|
|
451
|
+
.map(th => th.querySelector('.th-title')?.textContent.trim() || '');
|
|
429
452
|
|
|
430
453
|
// Get data rows with type information
|
|
431
454
|
const rows = Array.from(table.querySelectorAll('tbody tr'))
|
|
@@ -628,11 +651,11 @@ def parse_input_file(filename: str) -> List[Tuple[str, List[int]]]:
|
|
|
628
651
|
host_dict = {}
|
|
629
652
|
with open(filename, 'r') as f:
|
|
630
653
|
for line in f:
|
|
631
|
-
line = line.strip()
|
|
654
|
+
line = line.strip()
|
|
632
655
|
if not line or line.startswith('#'):
|
|
633
656
|
continue
|
|
634
657
|
words = line.split()
|
|
635
|
-
fqdn = words[0]
|
|
658
|
+
fqdn = words[0].lower()
|
|
636
659
|
ports = words[1] if len(words) > 1 else '22'
|
|
637
660
|
port_list = [int(p) for p in ports.split(',')]
|
|
638
661
|
desc = ' '.join(words[2:]).strip() if len(words) > 2 else ''
|
|
@@ -662,8 +685,12 @@ def ping_host(ip: str, timeout: float = 2.0) -> bool:
|
|
|
662
685
|
"""
|
|
663
686
|
try:
|
|
664
687
|
# Using -c 1 for count=1, -W timeout for timeout in seconds
|
|
688
|
+
# Windows uses -n 1 for count=1, -w timeout in milliseconds
|
|
665
689
|
# These are standard Linux ping parameters
|
|
666
|
-
|
|
690
|
+
if platform.system().lower() == "windows":
|
|
691
|
+
command = ["ping", "-n", "1", "-w", str(int(timeout * 1000)), ip]
|
|
692
|
+
else:
|
|
693
|
+
command = ['ping', '-c', '1', '-W', str(int(timeout)), ip]
|
|
667
694
|
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout)
|
|
668
695
|
return output.returncode == 0
|
|
669
696
|
except Exception:
|
|
@@ -1158,7 +1185,8 @@ def generate_html_report(
|
|
|
1158
1185
|
parallelism: int,
|
|
1159
1186
|
noping: bool,
|
|
1160
1187
|
stats: Dict[str, Any],
|
|
1161
|
-
input_file: str = ''
|
|
1188
|
+
input_file: str = '',
|
|
1189
|
+
desc_titles: List[str] = [],
|
|
1162
1190
|
) -> None:
|
|
1163
1191
|
"""Generate a complete HTML report of the port scan results.
|
|
1164
1192
|
|
|
@@ -1203,6 +1231,9 @@ def generate_html_report(
|
|
|
1203
1231
|
f.write(f'<h3 class="icon">Port Accessibility Report from {HOSTNAME} ({MY_IP}) to {os.path.basename(input_file)} - {time.strftime("%Y-%m-%d %H:%M:%S", scan_time)}</h3>\n')
|
|
1204
1232
|
|
|
1205
1233
|
# Write detailed results table
|
|
1234
|
+
if not desc_titles:
|
|
1235
|
+
_, _, _, _, _, desc = results[0]
|
|
1236
|
+
desc_titles = ["Description" for d in desc.split("|")]
|
|
1206
1237
|
f.write(f'''
|
|
1207
1238
|
<div class="table-container" id="result-container">
|
|
1208
1239
|
<table id="commandTable">
|
|
@@ -1214,7 +1245,7 @@ def generate_html_report(
|
|
|
1214
1245
|
<th>Port</th>
|
|
1215
1246
|
<th>Status</th>
|
|
1216
1247
|
<th>Ping</th>
|
|
1217
|
-
<th>
|
|
1248
|
+
{"\n".join([f"<th>{d}</th>" for d in desc_titles])}
|
|
1218
1249
|
</tr>
|
|
1219
1250
|
</thead>
|
|
1220
1251
|
<tbody>
|
|
@@ -1233,7 +1264,7 @@ def generate_html_report(
|
|
|
1233
1264
|
<td style="text-align: right;">{port}</td>
|
|
1234
1265
|
<td style="text-align: center;"><span class="{status_class} status">{escape(status)}</span></td>
|
|
1235
1266
|
<td style="text-align: center;"><span class="{ping_class} ping">{ping_status}</span></td>
|
|
1236
|
-
<td class="desc">{escape(str(
|
|
1267
|
+
{"\n".join([f'<td class="desc">{escape(str(d))}</td>' for d in desc.split("|")])}
|
|
1237
1268
|
</tr>
|
|
1238
1269
|
''')
|
|
1239
1270
|
|
|
@@ -1417,7 +1448,7 @@ def main():
|
|
|
1417
1448
|
parser.add_argument('-n', '--noping', action="store_true", help='No ping check')
|
|
1418
1449
|
parser.add_argument('-s', '--summary', action="store_true", help='Print scan summary information')
|
|
1419
1450
|
parser.add_argument('-b', '--bits', type=int, default=16, help='VLAN bits for timeout summary (default: 16)')
|
|
1420
|
-
|
|
1451
|
+
parser.add_argument('-d', '--desc_titles', type=str, nargs='*', help='List of custom description titles for hosts (optional)')
|
|
1421
1452
|
# Email related arguments
|
|
1422
1453
|
email_group = parser.add_argument_group('Email Options')
|
|
1423
1454
|
email_group.add_argument('--email-to', help='Comma-separated list of email recipients')
|
|
@@ -1475,7 +1506,17 @@ def main():
|
|
|
1475
1506
|
|
|
1476
1507
|
# Generate report
|
|
1477
1508
|
results.sort(key=lambda x: (x[0], x[2]))
|
|
1478
|
-
generate_html_report(
|
|
1509
|
+
generate_html_report(
|
|
1510
|
+
results,
|
|
1511
|
+
args.output,
|
|
1512
|
+
time.localtime(start_time),
|
|
1513
|
+
args.timeout,
|
|
1514
|
+
args.parallelism,
|
|
1515
|
+
args.noping,
|
|
1516
|
+
stats,
|
|
1517
|
+
args.input_file,
|
|
1518
|
+
args.desc_titles,
|
|
1519
|
+
)
|
|
1479
1520
|
|
|
1480
1521
|
# Print summary
|
|
1481
1522
|
# Display detailed results in table format
|
portune/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: portune
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
|
5
5
|
Author: Franck Jouvanceau
|
|
6
6
|
Maintainer: Franck Jouvanceau
|
|
@@ -52,13 +52,19 @@ Description-Content-Type: text/markdown
|
|
|
52
52
|
License-File: LICENSE
|
|
53
53
|
Dynamic: license-file
|
|
54
54
|
|
|
55
|
+
[](https://pypi.org/project/portune/)
|
|
56
|
+

|
|
57
|
+
[](https://shields.io/)
|
|
58
|
+
[](https://pepy.tech/project/portune)
|
|
59
|
+
[](https://shields.io/)
|
|
60
|
+
|
|
55
61
|
# portune
|
|
56
62
|
|
|
57
63
|
Multitreaded port scanner
|
|
58
64
|
|
|
59
65
|
# features
|
|
60
66
|
|
|
61
|
-
* parallel check of port availability against
|
|
67
|
+
* parallel check of port availability against servers/ports
|
|
62
68
|
* console output result / summary
|
|
63
69
|
* html full report / dns domain summary / vlan timeout summary
|
|
64
70
|
* mail with html summary / report attachment (mailhost relay)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
portune/__init__.py,sha256=RfXuNfHBqfRt_z4IukwN1a0oeCXahuMOO8_eBt4T8NM,58
|
|
2
|
+
portune/portune.py,sha256=cMn0fosBTV98wXWHKdFYtUN9S1ZseRXJ6emNe2rWFns,65846
|
|
3
|
+
portune/version.py,sha256=Y4jy4bEMmwl_qNPCmiMFnlQ2ofMoqyG37hp8uwI3m10,511
|
|
4
|
+
portune-0.1.5.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
|
5
|
+
portune-0.1.5.dist-info/METADATA,sha256=hHJ5KFpUxEbSeF4FOXpbhqzjdZ92jf55g3iUTOk2-2g,3281
|
|
6
|
+
portune-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
portune-0.1.5.dist-info/entry_points.txt,sha256=6j7jAf5fOZrLPbVIs3z92R1tT891WyY9YxQ6OVnPKG0,80
|
|
8
|
+
portune-0.1.5.dist-info/top_level.txt,sha256=CITDikHhRKAsSOGmNJzD-xSp6D5iBhSr9ZS1qy8-SL0,8
|
|
9
|
+
portune-0.1.5.dist-info/RECORD,,
|
portune-0.1.3.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
portune/__init__.py,sha256=RfXuNfHBqfRt_z4IukwN1a0oeCXahuMOO8_eBt4T8NM,58
|
|
2
|
-
portune/portune.py,sha256=ZSZQlqJ7ebjSFJmO5cC5NHzNX6NwOHOEdEp0MG11B_g,62820
|
|
3
|
-
portune/version.py,sha256=NIzzV8ZM0W-CSLuEs1weG4zPrn_-8yr1AwwI1iuS6yo,511
|
|
4
|
-
portune-0.1.3.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
|
5
|
-
portune-0.1.3.dist-info/METADATA,sha256=E5QlqZso2uL0VnLdldXI73x_wG0EkgJCnF2pgnvXseM,2837
|
|
6
|
-
portune-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
portune-0.1.3.dist-info/entry_points.txt,sha256=6j7jAf5fOZrLPbVIs3z92R1tT891WyY9YxQ6OVnPKG0,80
|
|
8
|
-
portune-0.1.3.dist-info/top_level.txt,sha256=CITDikHhRKAsSOGmNJzD-xSp6D5iBhSr9ZS1qy8-SL0,8
|
|
9
|
-
portune-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|