lanscape 2.0.0a1__tar.gz → 2.0.0b1__tar.gz

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 lanscape might be problematic. Click here for more details.

Files changed (99) hide show
  1. {lanscape-2.0.0a1/lanscape.egg-info → lanscape-2.0.0b1}/PKG-INFO +5 -2
  2. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/README.md +1 -1
  3. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/__init__.py +0 -1
  4. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/__main__.py +0 -1
  5. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/app_scope.py +0 -1
  6. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/decorators.py +0 -1
  7. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/device_alive.py +1 -2
  8. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/errors.py +0 -1
  9. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/ip_parser.py +1 -26
  10. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/logger.py +0 -1
  11. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/mac_lookup.py +0 -1
  12. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/net_tools.py +0 -1
  13. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/port_manager.py +0 -1
  14. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/runtime_args.py +0 -1
  15. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/scan_config.py +0 -1
  16. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/service_scan.py +3 -21
  17. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/subnet_scan.py +0 -1
  18. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/version_manager.py +0 -1
  19. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/web_browser.py +0 -1
  20. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/mac_addresses/convert_csv.py +0 -1
  21. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/convert_csv.py +0 -1
  22. lanscape-2.0.0b1/lanscape/resources/ports/test_port_list_scan.json +4 -0
  23. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/app.py +13 -2
  24. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/__init__.py +0 -1
  25. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/__init__.py +0 -1
  26. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/port.py +0 -1
  27. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/scan.py +0 -1
  28. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/tools.py +0 -1
  29. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/web/__init__.py +0 -1
  30. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/web/routes.py +0 -1
  31. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/main.py +0 -1
  32. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/shutdown_handler.py +0 -1
  33. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/config.html +1 -1
  34. {lanscape-2.0.0a1 → lanscape-2.0.0b1/lanscape.egg-info}/PKG-INFO +5 -2
  35. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/SOURCES.txt +1 -0
  36. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/requires.txt +4 -0
  37. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/pyproject.toml +7 -1
  38. lanscape-2.0.0b1/tests/test_api.py +281 -0
  39. lanscape-2.0.0b1/tests/test_decorators.py +333 -0
  40. lanscape-2.0.0b1/tests/test_env.py +147 -0
  41. lanscape-2.0.0b1/tests/test_library.py +108 -0
  42. lanscape-2.0.0b1/tests/test_logging.py +102 -0
  43. lanscape-2.0.0b1/tests/test_port_scan.py +277 -0
  44. lanscape-2.0.0b1/tests/test_service_scan.py +270 -0
  45. lanscape-2.0.0b1/tests/test_utils.py +160 -0
  46. lanscape-2.0.0a1/tests/test_api.py +0 -244
  47. lanscape-2.0.0a1/tests/test_decorators.py +0 -283
  48. lanscape-2.0.0a1/tests/test_env.py +0 -46
  49. lanscape-2.0.0a1/tests/test_library.py +0 -105
  50. lanscape-2.0.0a1/tests/test_logging.py +0 -79
  51. lanscape-2.0.0a1/tests/test_port_scan.py +0 -251
  52. lanscape-2.0.0a1/tests/test_service_scan.py +0 -253
  53. lanscape-2.0.0a1/tests/test_utils.py +0 -110
  54. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/LICENSE +0 -0
  55. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/MANIFEST.in +0 -0
  56. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/__init__.py +0 -0
  57. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/mac_addresses/mac_db.json +0 -0
  58. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/full.json +0 -0
  59. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/large.json +0 -0
  60. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/medium.json +0 -0
  61. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/small.json +0 -0
  62. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/services/definitions.jsonc +0 -0
  63. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/__init__.py +0 -0
  64. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/css/style.css +0 -0
  65. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/android-chrome-192x192.png +0 -0
  66. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/android-chrome-512x512.png +0 -0
  67. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/apple-touch-icon.png +0 -0
  68. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon-16x16.png +0 -0
  69. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon-32x32.png +0 -0
  70. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon.ico +0 -0
  71. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/site.webmanifest +0 -0
  72. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/core.js +0 -0
  73. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/layout-sizing.js +0 -0
  74. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/main.js +0 -0
  75. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/on-tab-close.js +0 -0
  76. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/quietReload.js +0 -0
  77. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/scan-config.js +0 -0
  78. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/shutdown-server.js +0 -0
  79. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/subnet-info.js +0 -0
  80. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/subnet-selector.js +0 -0
  81. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/lanscape.webmanifest +0 -0
  82. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/base.html +0 -0
  83. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/core/head.html +0 -0
  84. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/core/scripts.html +0 -0
  85. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/error.html +0 -0
  86. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/info.html +0 -0
  87. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/main.html +0 -0
  88. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/device-detail.html +0 -0
  89. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/export.html +0 -0
  90. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/ip-table-row.html +0 -0
  91. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/ip-table.html +0 -0
  92. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/overview.html +0 -0
  93. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/scan-error.html +0 -0
  94. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan.html +0 -0
  95. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/shutdown.html +0 -0
  96. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/dependency_links.txt +0 -0
  97. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/entry_points.txt +0 -0
  98. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/top_level.txt +0 -0
  99. {lanscape-2.0.0a1 → lanscape-2.0.0b1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lanscape
3
- Version: 2.0.0a1
3
+ Version: 2.0.0b1
4
4
  Summary: A python based local network scanner
5
5
  Author-email: Michael Dennis <michael@dipduo.com>
6
6
  License-Expression: MIT
@@ -25,6 +25,9 @@ Requires-Dist: scapy<3.0,>=2.3.2
25
25
  Requires-Dist: tabulate==0.9.0
26
26
  Requires-Dist: pydantic
27
27
  Requires-Dist: icmplib
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
28
31
  Dynamic: license-file
29
32
 
30
33
  # LANscape
@@ -85,7 +88,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
85
88
  Recommendations:
86
89
 
87
90
  - Adjust scan configuration
88
- - Configure ARP lookup [ARP lookup setup](./support/arp-issues.md)
91
+ - Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
89
92
  - Create a bug
90
93
 
91
94
 
@@ -56,7 +56,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
56
56
  Recommendations:
57
57
 
58
58
  - Adjust scan configuration
59
- - Configure ARP lookup [ARP lookup setup](./support/arp-issues.md)
59
+ - Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
60
60
  - Create a bug
61
61
 
62
62
 
@@ -22,4 +22,3 @@ from lanscape.core.scan_config import (
22
22
  from lanscape.core.port_manager import PortManager
23
23
 
24
24
  from lanscape.core import net_tools
25
-
@@ -7,4 +7,3 @@ from lanscape.ui.main import main
7
7
 
8
8
  if __name__ == "__main__":
9
9
  main()
10
-
@@ -90,4 +90,3 @@ def is_local_run() -> bool:
90
90
  if any(parts):
91
91
  return False
92
92
  return True # Installed package
93
-
@@ -229,4 +229,3 @@ def timeout_enforcer(timeout: int, raise_on_timeout: bool = True):
229
229
  return None # Return None if not raising an exception
230
230
  return wrapper
231
231
  return decorator
232
-
@@ -156,7 +156,7 @@ class ArpLookup():
156
156
  NOTE: This lookup method requires elevated privileges to access the ARP cache.
157
157
 
158
158
 
159
- [Arp Lookup Requirements](/support/arp-issues.md)
159
+ [Arp Lookup Requirements](/docs/arp-issues.md)
160
160
  """
161
161
 
162
162
  @classmethod
@@ -227,4 +227,3 @@ class Poker():
227
227
  sock.close()
228
228
 
229
229
  do_poke()
230
-
@@ -40,4 +40,3 @@ class DeviceError(Exception):
40
40
 
41
41
  def __str__(self):
42
42
  return f'Error(source={self.method}, msg={self.base})'
43
-
@@ -10,7 +10,6 @@ This module provides utilities for parsing various IP address formats including:
10
10
  It also includes validation to prevent processing excessively large IP ranges.
11
11
  """
12
12
  import ipaddress
13
- import re
14
13
 
15
14
  from lanscape.core.errors import SubnetTooLargeError
16
15
 
@@ -50,14 +49,10 @@ def parse_ip_input(ip_input):
50
49
  for ip in net.hosts():
51
50
  ip_ranges.append(ip)
52
51
 
53
- # Handle IP range (e.g., 10.0.0.15-10.0.0.25)
52
+ # Handle IP range (e.g., 10.0.0.15-10.0.0.25) and (e.g., 10.0.9.1-253)
54
53
  elif '-' in entry:
55
54
  ip_ranges += parse_ip_range(entry)
56
55
 
57
- # Handle shorthand IP range (e.g., 10.0.9.1-253)
58
- elif re.search(r'\d+\-\d+', entry):
59
- ip_ranges += parse_shorthand_ip_range(entry)
60
-
61
56
  # If no CIDR or range, assume a single IP
62
57
  else:
63
58
  ip_ranges.append(ipaddress.IPv4Address(entry))
@@ -106,25 +101,6 @@ def parse_ip_range(entry):
106
101
  return list(ip_range_to_list(start_ip, end_ip))
107
102
 
108
103
 
109
- def parse_shorthand_ip_range(entry):
110
- """
111
- Parse a shorthand IP range (e.g., 192.168.1.1-10).
112
-
113
- In this format, only the last octet of the end IP is specified.
114
-
115
- Args:
116
- entry (str): String containing a shorthand IP range
117
-
118
- Returns:
119
- list: List of IPv4Address objects in the range (inclusive)
120
- """
121
- start_ip, end_part = entry.split('-')
122
- start_ip = ipaddress.IPv4Address(start_ip.strip())
123
- end_ip = start_ip.exploded.rsplit('.', 1)[0] + '.' + end_part.strip()
124
-
125
- return list(ip_range_to_list(start_ip, ipaddress.IPv4Address(end_ip)))
126
-
127
-
128
104
  def ip_range_to_list(start_ip, end_ip):
129
105
  """
130
106
  Convert an IP range defined by start and end addresses to a list of addresses.
@@ -139,4 +115,3 @@ def ip_range_to_list(start_ip, end_ip):
139
115
  # Yield the range of IPs
140
116
  for ip_int in range(int(start_ip), int(end_ip) + 1):
141
117
  yield ipaddress.IPv4Address(ip_int)
142
-
@@ -72,4 +72,3 @@ def disable_flask_logging() -> None:
72
72
  werkzeug_log.setLevel(logging.ERROR)
73
73
 
74
74
  override_click_logging()
75
-
@@ -105,4 +105,3 @@ def lookup_mac(mac: str) -> Optional[str]:
105
105
  def get_macs(ip: str) -> List[str]:
106
106
  """Backward compatibility function for MAC resolution."""
107
107
  return MacResolver().get_macs(ip)
108
-
@@ -566,4 +566,3 @@ def is_arp_supported():
566
566
  return True
567
567
  except (Scapy_Exception, PermissionError, RuntimeError):
568
568
  return False
569
-
@@ -148,4 +148,3 @@ class PortManager:
148
148
  return True
149
149
  except BaseException:
150
150
  return False
151
-
@@ -63,4 +63,3 @@ def parse_args() -> RuntimeArgs:
63
63
 
64
64
  # Return the dataclass instance with the dynamically assigned values
65
65
  return RuntimeArgs(**filtered_args)
66
-
@@ -395,4 +395,3 @@ DEFAULT_CONFIGS: Dict[str, ScanConfig] = {
395
395
  )
396
396
  )
397
397
  }
398
-
@@ -2,7 +2,6 @@
2
2
  """
3
3
 
4
4
  from typing import Optional, Union
5
- import sys
6
5
  import asyncio
7
6
  import logging
8
7
  import traceback
@@ -10,6 +9,9 @@ import traceback
10
9
  from lanscape.core.app_scope import ResourceManager
11
10
  from lanscape.core.scan_config import ServiceScanConfig, ServiceScanStrategy
12
11
 
12
+ # asyncio complains more than it needs to
13
+ logging.getLogger("asyncio").setLevel(logging.WARNING)
14
+
13
15
  log = logging.getLogger('ServiceScan')
14
16
  SERVICES = ResourceManager('services').get_jsonc('definitions.jsonc')
15
17
 
@@ -183,23 +185,3 @@ def scan_service(ip: str, port: int, cfg: ServiceScanConfig) -> str:
183
185
 
184
186
  # Use asyncio.run to execute the asynchronous logic synchronously
185
187
  return asyncio.run(_async_scan_service(ip, port, cfg=cfg))
186
-
187
-
188
- def asyncio_logger_suppression():
189
- """Suppress the noisy asyncio transport errors since they are expected in service scanning."""
190
-
191
- # Reduce noisy asyncio transport errors on Windows by switching to Selector policy
192
- if sys.platform.startswith("win"):
193
- try:
194
- asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
195
- except Exception:
196
- pass
197
- # Also tone down asyncio logger noise from transport callbacks
198
- try:
199
- logging.getLogger("asyncio").setLevel(logging.WARNING)
200
- except Exception:
201
- pass
202
-
203
-
204
- asyncio_logger_suppression()
205
-
@@ -428,4 +428,3 @@ class ScanManager:
428
428
  t = threading.Thread(target=scan.start)
429
429
  t.start()
430
430
  return t
431
-
@@ -95,4 +95,3 @@ 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
-
@@ -208,4 +208,3 @@ def windows_get_browser_from_registry() -> Optional[str]:
208
208
  system_browser = get_system_default_browser()
209
209
  if system_browser:
210
210
  return extract_executable(system_browser)
211
-
@@ -38,4 +38,3 @@ def csv_to_dict(data):
38
38
 
39
39
 
40
40
  main()
41
-
@@ -0,0 +1,4 @@
1
+ {
2
+ "443": "https",
3
+ "80": "http"
4
+ }
@@ -51,6 +51,18 @@ app.jinja_env.filters['is_substring_in_values'] = is_substring_in_values
51
51
  ################################
52
52
 
53
53
 
54
+ def get_runtime_args_safe():
55
+ """
56
+ Safely get runtime args, returning empty dict if parsing fails.
57
+ This prevents conflicts when the module is imported during testing.
58
+ """
59
+ try:
60
+ return vars(parse_args())
61
+ except SystemExit:
62
+ # This happens when pytest tries to import the module
63
+ return {}
64
+
65
+
54
66
  def set_global_safe(key: str, value):
55
67
  """ Safely set global vars without worrying about an exception """
56
68
  app_globals = app.jinja_env.globals
@@ -73,7 +85,7 @@ def set_global_safe(key: str, value):
73
85
  set_global_safe('app_version', get_installed_version)
74
86
  set_global_safe('update_available', is_update_available)
75
87
  set_global_safe('latest_version', lookup_latest_version)
76
- set_global_safe('runtime_args', vars(parse_args()))
88
+ set_global_safe('runtime_args', get_runtime_args_safe)
77
89
  set_global_safe('is_local', is_local_run)
78
90
  set_global_safe('is_arp_supported', is_arp_supported)
79
91
 
@@ -122,4 +134,3 @@ def start_webserver(args: RuntimeArgs) -> int:
122
134
  'use_reloader': args.reloader
123
135
  }
124
136
  app.run(**run_args)
125
-
@@ -8,4 +8,3 @@ from lanscape.core.subnet_scan import ScanManager
8
8
  scan_manager = ScanManager()
9
9
 
10
10
  log = logging.getLogger('Blueprints')
11
-
@@ -3,4 +3,3 @@
3
3
  from flask import Blueprint
4
4
 
5
5
  api_bp = Blueprint('api', __name__)
6
-
@@ -77,4 +77,3 @@ 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
-
@@ -121,4 +121,3 @@ def get_scan_config():
121
121
  """
122
122
  data = request.get_json()
123
123
  return ScanConfig.from_dict(data)
124
-
@@ -69,4 +69,3 @@ def get_default_configs():
69
69
  configs[key] = config_dict
70
70
 
71
71
  return jsonify(configs)
72
-
@@ -5,4 +5,3 @@ Blueprint for web-related routes and views.
5
5
  from flask import Blueprint
6
6
 
7
7
  web_bp = Blueprint('web', __name__)
8
-
@@ -150,4 +150,3 @@ def app_info():
150
150
  Rendered info template
151
151
  """
152
152
  return render_template('info.html')
153
-
@@ -136,4 +136,3 @@ def terminate():
136
136
 
137
137
  if __name__ == "__main__":
138
138
  main()
139
-
@@ -55,4 +55,3 @@ 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
-
@@ -56,7 +56,7 @@
56
56
  data-bs-toggle="tooltip"
57
57
  data-bs-placement="top"
58
58
  title="ARP lookup is not supported on this system, click for more info"
59
- onclick="window.open('https://github.com/mdennis281/LANscape/blob/main/support/arp-issues.md', '_blank')"
59
+ onclick="window.open('https://github.com/mdennis281/LANscape/blob/main/docs/arp-issues.md', '_blank')"
60
60
  >
61
61
  help
62
62
  </span>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lanscape
3
- Version: 2.0.0a1
3
+ Version: 2.0.0b1
4
4
  Summary: A python based local network scanner
5
5
  Author-email: Michael Dennis <michael@dipduo.com>
6
6
  License-Expression: MIT
@@ -25,6 +25,9 @@ Requires-Dist: scapy<3.0,>=2.3.2
25
25
  Requires-Dist: tabulate==0.9.0
26
26
  Requires-Dist: pydantic
27
27
  Requires-Dist: icmplib
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
28
31
  Dynamic: license-file
29
32
 
30
33
  # LANscape
@@ -85,7 +88,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
85
88
  Recommendations:
86
89
 
87
90
  - Adjust scan configuration
88
- - Configure ARP lookup [ARP lookup setup](./support/arp-issues.md)
91
+ - Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
89
92
  - Create a bug
90
93
 
91
94
 
@@ -33,6 +33,7 @@ lanscape/resources/ports/full.json
33
33
  lanscape/resources/ports/large.json
34
34
  lanscape/resources/ports/medium.json
35
35
  lanscape/resources/ports/small.json
36
+ lanscape/resources/ports/test_port_list_scan.json
36
37
  lanscape/resources/services/definitions.jsonc
37
38
  lanscape/ui/__init__.py
38
39
  lanscape/ui/app.py
@@ -6,3 +6,7 @@ scapy<3.0,>=2.3.2
6
6
  tabulate==0.9.0
7
7
  pydantic
8
8
  icmplib
9
+
10
+ [dev]
11
+ pytest>=8.0
12
+ pytest-cov>=5.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lanscape"
3
- version = "2.0.0a1"
3
+ version = "2.0.0b1"
4
4
  authors = [
5
5
  { name="Michael Dennis", email="michael@dipduo.com" },
6
6
  ]
@@ -29,6 +29,12 @@ dependencies = [
29
29
  "pydantic",
30
30
  "icmplib"
31
31
  ]
32
+
33
+ [project.optional-dependencies]
34
+ dev = [
35
+ "pytest>=8.0",
36
+ "pytest-cov>=5.0"
37
+ ]
32
38
  [project.urls]
33
39
  Homepage = "https://github.com/mdennis281/py-lanscape"
34
40
  Issues = "https://github.com/mdennis281/py-lanscape/issues"