lanscape 1.3.0a6__tar.gz → 1.3.1a1__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.
Files changed (78) hide show
  1. {lanscape-1.3.0a6/src/lanscape.egg-info → lanscape-1.3.1a1}/PKG-INFO +12 -3
  2. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/README.md +10 -1
  3. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/pyproject.toml +2 -2
  4. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/net_tools.py +22 -9
  5. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/runtime_args.py +2 -0
  6. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/web_browser.py +14 -3
  7. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/tests/test_api.py +0 -1
  8. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/app.py +15 -4
  9. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/main.py +4 -4
  10. lanscape-1.3.1a1/src/lanscape/ui/static/js/on-tab-close.js +29 -0
  11. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/core/scripts.html +1 -0
  12. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/info.html +2 -2
  13. {lanscape-1.3.0a6 → lanscape-1.3.1a1/src/lanscape.egg-info}/PKG-INFO +12 -3
  14. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape.egg-info/SOURCES.txt +1 -0
  15. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape.egg-info/requires.txt +1 -1
  16. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/LICENSE +0 -0
  17. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/MANIFEST.in +0 -0
  18. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/setup.cfg +0 -0
  19. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/__init__.py +0 -0
  20. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/__main__.py +0 -0
  21. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/app_scope.py +0 -0
  22. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/decorators.py +0 -0
  23. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/errors.py +0 -0
  24. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/ip_parser.py +0 -0
  25. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/logger.py +0 -0
  26. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/mac_lookup.py +0 -0
  27. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/port_manager.py +0 -0
  28. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/service_scan.py +0 -0
  29. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/subnet_scan.py +0 -0
  30. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/libraries/version_manager.py +0 -0
  31. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/mac_addresses/convert_csv.py +0 -0
  32. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/mac_addresses/mac_db.json +0 -0
  33. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/ports/convert_csv.py +0 -0
  34. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/ports/full.json +0 -0
  35. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/ports/large.json +0 -0
  36. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/ports/medium.json +0 -0
  37. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/ports/small.json +0 -0
  38. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/resources/services/definitions.jsonc +0 -0
  39. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/tests/__init__.py +0 -0
  40. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/tests/_helpers.py +0 -0
  41. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/tests/test_env.py +0 -0
  42. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/tests/test_library.py +0 -0
  43. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/__init__.py +0 -0
  44. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/api/__init__.py +0 -0
  45. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/api/port.py +0 -0
  46. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/api/scan.py +0 -0
  47. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/api/tools.py +0 -0
  48. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/web/__init__.py +0 -0
  49. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/blueprints/web/routes.py +0 -0
  50. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/css/style.css +0 -0
  51. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/android-chrome-192x192.png +0 -0
  52. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/android-chrome-512x512.png +0 -0
  53. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/apple-touch-icon.png +0 -0
  54. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/favicon-16x16.png +0 -0
  55. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/favicon-32x32.png +0 -0
  56. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/favicon.ico +0 -0
  57. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/img/ico/site.webmanifest +0 -0
  58. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/core.js +0 -0
  59. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/layout-sizing.js +0 -0
  60. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/main.js +0 -0
  61. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/quietReload.js +0 -0
  62. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/shutdown-server.js +0 -0
  63. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/subnet-info.js +0 -0
  64. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/js/subnet-selector.js +0 -0
  65. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/static/lanscape.webmanifest +0 -0
  66. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/base.html +0 -0
  67. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/core/head.html +0 -0
  68. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/error.html +0 -0
  69. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/main.html +0 -0
  70. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan/export.html +0 -0
  71. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan/ip-table-row.html +0 -0
  72. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan/ip-table.html +0 -0
  73. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan/overview.html +0 -0
  74. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan/scan-error.html +0 -0
  75. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/scan.html +0 -0
  76. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape/ui/templates/shutdown.html +0 -0
  77. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape.egg-info/dependency_links.txt +0 -0
  78. {lanscape-1.3.0a6 → lanscape-1.3.1a1}/src/lanscape.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lanscape
3
- Version: 1.3.0a6
3
+ Version: 1.3.1a1
4
4
  Summary: A python based local network scanner
5
5
  Author-email: Michael Dennis <michael@dipduo.com>
6
6
  Project-URL: Homepage, https://github.com/mdennis281/py-lanscape
@@ -14,7 +14,7 @@ License-File: LICENSE
14
14
  Requires-Dist: Flask<5.0,>=3.0
