Skip to content

Commit 997461e

Browse files
authored
Merge pull request #9 from WordPress/remove/python3-dependency
Remove python3 as a dependency
2 parents d77a848 + fd9e427 commit 997461e

2 files changed

Lines changed: 107 additions & 70 deletions

File tree

rtc-helpers.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/**
3+
* CLI helpers for rtc-test.sh — no WordPress required.
4+
*
5+
* Usage:
6+
* php rtc-helpers.php capture-sanitize <fixture.json>
7+
* php rtc-helpers.php replay-extract <fixture.json>
8+
*/
9+
10+
$command = $argv[1] ?? '';
11+
$file = $argv[2] ?? '';
12+
13+
// Use realpath() + is_file() rather than file_exists() — the latter resolves
14+
// PHP stream wrappers (php://filter, phar://) which would bypass this guard.
15+
$real = '' !== $file ? realpath( $file ) : false;
16+
if ( false === $real || ! is_file( $real ) ) {
17+
fwrite( STDERR, "Usage: php rtc-helpers.php <capture-sanitize|replay-extract> <fixture.json>\n" );
18+
exit( 1 );
19+
}
20+
$file = $real;
21+
22+
switch ( $command ) {
23+
case 'capture-sanitize':
24+
rtctest_capture_sanitize( $file );
25+
break;
26+
case 'replay-extract':
27+
rtctest_replay_extract( $file );
28+
break;
29+
default:
30+
fwrite( STDERR, "Unknown command: {$command}\n" );
31+
exit( 1 );
32+
}
33+
34+
// -----------------------------------------------------------------------------
35+
36+
function rtctest_capture_sanitize( string $file ) {
37+
$data = json_decode( file_get_contents( $file ), true );
38+
if ( null === $data ) {
39+
fwrite( STDERR, 'capture-sanitize: ' . json_last_error_msg() . "\n" );
40+
exit( 1 );
41+
}
42+
$frames_in = $data['frames'] ?? [];
43+
$frames_out = [];
44+
45+
foreach ( $frames_in as $frame ) {
46+
$rooms = $frame['request']['rooms'] ?? [];
47+
$post_room = null;
48+
foreach ( $rooms as $r ) {
49+
if ( strpos( $r['room'] ?? '', 'postType/post:' ) === 0 ) {
50+
$post_room = $r;
51+
break;
52+
}
53+
}
54+
if ( null === $post_room ) {
55+
continue;
56+
}
57+
$frames_out[] = [
58+
'n' => $frame['n'] ?? count( $frames_out ) + 1,
59+
'elapsed_ms' => $frame['elapsed_ms'] ?? 0,
60+
'client_id' => $frame['client_id'] ?? 0,
61+
'request' => [ 'rooms' => [ [
62+
'room' => 'postType/post:0',
63+
'client_id' => $post_room['client_id'] ?? ( $frame['client_id'] ?? 0 ),
64+
'awareness' => new stdClass(),
65+
'after' => 0,
66+
'updates' => $post_room['updates'] ?? [],
67+
] ] ],
68+
];
69+
}
70+
71+
$out = [
72+
'session_id' => $data['session_id'] ?? '',
73+
'frame_count' => count( $frames_out ),
74+
'frames' => $frames_out,
75+
];
76+
77+
echo json_encode( $out, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n";
78+
}
79+
80+
function rtctest_replay_extract( string $file ) {
81+
$data = json_decode( file_get_contents( $file ), true );
82+
if ( null === $data ) {
83+
fwrite( STDERR, 'replay-extract: ' . json_last_error_msg() . "\n" );
84+
exit( 1 );
85+
}
86+
87+
foreach ( $data['frames'] ?? [] as $frame ) {
88+
$elapsed_ms = (int) ( $frame['elapsed_ms'] ?? 0 );
89+
$client_id = (int) ( $frame['client_id'] ?? 0 );
90+
$rooms = $frame['request']['rooms'] ?? [];
91+
foreach ( $rooms as $r ) {
92+
if ( strpos( $r['room'] ?? '', 'postType/post:' ) === 0 ) {
93+
$updates = $r['updates'] ?? [];
94+
$updates_str = implode( ',', array_map( function ( $u ) {
95+
return json_encode( $u, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
96+
}, $updates ) );
97+
echo $elapsed_ms . "\t" . $client_id . "\t" . $updates_str . "\n";
98+
break;
99+
}
100+
}
101+
}
102+
}

rtc-test.sh

Lines changed: 5 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,48 +1892,9 @@ cmd_capture_sanitize() {
18921892
local fixture_file="${1:-}"
18931893
[ -z "${fixture_file}" ] && die "Usage: bash rtc-test.sh capture-sanitize <fixture.json>"
18941894
[ -f "${fixture_file}" ] || die "File not found: ${fixture_file}"
1895-
command -v python3 >/dev/null 2>&1 || die "capture-sanitize requires python3"
1896-
1897-
python3 -c '
1898-
import json, sys
1899-
1900-
with open(sys.argv[1]) as f:
1901-
data = json.load(f)
1902-
1903-
frames_in = data.get("frames", [])
1904-
frames_out = []
1905-
for frame in frames_in:
1906-
rooms = frame.get("request", {}).get("rooms", [])
1907-
post_room = None
1908-
for r in rooms:
1909-
if r.get("room", "").startswith("postType/post:"):
1910-
post_room = r
1911-
break
1912-
if post_room is None:
1913-
continue
1914-
frames_out.append({
1915-
"n": frame.get("n", len(frames_out) + 1),
1916-
"elapsed_ms": frame.get("elapsed_ms", 0),
1917-
"client_id": frame.get("client_id", 0),
1918-
"request": {
1919-
"rooms": [{
1920-
"room": "postType/post:0",
1921-
"client_id": post_room.get("client_id", frame.get("client_id", 0)),
1922-
"awareness": {},
1923-
"after": 0,
1924-
"updates": post_room.get("updates", [])
1925-
}]
1926-
}
1927-
})
1928-
1929-
out = {
1930-
"session_id": data.get("session_id", ""),
1931-
"frame_count": len(frames_out),
1932-
"frames": frames_out,
1933-
}
1934-
json.dump(out, sys.stdout, separators=(",", ":"))
1935-
sys.stdout.write("\n")
1936-
' "${fixture_file}"
1895+
command -v php >/dev/null 2>&1 || die "capture-sanitize requires php"
1896+
1897+
php "${SCRIPT_DIR}/rtc-helpers.php" capture-sanitize "${fixture_file}"
19371898
}
19381899

19391900
# replay FIXTURE_FILE -- replay a captured session JSON against the current RTC endpoint.
@@ -1950,38 +1911,12 @@ cmd_replay() {
19501911
local fixture_file="${1:-}"
19511912
[ -z "${fixture_file}" ] && die "Usage: bash rtc-test.sh replay <fixture.json>"
19521913
[ -f "${fixture_file}" ] || die "File not found: ${fixture_file}"
1953-
command -v python3 >/dev/null 2>&1 || die "replay requires python3 to parse fixture JSON"
1914+
command -v php >/dev/null 2>&1 || die "replay requires php to parse fixture JSON"
19541915

19551916
local speed="${REPLAY_SPEED:-1}"
19561917
print_header "replay ($(basename "${fixture_file}"), speed=${speed}x)"
19571918
require_auth
19581919

1959-
# Extract per-frame update payloads from the fixture using python3 -c (no temp file).
1960-
# Output format (one line per frame): elapsed_ms <TAB> client_id <TAB> updates_json
1961-
# updates_json is comma-separated {type,data} objects; empty string if no updates.
1962-
# Only the postType/post:* room is extracted; other rooms (root/comment etc.) skipped.
1963-
# sys.stdout.flush() after each line prevents Python pipe-buffering from stalling bash.
1964-
local _py_extractor
1965-
_py_extractor='
1966-
import json, sys
1967-
try:
1968-
with open(sys.argv[1]) as f:
1969-
data = json.load(f)
1970-
except Exception as e:
1971-
sys.stderr.write("replay: " + str(e) + "\n")
1972-
sys.exit(1)
1973-
for frame in data.get("frames", []):
1974-
elapsed_ms = int(frame.get("elapsed_ms", 0))
1975-
client_id = frame.get("client_id", 0)
1976-
rooms = frame.get("request", {}).get("rooms", [])
1977-
for r in rooms:
1978-
if r.get("room", "").startswith("postType/post:"):
1979-
updates = r.get("updates", [])
1980-
updates_str = ",".join(json.dumps(u, separators=(",",":")) for u in updates)
1981-
sys.stdout.write("{}\t{}\t{}\n".format(elapsed_ms, client_id, updates_str))
1982-
sys.stdout.flush()
1983-
break
1984-
'
19851920

19861921
local cursor=0
19871922
local prev_elapsed=0
@@ -2029,7 +1964,7 @@ for frame in data.get("frames", []):
20291964
"${frame_num}" "${frame_elapsed}" "${ui_count}" "${uo_count}" \
20301965
"${cursor}" "${total_updates:-0}" "${compact:-false}"
20311966

2032-
done < <(python3 -c "${_py_extractor}" "${fixture_file}")
1967+
done < <(php "${SCRIPT_DIR}/rtc-helpers.php" replay-extract "${fixture_file}")
20331968

20341969
if [ "${frame_num}" -eq 0 ]; then
20351970
printf 'ERROR: no frames extracted. Check fixture format (expected capture-export JSON).\n' >&2

0 commit comments

Comments
 (0)