Skip to content

Commit aa89770

Browse files
Merge branch 'master' into ai_server
2 parents 55aba48 + 9c9a2dc commit aa89770

File tree

17 files changed

+268
-58
lines changed

17 files changed

+268
-58
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
name: build-native-packages-signed-aarch64
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
workflow_dispatch:
7+
permissions:
8+
contents: write
9+
env:
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+
DEBEMAIL: "info@zoneminder.com"
14+
DEBFULLNAME: "Github CI"
15+
TZ: America/New_York
16+
DEBIAN_FRONTEND: noninteractive
17+
DEBSIGN_KEYID: ${{ secrets.ZMREPO_GPG_KEY_ID }}
18+
SMPFLAGS: -j10
19+
20+
jobs:
21+
build-debian:
22+
name: Build & sign .deb (${{ matrix.distro }})
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
distro: ["debian:13", "debian:12", "ubuntu:22.04", "ubuntu:24.04"]
27+
runs-on: self-hosted
28+
29+
container:
30+
image: ${{ matrix.distro }}
31+
32+
steps:
33+
- name: Prep apt
34+
run: |
35+
set -eux
36+
echo "Acquire::HTTP::Proxy \"http://192.168.9.129:3142\";" > /etc/apt/apt.conf.d/01proxy
37+
38+
if grep -q '^deb http' /etc/apt/sources.list && ! grep -q '^deb-src'\
39+
/etc/apt/sources.list; then
40+
sed -n 's/^deb /deb-src /p' /etc/apt/sources.list >> \
41+
/etc/apt/sources.list
42+
fi
43+
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
44+
sed -i 's/^Types: deb$/Types: deb deb-src/g' \
45+
/etc/apt/sources.list.d/debian.sources
46+
fi
47+
if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then
48+
sed -i 's/^Types: deb$/Types: deb deb-src/g' \
49+
/etc/apt/sources.list.d/ubuntu.sources
50+
fi
51+
apt-get update
52+
- name: Install build tools
53+
run: |
54+
set -eux
55+
apt install -y --no-install-recommends \
56+
git ca-certificates gnupg lsb-release \
57+
build-essential devscripts debhelper equivs fakeroot \
58+
cmake pkg-config ccache curl bash rsync openssh-client
59+
apt install -y debhelper sphinx-doc dh-linktree dh-apache2 cmake \
60+
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
61+
libswresample-dev libswscale-dev libbz2-dev \
62+
libturbojpeg0-dev default-libmysqlclient-dev \
63+
libpolkit-gobject-1-dev libv4l-dev libvlc-dev libssl-dev \
64+
libvncserver-dev libjwt-gnutls-dev libgsoap-dev gsoap \
65+
libmosquittopp-dev
66+
67+
- name: Checkout
68+
uses: actions/checkout@v5
69+
with:
70+
fetch-depth: 0
71+
72+
- name: Import GPG key
73+
uses: crazy-max/ghaction-import-gpg@v6
74+
with:
75+
gpg_private_key: ${{ secrets.ZMREPO_GPG_PRIVATE_KEY }}
76+
passphrase: ${{ secrets.ZMREPO_GPG_PASSPHRASE }}
77+
git_user_signingkey: false
78+
git_commit_gpgsign: false
79+
80+
- name: Install build-deps from debian/control
81+
run: |
82+
set -eux
83+
ln -sf distros/ubuntu2004 debian
84+
mk-build-deps -ir -t "apt-get -y --no-install-recommends" \
85+
debian/control
86+
- name: Build (signed)
87+
env:
88+
DEB_BUILD_OPTIONS: "parallel=$(nproc)"
89+
# gpg picks passphrase from environment via loopback
90+
run: |
91+
cd ../
92+
ln -sf zoneminder ZoneMinder_ZoneMinder.git
93+
# Needed because we are running as root
94+
git config --global --add safe.directory /__w/zoneminder/zoneminder
95+
git config --global --add safe.directory /__w/zoneminder/ZoneMinder_ZoneMinder.git/.git
96+
#git submodule init
97+
#git submodule update --init --recursive
98+
curl -s -o do_debian_package.sh https://raw.githubusercontent.com/ZoneMinder/zoneminder/refs/heads/master/utils/do_debian_package.sh
99+
chmod +x do_debian_package.sh
100+
101+
# Tell gpg to use loopback + passphrase
102+
export GPG_TTY=$(tty || true)
103+
ls -l /bin/bash
104+
./do_debian_package.sh -s=CURRENT -t=binary
105+
- name: Collect .deb artifacts (incl. signed metadata & public key)
106+
run: |
107+
set -eux
108+
mkdir -p artifacts/deb
109+
mv ../*.deb ../*.buildinfo ../*.changes ../*.dsc ../*.tar.xz ../*.tar.gz artifacts/deb/ || true
110+
# quick verify signatures (non-fatal)
111+
gpg --verify artifacts/deb/*.changes || true
112+
gpg --verify artifacts/deb/*.buildinfo || true
113+
- name: Sanitize Artifact name
114+
id: prep_artifact_name
115+
run: |
116+
# Use `sed` to replace invalid characters with a hyphen
117+
sanitized_distro_name=$(echo -n "${{ matrix.distro }}" | sed -e 's/[;\\\/:<>"|*?]/_/g' -e 's/__*/_/g')
118+
echo "artifact_name=binary-${sanitized_distro_name}" >> $GITHUB_ENV
119+
120+
- name: Upload .deb artifacts
121+
uses: actions/upload-artifact@v5
122+
with:
123+
path: artifacts/deb
124+
name: ${{ env.artifact_name }}
125+
- name: Publish to ZMREPO
126+
uses: easingthemes/ssh-deploy@main
127+
env:
128+
SSH_PRIVATE_KEY: ${{ secrets.ZMREPO_SSH_KEY }}
129+
ARGS: "-rltgoDzvO"
130+
SOURCE: artifacts/deb/
131+
REMOTE_HOST: ${{ secrets.ZMREPO_HOST }}
132+
REMOTE_USER: ${{ secrets.ZMREPO_SSH_USER }}
133+
TARGET: debian/master/mini-dinstall/incoming/
134+
135+
release:
136+
name: Create GitHub Release (on tag)
137+
needs: build-debian
138+
if: startsWith(github.ref, 'refs/tags/')
139+
runs-on: ubuntu-latest
140+
steps:
141+
- name: Download artifacts
142+
uses: actions/download-artifact@v6
143+
with:
144+
path: dist
145+
- name: Create release
146+
uses: softprops/action-gh-release@v2
147+
with:
148+
files: dist/**/*

