sharkit 0.2.1.dev2__tar.gz → 0.2.1.dev4__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 (35) hide show
  1. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/PKG-INFO +1 -1
  2. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/pyproject.toml +1 -1
  3. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/commands/builtins.py +91 -21
  4. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/output/renderer.py +4 -1
  5. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/manager.py +12 -1
  6. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/osint/recon/hybrid/blackbird.py +1 -1
  7. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/.gitignore +0 -0
  8. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/LICENSE +0 -0
  9. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/README.md +0 -0
  10. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/__init__.py +0 -0
  11. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/__main__.py +0 -0
  12. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/app.py +0 -0
  13. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/commands/__init__.py +0 -0
  14. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/commands/base.py +0 -0
  15. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/commands/registry.py +0 -0
  16. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/config/__init__.py +0 -0
  17. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/config/manager.py +0 -0
  18. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/config/paths.py +0 -0
  19. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/console/__init__.py +0 -0
  20. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/console/completion.py +0 -0
  21. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/console/prompt.py +0 -0
  22. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/console/repl.py +0 -0
  23. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/exceptions.py +0 -0
  24. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/history/__init__.py +0 -0
  25. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/history/manager.py +0 -0
  26. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/network/__init__.py +0 -0
  27. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/network/client.py +0 -0
  28. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/output/__init__.py +0 -0
  29. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/output/theme.py +0 -0
  30. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/__init__.py +0 -0
  31. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/base.py +0 -0
  32. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/loader.py +0 -0
  33. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/osint/recon/username/maigret.py +0 -0
  34. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/osint/recon/username/sherlock.py +0 -0
  35. {sharkit-0.2.1.dev2 → sharkit-0.2.1.dev4}/src/sharkit/tools/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sharkit
3
- Version: 0.2.1.dev2
3
+ Version: 0.2.1.dev4
4
4
  Summary: OSINT / HUMINT / GEOINT research framework
5
5
  Project-URL: Homepage, https://github.com/sshsrv/sharkit
6
6
  Project-URL: Repository, https://github.com/sshsrv/sharkit
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sharkit"
3
- version = "0.2.1.dev2"
3
+ version = "0.2.1.dev4"
4
4
  description = "OSINT / HUMINT / GEOINT research framework"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -193,10 +193,16 @@ class UseCommand(Command):
193
193
  self._log(context, f'Tool "{name}" is not installed. Run: install {name}')
194
194
  return None
195
195
  renderer = context.session.get("renderer")
196
+ first_progress = [True]
196
197
 
197
198
  def on_progress(msg: str) -> None:
198
199
  if renderer is not None:
199
- renderer.log_line(f"install {display}", msg, color=GREEN)
200
+ tag = f"install {display}"
201
+ if first_progress[0]:
202
+ renderer.gutter(tag, msg, GREEN, is_first=True)
203
+ first_progress[0] = False
204
+ else:
205
+ renderer.gutter(tag, msg, GREEN, is_first=False)
200
206
 
201
207
  ok, message = tool_manager.install(name, spec, on_progress=on_progress)
202
208
  if not ok:
@@ -633,24 +639,45 @@ class InstallCommand(Command):
633
639
  tool_cls = tool_registry.get_tool(name)
634
640
  if tool_cls is None or tool_cls.metadata.install is None:
635
641
  return f'Tool "{name}" is not an external tool or was not found.'
636
- display = tool_registry.format_display(tool_registry.get_tool_path(name))
637
- if tool_manager.is_installed(name):
642
+ tool_name = tool_cls.metadata.name
643
+ display = tool_registry.format_display(tool_registry.get_tool_path(tool_name))
644
+ if tool_manager.is_installed(tool_name):
638
645
  renderer = context.session.get("renderer")
639
646
  if renderer is not None:
640
647
  renderer.log_line(f"install {display}", "already installed", color=GREEN)
641
648
  return None
642
649
  renderer = context.session.get("renderer")
650
+ first_progress = [True]
643
651
 
644
652
  def on_progress(msg: str) -> None:
645
653
  if renderer is not None:
646
- renderer.log_line(f"install {display}", msg, color=GREEN)
654
+ tag = f"install {display}"
655
+ if first_progress[0]:
656
+ renderer.gutter(tag, msg, GREEN, is_first=True)
657
+ first_progress[0] = False
658
+ else:
659
+ renderer.gutter(tag, msg, GREEN, is_first=False)
647
660
 
648
- ok, message = tool_manager.install(name, tool_cls.metadata.install, on_progress=on_progress)
661
+ install_spec = tool_cls.metadata.install
662
+ ok, message = tool_manager.install(
663
+ tool_name, install_spec, on_progress=on_progress
664
+ )
649
665
  if renderer is not None:
