Metadata-Version: 2.4
Name: capture-pkg
Version: 0.3.4
Summary: A modular capture package for integration with x-ray application and PyPI distribution.
Author-email: wisnubaldas <wisnubaldas@gmail.com>
License-Expression: MIT
Keywords: capture,x-ray,hyfetch,imaging
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: hyfetch>=1.4.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-env>=1.0.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"

# capture-pkg

[![PyPI Version](https://img.shields.io/pypi/v/capture-pkg.svg)](https://pypi.org/project/capture-pkg/)
[![Python Version](https://img.shields.io/pypi/pyversions/capture-pkg.svg)](https://pypi.org/project/capture-pkg/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A modular Python package providing dual-camera capture utilities, HyFetch console branding, and a hardware-bound licensing system for the **x-ray** application and standalone Python services. Includes digital signature verification using HMAC-SHA256 and an intuitive artisan-style command-line interface (`capture-pkg`).

---

## Features

- **Artisan-Style CLI Utility (`capture-pkg`)**: Built-in CLI for hardware inspection, license generation, validation, and system info.
- **Hardware-Bound Licensing**: HMAC-SHA256 digitally signed licenses locked to server MAC Address and Hard Disk Serial Number.
- **HyFetch Console Branding**: Automatic system fetch console banner with custom `xenogender` preset and `fastfetch` / `neofetch` backend.
- **Non-Blocking Auto Configuration**: Auto-generates `hyfetch.json` when missing to ensure non-interactive servers (FastAPI/Uvicorn) never hang on setup wizards.
- **FastAPI / Server Integration**: Helper functions (`print_banner()`, `get_info()`, `process_capture()`) designed for API consumption.
- **Background Auto-Update**: Checks PyPI for new versions periodically in a non-blocking background thread and upgrades automatically.

---

## Quick Start

### 1. Installation

```bash
pip install capture-pkg
```

### 2. Run CLI Command

Execute `capture-pkg` directly in your terminal to see the help menu:

```bash
capture-pkg help
```

*(You can also use `python -m capture_pkg.cli <command>`)*

---

## CLI Command Reference (`capture-pkg`)

The `capture-pkg` command suite provides tools for server inspection, licensing, and diagnostics:

```text
Capture Package Licensing CLI v0.3.4

Usage:
  capture-pkg <command> [options]
  python -m capture_pkg.cli <command> [options]

Available Commands:
  [Hardware & Machine]
    machine              Display server hardware specs (MAC, Disk, OS) for license binding
                         (Aliases: hardware, specs, fingerprint)
  [Licensing]
    verify               Verify license file validity, digital signature, and hardware binding
                         (Aliases: check, license:verify)
    generate             Generate a digitally signed client license file
                         (Aliases: key:generate, license:generate, make:license)
  [System & Info]
    info                 Display package banner, version, and license status
                         (Aliases: status, banner)
    help                 Display this help menu and command list
                         (Aliases: list, --help, -h)
```

### 1. Inspect Server Hardware (`machine`)

Displays hostname, platform OS, CPU, Python version, MAC Address, and Hard Disk Serial:

```bash
capture-pkg machine
```
*Aliases: `hardware`, `specs`, `fingerprint`*

**Example Output:**
```text
=================================================================
                   SERVER HARDWARE SPECIFICATIONS
=================================================================
  Hostname         : SERVER-PROD-01
  OS / Platform    : Linux-5.15.0-88-generic-x86_64
  Processor        : x86_64
  Python Version   : 3.11.4
-----------------------------------------------------------------
  MAC Address      : FB:A1:8E:DB:37:D0
  Disk Serial      : WD-WX12345ABCDE
=================================================================
  [QUICK COMMAND TO GENERATE LICENSE FOR THIS MACHINE]
  capture-pkg generate --client "Client Name" --mac "FB:A1:8E:DB:37:D0" --expiry "2027-12-31"
=================================================================
```

### 2. Generate Client License (`generate`)

Generates a new digitally signed license file with HMAC-SHA256 anti-tamper protection:

```bash
# Lock to current server machine automatically using 'this'
capture-pkg generate --client "PT Terminal Petikemas" --mac this --expiry "2027-12-31"

# Lock to a specific remote client MAC address
capture-pkg generate --client "PT Pelabuhan Indonesia" --mac "FB:A1:8E:DB:37:D0" --expiry "2027-12-31" --output "license.json"

# Generate an unbound license (valid on any machine until expiry)
capture-pkg generate --client "Demo / Evaluation Client" --expiry "2028-01-01"
```
*Aliases: `key:generate`, `license:generate`, `make:license`*

**Parameters:**
- `-c`, `--client`: Client or company name (default: `"Client Server"`).
- `-m`, `--mac`: MAC address to bind (`this` for current machine, specific MAC, or omitted for unbound).
- `-d`, `--disk`: Hard disk serial to bind (`this` for current machine, specific serial, or omitted for unbound).
- `-e`, `--expiry`: Expiry date formatted as `YYYY-MM-DD` (default: 1 year from today).
- `-o`, `--output`: Output file destination (default: `license.json`).

### 3. Verify License File (`verify`)

Validates digital signature integrity, expiry date, and hardware binding against the current server:

```bash
# Auto-discover license in standard locations
capture-pkg verify

# Specify explicit license file path
capture-pkg verify --path /opt/x-ray/license.json
```
*Aliases: `check`, `license:verify`*

**Example Output:**
```text
=================================================================
                      LICENSE VERIFICATION
=================================================================
  Target File      : /opt/x-ray/license.json
  License ID       : LIC-20260819082211
  Issued To        : PT Terminal Petikemas
  Expiry Date      : 2027-12-31 (ACTIVE)
  Bound MAC        : FB:A1:8E:DB:37:D0 [MATCH]
  Bound Disk       : UNBOUND (Any Disk) [MATCH]
  HMAC Signature   : VALID (Authentic)
-----------------------------------------------------------------
  Result: [OK] License is VALID and ACTIVE for this server.
=================================================================
```

### 4. Package Info & Status (`info`)

Displays the HyFetch console banner and package runtime status:

```bash
capture-pkg info
```
*Aliases: `status`, `banner`*

---

## Usage in FastAPI (`x-ray`)

Integrate `capture-pkg` directly into your FastAPI routes and application lifecycle:

```python
from fastapi import APIRouter
import capture_pkg

router = APIRouter()

# Print HyFetch banner on startup (Non-blocking)
capture_pkg.print_banner()

@router.get("/api/v1/capture/info")
def get_capture_info():
    """Retrieve package metadata and license status."""
    return capture_pkg.get_info()

@router.post("/api/v1/capture/process")
def trigger_capture(bl_number: str, camera_id: int = 1):
    """Process camera capture with built-in license enforcement."""
    return capture_pkg.process_capture(source_id=bl_number, camera_id=camera_id)
```

---

## License File Locations

When verifying licenses, `capture_pkg` automatically searches the following paths in order of priority:

| Priority | Location | Description |
|---|---|---|
| 1 | `<current working directory>/license.lic` | Application root directory (.lic) |
| 2 | `<current working directory>/license.json` | Application root directory (.json) |
| 3 | `~/.config/x-ray/license.json` | User configuration directory (Linux/macOS) |
| 4 | `%APPDATA%/x-ray/license.json` | Windows Application Data directory |

---

## Environment Variables

Configure these variables in your application `.env` file (e.g. `x-ray/.env`):

| Variable | Default | Description |
|---|---|---|
| `APP_ENV` | `production` | Set to `development` to bypass license verification during local development |
| `CAPTURE_LICENSE_ENFORCE` | `false` | Set to `true` to force license verification even in `development` mode (useful for QA) |
| `CAPTURE_UPDATE_INTERVAL_DAYS` | `7` | Number of days between automatic PyPI version checks |
| `CAPTURE_DISABLE_AUTOUPDATE` | `false` | Set to `true` to disable background auto-updates |

### License Gate Behavior Matrix

| `APP_ENV` | `CAPTURE_LICENSE_ENFORCE` | Result |
|---|---|---|
| `production` (default) | Any value | **ENFORCE** — License validation is strictly required |
| `development` | Not set / `false` | **BYPASS** — License validation is skipped |
| `development` | `true` | **ENFORCE** — License is validated for QA/testing |

---

## Automatic PyPI Updates

`capture-pkg` checks for new versions on PyPI every **7 days** (configurable) using a background thread:

1. On module import, the library reads the last check timestamp from `~/.config/capture-pkg/update_state.json`.
2. If the check interval has elapsed, a background worker queries the PyPI JSON API.
3. When a newer version is available, it performs `pip install --upgrade capture-pkg` in the background.
4. The new version takes effect seamlessly on the next application restart.

---

## Local Development (Editable Mode)

For local development and testing:

```bash
# Clone the repository and install dependencies in editable mode
pip install -e .[dev]

# Run the test suite
python -m pytest
```

---

## CI/CD Pipeline & Release Workflow

This project includes a GitLab CI/CD pipeline (`.gitlab-ci.yml`) for automated testing and releases to PyPI.

### Pipeline Stages

1. **Test (`test:job`)**: Runs `pytest` on every push to any branch.
2. **Publish (`pypi:publish`)**: Triggered when a Git Tag matching `v*.*.*` is pushed. Builds the distribution package and uploads to PyPI via `twine`.

### Release Steps

```bash
# 1. Update version in pyproject.toml and capture_pkg/__init__.py
# 2. Commit and push tag
git add .
git commit -m "chore: release v0.3.4"
git tag v0.3.4
git push origin master --tags
```

---

## License

Distributed under the [MIT License](LICENSE).
