Skip to content

Instantly share code, notes, and snippets.

View curtishall's full-sized avatar

Curtis Hall curtishall

  • Bluecherry
  • Missouri
View GitHub Profile
@curtishall
curtishall / bluecherry-v3-vs-v4-licensing.md
Created October 17, 2026 13:25
Bluecherry licensing: v3 vs v4 (revised)

Bluecherry licensing: v3 vs v4

Bluecherry is open source. That one fact shapes our whole licensing philosophy: since anyone can read — or remove — the license check, DRM would only ever punish paying customers. So v4 licensing isn't copy protection, it's a payment mechanism. v3 licensing treated every install as suspect. v4 assumes you're a customer.

No more calling home

In v3, routine license checks ran a server sync against Cryptlex's servers. No internet, a proxy change, or an outage on their end meant licensing trouble on yours. In v4, verification is local math: an Ed25519 signature checked against pinned keys on disk. The portal is contacted only when you click activate, reissue, or deactivate — never on its own, never in the recording path.

Fail-open instead of fail-closed

@curtishall
curtishall / bluecherry-v3-vs-v4-licensing.md
Created October 17, 2026 08:36
Bluecherry licensing: v3 vs v4

Bluecherry licensing: v3 vs v4

v3 licensing worked, but it was built on a third-party DRM kit with the usual DRM tradeoffs: call-homes, machine locks, and failure modes that punished paying customers. v4 licensing was rewritten from scratch around one rule — a license problem should never stop recording that was already working.

No more calling home

In v3, routine license checks ran a server sync against Cryptlex's servers. No internet, a proxy change, or an outage on their end meant licensing trouble on yours. In v4, verification is local math: an Ed25519 signature checked against pinned keys on disk. The portal is contacted only when you click activate, reissue, or deactivate — never on its own, never in the recording path.

Fail-open instead of fail-closed

@curtishall
curtishall / bluecherry-v4-roadmap.md
Created October 17, 2026 02:21
Bluecherry v4 — what's ready and what's coming

Bluecherry v4 — what's ready and what's coming

v4 replaces the old PHP web UI with a new stack (Next.js frontend + Node REST API, same battle-tested bc-server underneath), adds licensing, typed recording triggers, and a set of bigger "v4 Connect" features. Everything below marked ready is working on the v4-dev branch today.

Ready now

New web UI + API

  • Full dashboard: live view, devices, recordings, events, reports, licenses, system, users, settings — dark default theme, collapsible sidebar, ⌘K palette, per-user preferences
  • REST API with JWT auth, personal API keys (bcv4_…), and vitest suites (375/375)
  • Old PHP www/ retired (776 files gone), including the SwiftMailer-based mailer — replaced by a Node mailer CLI with the same contract
$hex = "ff00aa55005a4343494320202020204441432020202020202055535220202020202020535553522020202020204543484f20202020204e323032363037303420303132303530202020202030313031202020202055aa00ff"
$frame = for ($i=0; $i -lt $hex.Length; $i+=2) { [Convert]::ToByte($hex.Substring($i,2), 16) }
$sw = [Diagnostics.Stopwatch]::StartNew()
$c = New-Object Net.Sockets.TcpClient
$c.Connect("10.101.240.5", 4518)
$s = $c.GetStream()
$s.Write($frame, 0, $frame.Length)
Write-Host "Sent ECHO at $($sw.ElapsedMilliseconds) ms"
Start-Sleep -Milliseconds 500
if ($s.DataAvailable) {
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$client = New-Object System.Net.Sockets.TcpClient
try {
$client.Connect("10.101.240.5", 4518)
Write-Host "Connected at $($sw.ElapsedMilliseconds) ms"
$stream = $client.GetStream()
$stream.ReadTimeout = 15000
$buf = New-Object byte[] 4096
try {
$n = $stream.Read($buf, 0, $buf.Length)
version: "3.8"
services:
big-coder:
image: vllm/vllm-openai:latest
container_name: big-coder
restart: unless-stopped
runtime: nvidia
environment:
- CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES:-0,1}
@curtishall
curtishall / bc-check-onvif.js
Last active March 15, 2025 20:56
nodejs onvif script to return available event types.
/**
* bc-check-onvif.js
*
* This script reports:
* - MyRuleDetector rules (e.g. People Detect, Vehicle Detect, Dog Cat Detect)
* - RuleEngine events such as CellMotionDetector/Motion
* - VideoSource events such as MotionAlarm
*
* Usage:
* node bc-check-onvif.js <ip> <port> <username> <password>
{
"openapi": "3.1.0",
"info": {
"version": "0.3.6",
"title": "Bluecherry Server API",
"description": "The Bluecherry Server API allows users to use software to create custom integrations with Bluecherry DVR",
"contact": {
"name": "Bluecherry Team",
"email": "support@bluecherrydvr.com",
"url": "https://github.com/bluecherrydvr/"
@curtishall
curtishall / intercom_to_chatwoot.py
Created February 19, 2025 15:01
Intercom to Chatwoot migration python script
import requests
import time
import sys
from datetime import datetime
from bs4 import BeautifulSoup
# API credentials
INTERCOM_API_KEY = 'INTERCOM_API_KEY' # Found on Intercom developer hub
CHATWOOT_API_KEY = 'CHATWOOT_API_KEY' # Can NOT be a SuperAdmin account, has to be an admin account.
CHATWOOT_HOST = 'https://support.bluecherrydvr.com' # Just the base URL, script does the rest and will add paths
@curtishall
curtishall / gist:4acbc1504bb54bbb87f67c44fc72e0c1
Last active August 13, 2024 19:44
TAK Server custom iconsets
XML example:
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<event version="2.0" uid="6276" type="a-u-G" how="h-g-i-g-o" time="2024-08-11T21:09:06.000+00:00" start="2024-08-11T21:09:06.000+00:00" icon="f7f71666-8b28-4b57-9fbb-e38e61d33b79/Service/firebrigade.png" stale="2024-08-13T18:12:06.712Z">
<point lat="38.713837" lon="-91.714066" hae="200.4" ce="9999999.0" le="9999999.0"/>
<detail>
<contact callsign="BRUSH 1106"/>
<usericon iconsetpath="6d781afb-89a6-4c07-b2b9-a89748b6a38f/Service/firebrigade.png"/>
<remarks>No Address</remarks>