Skip to content

Commit b816840

Browse files
Merge remote-tracking branch 'upstream/master' into ai_server
2 parents c1fe4a6 + 44ca1a5 commit b816840

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+141373
-109443
lines changed

.eslintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ web/skins/classic/js/video.js
2121
web/skins/classic/assets
2222
web/js/janus.js
2323
web/js/ajaxQueue.js
24-
web/js/hls-1.5.20/
24+
web/js/hls-1.6.13/
2525
web/js/noUiSlider-15.8.1/
2626
web/js/dms.js
2727

Lines changed: 50 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
name: build-native-packages-signed
2+
23
on:
34
push:
45
tags: ["v*"]
56
workflow_dispatch:
67
permissions:
78
contents: write
89
env:
9-
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
10-
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
11-
GPG_PRIVATE_KEY_B64: ${{ secrets.GPG_PRIVATE_KEY_B64 }}
10+
GPG_KEY_ID: ${{ secrets.ZMREPO_GPG_KEY_ID }}
11+
GPG_PASSPHRASE: ${{ secrets.ZMREPO_GPG_PASSPHRASE }}
12+
GPG_PRIVATE_KEY_B64: ${{ secrets.ZMREPO_GPG_PRIVATE_KEY_B64 }}
13+
1214
jobs:
1315
build-debian:
1416
name: Build & sign .deb (${{ matrix.distro }})
@@ -19,53 +21,65 @@ jobs:
1921
distro: ["debian:13", "debian:12", "ubuntu:22.04", "ubuntu:24.04"]
2022
container:
2123
image: ${{ matrix.distro }}
24+
2225
steps:
23-
name: Prep apt
24-
run:
26+
- name: Prep apt
27+
run: |
2528
set -eux
26-
if grep -q '^deb http' /etc/apt/sources.list && ! grep -q '^deb-src' /etc/apt/sources.list; then
27-
sed -n 's/^deb /deb-src /p' /etc/apt/sources.list >> /etc/apt/sources.list
29+
if grep -q '^deb http' /etc/apt/sources.list && ! grep -q '^deb-src'\
30+
/etc/apt/sources.list; then
31+
sed -n 's/^deb /deb-src /p' /etc/apt/sources.list >> \
32+
/etc/apt/sources.list
2833
fi
2934
apt-get update
30-
name: Install build tools
31-
run:
35+
- name: Install build tools
36+
run: |
3237
set -eux
33-
apt-get install -y --no-install-recommends \
38+
apt install -y --no-install-recommends \
3439
git ca-certificates gnupg lsb-release tzdata \
3540
build-essential devscripts debhelper equivs fakeroot \
3641
cmake pkg-config ccache
37-
name: Checkout
38-
uses: actions/checkout@v4
42+
apt install -y debhelper sphinx-doc dh-linktree dh-apache2 cmake \
43+
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
44+
libswresample-dev libswscale-dev libbz2-dev \
45+
libturbojpeg0-dev default-libmysqlclient-dev \
46+
libpolkit-gobject-1-dev libv4l-dev libvlc-dev libssl-dev \
47+
libvncserver-dev libjwt-gnutls-dev libgsoap-dev gsoap \
48+
libmosquittopp-dev
49+
50+
- name: Checkout
51+
uses: actions/checkout@v5
3952
with:
4053
fetch-depth: 0
41-
name: Import GPG key (Debian)
42-
run:
54+
- name: Import GPG key (Debian)
55+
run: |
4356
set -eux
4457
mkdir -p ~/.gnupg
4558
chmod 700 ~/.gnupg
4659
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
4760
echo "$GPG_PRIVATE_KEY_B64" | base64 -d > /tmp/priv.asc
4861
gpg --batch --import /tmp/priv.asc
4962
gpg --batch --yes --edit-key "$GPG_KEY_ID" trust quit <<< "5\ny"
50-
gpg --batch --armor --export "$GPG_KEY_ID" > public.asc
63+
gpg --batch --armor --export "$GPG_KEY_ID" --output public.asc
5164
chmod 600 ~/.gnupg/*
5265
export GPG_TTY=$(tty || true)
53-
name: Install build-deps from debian/control
54-
run:
66+
- name: Install build-deps from debian/control
67+
run: |
5568
set -eux
56-
mk-build-deps -ir -t "apt-get -y --no-install-recommends" debian/control
57-
name: Build (signed)
69+
mk-build-deps -ir -t "apt-get -y --no-install-recommends" \
70+
debian/control
71+
- name: Build (signed)
5872
env:
5973
DEB_BUILD_OPTIONS: "parallel=$(nproc)"
6074
# gpg picks passphrase from environment via loopback
61-
run:
75+
run: |
6276
set -eux
6377
# Tell gpg to use loopback + passphrase
6478
export GPG_TTY=$(tty || true)
6579
export DEB_SIGN_KEYID="$GPG_KEY_ID"
6680
dpkg-buildpackage -k"$DEB_SIGN_KEYID" -b
67-
name: Collect .deb artifacts (incl. signed metadata & public key)
68-
run:
81+
- name: Collect .deb artifacts (incl. signed metadata & public key)
82+
run: |
6983
set -eux
7084
mkdir -p artifacts/deb
7185
shopt -s nullglob
@@ -74,96 +88,32 @@ name: Collect .deb artifacts (incl. signed metadata & public key)
7488
# quick verify signatures (non-fatal)
7589
gpg --verify artifacts/deb/*.changes || true
7690
gpg --verify artifacts/deb/*.buildinfo || true
77-
name: Upload .deb artifacts
91+
- name: Upload .deb artifacts
7892
uses: actions/upload-artifact@v4
7993
with:
8094
name: debian-${{ matrix.distro }}
8195
path: artifacts/deb
82-
build-rpm:
83-
name: Build & sign .rpm (${{ matrix.distro }})
84-
runs-on: ubuntu-latest
85-
strategy:
86-
fail-fast: false
87-
matrix:
88-
distro: ["rockylinux:9", "fedora:40"]
89-
container:
90-
image: ${{ matrix.distro }}
91-
steps:
92-
name: Install build tools
93-
run:
94-
set -eux
95-
if command -v dnf >/dev/null; then PM=dnf; else PM=yum; fi
96-
$PM -y install git rpm-build make gcc gcc-c++ cmake pkgconfig ccache which \
97-
redhat-rpm-config gnupg2 rpm-sign
98-
name: Checkout
99-
uses: actions/checkout@v4
100-
with:
101-
fetch-depth: 0
102-
name: Import GPG key (RPM)
103-
run:
104-
set -eux
105-
mkdir -p ~/.gnupg
106-
chmod 700 ~/.gnupg
107-
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
108-
echo "$GPG_PRIVATE_KEY_B64" | base64 -d > /tmp/priv.asc
109-
gpg --batch --import /tmp/priv.asc
110-
gpg --batch --yes --edit-key "$GPG_KEY_ID" trust quit <<< "5\ny"
111-
gpg --batch --armor --export "$GPG_KEY_ID" > public.asc
112-
printf '%%_signature gpg\n' >> ~/.rpmmacros
113-
printf '%%_gpg_name %s\n' "$GPG_KEY_ID" >> ~/.rpmmacros
114-
# custom sign cmd with loopback pinentry; rpmsign passes files via macros
115-
cat >> ~/.rpmmacros <<'EOF'
116-
%__gpg /usr/bin/gpg
117-
%__gpg_sign_cmd %{__gpg} gpg --batch --no-verbose --no-armor --pinentry-mode loopback --passphrase %{?__gpg_passphrase} -u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}
118-
EOF
119-
name: Prepare rpmbuild tree & source
120-
run:
121-
set -eux
122-
mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
123-
VERSION="${GITHUB_REF_NAME:-dev}"
124-
git archive --format=tar --prefix=zoneminder-${VERSION}/ HEAD | gzip -9 > rpmbuild/SOURCES/zoneminder-${VERSION}.tar.gz
125-
cp packaging/zoneminder.spec rpmbuild/SPECS/zoneminder.spec
126-
name: Install BuildRequires
127-
run:
128-
set -eux
129-
if command -v dnf >/dev/null; then PM=dnf; else PM=yum; fi
130-
$PM -y builddep rpmbuild/SPECS/zoneminder.spec || true
131-
name: Build RPMs
132-
run:
133-
set -eux
134-
rpmbuild -ba rpmbuild/SPECS/zoneminder.spec \
135-
--define "_topdir $(pwd)/rpmbuild" \
136-
--define "version ${GITHUB_REF_NAME:-dev}"
137-
name: Sign RPMs
96+
- name: Publish to ZMREPO
97+
uses: easingthemes/ssh-deploy@main
13898
env:
139-
__gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
140-
run:
141-
set -eux
142-
find rpmbuild/RPMS -name "*.rpm" -print0 | xargs -0 -n1 -I{} rpmsign --addsign {}
143-
# quick verify (non-fatal if gpg keyring missing pub)
144-
rpm -Kv rpmbuild/RPMS/*/*.rpm || true
145-
name: Collect .rpm artifacts (incl. public key)
146-
run:
147-
set -eux
148-
mkdir -p artifacts/rpm
149-
find rpmbuild/RPMS -name "*.rpm" -exec cp -v {} artifacts/rpm/ \;
150-
cp -v public.asc artifacts/rpm/
151-
name: Upload .rpm artifacts
152-
uses: actions/upload-artifact@v4
153-
with:
154-
name: rpm-${{ matrix.distro }}
155-
path: artifacts/rpm
99+
SSH_PRIVATE_KEY: ${{ secrets.ZMREPO_SSH_KEY }}
100+
ARGS: "-rltgoDzvO"
101+
SOURCE: artifacts/deb/
102+
REMOTE_HOST: ${{ secrets.ZMREPO_HOST }}
103+
REMOTE_USER: ${{ secrets.ZMREPO_SSH_USER }}
104+
TARGET: debian/master/mini-dinstall/incoming/
105+
156106
release:
157107
name: Create GitHub Release (on tag)
158-
needs: [build-debian, build-rpm]
108+
needs: build-debian
159109
if: startsWith(github.ref, 'refs/tags/')
160110
runs-on: ubuntu-latest
161111
steps:
162-
name: Download artifacts
163-
uses: actions/download-artifact@v4
112+
- name: Download artifacts
113+
uses: actions/download-artifact@v5
164114
with:
165115
path: dist
166-
name: Create release
116+
- name: Create release
167117
uses: softprops/action-gh-release@v2
168118
with:
169119
files: dist/**/*

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545