.github/workflows/build-native-packages.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ jobs:
101101
run: |
102102
set -eux
103103
mkdir -p artifacts/deb
104-
mv ../*.deb ../*.buildinfo ../*.changes ../*.tar.gz artifacts/deb/ || true
104+
ls -l ../
105+
mv ../*.deb ../*.buildinfo ../*.changes ../*.dsc ../*.tar.xz ../*.tar.gz artifacts/deb/ || true
105106
# quick verify signatures (non-fatal)
106107
gpg --verify artifacts/deb/*.changes || true
107108
gpg --verify artifacts/deb/*.buildinfo || true

distros/redhat/zoneminder.spec

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# RtspServer is configured as a git submodule
1212
%global rtspserver_commit 055d81fe1293429e496b19104a9ed3360755a440
1313
# CxxUrl is configured as a git submodule
14-
%global CxxUrl_version v0.3
14+
%global CxxUrl_version eaf46c0207df24853a238d4499e7f4426d9d234c
1515

1616
%global sslcert %{_sysconfdir}/pki/tls/certs/localhost.crt
1717
%global sslkey %{_sysconfdir}/pki/tls/private/localhost.key
@@ -39,7 +39,7 @@ Source0: https://github.com/ZoneMinder/ZoneMinder/archive/%{version}.tar.gz#/zon
3939
Source1: https://github.com/FriendsOfCake/crud/archive/v%{crud_version}.tar.gz#/crud-%{crud_version}.tar.gz
4040
Source2: https://github.com/ZoneMinder/CakePHP-Enum-Behavior/archive/%{ceb_version}.tar.gz#/cakephp-enum-behavior-%{ceb_version}.tar.gz
4141
Source3: https://github.com/ZoneMinder/RtspServer/archive/%{rtspserver_commit}.tar.gz#/RtspServer-%{rtspserver_commit}.tar.gz
42-
Source3: https://github.com/chmike/CxxUrl/archive/%{CxxUrl_version}.tar.gz#/CxxUrl-%{CxxUrl_version}.tar.gz
42+
Source4: https://github.com/chmike/CxxUrl/archive/%{CxxUrl_version}.tar.gz#/CxxUrl-%{CxxUrl_version}.tar.gz
4343

4444
%{?rhel:BuildRequires: epel-rpm-macros}
4545
BuildRequires: systemd-devel
@@ -241,6 +241,7 @@ find %{buildroot} \( -name .htaccess -or -name .editorconfig -or -name .packlist
241241

242242
# Remove third-party header and cmake files that should not have been installed
243243
rm -rf %{buildroot}%{_prefix}/cmake
244+
rm -rf %{buildroot}%{_prefix}/%{_lib}/cmake/CxxUrl
244245
rm -rf %{buildroot}%{_includedir}
245246

246247
# Recursively change shebang in all relevant scripts and set execute permission
@@ -337,6 +338,7 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin
337338

338339
%postun
339340
%systemd_postun_with_restart %{name}.service
341+
%systemd_postun_with_restart php-fpm.service
340342

341343
%files
342344
# nothing
@@ -384,6 +386,7 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin
384386
%{_bindir}/zmrecover.pl
385387
%{_bindir}/zm_rtsp_server
386388

389+
%{_libdir}/libCxxUrl.a
387390
%{perl_vendorlib}/ZoneMinder*
388391
%{perl_vendorlib}/ONVIF*
389392
%{perl_vendorlib}/WSDiscovery*

docs/installationguide/easydocker.rst

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs/installationguide/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Contents:
77

88
.. toctree::
99
:maxdepth: 2
10+
1011
packpack
1112
ubuntu
1213
debian

scripts/ZoneMinder/lib/ZoneMinder/Event.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ sub LinkPath {
222222
'.'.$$event{Id}
223223
);
224224
} elsif ( $$event{Path} ) {
225-
if ( ( $event->RelativePath() =~ /^(\d+\/\d{4}\/\d{2}\/\d{2})/ ) ) {
225+
if ( ( $event->RelativePath() =~ /^(\d+\/\d{2}\/\d{2}\/\d{2})/ ) ) {
226226
$$event{LinkPath} = $1.'/.'.$$event{Id};
227227
} else {
228228
Error("Unable to get LinkPath from Path for $$event{Id} $$event{Path}");

scripts/zmaudit.pl.in

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,7 @@ MAIN: while( $loop ) {
281281
next;
282282
}
283283
#Event path is hour/minute/sec
284-
my $event_path = readlink($event_link);
285-
$event_path = '' if ! defined($event_path);
284+
my $event_path = readlink($event_link) // '';
286285
Debug("Checking link $event_link points to: $event_path");
287286

288287
if ( !($event_path and -e $event_path) ) {
@@ -329,8 +328,6 @@ MAIN: while( $loop ) {
329328
} # end if event found
330329

331330
if ( ! $Event->SaveJPEGs() ) {
332-
my $saveJPegs = ( $Event->has_capture_jpegs() ? 1 : 0 ) | ( $Event->has_analyse_jpegs() ? 2 : 0 );
333-
334331
if ( $Event->SaveJPEGs(
335332
( $Event->has_capture_jpegs() ? 1 : 0 ) | ( $Event->has_analyse_jpegs() ? 2 : 0 )
336333
) ) {

web/ajax/modals/filterdebug.php

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,58 @@
3434
?>
3535
<p><label>SQL</label>
3636
<?php
37-
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale<br/>FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId)<br/>WHERE<br/>';
37+
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId)
38+
WHERE
39+
';
3840
$sql .= $filter->sql();
3941
$sql .= $filter->sort_field() ? ' ORDER BY '.$filter->sort_field(). ' ' .($filter->sort_asc() ? 'ASC' : 'DESC') : '';
4042
$sql .= $filter->limit() ? ' LIMIT '.$filter->limit() : '';
4143
$sql .= $filter->skip_locked() ? ' SKIP LOCKED' : '';
4244

43-
echo $sql;
45+
46+
echo preg_replace('/\n/', '<br/>', $sql);
4447
?></p>
48+
<p><label>MySQL Explanation</label>
49+
<?php
50+
echo '
51+
<table>
52+
<thead>
53+
<tr>
54+
<th>Select Type</th>
55+
<th>Table</th>
56+
<th>Partitions</th>
57+
<th>Type</th>
58+
<th>Possible Keys</th>
59+
<th>Key</th>
60+
<th>Key Length</th>
61+
<th>Ref</th>
62+
<th>Rows</th>
63+
<th>Filtered</th>
64+
<th>Extra</th>
65+
</tr>
66+
</thead>
67+
<tbody>
68+
';
69+
$result = dbFetchAll('EXPLAIN '.$sql);
70+
foreach ($result as $row) {
71+
echo '<tr>'.PHP_EOL.
72+
'<td>'.$row['select_type'].'</td>'.
73+
'<td>'.$row['table'].'</td>'.
74+
'<td>'.$row['partitions'].'</td>'.
75+
'<td>'.$row['type'].'</td>'.
76+
'<td>'.$row['possible_keys'].'</td>'.
77+
'<td>'.$row['key'].'</td>'.
78+
'<td>'.$row['key_len'].'</td>'.
79+
'<td>'.$row['ref'].'</td>'.
80+
'<td>'.$row['rows'].'</td>'.
81+
'<td>'.$row['filtered'].'</td>'.
82+
'<td>'.$row['Extra'].'</td>';
83+
echo '</tr>';
84+
}
85+
echo '</tbody></table>';
86+
87+
?>
88+
</p>
4589
<div class="modal-footer">
4690
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Close')?> </button>
4791
</div>

web/api/app/Controller/EventsController.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public function index() {
6666
}
6767
}
6868
$conditions = $this->FilterComponent->buildFilter($named_params);
69+
#ZM\Debug(print_r($conditions, true));
6970
foreach ($conditions as $k=>$v) {
7071
if ( 0 === strpos($k, 'DateTime') ) {
7172
$new_start = preg_replace('/DateTime/', 'StartDateTime', $k);
@@ -75,19 +76,29 @@ public function index() {
7576
['OR' => $conditions['OR']],
7677
[
7778
[$new_start => $conditions[$k]],
78-
[$new_end => $conditions[$k]]
79+
['OR'=>[
80+
$new_end => $conditions[$k],
81+
'EndDateTime IS NULL',
82+
]
83+
]
7984
]
8085
];
8186
unset($conditions['OR']);
8287
} else {
8388
$conditions['OR'] = [
8489
[$new_start => $conditions[$k]],
85-
[$new_end => $conditions[$k]]
90+
[
91+
'OR'=>[
92+
$new_end => $conditions[$k],
93+
'EndDateTime IS NULL',
94+
]
95+
]
8696
];
8797
}
8898
unset($conditions[$k]);
8999
}
90100
} // end foreach condition
101+
#ZM\Debug(print_r($conditions, true));
91102

92103
} else {
93104
$conditions = $this->FilterComponent->buildFilter($_REQUEST);
@@ -127,6 +138,7 @@ public function index() {
127138
} else {
128139
$events = $this->Event->find('all', $settings);
129140
}
141+
#ZM\Debug(print_r($this->Event->getDataSource()->getLog(false, false), true));
130142
// For each event, get the frameID which has the largest score also add FS path
131143

132144
foreach ( $events as $key => $value ) {

web/includes/config.php.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ if (!defined('ZM_SERVER_ID')) {
282282
}
283283
} else {
284284
$thisServer = ZM\Server::find_one(['Id'=>ZM_SERVER_ID]); // Should be cached
285+
if(!$thisServer) {
286+
error_log('No server found for ZM_SERVER_ID '+ZM_SERVER_ID);
287+
}
285288
}
286289

287290
if ( defined('ZM_TIMEZONE') and ZM_TIMEZONE )

0 commit comments

Comments
 (0)