mirror of
https://github.com/PR0M3TH3AN/VoxVera.git
synced 2026-10-27 17:50:42 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
004cce2a4f | ||
|
|
ec0abd856c |
No files matched your search
@@ -106,6 +106,10 @@ When you host a flyer, the **"Download Source Code"** button on the landing page
|
||||
- Installation and setup scripts for all platforms.
|
||||
- Complete documentation and templates.
|
||||
|
||||
To keep the mirrored download practical for low-bandwidth redistribution, the
|
||||
source archive does not ship pre-downloaded Tor binaries. Normal installer and
|
||||
release builds still fetch or bundle those artifacts separately.
|
||||
|
||||
This allows anyone who scans your flyer to become a new distributor of the VoxVera tool.
|
||||
|
||||
## Export & Backup
|
||||
|
||||
@@ -106,6 +106,10 @@ When you host a flyer, the **"הורד כלי וקוד מקור"** button on the
|
||||
- Installation and setup scripts for all platforms.
|
||||
- Complete documentation and templates.
|
||||
|
||||
To keep the mirrored download practical for low-bandwidth redistribution, the
|
||||
source archive does not ship pre-downloaded Tor binaries. Normal installer and
|
||||
release builds still fetch or bundle those artifacts separately.
|
||||
|
||||
This allows anyone who scans your flyer to become a new distributor of the VoxVera tool.
|
||||
|
||||
## Export & Backup
|
||||
|
||||
Vendored
+4
@@ -106,6 +106,10 @@ When you host a flyer, the **"{{t('web.download_button')}}"** button on the land
|
||||
- Installation and setup scripts for all platforms.
|
||||
- Complete documentation and templates.
|
||||
|
||||
To keep the mirrored download practical for low-bandwidth redistribution, the
|
||||
source archive does not ship pre-downloaded Tor binaries. Normal installer and
|
||||
release builds still fetch or bundle those artifacts separately.
|
||||
|
||||
This allows anyone who scans your flyer to become a new distributor of the VoxVera tool.
|
||||
|
||||
## Export & Backup
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ voxvera = ["templates/**", "src/**", "resources/**", "locales/**", "resources/bi
|
||||
|
||||
[project]
|
||||
name = "voxvera"
|
||||
version = "0.3.9"
|
||||
version = "0.3.11"
|
||||
description = "VoxVera CLI utilities"
|
||||
readme = "README.md"
|
||||
authors = [{name = "VoxVera"}]
|
||||
|
||||
Binary file not shown.
@@ -115,6 +115,23 @@ def test_init_seeds_missing_default_config(tmp_path, monkeypatch):
|
||||
assert saved["content"] == "Fresh content"
|
||||
|
||||
|
||||
def test_init_noninteractive_does_not_prompt_for_language(tmp_path, monkeypatch):
|
||||
_setup_tmp(monkeypatch, tmp_path)
|
||||
test_data_dir = tmp_path / "data"
|
||||
config_path = test_data_dir / "fresh-config.json"
|
||||
|
||||
def _fail_choose_language(*args, **kwargs):
|
||||
raise AssertionError("choose_language should not run for non-interactive init")
|
||||
|
||||
monkeypatch.setattr(cli, "choose_language", _fail_choose_language)
|
||||
|
||||
cli.main(["--config", str(config_path), "init", "--non-interactive"])
|
||||
|
||||
saved = cli.load_config(config_path)
|
||||
assert saved["lang"] == "en"
|
||||
assert (test_data_dir / "host" / saved["folder_name"] / "index.html").exists()
|
||||
|
||||
|
||||
def test_create_from_template_persists_current_language(tmp_path, monkeypatch):
|
||||
_setup_tmp(monkeypatch, tmp_path)
|
||||
cli.load_locale("es")
|
||||
|
||||
@@ -230,3 +230,28 @@ def test_portable_bundle_integrity(tmp_path, monkeypatch):
|
||||
|
||||
# Verify root scripts
|
||||
assert "voxvera-run.sh" in names
|
||||
|
||||
|
||||
def test_portable_bundle_excludes_prebuilt_tor_binaries(tmp_path, monkeypatch):
|
||||
project_root = tmp_path
|
||||
voxvera_dir = project_root / "voxvera"
|
||||
voxvera_dir.mkdir()
|
||||
|
||||
shutil.copytree(REPO_ROOT / "voxvera" / "src", voxvera_dir / "src")
|
||||
shutil.copytree(REPO_ROOT / "voxvera" / "locales", voxvera_dir / "locales")
|
||||
shutil.copytree(REPO_ROOT / "voxvera" / "resources", voxvera_dir / "resources")
|
||||
os.makedirs(voxvera_dir / "vendor", exist_ok=True)
|
||||
(voxvera_dir / "vendor" / "anchor.txt").write_text("anchor")
|
||||
|
||||
for script in ["voxvera-run.sh", "uninstall.sh", "uninstall.ps1", "install.sh", "install.ps1", "setup.sh"]:
|
||||
if (REPO_ROOT / script).exists():
|
||||
shutil.copy(REPO_ROOT / script, project_root / script)
|
||||
|
||||
monkeypatch.setattr(cli, "ROOT", voxvera_dir)
|
||||
|
||||
bundle_zip = project_root / "voxvera-portable.zip"
|
||||
cli.bundle_portable(bundle_zip)
|
||||
|
||||
with zipfile.ZipFile(bundle_zip, "r") as zf:
|
||||
names = zf.namelist()
|
||||
assert not any(name.startswith("voxvera/resources/tor/") for name in names)
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
__version__ = "0.3.9"
|
||||
__version__ = "0.3.11"
|
||||
|
||||
# Add the vendor directory to sys.path ONLY for PyInstaller (frozen) builds.
|
||||
# For pip/pipx installs the system/venv packages are correct and the vendored
|
||||
|
||||
+33
-5
@@ -693,12 +693,26 @@ def copy_template(name: str) -> str:
|
||||
|
||||
|
||||
def bundle_source(dest_zip: Path):
|
||||
"""Bundle the VoxVera source code, dependencies (vendor), and root scripts."""
|
||||
"""Bundle the VoxVera source tree and install scripts for viral mirroring.
|
||||
|
||||
We intentionally exclude pre-downloaded Tor binaries from the mirrored source
|
||||
archive. They dominate the zip size and are regenerated by the normal
|
||||
packaging/build flows, while the mirrored source bundle is meant to stay
|
||||
small enough for practical redistribution from flyer sites.
|
||||
"""
|
||||
with zipfile.ZipFile(dest_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
# 1. Include the voxvera/ source directory (excluding host, bin, pycache)
|
||||
# We DO include vendor here so the source zip is fully functional offline.
|
||||
# 1. Include the voxvera/ source directory (excluding host, bin,
|
||||
# bundled Tor artifacts, and pycache). We still include vendor so the
|
||||
# source zip remains portable without re-resolving Python deps.
|
||||
for root, dirs, files in os.walk(ROOT):
|
||||
if "__pycache__" in root or "host" in root or "resources/bin" in root:
|
||||
root_path = Path(root)
|
||||
if (
|
||||
"__pycache__" in root
|
||||
or "host" in root
|
||||
or "resources/bin" in root
|
||||
or root_path == ROOT / "resources" / "tor"
|
||||
or (ROOT / "resources" / "tor") in root_path.parents
|
||||
):
|
||||
continue
|
||||
for file in files:
|
||||
file_path = Path(root) / file
|
||||
@@ -2043,7 +2057,10 @@ def main(argv=None):
|
||||
pass
|
||||
|
||||
if not current_lang and args.command in ("init", "quickstart", "manage"):
|
||||
current_lang = choose_language()
|
||||
if getattr(args, "non_interactive", False):
|
||||
current_lang = "en"
|
||||
else:
|
||||
current_lang = choose_language()
|
||||
# Save choice to config if possible
|
||||
if config_path.exists():
|
||||
config_data["lang"] = current_lang
|
||||
@@ -2077,6 +2094,11 @@ def main(argv=None):
|
||||
copy_template(args.template)
|
||||
return
|
||||
ensure_config_exists(config_path)
|
||||
if current_lang:
|
||||
config_data = load_config(str(config_path))
|
||||
if not config_data.get("lang"):
|
||||
config_data["lang"] = current_lang
|
||||
save_config(config_data, str(config_path))
|
||||
if not args.non_interactive:
|
||||
interactive_update(config_path)
|
||||
build_assets(config_path)
|
||||
@@ -2108,6 +2130,12 @@ def main(argv=None):
|
||||
else:
|
||||
install_autostart()
|
||||
elif args.command == "quickstart":
|
||||
ensure_config_exists(config_path)
|
||||
if current_lang:
|
||||
config_data = load_config(str(config_path))
|
||||
if not config_data.get("lang"):
|
||||
config_data["lang"] = current_lang
|
||||
save_config(config_data, str(config_path))
|
||||
if not args.non_interactive:
|
||||
if not sys.stdin.isatty():
|
||||
print(
|
||||
|
||||
Reference in new issue
Block a user