4646
# Initializes the CodeQL tools for scanning.
4747
- name: Initialize CodeQL
48-
uses: github/codeql-action/init@v3
48+
uses: github/codeql-action/init@v4
4949
with:
5050
languages: ${{ matrix.language }}
5151
config-file: ./.github/codeql/codeql-config.yml
@@ -68,7 +68,7 @@ jobs:
6868
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
6969
# If this step fails, then you should remove it and run the build manually (see below)
7070
- name: Autobuild
71-
uses: github/codeql-action/autobuild@v3
71+
uses: github/codeql-action/autobuild@v4
7272

7373
# ℹ️ Command-line programs to run using the OS shell.
7474
# 📚 https://git.io/JvXDl-
@@ -83,4 +83,4 @@ jobs:
8383
# make release
8484

8585
- name: Perform CodeQL Analysis
86-
uses: github/codeql-action/analyze@v3
86+
uses: github/codeql-action/analyze@v4

db/zm_update-1.37.73.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UPDATE `Config` SET Value='https://telemetry.zoneminder.com/index.php' WHERE Value='https://zmanon:2b2d0b4skps@telemetry.zoneminder.com/zmtelemetry/testing5';

distros/redhat/zoneminder.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
%global zmtargetdistro %{?rhel:el%{rhel}}%{!?rhel:fc%{fedora}}
2121