666
+ tag = f"install {display}"
650
667
  if ok:
651
- renderer.log_line(f"install {display}", "installed", color=GREEN)
668
+ msg = "installed"
669
+ elif message == "Aborted":
670
+ msg = "aborted"
671
+ print("\r\033[K", end="")
672
+ else:
673
+ msg = f"failed: {message}"
674
+ if first_progress[0]:
675
+ renderer.log_line(tag, msg, color=GREEN)
652
676
  else:
653
- renderer.log_line(f"install {display}", f"failed: {message}", color=GREEN)
677
+ lines = msg.splitlines() or [""]
678
+ renderer.gutter(tag, lines[0], GREEN, is_first=False)
679
+ for line in lines[1:]:
680
+ print(f"{GREEN}{BOLD}│{RESET} {line}")
654
681
  return None
655
682
  return str(message)
656
683
 
@@ -677,24 +704,45 @@ class UpgradeCommand(Command):
677
704
  tool_cls = tool_registry.get_tool(name)
678
705
  if tool_cls is None or tool_cls.metadata.install is None:
679
706
  return f'Tool "{name}" is not an external tool or was not found.'
680
- display = tool_registry.format_display(tool_registry.get_tool_path(name))
681
- if not tool_manager.is_installed(name):
707
+ tool_name = tool_cls.metadata.name
708
+ display = tool_registry.format_display(tool_registry.get_tool_path(tool_name))
709
+ if not tool_manager.is_installed(tool_name):
682
710
  renderer = context.session.get("renderer")
683
711
  if renderer is not None:
684
712
  renderer.log_line(f"upgrade {display}", "not installed (skipped)", color=BLUE)
685
713
  return None
686
714
  renderer = context.session.get("renderer")
715
+ first_progress = [True]
687
716
 
688
717
  def on_progress(msg: str) -> None:
689
718
  if renderer is not None:
690
- renderer.log_line(f"upgrade {display}", msg, color=BLUE)
719
+ tag = f"upgrade {display}"
720
+ if first_progress[0]:
721
+ renderer.gutter(tag, msg, BLUE, is_first=True)
722
+ first_progress[0] = False
723
+ else:
724
+ renderer.gutter(tag, msg, BLUE, is_first=False)
691
725
 
692
- ok, message = tool_manager.update(name, tool_cls.metadata.install, on_progress=on_progress)
726
+ upgrade_spec = tool_cls.metadata.install
727
+ ok, message = tool_manager.update(
728
+ tool_name, upgrade_spec, on_progress=on_progress
729
+ )
693
730
  if renderer is not None:
731
+ tag = f"upgrade {display}"
694
732
  if ok:
695
- renderer.log_line(f"upgrade {display}", "upgraded", color=BLUE)
733
+ msg = "upgraded"
734
+ elif message == "Aborted":
735
+ msg = "aborted"
736
+ print("\r\033[K", end="")
737
+ else:
738
+ msg = f"failed: {message}"
739
+ if first_progress[0]:
740
+ renderer.log_line(tag, msg, color=BLUE)
696
741
  else:
697
- renderer.log_line(f"upgrade {display}", f"failed: {message}", color=BLUE)
742
+ lines = msg.splitlines() or [""]
743
+ renderer.gutter(tag, lines[0], BLUE, is_first=False)
744
+ for line in lines[1:]:
745
+ print(f"{BLUE}{BOLD}│{RESET} {line}")
698
746
  return None
699
747
  return str(message)
700
748
 
@@ -727,17 +775,38 @@ class UpgradeCommand(Command):
727
775
  renderer.log_line(f"upgrade {display}", "not installed (skipped)", color=BLUE)
728
776
  continue
729
777
  renderer = context.session.get("renderer")
730
-
731
- def on_progress(msg: str, display: str = display, renderer: Any = renderer) -> None:
732
- if renderer is not None:
733
- renderer.log_line(f"upgrade {display}", msg, color=BLUE)
778
+ first_progress = [True]
779
+
780
+ def on_progress(
781
+ msg: str,
782
+ _first: list[bool] = first_progress,
783
+ _tag: str = f"upgrade {display}",
784
+ _renderer: Any = renderer,
785
+ ) -> None:
786
+ if _renderer is not None:
787
+ if _first[0]:
788
+ _renderer.gutter(_tag, msg, BLUE, is_first=True)
789
+ _first[0] = False
790
+ else:
791
+ _renderer.gutter(_tag, msg, BLUE, is_first=False)
734
792
 
