lanscape 1.5.0__py3-none-any.whl → 2.0.0a1__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/__init__.py +5 -4
- lanscape/__main__.py +1 -0
- lanscape/{libraries → core}/app_scope.py +1 -0
- lanscape/{libraries → core}/decorators.py +85 -51
- lanscape/{libraries → core}/device_alive.py +4 -3
- lanscape/{libraries → core}/errors.py +1 -0
- lanscape/{libraries → core}/ip_parser.py +2 -1
- lanscape/{libraries → core}/logger.py +1 -0
- lanscape/{libraries → core}/mac_lookup.py +1 -0
- lanscape/{libraries → core}/net_tools.py +7 -6
- lanscape/{libraries → core}/port_manager.py +1 -0
- lanscape/{libraries → core}/runtime_args.py +1 -0
- lanscape/{libraries → core}/scan_config.py +3 -2
- lanscape/{libraries → core}/service_scan.py +3 -2
- lanscape/{libraries → core}/subnet_scan.py +6 -5
- lanscape/{libraries → core}/version_manager.py +3 -2
- lanscape/{libraries → core}/web_browser.py +1 -0
- lanscape/resources/mac_addresses/convert_csv.py +1 -0
- lanscape/resources/ports/convert_csv.py +1 -0
- lanscape/ui/app.py +5 -4
- lanscape/ui/blueprints/__init__.py +2 -1
- lanscape/ui/blueprints/api/__init__.py +1 -0
- lanscape/ui/blueprints/api/port.py +2 -1
- lanscape/ui/blueprints/api/scan.py +2 -1
- lanscape/ui/blueprints/api/tools.py +5 -4
- lanscape/ui/blueprints/web/__init__.py +1 -0
- lanscape/ui/blueprints/web/routes.py +2 -1
- lanscape/ui/main.py +5 -4
- lanscape/ui/shutdown_handler.py +2 -1
- {lanscape-1.5.0.dist-info → lanscape-2.0.0a1.dist-info}/METADATA +7 -2
- {lanscape-1.5.0.dist-info → lanscape-2.0.0a1.dist-info}/RECORD +36 -35
- lanscape-2.0.0a1.dist-info/entry_points.txt +2 -0
- /lanscape/{libraries → core}/__init__.py +0 -0
- {lanscape-1.5.0.dist-info → lanscape-2.0.0a1.dist-info}/WHEEL +0 -0
- {lanscape-1.5.0.dist-info → lanscape-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {lanscape-1.5.0.dist-info → lanscape-2.0.0a1.dist-info}/top_level.txt +0 -0
lanscape/__init__.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Local network scanner
|
|
3
3
|
"""
|
|
4
|
-
from lanscape.
|
|
4
|
+
from lanscape.core.subnet_scan import (
|
|
5
5
|
SubnetScanner,
|
|
6
6
|
ScannerResults,
|
|
7
7
|
ScanManager
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
-
from lanscape.
|
|
10
|
+
from lanscape.core.scan_config import (
|
|
11
11
|
ScanConfig,
|
|
12
12
|
ArpConfig,
|
|
13
13
|
PingConfig,
|
|
@@ -19,6 +19,7 @@ from lanscape.libraries.scan_config import (
|
|
|
19
19
|
ScanType
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
-
from lanscape.
|
|
22
|
+
from lanscape.core.port_manager import PortManager
|
|
23
|
+
|
|
24
|
+
from lanscape.core import net_tools
|
|
23
25
|
|
|
24
|
-
from lanscape.libraries import net_tools
|
lanscape/__main__.py
CHANGED
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
"""Decorators and job tracking utilities for Lanscape."""
|
|
3
3
|
|
|
4
4
|
from time import time
|
|
5
|
-
from dataclasses import dataclass, field
|
|
6
|
-
from typing import DefaultDict
|
|
7
5
|
from collections import defaultdict
|
|
8
|
-
import inspect
|
|
9
6
|
import functools
|
|
10
7
|
import concurrent.futures
|
|
11
8
|
import logging
|
|
9
|
+
import threading
|
|
12
10
|
from tabulate import tabulate
|
|
13
11
|
|
|
14
12
|
|
|
@@ -39,31 +37,74 @@ def run_once(func):
|
|
|
39
37
|
return wrapper
|
|
40
38
|
|
|
41
39
|
|
|
42
|
-
@dataclass
|
|
43
40
|
class JobStats:
|
|
44
41
|
"""
|
|
42
|
+
Thread-safe singleton for tracking job statistics across all classes.
|
|
45
43
|
Tracks statistics for job execution, including running, finished, and timing data.
|
|
46
44
|
"""
|
|
47
|
-
running: DefaultDict[str, int] = field(
|
|
48
|
-
default_factory=lambda: defaultdict(int))
|
|
49
|
-
finished: DefaultDict[str, int] = field(
|
|
50
|
-
default_factory=lambda: defaultdict(int))
|
|
51
|
-
timing: DefaultDict[str, float] = field(
|
|
52
|
-
default_factory=lambda: defaultdict(float))
|
|
53
45
|
|
|
54
46
|
_instance = None
|
|
47
|
+
_lock = threading.Lock()
|
|
48
|
+
|
|
49
|
+
def __new__(cls):
|
|
50
|
+
if cls._instance is None:
|
|
51
|
+
with cls._lock:
|
|
52
|
+
if cls._instance is None: # Double-checked locking
|
|
53
|
+
cls._instance = super().__new__(cls)
|
|
54
|
+
return cls._instance
|
|
55
55
|
|
|
56
56
|
def __init__(self):
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
if not hasattr(self, '_initialized'):
|
|
58
|
+
self._stats_lock = threading.RLock()
|
|
59
59
|
self.running = defaultdict(int)
|
|
60
60
|
self.finished = defaultdict(int)
|
|
61
61
|
self.timing = defaultdict(float)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
self._initialized = True
|
|
63
|
+
|
|
64
|
+
def start_job(self, func_name: str):
|
|
65
|
+
"""Thread-safe increment of running counter."""
|
|
66
|
+
with self._stats_lock:
|
|
67
|
+
self.running[func_name] += 1
|
|
68
|
+
|
|
69
|
+
def finish_job(self, func_name: str, elapsed_time: float):
|
|
70
|
+
"""Thread-safe update of job completion and timing."""
|
|
71
|
+
with self._stats_lock:
|
|
72
|
+
self.running[func_name] -= 1
|
|
73
|
+
self.finished[func_name] += 1
|
|
74
|
+
|
|
75
|
+
# Calculate running average
|
|
76
|
+
count = self.finished[func_name]
|
|
77
|
+
old_avg = self.timing[func_name]
|
|
78
|
+
new_avg = (old_avg * (count - 1) + elapsed_time) / count
|
|
79
|
+
self.timing[func_name] = round(new_avg, 4)
|
|
80
|
+
|
|
81
|
+
# Cleanup running if zero
|
|
82
|
+
if self.running[func_name] <= 0:
|
|
83
|
+
self.running.pop(func_name, None)
|
|
84
|
+
|
|
85
|
+
def clear_stats(self):
|
|
86
|
+
"""Clear all statistics (useful between scans)."""
|
|
87
|
+
with self._stats_lock:
|
|
88
|
+
self.running.clear()
|
|
89
|
+
self.finished.clear()
|
|
90
|
+
self.timing.clear()
|
|
91
|
+
|
|
92
|
+
def get_stats_copy(self) -> dict:
|
|
93
|
+
"""Get a thread-safe copy of current statistics."""
|
|
94
|
+
with self._stats_lock:
|
|
95
|
+
return {
|
|
96
|
+
'running': dict(self.running),
|
|
97
|
+
'finished': dict(self.finished),
|
|
98
|
+
'timing': dict(self.timing)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def reset_for_testing(cls):
|
|
103
|
+
"""Reset singleton instance for testing purposes only."""
|
|
104
|
+
with cls._lock:
|
|
105
|
+
if cls._instance:
|
|
106
|
+
cls._instance.clear_stats()
|
|
107
|
+
cls._instance = None
|
|
67
108
|
|
|
68
109
|
def __str__(self):
|
|
69
110
|
"""Return a formatted string representation of the job statistics."""
|
|
@@ -106,48 +147,40 @@ def job_tracker(func):
|
|
|
106
147
|
Return the function name with the class name prepended if available.
|
|
107
148
|
"""
|
|
108
149
|
qual_parts = func.__qualname__.split(".")
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if
|
|
116
|
-
|
|
150
|
+
|
|
151
|
+
# If function has class context (e.g., "ClassName.method_name")
|
|
152
|
+
if len(qual_parts) > 1:
|
|
153
|
+
cls_name = qual_parts[-2]
|
|
154
|
+
|
|
155
|
+
# Check if first_arg is an instance and has the expected class name
|
|
156
|
+
if first_arg is not None and hasattr(first_arg, '__class__'):
|
|
157
|
+
if first_arg.__class__.__name__ == cls_name:
|
|
158
|
+
return f"{cls_name}.{func.__name__}"
|
|
159
|
+
|
|
117
160
|
return func.__name__
|
|
118
161
|
|
|
162
|
+
@functools.wraps(func)
|
|
119
163
|
def wrapper(*args, **kwargs):
|
|
120
164
|
"""Wrap the function to update job statistics before and after execution."""
|
|
121
|
-
class_instance = args[0]
|
|
122
165
|
job_stats = JobStats()
|
|
123
|
-
fxn = get_fxn_src_name(
|
|
124
|
-
func,
|
|
125
|
-
class_instance
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
# Increment running counter and track execution time
|
|
129
|
-
job_stats.running[fxn] += 1
|
|
130
|
-
start = time()
|
|
131
166
|
|
|
132
|
-
|
|
167
|
+
# Determine function name for tracking
|
|
168
|
+
if args:
|
|
169
|
+
fxn = get_fxn_src_name(func, args[0])
|
|
170
|
+
else:
|
|
171
|
+
fxn = func.__name__
|
|
133
172
|
|
|
134
|
-
#
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
job_stats.finished[fxn] += 1
|
|
138
|
-
|
|
139
|
-
# Calculate the new average timing for the function
|
|
140
|
-
job_stats.timing[fxn] = round(
|
|
141
|
-
((job_stats.finished[fxn] - 1) * job_stats.timing[fxn] + elapsed)
|
|
142
|
-
/ job_stats.finished[fxn],
|
|
143
|
-
4
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
# Clean up if no more running instances of this function
|
|
147
|
-
if job_stats.running[fxn] == 0:
|
|
148
|
-
job_stats.running.pop(fxn)
|
|
173
|
+
# Start job tracking
|
|
174
|
+
job_stats.start_job(fxn)
|
|
175
|
+
start = time()
|
|
149
176
|
|
|
150
|
-
|
|
177
|
+
try:
|
|
178
|
+
result = func(*args, **kwargs) # Execute the wrapped function
|
|
179
|
+
return result
|
|
180
|
+
finally:
|
|
181
|
+
# Always update statistics, even if function raises exception
|
|
182
|
+
elapsed = time() - start
|
|
183
|
+
job_stats.finish_job(fxn, elapsed)
|
|
151
184
|
|
|
152
185
|
return wrapper
|
|
153
186
|
|
|
@@ -196,3 +229,4 @@ def timeout_enforcer(timeout: int, raise_on_timeout: bool = True):
|
|
|
196
229
|
return None # Return None if not raising an exception
|
|
197
230
|
return wrapper
|
|
198
231
|
return decorator
|
|
232
|
+
|
|
@@ -13,12 +13,12 @@ from scapy.sendrecv import srp
|
|
|
13
13
|
from scapy.layers.l2 import ARP, Ether
|
|
14
14
|
from icmplib import ping
|
|
15
15
|
|
|
16
|
-
from lanscape.
|
|
17
|
-
from lanscape.
|
|
16
|
+
from lanscape.core.net_tools import Device
|
|
17
|
+
from lanscape.core.scan_config import (
|
|
18
18
|
ScanConfig, ScanType, PingConfig,
|
|
19
19
|
ArpConfig, PokeConfig, ArpCacheConfig
|
|
20
20
|
)
|
|
21
|
-
from lanscape.
|
|
21
|
+
from lanscape.core.decorators import timeout_enforcer, job_tracker
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def is_device_alive(device: Device, scan_config: ScanConfig) -> bool:
|
|
@@ -227,3 +227,4 @@ class Poker():
|
|
|
227
227
|
sock.close()
|
|
228
228
|
|
|
229
229
|
do_poke()
|
|
230
|
+
|
|
@@ -12,7 +12,7 @@ It also includes validation to prevent processing excessively large IP ranges.
|
|
|
12
12
|
import ipaddress
|
|
13
13
|
import re
|
|
14
14
|
|
|
15
|
-
from lanscape.
|
|
15
|
+
from lanscape.core.errors import SubnetTooLargeError
|
|
16
16
|
|
|
17
17
|
MAX_IPS_ALLOWED = 100000
|
|
18
18
|
|
|
@@ -139,3 +139,4 @@ def ip_range_to_list(start_ip, end_ip):
|
|
|
139
139
|
# Yield the range of IPs
|
|
140
140
|
for ip_int in range(int(start_ip), int(end_ip) + 1):
|
|
141
141
|
yield ipaddress.IPv4Address(ip_int)
|
|
142
|
+
|
|
@@ -29,12 +29,12 @@ else:
|
|
|
29
29
|
COMPUTED_FIELD = computed_field # pylint: disable=invalid-name
|
|
30
30
|
MODEL_SERIALIZER = model_serializer # pylint: disable=invalid-name
|
|
31
31
|
|
|
32
|
-
from lanscape.
|
|
33
|
-
from lanscape.
|
|
34
|
-
from lanscape.
|
|
35
|
-
from lanscape.
|
|
36
|
-
from lanscape.
|
|
37
|
-
from lanscape.
|
|
32
|
+
from lanscape.core.service_scan import scan_service
|
|
33
|
+
from lanscape.core.mac_lookup import MacLookup, get_macs
|
|
34
|
+
from lanscape.core.ip_parser import get_address_count, MAX_IPS_ALLOWED
|
|
35
|
+
from lanscape.core.errors import DeviceError
|
|
36
|
+
from lanscape.core.decorators import job_tracker, run_once, timeout_enforcer
|
|
37
|
+
from lanscape.core.scan_config import ServiceScanConfig, PortScanConfig
|
|
38
38
|
|
|
39
39
|
log = logging.getLogger('NetTools')
|
|
40
40
|
mac_lookup = MacLookup()
|
|
@@ -566,3 +566,4 @@ def is_arp_supported():
|
|
|
566
566
|
return True
|
|
567
567
|
except (Scapy_Exception, PermissionError, RuntimeError):
|
|
568
568
|
return False
|
|
569
|
+
|
|
@@ -11,8 +11,8 @@ from enum import Enum
|
|
|
11
11
|
|
|
12
12
|
from pydantic import BaseModel, Field
|
|
13
13
|
|
|
14
|
-
from lanscape.
|
|
15
|
-
from lanscape.
|
|
14
|
+
from lanscape.core.port_manager import PortManager
|
|
15
|
+
from lanscape.core.ip_parser import parse_ip_input
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class PingConfig(BaseModel):
|
|
@@ -395,3 +395,4 @@ DEFAULT_CONFIGS: Dict[str, ScanConfig] = {
|
|
|
395
395
|
)
|
|
396
396
|
)
|
|
397
397
|
}
|
|
398
|
+
|
|
@@ -7,8 +7,8 @@ import asyncio
|
|
|
7
7
|
import logging
|
|
8
8
|
import traceback
|
|
9
9
|
|
|
10
|
-
from lanscape.
|
|
11
|
-
from lanscape.
|
|
10
|
+
from lanscape.core.app_scope import ResourceManager
|
|
11
|
+
from lanscape.core.scan_config import ServiceScanConfig, ServiceScanStrategy
|
|
12
12
|
|
|
13
13
|
log = logging.getLogger('ServiceScan')
|
|
14
14
|
SERVICES = ResourceManager('services').get_jsonc('definitions.jsonc')
|
|
@@ -202,3 +202,4 @@ def asyncio_logger_suppression():
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
asyncio_logger_suppression()
|
|
205
|
+
|
|
@@ -20,11 +20,11 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
20
20
|
from tabulate import tabulate
|
|
21
21
|
|
|
22
22
|
# Local imports
|
|
23
|
-
from lanscape.
|
|
24
|
-
from lanscape.
|
|
25
|
-
from lanscape.
|
|
26
|
-
from lanscape.
|
|
27
|
-
from lanscape.
|
|
23
|
+
from lanscape.core.scan_config import ScanConfig
|
|
24
|
+
from lanscape.core.decorators import job_tracker, terminator, JobStats
|
|
25
|
+
from lanscape.core.net_tools import Device
|
|
26
|
+
from lanscape.core.errors import SubnetScanTerminationFailure
|
|
27
|
+
from lanscape.core.device_alive import is_device_alive
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class SubnetScanner():
|
|
@@ -428,3 +428,4 @@ class ScanManager:
|
|
|
428
428
|
t = threading.Thread(target=scan.start)
|
|
429
429
|
t.start()
|
|
430
430
|
return t
|
|
431
|
+
|
|
@@ -11,8 +11,8 @@ from random import randint
|
|
|
11
11
|
|
|
12
12
|
import requests
|
|
13
13
|
|
|
14
|
-
from lanscape.
|
|
15
|
-
from lanscape.
|
|
14
|
+
from lanscape.core.app_scope import is_local_run
|
|
15
|
+
from lanscape.core.decorators import run_once
|
|
16
16
|
|
|
17
17
|
log = logging.getLogger('VersionManager')
|
|
18
18
|
|
|
@@ -95,3 +95,4 @@ def get_installed_version(package=PACKAGE):
|
|
|
95
95
|
log.debug(traceback.format_exc())
|
|
96
96
|
log.warning(f'Cannot find {package} installation')
|
|
97
97
|
return LOCAL_VERSION
|
|
98
|
+
|
lanscape/ui/app.py
CHANGED
|
@@ -8,12 +8,12 @@ import logging
|
|
|
8
8
|
from flask import Flask, render_template
|
|
9
9
|
from lanscape.ui.blueprints.web import web_bp, routes # pylint: disable=unused-import
|
|
10
10
|
from lanscape.ui.blueprints.api import api_bp, tools, port, scan # pylint: disable=unused-import
|
|
11
|
-
from lanscape.
|
|
12
|
-
from lanscape.
|
|
11
|
+
from lanscape.core.runtime_args import RuntimeArgs, parse_args
|
|
12
|
+
from lanscape.core.version_manager import (
|
|
13
13
|
is_update_available, get_installed_version, lookup_latest_version
|
|
14
14
|
)
|
|
15
|
-
from lanscape.
|
|
16
|
-
from lanscape.
|
|
15
|
+
from lanscape.core.app_scope import is_local_run
|
|
16
|
+
from lanscape.core.net_tools import is_arp_supported
|
|
17
17
|
from lanscape.ui.shutdown_handler import FlaskShutdownHandler
|
|
18
18
|
|
|
19
19
|
app = Flask(
|
|
@@ -122,3 +122,4 @@ def start_webserver(args: RuntimeArgs) -> int:
|
|
|
122
122
|
'use_reloader': args.reloader
|
|
123
123
|
}
|
|
124
124
|
app.run(**run_args)
|
|
125
|
+
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"""Source for all things blueprint related in LANscape UI"""
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
from lanscape.
|
|
4
|
+
from lanscape.core.subnet_scan import ScanManager
|
|
5
5
|
|
|
6
6
|
# defining here so blueprints can access the same
|
|
7
7
|
# manager instance
|
|
8
8
|
scan_manager = ScanManager()
|
|
9
9
|
|
|
10
10
|
log = logging.getLogger('Blueprints')
|
|
11
|
+
|
|
@@ -4,7 +4,7 @@ Provides CRUD operations for managing port lists used in network scans.
|
|
|
4
4
|
"""
|
|
5
5
|
from flask import request, jsonify
|
|
6
6
|
from lanscape.ui.blueprints.api import api_bp
|
|
7
|
-
from lanscape.
|
|
7
|
+
from lanscape.core.port_manager import PortManager
|
|
8
8
|
|
|
9
9
|
# Port Manager API
|
|
10
10
|
############################################
|
|
@@ -77,3 +77,4 @@ def delete_port_list(port_list):
|
|
|
77
77
|
JSON response indicating success or failure
|
|
78
78
|
"""
|
|
79
79
|
return jsonify(PortManager().delete_port_list(port_list))
|
|
80
|
+
|
|
@@ -9,7 +9,7 @@ import traceback
|
|
|
9
9
|
from flask import request, jsonify
|
|
10
10
|
|
|
11
11
|
from lanscape.ui.blueprints.api import api_bp
|
|
12
|
-
from lanscape.
|
|
12
|
+
from lanscape.core.subnet_scan import ScanConfig
|
|
13
13
|
from lanscape.ui.blueprints import scan_manager
|
|
14
14
|
|
|
15
15
|
# Subnet Scanner API
|
|
@@ -121,3 +121,4 @@ def get_scan_config():
|
|
|
121
121
|
"""
|
|
122
122
|
data = request.get_json()
|
|
123
123
|
return ScanConfig.from_dict(data)
|
|
124
|
+
|
|
@@ -5,10 +5,10 @@ API endpoints for subnet testing and listing.
|
|
|
5
5
|
import traceback
|
|
6
6
|
from flask import request, jsonify
|
|
7
7
|
from lanscape.ui.blueprints.api import api_bp
|
|
8
|
-
from lanscape.
|
|
9
|
-
from lanscape.
|
|
10
|
-
from lanscape.
|
|
11
|
-
from lanscape.
|
|
8
|
+
from lanscape.core.net_tools import get_all_network_subnets, is_arp_supported
|
|
9
|
+
from lanscape.core.ip_parser import parse_ip_input
|
|
10
|
+
from lanscape.core.errors import SubnetTooLargeError
|
|
11
|
+
from lanscape.core.scan_config import DEFAULT_CONFIGS
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@api_bp.route('/api/tools/subnet/test')
|
|
@@ -69,3 +69,4 @@ def get_default_configs():
|
|
|
69
69
|
configs[key] = config_dict
|
|
70
70
|
|
|
71
71
|
return jsonify(configs)
|
|
72
|
+
|
|
@@ -4,7 +4,7 @@ Handles UI views including the main dashboard, scan results, error display, and
|
|
|
4
4
|
"""
|
|
5
5
|
from flask import render_template, request, redirect, url_for
|
|
6
6
|
from lanscape.ui.blueprints.web import web_bp
|
|
7
|
-
from lanscape.
|
|
7
|
+
from lanscape.core.net_tools import (
|
|
8
8
|
get_all_network_subnets,
|
|
9
9
|
smart_select_primary_subnet
|
|
10
10
|
)
|
|
@@ -150,3 +150,4 @@ def app_info():
|
|
|
150
150
|
Rendered info template
|
|
151
151
|
"""
|
|
152
152
|
return render_template('info.html')
|
|
153
|
+
|
lanscape/ui/main.py
CHANGED
|
@@ -9,10 +9,10 @@ import traceback
|
|
|
9
9
|
import os
|
|
10
10
|
import requests
|
|
11
11
|
|
|
12
|
-
from lanscape.
|
|
13
|
-
from lanscape.
|
|
14
|
-
from lanscape.
|
|
15
|
-
from lanscape.
|
|
12
|
+
from lanscape.core.logger import configure_logging
|
|
13
|
+
from lanscape.core.runtime_args import parse_args
|
|
14
|
+
from lanscape.core.web_browser import open_webapp
|
|
15
|
+
from lanscape.core.version_manager import get_installed_version, is_update_available
|
|
16
16
|
from lanscape.ui.app import start_webserver_daemon, start_webserver
|
|
17
17
|
# do this so any logs generated on import are displayed
|
|
18
18
|
args = parse_args()
|
|
@@ -136,3 +136,4 @@ def terminate():
|
|
|
136
136
|
|
|
137
137
|
if __name__ == "__main__":
|
|
138
138
|
main()
|
|
139
|
+
|
lanscape/ui/shutdown_handler.py
CHANGED
|
@@ -5,7 +5,7 @@ import os
|
|
|
5
5
|
from flask import request
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
from lanscape.
|
|
8
|
+
from lanscape.core.runtime_args import parse_args
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
log = logging.getLogger('shutdown_handler')
|
|
@@ -55,3 +55,4 @@ class FlaskShutdownHandler:
|
|
|
55
55
|
"""Exits the application if a shutdown request has been made."""
|
|
56
56
|
if self._exiting:
|
|
57
57
|
os._exit(0)
|
|
58
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0a1
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,8 +8,13 @@ Project-URL: Homepage, https://github.com/mdennis281/py-lanscape
|
|
|
8
8
|
Project-URL: Issues, https://github.com/mdennis281/py-lanscape/issues
|
|
9
9
|
Keywords: network,scanner,lan,local,python
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
16
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
17
|
+
Requires-Python: >=3.10
|
|
13
18
|
Description-Content-Type: text/markdown
|
|
14
19
|
License-File: LICENSE
|
|
15
20
|
Requires-Dist: Flask<5.0,>=3.0
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
lanscape/__init__.py,sha256=
|
|
2
|
-
lanscape/__main__.py,sha256=
|
|
3
|
-
lanscape/
|
|
4
|
-
lanscape/
|
|
5
|
-
lanscape/
|
|
6
|
-
lanscape/
|
|
7
|
-
lanscape/
|
|
8
|
-
lanscape/
|
|
9
|
-
lanscape/
|
|
10
|
-
lanscape/
|
|
11
|
-
lanscape/
|
|
12
|
-
lanscape/
|
|
13
|
-
lanscape/
|
|
14
|
-
lanscape/
|
|
15
|
-
lanscape/
|
|
16
|
-
lanscape/
|
|
17
|
-
lanscape/
|
|
18
|
-
lanscape/
|
|
19
|
-
lanscape/resources/mac_addresses/convert_csv.py,sha256=
|
|
1
|
+
lanscape/__init__.py,sha256=XFRrhe1uiIw7WpYvnx-5wbBKR9P_wjWl5gNHrUtZP4w,424
|
|
2
|
+
lanscape/__main__.py,sha256=yJpYmbQpYmXgtya-cSZmgNKVSYnyT1lO463R6k-5IPw,171
|
|
3
|
+
lanscape/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
lanscape/core/app_scope.py,sha256=kiKDWjkIf8SYluTmPm5JYEWa4t47ax0XRFoR3kKNM_o,3299
|
|
5
|
+
lanscape/core/decorators.py,sha256=3sNGj-pKqYlY_yAlFNLuAXACwqdPGPdbsLEinNkUTVc,7265
|
|
6
|
+
lanscape/core/device_alive.py,sha256=o5MdqkrbA9UjJ4xMd0yNI_p7C5PrR6xdhrellF9azNQ,6837
|
|
7
|
+
lanscape/core/errors.py,sha256=TnifbydUzT2i_aMz9iU_A7vwdWmbYbOclgJDdHwnj-I,1323
|
|
8
|
+
lanscape/core/ip_parser.py,sha256=U7BqZWKpsmD43WUuephqkxIlMW4EdziRZ-WUdh3zEJA,4197
|
|
9
|
+
lanscape/core/logger.py,sha256=pdaCJ41pEMzA9PImFY0eJ_uRaMDRv0Eb87Wr9_5dN0A,2535
|
|
10
|
+
lanscape/core/mac_lookup.py,sha256=1y-WQ9CLvHTItu9kJrFja6iClLZ_ABYGRi_mFF1PQFY,3520
|
|
11
|
+
lanscape/core/net_tools.py,sha256=3dzo0OWMBX7eg3S_iAxUpixXy72kn0eNIbR9Phi8Sto,19677
|
|
12
|
+
lanscape/core/port_manager.py,sha256=dbeQEhVqKmI7CYPEgW1UFcCa7HxkyJwy8ms9Jajk-ss,4480
|
|
13
|
+
lanscape/core/runtime_args.py,sha256=BASAsIZgZwMi3GHO_oY3oeehVrywVAXUip-Bi51Ocjo,2544
|
|
14
|
+
lanscape/core/scan_config.py,sha256=lG093Gn-j6NIK9JVn7JPMxkkX-9P6fFWP_ghec6-dB0,11115
|
|
15
|
+
lanscape/core/service_scan.py,sha256=m3cI9cYUsP5s3rDYtpp7k2ZiqXddF3Akd_4zlgZVyrg,6949
|
|
16
|
+
lanscape/core/subnet_scan.py,sha256=2HHQH2RVdHdAOwnppKrGr0JHvgNSXTAt-Rheo7-KV1s,14445
|
|
17
|
+
lanscape/core/version_manager.py,sha256=dd7B89L--Zi-0-aqSngM1co6Le7SVePzUJ3GKN3-Ud0,2842
|
|
18
|
+
lanscape/core/web_browser.py,sha256=Uv8isfQk7iTiH5YtBd-aDO9kYQdBhnapA0hM0xM-NKo,6737
|
|
19
|
+
lanscape/resources/mac_addresses/convert_csv.py,sha256=NE2WLgFL4Rw-8zm2YGJ1ZnK19MUR9xwVv3Yg4vNcOVA,1190
|
|
20
20
|
lanscape/resources/mac_addresses/mac_db.json,sha256=Lng2yJerwO7vjefzxzgtE203hry1lIsCadHL1A5Rptg,2136137
|
|
21
|
-
lanscape/resources/ports/convert_csv.py,sha256=
|
|
21
|
+
lanscape/resources/ports/convert_csv.py,sha256=JG4kFZ_suoKL8WlkpGlkG0QEbNTEN9J0oBTsdxXB7hQ,1144
|
|
22
22
|
lanscape/resources/ports/full.json,sha256=O8XBW52QvEVSGMQDbXe4-c4qq6XAecw6KJW4m2HkTLo,1441444
|
|
23
23
|
lanscape/resources/ports/large.json,sha256=CzlCcIGCBW1QAgjz4NDerCYA8HcYf6lNxehh7F928y0,138410
|
|
24
24
|
lanscape/resources/ports/medium.json,sha256=T5Rc7wa47MtroHxuZrHSftOqRWbQzhZULJdE1vpsTvU,3518
|
|
25
25
|
lanscape/resources/ports/small.json,sha256=F_lo_5xHwHBfOVfVgxP7ejblR3R62SNtC1Mm33brhYc,376
|
|
26
26
|
lanscape/resources/services/definitions.jsonc,sha256=M9BDeK-mh25sEVj8xDEYbU2ix7EETVWhbiYmMb14Gjg,20905
|
|
27
27
|
lanscape/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
lanscape/ui/app.py,sha256=
|
|
29
|
-
lanscape/ui/main.py,sha256=
|
|
30
|
-
lanscape/ui/shutdown_handler.py,sha256=
|
|
31
|
-
lanscape/ui/blueprints/__init__.py,sha256=
|
|
32
|
-
lanscape/ui/blueprints/api/__init__.py,sha256=
|
|
33
|
-
lanscape/ui/blueprints/api/port.py,sha256=
|
|
34
|
-
lanscape/ui/blueprints/api/scan.py,sha256=
|
|
35
|
-
lanscape/ui/blueprints/api/tools.py,sha256=
|
|
36
|
-
lanscape/ui/blueprints/web/__init__.py,sha256=
|
|
37
|
-
lanscape/ui/blueprints/web/routes.py,sha256=
|
|
28
|
+
lanscape/ui/app.py,sha256=aAS21f8361oAcGKwvD1W5oLbTk7f9_H5EJEANBnvAHQ,3741
|
|
29
|
+
lanscape/ui/main.py,sha256=teeiGumDG--zU4fBF9nen9q65vhSl7CvIxzkibwSt1c,4177
|
|
30
|
+
lanscape/ui/shutdown_handler.py,sha256=4B5gEaRBucYZZvVKSF8Unq1hQhJDC2W3_W5JK7wyMUE,1706
|
|
31
|
+
lanscape/ui/blueprints/__init__.py,sha256=rEtm7ZT_K5Hd9UYFvsjP-cqmA01RBhKybjMhhUNVwCY,266
|
|
32
|
+
lanscape/ui/blueprints/api/__init__.py,sha256=9G0qtzcSmV2qjLNx4nedsUGU7rKkEGSuFAIbRIWWSyI,104
|
|
33
|
+
lanscape/ui/blueprints/api/port.py,sha256=2QLq03HOMz9y_7q41rah8kOOXF0oKCOczoUfJ3j-QFI,1977
|
|
34
|
+
lanscape/ui/blueprints/api/scan.py,sha256=_kg9qtshoUHTU8b9a2gzEfNWQsx8uixLNE3PO_o8uRA,3327
|
|
35
|
+
lanscape/ui/blueprints/api/tools.py,sha256=wrn3OG-SyUhgiHHovovwbhKIPI7db1iYOIXKnGx5DMY,2433
|
|
36
|
+
lanscape/ui/blueprints/web/__init__.py,sha256=_83Mu7yUAME-lEsK82U_WNEMyfZwQGc9M1LPSDOO4so,119
|
|
37
|
+
lanscape/ui/blueprints/web/routes.py,sha256=WmKFPgslMXoxfy9C6NQqKNvc6Lf1pWSOLbnYL2WqzaI,4535
|
|
38
38
|
lanscape/ui/static/lanscape.webmanifest,sha256=07CqA-PQsO35KJD8R96sI3Pxix6UuBjijPDCuy9vM3s,446
|
|
39
39
|
lanscape/ui/static/css/style.css,sha256=qXDshNhj77__06AuL-RhsxlrqZ5S0JFAmy3M1sk1Sm8,21098
|
|
40
40
|
lanscape/ui/static/img/ico/android-chrome-192x192.png,sha256=JmFT6KBCCuoyxMV-mLNtF9_QJbVBvfWPUizKN700fi8,18255
|
|
@@ -68,8 +68,9 @@ lanscape/ui/templates/scan/ip-table-row.html,sha256=nO5ZMhl3Gnlc8lg5nWmE05_6_5oz
|
|
|
68
68
|
lanscape/ui/templates/scan/ip-table.html,sha256=AT2ZvCPYdKl-XJiAkEAawPOVuQw-w0MXumGQTr3zyKM,926
|
|
69
69
|
lanscape/ui/templates/scan/overview.html,sha256=xWj9jWDPg2KcPLvS8fnSins23_UXjKCdb2NJwNG2U2Q,1176
|
|
70
70
|
lanscape/ui/templates/scan/scan-error.html,sha256=wmAYQ13IJHUoO8fAGNDjMvNml7tu4rsIU3Vav71ETlA,999
|
|
71
|
-
lanscape-
|
|
72
|
-
lanscape-
|
|
73
|
-
lanscape-
|
|
74
|
-
lanscape-
|
|
75
|
-
lanscape-
|
|
71
|
+
lanscape-2.0.0a1.dist-info/licenses/LICENSE,sha256=VLoE0IrNTIc09dFm7hMN0qzk4T3q8V0NaPcFQqMemDs,1070
|
|
72
|
+
lanscape-2.0.0a1.dist-info/METADATA,sha256=cV6SLhKrEqhVDFUHUalq11D09qVtp6fa7NkGi7ieJgw,3379
|
|
73
|
+
lanscape-2.0.0a1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
74
|
+
lanscape-2.0.0a1.dist-info/entry_points.txt,sha256=evxSxUikFa1OEd4e0Boky9sLH87HdgM0YqB_AbB2HYc,51
|
|
75
|
+
lanscape-2.0.0a1.dist-info/top_level.txt,sha256=E9D4sjPz_6H7c85Ycy_pOS2xuv1Wm-ilKhxEprln2ps,9
|
|
76
|
+
lanscape-2.0.0a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|