adding P-CERAS. A legacy python screen recorder

This commit is contained in:
klein panic
2025-04-13 02:32:14 -04:00
parent 90b736a198
commit f30b6d462c
9 changed files with 1041 additions and 0 deletions

194
P-CERAS/setup.py Normal file
View File

@@ -0,0 +1,194 @@
#!/usr/bin/env python3
import argparse
import subprocess
import os
import shutil
import sys
import sysconfig
VERSION = "1.0.7"
HOOK_FILENAME = "hook-ffmpeg.py"
# This hook is used by PyInstaller. It tells PyInstaller to treat "ffmpeg" as a hidden import.
# (PyInstaller sometimes misses modules that are single-file or not recognized as packages.)
HOOK_CONTENT = "hiddenimports = ['ffmpeg']\n"
# Global flag to know if we created the hook file (so we can delete it later)
created_hook = False
def create_ffmpeg_hook():
"""Create a hook file for ffmpeg in the current directory if it doesn't already exist."""
global created_hook
if not os.path.exists(HOOK_FILENAME):
with open(HOOK_FILENAME, "w", encoding="utf-8") as hook_file:
hook_file.write(HOOK_CONTENT)
print(f"Created hook file: {HOOK_FILENAME}")
created_hook = True
def get_extra_pyinstaller_args():
"""
Returns a list of extra arguments for PyInstaller:
- Forces inclusion of the ffmpeg module.
- Adds our additional hooks directory.
- Adds the Python shared library using the correct INSTSONAME.
"""
extra_args = [
"--hidden-import", "ffmpeg",
"--collect-submodules", "ffmpeg",
"--additional-hooks-dir", "."
]
instsoname = sysconfig.get_config_var("INSTSONAME") # e.g., libpython3.11.so.1.0
if instsoname:
libdir = sysconfig.get_config_var("LIBDIR")
libpython_path = os.path.join(libdir, instsoname) if libdir else None
if not libpython_path or not os.path.exists(libpython_path):
fallback = os.path.join("/usr/lib/x86_64-linux-gnu", instsoname)
if os.path.exists(fallback):
libpython_path = fallback
if libpython_path and os.path.exists(libpython_path):
extra_args.extend(["--add-binary", f"{libpython_path}:."])
else:
print("Warning: Could not locate the Python shared library.")
return extra_args
def build_binary():
"""
Builds a one-file binary from screenrecord.py using PyInstaller.
Attempts:
1. A locally installed PyInstaller.
2. pipx if available.
3. Installing PyInstaller in a virtual environment (with --break-system-packages).
Returns True on success, False otherwise.
"""
create_ffmpeg_hook()
pyinstaller_args = ["--onefile"] + get_extra_pyinstaller_args() + ["screenrecord.py"]
# Try using a locally installed PyInstaller.
try:
import PyInstaller.__main__
print("Using locally installed PyInstaller.")
PyInstaller.__main__.run(pyinstaller_args)
return True
except ImportError:
pass
# Try using pipx.
if shutil.which("pipx"):
print("PyInstaller not found locally. Using pipx to run PyInstaller.")
try:
cmd = ["pipx", "run", "pyinstaller"] + pyinstaller_args
subprocess.check_call(cmd)
return True
except subprocess.CalledProcessError:
print("Error: 'pipx run pyinstaller' failed.")
return False
# If pipx isn't available, check if we're in a virtual environment.
if os.environ.get("VIRTUAL_ENV") is not None:
print("In a virtual environment. Installing PyInstaller using pip with --break-system-packages...")
try:
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "--break-system-packages", "pyinstaller"]
)
except subprocess.CalledProcessError:
print("Error: Failed to install PyInstaller in the virtual environment.")
return False
try:
import PyInstaller.__main__
PyInstaller.__main__.run(pyinstaller_args)
return True
except Exception as e:
print("Error: PyInstaller run failed after installation in venv:", e)
return False
print("Error: PyInstaller is not installed and neither pipx nor a virtual environment is available.")
print("Please install pipx or run this installer in a virtual environment, then try again.")
return False
def cleanup():
"""Remove temporary build files and our hook file if we created it."""
dirs_to_remove = ["build"]
files_to_remove = [HOOK_FILENAME, "screenrecord.spec"]
for d in dirs_to_remove:
if os.path.isdir(d):
try:
shutil.rmtree(d)
print(f"Removed directory: {d}")
except Exception as e:
print(f"Warning: Could not remove directory {d}: {e}")
for f in files_to_remove:
if os.path.exists(f):
try:
os.remove(f)
print(f"Removed file: {f}")
except Exception as e:
print(f"Warning: Could not remove file {f}: {e}")
def install():
print("Building binary with PyInstaller...")
if not build_binary():
sys.exit(1)
# Determine the binary name; PyInstaller typically creates "screenrecord" in the dist folder.
binary_name = "screenrecord"
dist_path = os.path.join("dist", binary_name)
if not os.path.exists(dist_path):
# As a fallback, check for a .py extension.
dist_path = os.path.join("dist", "screenrecord.py")
if not os.path.exists(dist_path):
print("Error: Binary not found in the 'dist' folder after build.")
sys.exit(1)
print(f"Built binary located at: {dist_path}")
confirm = input("Do you want to move the binary to ~/.local/bin for global access? [y/N]: ")
if confirm.lower() in ["y", "yes"]:
local_bin = os.path.expanduser("~/.local/bin")
os.makedirs(local_bin, exist_ok=True)
destination = os.path.join(local_bin, binary_name)
try:
shutil.move(dist_path, destination)
print(f"Installation successful! Binary moved to {destination}")
except Exception as e:
print(f"Error moving binary to {destination}: {e}")
sys.exit(1)
else:
print("Installation complete. The binary remains in the 'dist' folder.")
# Cleanup temporary files created by PyInstaller and this installer.
cleanup()
def uninstall():
local_bin = os.path.expanduser("~/.local/bin")
binary_path = os.path.join(local_bin, "screenrecord")
if os.path.exists(binary_path):
try:
os.remove(binary_path)
print(f"Uninstalled: Removed {binary_path}")
except Exception as e:
print(f"Error removing {binary_path}: {e}")
sys.exit(1)
else:
print("Uninstall: 'screenrecord' binary not found in ~/.local/bin.")
def main():
parser = argparse.ArgumentParser(description="Installer for screenrecord.py")
parser.add_argument("command", choices=["install", "uninstall", "version", "help"],
help="Command: install, uninstall, version, or help")
args = parser.parse_args()
if args.command == "install":
install()
elif args.command == "uninstall":
uninstall()
elif args.command == "version":
print(f"screenrecord installer version {VERSION}")
elif args.command == "help":
parser.print_help()
if __name__ == "__main__":
main()