735
793
  ok, message = tool_manager.update(name, spec, on_progress=on_progress)
736
794
  if renderer is not None:
795
+ tag = f"upgrade {display}"
737
796
  if ok:
738
- renderer.log_line(f"upgrade {display}", "upgraded", color=BLUE)
797
+ msg = "upgraded"
798
+ elif message == "Aborted":
799
+ msg = "aborted"
800
+ print("\r\033[K", end="")
801
+ else:
802
+ msg = f"failed: {message}"
803
+ if first_progress[0]:
804
+ renderer.log_line(tag, msg, color=BLUE)
739
805
  else:
740
- renderer.log_line(f"upgrade {display}", f"failed: {message}", color=BLUE)
806
+ lines = msg.splitlines() or [""]
807
+ renderer.gutter(tag, lines[0], BLUE, is_first=False)
808
+ for line in lines[1:]:
809
+ print(f"{BLUE}{BOLD}│{RESET} {line}")
741
810
  return None
742
811
 
743
812
 
@@ -759,9 +828,10 @@ class RemoveCommand(Command):
759
828
  tool_cls = tool_registry.get_tool(name)
760
829
  if tool_cls is None or tool_cls.metadata.install is None:
761
830
  return f'Tool "{name}" is not an external tool or was not found.'
762
- display = tool_registry.format_display(tool_registry.get_tool_path(name))
831
+ tool_name = tool_cls.metadata.name
832
+ display = tool_registry.format_display(tool_registry.get_tool_path(tool_name))
763
833
  renderer = context.session.get("renderer")
764
- ok, message = tool_manager.uninstall(name)
834
+ ok, message = tool_manager.uninstall(tool_name)
765
835
  if renderer is not None:
766
836
  if ok:
767
837
  renderer.log_line(f"remove {display}", "removed", color=RED)
@@ -253,7 +253,10 @@ class Renderer:
253
253
  print(text, end="")
254
254
 
255
255
  def log_line(self, tag: str, message: str, color: str = PINK) -> None:
256
- print(f"{color}{BOLD}{tag} - {RESET}{message}")
256
+ lines = message.splitlines() or [""]
257
+ self.gutter(tag, lines[0], color, is_first=True)
258
+ for line in lines[1:]:
259
+ print(f"{color}{BOLD}│{RESET} {line}")
257
260
 
258
261
  def gutter(self, name: str, line: str, color: str, is_first: bool) -> None:
259
262
  if is_first:
@@ -54,7 +54,11 @@ class ToolManager:
54
54
  self._run([pip, "install", *spec.pip_args])
55
55
  dest.joinpath(".installed").write_text(name)
56
56
  return True, f'Tool "{name}" installed.'
57
+ except KeyboardInterrupt:
58
+ shutil.rmtree(dest, ignore_errors=True)
59
+ return False, "Aborted"
57
60
  except Exception as e:
61
+ shutil.rmtree(dest, ignore_errors=True)
58
62
  return False, f'Failed to install "{name}": {e}'
59
63
 
60
64
  def update(
@@ -82,6 +86,8 @@ class ToolManager:
82
86
  on_progress("upgrading packages...")
83
87
  self._run([pip, "install", "--upgrade", *spec.pip_args])
84
88
  return True, f'Tool "{name}" updated.'
89
+ except KeyboardInterrupt:
90
+ return False, "Aborted"
85
91
  except Exception as e:
86
92
  return False, f'Failed to update "{name}": {e}'
87
93
 
@@ -98,5 +104,10 @@ class ToolManager:
98
104
  def _run(self, cmd: list[str]) -> None:
99
105
  result = subprocess.run(cmd, capture_output=True, text=True)
100
106
  if result.returncode != 0:
101
- detail = result.stderr.strip() or result.stdout.strip() or "No output"
107
+ stderr = result.stderr.strip() if result.stderr else ""
108
+ stdout = result.stdout.strip() if result.stdout else ""
109
+ raw = stderr or stdout or "No output"
110
+ # Truncate long build output — keep last 20 lines where the actual error lives
111
+ lines = raw.splitlines()
112
+ detail = "\n".join(lines[-20:]) if len(lines) > 20 else raw
102
113
  raise RuntimeError(detail)
@@ -107,7 +107,7 @@ class BlackbirdTool(Tool):
107
107
  success=False,
108
108
  error="Both 'type' and 'query' options are required.",
109
109
  )
110
- args = [f"--{stype}", query, "--no-update"]
110
+ args = [f"--{stype}", query]
111
111
  if parse_bool(context.options.get("pdf")):
112
112
  args.append("--pdf")
113
113
  renderer = context.renderer
File without changes
File without changes
File without changes