15
15
  Requires-Dist: psutil<7.0,>=6.0
16
16
  Requires-Dist: requests<3.0,>=2.32
17
- Requires-Dist: Setuptools<81
17
+ Requires-Dist: setuptools
18
18
  Requires-Dist: scapy<3.0,>=2.3.2
19
19
  Requires-Dist: tabulate==0.9.0
20
20
  Requires-Dist: pytest
@@ -32,7 +32,8 @@ python -m lanscape
32
32
  ```
33
33
 
34
34
  ## Flags
35
- - `--port <port number>` port of the flask app (default: 5001)
35
+ - `--port <port number>` port of the flask app (default: automagic)
36
+ - `--persistent` dont shutdown server when browser tab is closed (default: false)
36
37
  - `--reloader` essentially flask debug mode- good for local development (default: false)
37
38
  - `--logfile` save log output to lanscape.log
38
39
  - `--loglevel <level>` set the logger's log level (default: INFO)
@@ -55,6 +56,14 @@ can sometimes require admin-level permissions to retrieve accurate results.
55
56
  ### Message "WARNING: No libpcap provider available ! pcap won't be used"
56
57
  This is a missing dependency related to the ARP lookup. This is handled in the code, but you would get marginally faster/better results with this installed: [npcap download](https://npcap.com/#download)
57
58
 
59
+ ### The accuracy of the devices found is low
60
+ I use a combination of ARP and Ping to determine if a device is online. This method drops in stability when used in many threads.
61
+ Recommendations:
62
+
63
+ - Drop parallelism value (advanced dropdown)
64
+ - Use python > 3.10 im noticing threadpool improvements after this version
65
+ - Create a bug - I'm curious
66
+
58
67
 
59
68
  ### Something else
60
69
  Feel free to submit a github issue detailing your experience.
@@ -10,7 +10,8 @@ python -m lanscape
10
10
  ```
11
11
 
12
12
  ## Flags
13
- - `--port <port number>` port of the flask app (default: 5001)
13
+ - `--port <port number>` port of the flask app (default: automagic)
14
+ - `--persistent` dont shutdown server when browser tab is closed (default: false)
14
15
  - `--reloader` essentially flask debug mode- good for local development (default: false)
15
16
  - `--logfile` save log output to lanscape.log
16
17
  - `--loglevel <level>` set the logger's log level (default: INFO)
@@ -33,6 +34,14 @@ can sometimes require admin-level permissions to retrieve accurate results.
33
34
  ### Message "WARNING: No libpcap provider available ! pcap won't be used"