2222
Name: zoneminder
23-
Version: 1.37.72
23+
Version: 1.37.73
2424
Release: 1%{?dist}
2525
Summary: A camera monitoring and analysis tool
2626
Group: System Environment/Daemons

distros/ubuntu2004/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Build-Depends: debhelper (>= 11), sphinx-doc, python3-sphinx, python3-sphinx-rtd
1212
,libswscale-dev
1313
,ffmpeg
1414
,arp-scan
15-
,net-tools
15+
,net-tools, iproute2
1616
,libbz2-dev
1717
,libcurl4-gnutls-dev
1818
,libjpeg-turbo8-dev | libjpeg62-turbo-dev | libjpeg8-dev | libjpeg9-dev

scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,7 @@ our @options = (
16791679
},
16801680
{
16811681
name => 'ZM_HOME_URL',
1682-
default => 'http://zoneminder.com',
1682+
default => 'https://zoneminder.com',
16831683
description => 'The url used in the home/logo area of the navigation bar.',
16841684
help => q`
16851685
By default this takes you to the zoneminder.com website,
@@ -2740,7 +2740,7 @@ our @options = (
27402740
},
27412741
{
27422742
name => 'ZM_TELEMETRY_SERVER_ENDPOINT',
2743-
default => 'https://zmanon:2b2d0b4skps@telemetry.zoneminder.com/zmtelemetry/testing5',
2743+
default => 'https://telemetry.zoneminder.com/index.php',
27442744
description => 'URL that ZoneMinder will send usage data to',
27452745
help => '',
27462746
type => $types{url},

scripts/ZoneMinder/lib/ZoneMinder/Event.pm

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,10 @@ sub delete {
419419
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
420420

421421
my $storage = $event->Storage();
422-
$storage->save({DiskSpace=>$storage->DiskSpace()-$event->DiskSpace()}) if $event->DiskSpace() and $storage->Id();
422+
if ($event->DiskSpace() and $storage->Id()) {
423+
$storage->lock_and_load();
424+
$storage->save({DiskSpace=>$storage->DiskSpace()-$event->DiskSpace()});
425+
}
423426
}
424427

425428
if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) {
@@ -782,8 +785,14 @@ sub MoveTo {
782785
$ZoneMinder::Database::dbh->commit() if !$was_in_transaction;
783786

784787
# Update storage diskspace. The triggers no longer do this. This is ... less important so do it outside the transaction
785-
$OldStorage->save({DiskSpace => $OldStorage->DiskSpace()-$old_diskspace}) if $old_diskspace and $$OldStorage{Id};
786-
$NewStorage->save({DiskSpace => $NewStorage->DiskSpace()+$new_diskspace}) if $new_diskspace and $$NewStorage{Id};
788+
if ($old_diskspace and $$OldStorage{Id}) {
789+
$OldStorage->lock_and_load();
790+
$OldStorage->save({DiskSpace => $OldStorage->DiskSpace()-$old_diskspace});
791+
}
792+
if ($new_diskspace and $$NewStorage{Id}) {
793+
$NewStorage->lock_and_load();
794+
$NewStorage->save({DiskSpace => $NewStorage->DiskSpace()+$new_diskspace});
795+
}
787796

788797
$self->delete_files($OldStorage);
789798
return $error;

scripts/zmtelemetry.pl.in

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ my $show = 0;
5050
# Interval between version checks
5151
my $interval;
5252
my $version;
53+
my $dry_run = 0;
54+
my $verbose;
5355

5456
GetOptions(
55-
force => \$force,
56-
help => \$help,
57-
show => \$show,
58-
interval => \$interval,
59-
version => \$version
57+
force => \$force,
58+
help => \$help,
59+
show => \$show,
60+
interval=> \$interval,
61+
version => \$version,
62+
verbose => \$verbose,
63+
dry_run => \$dry_run,
6064
);
6165

6266
if ($version) {
@@ -76,7 +80,7 @@ if ($show) {
7680
collectData($dbh, \%telemetry);
7781
my $result = jsonEncode(\%telemetry);
7882
print($result);
79-
exit(0);
83+
exit(0) if $dry_run;
8084
}
8185

8286
if (!defined $interval) {
@@ -140,6 +144,7 @@ sub collectData {
140144
my $dbh = shift;
141145
my $telemetry = shift;
142146
$telemetry->{uuid} = getUUID($dbh);
147+
$telemetry->{timezone} = $Config{ZM_TIMEZONE};
143148
@$telemetry{qw(city region country latitude longitude)} = getGeo();
144149
$telemetry->{timestamp} = strftime('%Y-%m-%dT%H:%M:%S%z', localtime());
145150
$telemetry->{monitor_count} = countQuery($dbh, 'Monitors');
@@ -188,7 +193,7 @@ sub sendData {
188193
$ua->proxy('https', $Config{ZM_UPDATE_CHECK_PROXY});
189194
}
190195

191-
Debug("Posting telemetry data to: $server_endpoint");
196+
Debug("Posting telemetry data $msg to: $server_endpoint");
192197

193198
# set custom HTTP request header fields
194199
my $req = HTTP::Request->new(POST => $server_endpoint);
@@ -286,8 +291,8 @@ sub getMonitorRef {
286291
my $dbh = shift;
287292

288293
my $sql = 'SELECT `Id`,`Name`,`Type`,`Capturing`,`Analysing`,`Recording`,`Width`,`Height`,`Colours`,`MaxFPS`,`AlarmMaxFPS`,
289-
(SELECT Name FROM Manufacturers WHERE Manufacturers.Id = ManufacturerId),
290-
(SELECT Name FROM Models WHERE Models.Id = ModelId)
294+
(SELECT Name FROM Manufacturers WHERE Manufacturers.Id = ManufacturerId) AS Manufacturer,
295+
(SELECT Name FROM Models WHERE Models.Id = ModelId) AS Model
291296
FROM `Monitors`';
292297
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
293298
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );

src/zm_eventstream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,9 @@ bool EventStream::loadEventData(uint64_t event_id) {
230230

231231
event_data->n_frames = mysql_num_rows(result);
232232
if (event_data->frame_count < event_data->n_frames) {
233-
event_data->frame_count = event_data->n_frames;
234233
Warning("Event %" PRId64 " has more frames in the Frames table (%d) than in the Event record (%d)",
235234
event_data->event_id, event_data->n_frames, event_data->frame_count);
235+
event_data->frame_count = event_data->n_frames;
236236
}
237237
event_data->frames.clear();
238238
event_data->frames.reserve(event_data->frame_count);

0 commit comments

Comments
 (0)