34
35
  This is a missing dependency related to the ARP lookup. This is handled in the code, but you would get marginally faster/better results with this installed: [npcap download](https://npcap.com/#download)
35
36
 
37
+ ### The accuracy of the devices found is low
38
+ I use a combination of ARP and Ping to determine if a device is online. This method drops in stability when used in many threads.
39
+ Recommendations:
40
+
41
+ - Drop parallelism value (advanced dropdown)
42
+ - Use python > 3.10 im noticing threadpool improvements after this version
43
+ - Create a bug - I'm curious
44
+
36
45
 
37
46
  ### Something else
38
47
  Feel free to submit a github issue detailing your experience.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lanscape"
3
- version = "1.3.0a6"
3
+ version = "1.3.1a1"
4
4
  authors = [
5
5
  { name="Michael Dennis", email="michael@dipduo.com" },
6
6
  ]
@@ -16,7 +16,7 @@ dependencies = [
16
16
  "Flask>=3.0,<5.0",
17
17
  "psutil>=6.0,<7.0",
18
18
  "requests>=2.32,<3.0",
19
- "Setuptools<81",
19
+ "setuptools",
20
20
  "scapy>=2.3.2,<3.0",
21
21
  "tabulate==0.9.0",
22
22
  "pytest"
@@ -38,13 +38,19 @@ class IPAlive:
38
38
  for future in as_completed(futures):
39
39
  try:
40
40
  if future.result():
41
- # one check succeeded — dont block on the other
42
- executor.shutdown(wait=False, cancel_futures=True)
41
+ # one check succeeded — don't block on the other
42
+ # Cancel remaining futures in a version-compatible way
43
+ for f in futures:
44
+ if not f.done():
45
+ f.cancel()
46
+
47
+ executor.shutdown(wait=False) # Python 3.8 compatible
43
48
  return True
44
49
  except Exception as e:
45
50
  # treat any error as a False response
51
+ log.debug(f'Error while checking {ip}: {e}')
46
52
  self.caught_errors.append(DeviceError(e))
47
- pass
53
+
48
54
 
49
55
  # neither check found the host alive
50
56
  executor.shutdown()
@@ -341,17 +347,24 @@ def get_all_network_subnets():
341
347
 
342
348
  return subnets
343
349
 
344
- def smart_select_primary_subnet(subnets: List[dict]=get_all_network_subnets()) -> str:
350
+ def smart_select_primary_subnet(subnets: List[dict] | None = None) -> str:
345
351
  """
346
- Finds the largest subnet within max ip range
347
- not perfect, but works better than subnets[0]
352
+ Finds the largest subnet within max ip range. If no subnets are
353
+ available, returns an empty string instead of raising ``KeyError``.
348
354
  """
355
+ subnets = subnets or get_all_network_subnets()
356
+
357
+ if not subnets:
358
+ return ""
359
+
349
360
  selected = {}
350
361
  for subnet in subnets:
351
- if selected.get('address_cnt',0) < subnet['address_cnt'] < MAX_IPS_ALLOWED:
362
+ if selected.get("address_cnt", 0) < subnet["address_cnt"] < MAX_IPS_ALLOWED:
352
363
  selected = subnet
353
- if not selected and len(subnets):
364
+
365
+ if not selected:
354
366
  selected = subnets[0]
355
- return selected['subnet']
367
+
368
+ return selected.get("subnet", "")
356
369
 
357
370
 
@@ -10,6 +10,7 @@ class RuntimeArgs:
10
10
  logfile: bool = False
11
11
  loglevel: str = 'INFO'
12
12
  flask_logging: bool = False
13
+ persistent: bool = False
13
14
 
14
15
  def parse_args() -> RuntimeArgs:
15
16
  parser = argparse.ArgumentParser(description='LANscape')
@@ -19,6 +20,7 @@ def parse_args() -> RuntimeArgs:
19
20
  parser.add_argument('--logfile', action='store_true', help='Log output to lanscape.log')
20
21
  parser.add_argument('--loglevel', default='INFO', help='Set the log level')
21
22
  parser.add_argument('--flask-logging', action='store_true', help='Enable flask logging (disables click output)')
23
+ parser.add_argument('--persistent', action='store_true', help='Don\'t exit after browser is closed')
22
24
 
23
25
  # Parse the arguments
24
26
  args = parser.parse_args()
@@ -14,7 +14,7 @@ import webbrowser
14
14
  import logging
15
15
  import re
16
16
  import time
17
- import traceback
17
+ from typing import Optional
18
18
  from ..ui.app import app
19
19
 
20
20
  log = logging.getLogger('WebBrowser')
@@ -29,6 +29,13 @@ def open_webapp(url: str) -> bool:
29
29
  """
30
30
  start = time.time()
31
31
  try:
32
+ if sys.platform.startswith("darwin"):
33
+ # macOS does not support chrome-style app mode via the generic
34
+ # method. Fallback to the system "open" command which will use the
35
+ # default browser.
36
+ subprocess.run(["open", url], check=True)
37
+ return True
38
+
32
39
  exe = get_default_browser_executable()
33
40
  if not exe:
34
41
  raise RuntimeError('Unable to find browser binary')
@@ -56,7 +63,7 @@ def open_webapp(url: str) -> bool:
56
63
  return False
57
64
 
58
65
 
59
- def get_default_browser_executable() -> str | None:
66
+ def get_default_browser_executable() -> Optional[str]:
60
67
  if sys.platform.startswith("win"):
61
68
  try:
62
69
  import winreg
@@ -117,8 +124,12 @@ def get_default_browser_executable() -> str | None:
117
124
  # strip arguments like “%u”, “--flag”, etc.
118
125
  exec_cmd = exec_cmd.split()[0]
119
126
  exec_cmd = exec_cmd.split("%")[0]
120
- return exec_cmd
127
+ return exec_cmd
121
128
  return None
122
129
 
130
+ elif sys.platform.startswith("darwin"):
131
+ # macOS will use the system 'open' command to launch the default browser
132
+ return "/usr/bin/open"
133
+
123
134
  else:
124
135
  raise NotImplementedError(f"Unsupported platform: {sys.platform!r}")
@@ -90,7 +90,6 @@ class ApiTestCase(unittest.TestCase):
90
90
  ]
91
91
  for uri in uris:
92
92
  response = self.app.get(uri)
93
- print(uri, response.status_code)
94
93
  self.assertEqual(response.status_code,200)
95
94
 
96
95
 
@@ -1,4 +1,4 @@
1
- from flask import Flask, render_template
1
+ from flask import Flask, render_template, request
2
2
  from time import sleep
3
3
  import multiprocessing
4
4
  import traceback
@@ -62,11 +62,22 @@ set_global_safe('is_local',is_local_run)
62
62
  ################################
63
63
 
64
64
  exiting = False
65
- @app.route("/shutdown")
65
+ @app.route("/shutdown", methods=['GET', 'POST'])
66
66
  def exit_app():
67
+
68
+ req_type = request.args.get('type')
69
+ if req_type == 'browser-close':
70
+ args = parse_args()
71
+ if args.persistent:
72
+ log.info('Dectected browser close, not exiting flask.')
73
+ return "Ignored"
74
+ log.info('Web browser closed, terminating flask. (disable with --peristent)')
75
+ elif req_type == 'core':
76
+ log.info('Core requested exit, terminating flask.')
77
+ else:
78
+ log.info('Received external exit request. Terminating flask.')
67
79
  global exiting
68
80
  exiting = True
69
- log.info('Received external exit request. Terminating flask.')
70
81
  return "Done"
71
82
 
72
83
  @app.teardown_request
@@ -89,7 +100,7 @@ def internal_error(e):
89
100
  ## Webserver creation functions
90
101
  ################################
91
102
 
92
- def start_webserver_dameon(args: RuntimeArgs) -> threading.Thread:
103
+ def start_webserver_daemon(args: RuntimeArgs) -> threading.Thread:
93
104
  proc = threading.Thread(target=start_webserver, args=(args,))
94
105
  proc.daemon = True # Kill thread when main thread exits
95
106
  proc.start()
@@ -12,7 +12,7 @@ args = parse_args()
12
12
  configure_logging(args.loglevel, args.logfile, args.flask_logging)
13
13
 
14
14
  from ..libraries.version_manager import get_installed_version, is_update_available
15
- from .app import start_webserver_dameon, start_webserver
15
+ from .app import start_webserver_daemon, start_webserver
16
16
  import socket
17
17
 
18
18
 
@@ -100,13 +100,13 @@ def start_webserver_ui(args: RuntimeArgs):
100
100
  ).start()
101
101
  start_webserver(args)
102
102
  else:
103
- flask_thread = start_webserver_dameon(args)
103
+ flask_thread = start_webserver_daemon(args)
104
104
  app_closed = open_browser(uri)
105
105
 
106
106
  # depending on env, open_browser may or
107
107
  # may not be coupled with the closure of UI
108
108
  # (if in browser tab, it's uncoupled)
109
- if not app_closed:
109
+ if not app_closed or args.persistent:
110
110
  # not doing a direct join so i can still
111
111
  # terminate the app with ctrl+c
112
112
  while flask_thread.is_alive():
@@ -126,7 +126,7 @@ def get_valid_port(port: int):
126
126
  def terminate():
127
127
  import requests
128
128
  log.info('Attempting flask shutdown')
129
- requests.get(f'http://127.0.0.1:{args.port}/shutdown')
129
+ requests.get(f'http://127.0.0.1:{args.port}/shutdown?type=core')
130
130
 
131
131
 
132
132
 
@@ -0,0 +1,29 @@
1
+ // This is the payload you want to send on unload.
2
+ // It can be as simple as JSON or just an empty POST.
3
+ function sendOnUnload() {
4
+ const url = '/shutdown?type=browser-close';
5
+ const data = JSON.stringify({ });
6
+ // (1) Using navigator.sendBeacon
7
+ if (navigator.sendBeacon) {
8
+ const blob = new Blob([data], { type: 'application/json' });
9
+ navigator.sendBeacon(url, blob);
10
+ }
11
+ // (2) Or—you can use fetch with keepalive (supported in modern browsers)
12
+ else {
13
+ fetch(url, {
14
+ method: 'POST',
15
+ body: data,
16
+ headers: { 'Content-Type': 'application/json' },
17
+ keepalive: true
18
+ })
19
+ .catch((err) => {
20
+ // If it fails, there’s not much you can do here.
21
+ console.warn('sendOnUnload fetch failed:', err);
22
+ });
23
+ }
24
+ }
25
+
26
+ // Attach to both beforeunload and unload to increase reliability.
27
+ // beforeunload fires slightly earlier, but some browsers block async work there.
28
+ window.addEventListener('beforeunload', sendOnUnload);
29
+ window.addEventListener('unload', sendOnUnload);
@@ -3,3 +3,4 @@
3
3
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
4
4
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
5
5
  <script src="{{ url_for('static', filename='js/core.js') }}"></script>
6
+ <script src="{{ url_for('static', filename='js/on-tab-close.js') }}"></script>
@@ -33,8 +33,8 @@
33
33
  This project has been a learning journey, & I hope it helps you
34
34
  discover more about your network as well. Enjoy!
35
35
  </p>
36
- <a href="https://github.com/mdennis281/" target="_blank"></a>
37
- <button class="btn btn-primary m-2">Github</button>
36
+ <a href="https://github.com/mdennis281/" target="_blank">
37
+ <button class="btn btn-primary m-2">GitHub</button>
38
38
  </a>
39
39
  <a href="https://github.com/mdennis281/LANscape" target="_blank">
40
40
  <button class="btn btn-secondary m-2">Project Repo</button>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lanscape
3
- Version: 1.3.0a6
3
+ Version: 1.3.1a1
4
4
  Summary: A python based local network scanner
5
5
  Author-email: Michael Dennis <michael@dipduo.com>
6
6
  Project-URL: Homepage, https://github.com/mdennis281/py-lanscape
@@ -14,7 +14,7 @@ License-File: LICENSE
14
14
  Requires-Dist: Flask<5.0,>=3.0
15
15
  Requires-Dist: psutil<7.0,>=6.0
16
16
  Requires-Dist: requests<3.0,>=2.32
17
- Requires-Dist: Setuptools<81
17
+ Requires-Dist: setuptools
18
18
  Requires-Dist: scapy<3.0,>=2.3.2
19
19
  Requires-Dist: tabulate==0.9.0
20
20
  Requires-Dist: pytest
@@ -32,7 +32,8 @@ python -m lanscape
32
32
  ```
33
33
 
34
34
  ## Flags
35
- - `--port <port number>` port of the flask app (default: 5001)
35
+ - `--port <port number>` port of the flask app (default: automagic)
36
+ - `--persistent` dont shutdown server when browser tab is closed (default: false)
36
37
  - `--reloader` essentially flask debug mode- good for local development (default: false)
37
38
  - `--logfile` save log output to lanscape.log
38
39
  - `--loglevel <level>` set the logger's log level (default: INFO)
@@ -55,6 +56,14 @@ can sometimes require admin-level permissions to retrieve accurate results.
55
56
  ### Message "WARNING: No libpcap provider available ! pcap won't be used"
56
57
  This is a missing dependency related to the ARP lookup. This is handled in the code, but you would get marginally faster/better results with this installed: [npcap download](https://npcap.com/#download)
57
58
 
59
+ ### The accuracy of the devices found is low
60
+ I use a combination of ARP and Ping to determine if a device is online. This method drops in stability when used in many threads.
61
+ Recommendations:
62
+
63
+ - Drop parallelism value (advanced dropdown)
64
+ - Use python > 3.10 im noticing threadpool improvements after this version
65
+ - Create a bug - I'm curious
66
+
58
67
 
59
68
  ### Something else
60
69
  Feel free to submit a github issue detailing your experience.
@@ -56,6 +56,7 @@ src/lanscape/ui/static/img/ico/site.webmanifest
56
56
  src/lanscape/ui/static/js/core.js
57
57
  src/lanscape/ui/static/js/layout-sizing.js
58
58
  src/lanscape/ui/static/js/main.js
59
+ src/lanscape/ui/static/js/on-tab-close.js
59
60
  src/lanscape/ui/static/js/quietReload.js
60
61
  src/lanscape/ui/static/js/shutdown-server.js
61
62
  src/lanscape/ui/static/js/subnet-info.js
@@ -1,7 +1,7 @@
1
1
  Flask<5.0,>=3.0
2
2
  psutil<7.0,>=6.0
3
3
  requests<3.0,>=2.32
4
- Setuptools<81
4
+ setuptools
5
5
  scapy<3.0,>=2.3.2
6
6
  tabulate==0.9.0
7
7
  pytest
File without changes
File without changes
File without changes