Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas

pull/2356/head
Isaac Connor 2018-08-02 05:25:53 -04:00
commit 50c7eec0ff
135 changed files with 21250 additions and 19707 deletions

26
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,26 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "Under Review"
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -802,6 +802,24 @@ if(WITH_SYSTEMD)
endif(NOT POLKIT_FOUND)
endif(WITH_SYSTEMD)
# Find the path to an arp compatible executable
if(ZM_PATH_ARP STREQUAL "")
find_program(ARP_EXECUTABLE arp)
if(ARP_EXECUTABLE)
set(ZM_PATH_ARP "${ARP_EXECUTABLE}")
mark_as_advanced(ARP_EXECUTABLE)
else(ARP_EXECUTABLE)
find_program(ARP_EXECUTABLE ip)
if(ARP_EXECUTABLE)
set(ZM_PATH_ARP "${ARP_EXECUTABLE} neigh")
mark_as_advanced(ARP_EXECUTABLE)
endif(ARP_EXECUTABLE)
endif(ARP_EXECUTABLE)
if(ARP_EXECUTABLE-NOTFOUND)
message(WARNING "Unable to find a compatible arp binary. Monitor probe will not function." )
endif(ARP_EXECUTABLE-NOTFOUND)
endif(ZM_PATH_ARP STREQUAL "")
# Some variables that zm expects
set(ZM_PID "${ZM_RUNDIR}/zm.pid")
set(ZM_CONFIG "${ZM_CONFIG_DIR}/zm.conf")

View File

@ -517,6 +517,7 @@ CREATE TABLE `Monitors` (
`ArchivedEvents` int(10) default NULL,
`ArchivedEventDiskSpace` bigint default NULL,
`ZoneCount` TINYINT NOT NULL DEFAULT 0,
`Refresh` int(10) unsigned default NULL,
PRIMARY KEY (`Id`)
) ENGINE=@ZM_MYSQL_ENGINE@;
@ -559,7 +560,7 @@ CREATE TABLE `Servers` (
`Name` varchar(64) NOT NULL default '',
`State_Id` int(10) unsigned,
`Status` enum('Unknown','NotRunning','Running') NOT NULL default 'Unknown',
`Load` DECIMAL(5,1),
`CpuLoad` DECIMAL(5,1) default NULL,
`TotalMem` bigint unsigned default null,
`FreeMem` bigint unsigned default null,
`TotalSwap` bigint unsigned default null,
@ -777,7 +778,8 @@ INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-423','Ffmpeg','Reolink',0,0,1,1
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-411','Ffmpeg','Reolink',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'Reolink RLC-420','Ffmpeg','Reolink',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'D-LINK DCS-3415','Remote','DCS3415',0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'IOS Camera','Ffmpeg','IPCAMIOS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'Dericam P2','Ffmpeg','DericamP2',0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,1,1,1,0,0,0,1,1,0,0,0,0,1,1,45,0,0,1,0,0,0,0,1,1,45,0,0,0,0);
--
-- Add some monitor preset values
--

View File

@ -1,20 +0,0 @@
DROP TABLE IF EXISTS `Monitor_Status`;
CREATE TABLE `Monitor_Status` (
`MonitorId` int(10) unsigned NOT NULL,
`Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown',
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
PRIMARY KEY (`MonitorId`)
) ENGINE=MEMORY;
SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM Storage WHERE Name = 'Default' AND Id=0 AND Path='/var/cache/zoneminder/events'
) > 0,
"SELECT 'Default Storage Area already exists.'",
"INSERT INTO Storage (Id,Name,Path,Scheme,ServerId) VALUES (0,'Default','/var/cache/zoneminder/events','Medium',NULL)"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -16,7 +16,7 @@ SET @s = (SELECT IF(
AND column_name = 'Refresh'
) > 0,
"SELECT 'Column Refresh exists in Monitors'",
"ALTER TABLE Monitors ADD `Refresh` int(10) unsigned default NULL"
"ALTER TABLE Monitors ADD `Refresh` int(10) unsigned default NULL AFTER `ZoneCount`"
));
PREPARE stmt FROM @s;

23
db/zm_update-1.31.45.sql Normal file
View File

@ -0,0 +1,23 @@
--
-- This updates a 1.31.44 database to 1.31.45
--
-- Add WebSite enum to Monitor.Type
-- Add Refresh column to Monitors table
-- This is the same as the update to 1.31.43, but due to Refresh not being added to zm_create.sql.in we need to have it
-- again in order to fix people who did a fresh install from 1.31.43 or 1.31.44.
--
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'Refresh'
) > 0,
"SELECT 'Column Refresh exists in Monitors'",
"ALTER TABLE Monitors ADD `Refresh` int(10) unsigned default NULL AFTER `ZoneCount`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -13,6 +13,7 @@ Build-Depends: debhelper (>= 9), cmake
, libv4l-dev (>= 0.8.3)
, libbz2-dev
, ffmpeg | libav-tools
, net-tools
, libnetpbm10-dev
, libvlccore-dev, libvlc-dev
, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev

View File

@ -8,16 +8,6 @@ SET(zmgid_final www)
SET(webroot /srv/www/htdocs)
SET(zm_webdir ${webroot}/zoneminder)
# Download jscalendar & move files into position
file(DOWNLOAD http://downloads.sourceforge.net/jscalendar/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip STATUS download_jsc)
if(download_jsc EQUAL 0)
message(STATUS "Jscalander successfully downloaded. Installing...")
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc)
message(STATUS "Status of jscalender script was: ${unzip_jsc}")
else(download_jsc EQUAL 0)
message(STATUS "Unable to download optional jscalander. Skipping...")
endif(download_jsc EQUAL 0)
# Create several empty folders
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
@ -45,7 +35,3 @@ install(FILES zoneminder.tmpfiles DESTINATION /etc/tmpfiles.d RENAME zoneminder.
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES zoneminder.service DESTINATION /usr/lib/systemd/system PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
# Install jscalendar
if(unzip_jsc STREQUAL "")
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
endif(unzip_jsc STREQUAL "")

View File

@ -1,7 +0,0 @@
#!/bin/bash
unzip -o jscalendar-1.0.zip
mkdir -v jscalendar-doc
cd jscalendar-1.0
mv -v *html *php doc/* README ../jscalendar-doc
rmdir -v doc

View File

@ -16,7 +16,6 @@ Version: 1.27.0
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
# Mootools is under the MIT license: http://mootools.net/
License: GPLv2+ and LGPLv2+ and MIT
URL: http://www.zoneminder.com/
@ -141,7 +140,7 @@ fi
%files
%defattr(-,root,root,-)
%doc AUTHORS COPYING README.md distros/opensuse/README.OpenSuse distros/opensuse/jscalendar-doc
%doc AUTHORS COPYING README.md distros/opensuse/README.OpenSuse
%docdir /opt/zoneminder/share/man
%config %attr(640,root,%{zmgid_final}) /etc/zm.conf
%config(noreplace) %attr(644,root,root) /etc/apache2/conf.d/zoneminder.conf

View File

@ -27,18 +27,6 @@ else(ZM_WEB_USER STREQUAL "nginx")
configure_file(systemd/zoneminder.tmpfiles.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.tmpfiles @ONLY)
endif(ZM_WEB_USER STREQUAL "nginx")
# Unpack jscalendar & move files into position
message(STATUS "Unpacking and Installing jscalendar...")
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/misc/jscalendar.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
ERROR_VARIABLE unzip_jsc
)
if("${unzip_jsc}" STREQUAL "")
message(STATUS "jscalendar successfully installed.")
else("${unzip_jsc}" STREQUAL "")
message(FATAL_ERROR "\nAn error occurred while jscalendar was being processed:\n${unzip_jsc}")
endif("${unzip_jsc}" STREQUAL "")
# Create several empty folders
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
@ -58,7 +46,6 @@ install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DE
# Install auxiliary files
install(FILES misc/redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
# Install zoneminder service files
install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

View File

@ -1,7 +0,0 @@
#!/bin/bash
unzip -o misc/jscalendar-1.0.zip
mkdir -v jscalendar-doc
cd jscalendar-1.0
mv -v *html *php doc/* README ../jscalendar-doc
rmdir -v doc

View File

@ -85,7 +85,7 @@ New installs
When in doubt, proceed with the default:
sudo ln -s /etc/zm/www/zoneminder.conf /etc/httpd/conf.d/
sudo dnf install mod_ssl
sudo yum install mod_ssl
7. Now start the web server:

View File

@ -1,5 +1,5 @@
D @ZM_TMPDIR@ 0755 @WEB_USER@ @WEB_GROUP@
D @ZM_SOCKDIR@ 0755 @WEB_USER@ @WEB_GROUP@
D @ZM_CACHEDIR@ 0755 @WEB_USER@ @WEB_GROUP@
D @ZM_DIR_EVENTS@ 0755 @WEB_USER@ @WEB_GROUP@
d @ZM_DIR_EVENTS@ 0755 @WEB_USER@ @WEB_GROUP@
D @ZM_DIR_IMAGES@ 0755 @WEB_USER@ @WEB_GROUP@

View File

@ -30,7 +30,6 @@ Version: 1.31.44
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
# Mootools is inder the MIT license: http://mootools.net/
# CakePHP is under the MIT license: https://github.com/cakephp/cakephp
# Crud is under the MIT license: https://github.com/FriendsOfCake/crud
@ -53,6 +52,7 @@ BuildRequires: pcre-devel
BuildRequires: libjpeg-turbo-devel
BuildRequires: findutils
BuildRequires: coreutils
BuildRequires: net-tools
BuildRequires: perl
BuildRequires: perl-generators
BuildRequires: perl(Archive::Tar)
@ -74,8 +74,11 @@ BuildRequires: gcc-c++
BuildRequires: vlc-devel
BuildRequires: libcurl-devel
BuildRequires: libv4l-devel
BuildRequires: desktop-file-utils
# ZoneMinder looks for and records the location of the ffmpeg binary during build
BuildRequires: ffmpeg
BuildRequires: ffmpeg-devel
BuildRequires: desktop-file-utils
# Required for mp4 container support
BuildRequires: libmp4v2-devel
@ -89,6 +92,7 @@ BuildRequires: x264-devel
Requires: php-mysqli
Requires: php-common
Requires: php-gd
%{?fedora:Requires: php-json}
Requires: php-pecl-apcu
%{?with_apcu_bc:Requires: php-pecl-apcu-bc}
Requires: cambozola
@ -248,7 +252,7 @@ EOF
%files
%license COPYING
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https distros/redhat/jscalendar-doc
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https
# We want these two folders to have "normal" read permission
# compared to the folder contents

View File

@ -9,7 +9,17 @@ ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
# Order matters. This Alias must come first
Alias /zm/cache /var/cache/zoneminder/cache
<Directory /var/cache/zoneminder/cache>
Options -Indexes +FollowSymLinks
Options -Indexes +FollowSymLinks
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
Require all granted
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order deny,allow
Allow from all
</IfModule>
</Directory>
Alias /zm /usr/share/zoneminder/www
@ -45,4 +55,3 @@ Alias /zm /usr/share/zoneminder/www
RewriteRule ^ index.php [L]
RewriteBase /zm/api
</Directory>

View File

@ -9,7 +9,17 @@ ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
# Order matters. This alias must come first.
Alias /zm/cache /var/cache/zoneminder/cache
<Directory /var/cache/zoneminder/cache>
Options -Indexes +FollowSymLinks
Options -Indexes +FollowSymLinks
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
Require all granted
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order deny,allow
Allow from all
</IfModule>
</Directory>
Alias /zm /usr/share/zoneminder/www

View File

@ -11,6 +11,8 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
,libavformat-dev (>= 6:10~)
,libavutil-dev (>= 6:10~)
,libswscale-dev (>= 6:10~)
,ffmpeg | libav-tools
,net-tools
,libbz2-dev
,libgcrypt-dev | libgcrypt11-dev
,libcurl4-gnutls-dev

View File

@ -13,8 +13,8 @@ The API is built in CakePHP and lives under the ``/api`` directory. It
provides a RESTful service and supports CRUD (create, retrieve, update, delete)
functions for Monitors, Events, Frames, Zones and Config.
Security
^^^^^^^^^
Login, Logout & API Security
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The APIs tie into ZoneMinder's existing security model. This means if you have
OPT_AUTH enabled, you need to log into ZoneMinder using the same browser you plan to
use the APIs from. If you are developing an app that relies on the API, you need
@ -23,11 +23,32 @@ to do a POST login from the app into ZoneMinder before you can access the API.
Then, you need to re-use the authentication information of the login (returned as cookie states)
with subsequent APIs for the authentication information to flow through to the APIs.
This means if you plan to use cuRL to experiment with these APIs, you first need to do
This means if you plan to use cuRL to experiment with these APIs, you first need to login:
**Login process for ZoneMinder v1.32.0 and above**
::
curl -d "username=XXXX&password=YYYY&action=login&view=console" -c cookies.txt http://yourzmip/zm/index.php
curl -XPOST -d "user=XXXX&pass=YYYY" -c cookies.txt http://yourzmip/zm/api/login.json
Staring ZM 1.32.0, you also have a `logout` API that basically clears your session. It looks like this:
::
curl -b cookies.txt http://yourzmip/zm/api/logout.json
**Login process for older versions of ZoneMinder**
::
curl -d "username=XXXX&password=YYYY&action=login&view=console" -c cookies.txt http://yourzmip/zm/index.php
The equivalent logout process for older versions of ZoneMinder is:
::
curl -XPOST -d "username=XXXX&password=YYYY&action=logout&view=console" -b cookies.txt http://yourzmip/zm/index.php
replacing *XXXX* and *YYYY* with your username and password, respectively.
@ -36,25 +57,55 @@ and the command will silently fail.
What the "-c cookies.txt" does is store a cookie state reflecting that you have logged into ZM. You now need
to apply that cookie state to all subsequent APIs. You do that by using a '-b cookies.txt' to subsequent APIs if you are
to apply that cookie state to all subsequent APIs. You do that by using a '-b cookies.txt' to subsequent APIs if you are
using CuRL like so:
::
curl -b cookies.txt http://yourzmip/zm/api/monitors.json
curl -b cookies.txt http://yourzmip/zm/api/monitors.json
This would return a list of monitors and pass on the authentication information to the ZM API layer.
A deeper dive into the login process
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As you might have seen above, there are two ways to login, one that uses the `login.json` API and the other that logs in using the ZM portal. If you are running ZoneMinder 1.32.0 and above, it is *strongly* recommended you use the `login.json` approach. The "old" approach will still work but is not as powerful as the API based login. Here are the reasons why:
* The "old" approach basically uses the same login webpage (`index.php`) that a user would log into when viewing the ZM console. This is not really using an API and more importantly, if you have additional components like reCAPTCHA enabled, this will not work. Using the API approach is much cleaner and will work irrespective of reCAPTCHA
* The new login API returns important information that you can use to stream videos as well, right after login. Consider for example, a typical response to the login API (`/login.json`):
::
{
"credentials": "auth=f5b9cf48693fe8552503c8ABCD5",
"append_password": 0,
"version": "1.31.44",
"apiversion": "1.0"
}
In this example I have `OPT_AUTH` enabled in ZoneMinder and it returns my credential key. You can then use this key to stream images like so:
::
<img src="https://server/zm/cgi-bin/nph-zms?monitor=1&auth=<authval>" />
Where `authval` is the credentials returned to start streaming videos.
The `append_password` field will contain 1 when it is necessary for you to append your ZM password. This is the case when you set `AUTH_RELAY` in ZM options to "plain", for example. In that case, the `credentials` field may contain something like `&user=admin&pass=` and you have to add your password to that string.
.. NOTE:: It is recommended you invoke the `login` API once every 60 minutes to make sure the session stays alive. The same is true if you use the old login method too.
This would return a list of monitors and pass on the authentication information to the ZM API layer.
So remember, if you are using authentication, please add a ``-b cookies.txt`` to each of the commands below if you are using
CuRL. If you are not using CuRL and writing your own app, you need to make sure you pass on cookies to subsequent requests
in your app.
Examples (please read security notice above)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You will see each URL ending in either ``.xml`` or ``.json``. This is the
format of the request, and it determines the format that any data returned to
you will be in. I like json, however you can use xml if you'd like.
Please remember, if you are using authentication, please add a ``-b cookies.txt`` to each of the commands below if you are using
CuRL. If you are not using CuRL and writing your own app, you need to make sure you pass on cookies to subsequent requests
in your app.
(In all examples, replace 'server' with IP or hostname & port where ZoneMinder is running)

View File

@ -2711,7 +2711,7 @@ our @options = (
},
{
name => 'ZM_TELEMETRY_DATA',
default => 'yes',
default => 'no',
description => 'Send usage information to ZoneMinder',
help => q`
Enable collection of usage information of the local system and send
@ -2954,7 +2954,7 @@ our @options = (
When creating a Web Site monitor, if the target web site has
X-Frame-Options set to sameorigin in the header, the site will
not display in ZoneMinder. This is a design feature in most modern
browsers. When this condiction has occured, ZoneMinder will write a
browsers. When this condition occurs, ZoneMinder will write a
warning to the log file. To get around this, one can install a browser
plugin or extension to ignore X-Frame headers, and then the page will
display properly. Once the plugin or extenstion has ben installed,
@ -2963,6 +2963,37 @@ our @options = (
type => $types{boolean},
category => 'web',
},
{
name => 'ZM_WEB_FILTER_SOURCE',
default => 'Hostname',
description => 'How to filter information in the source column.',
help => q`
This option only affects monitors with a source type of Ffmpeg,
Libvlc, or WebSite. This setting controls what information is
displayed in the Source column on the console. Selecting 'None'
will not filter anything. The entire source string will be
displayed, which may contain sensitive information. Selecting
'NoCredentials' will strip out usernames and passwords from the
string. If there are any port numbers in the string and they are
common (80, 554, etc) then those will be removed as well.
Selecting 'Hostname' will filter out all information except for
the hostname or ip address. When in doubt, stay with the default
'Hostname'. This feature uses the php function 'url_parts' to
identify the various pieces of the url. If the url in question
is unusual or not standard in some way, then filtering may not
produce the desired results.
`,
type => {
db_type =>'string',
hint =>'None|Hostname|NoCredentials',
pattern =>qr|^([NH])|i,
format =>q( ($1 =~ /^Non/)
? 'None'
: ($1 =~ /^H/ ? 'Hostname' : 'NoCredentials' )
)
},
category => 'web',
},
{
name => 'ZM_WEB_H_REFRESH_MAIN',
default => '60',

View File

@ -0,0 +1,475 @@
# ==========================================================================
#
# ZoneMinder Dericam P2 Control Protocol Module
# Copyright (C) Roman Dissertori
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# ==========================================================================
#
# This module contains the implementation of the Dericam P2 device control protocol
#
package ZoneMinder::Control::DericamP2;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our %CamParams = ();
# ==========================================================================
#
# Dericam P2 Control Protocol
#
# On ControlAddress use the format :
# USERNAME:PASSWORD@ADDRESS:PORT
# eg : admin:@10.1.2.1:80
# zoneminder:zonepass@10.0.100.1:40000
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
Info( "http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed:'".$res->status_line()."'" );
}
return( $result );
}
sub getCamParams
{
my $self = shift;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=getimageattr";
my $req = $self->sendCmd( $cmd );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
# Parse results setting values in %FCParams
my $content = $res->decoded_content;
while ($content =~ s/var\s+([^=]+)=([^;]+);//ms) {
$CamParams{$1} = $2;
}
}
else
{
Error( "Error check failed:'".$res->status_line()."'" );
}
}
#autoStop
#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab
sub autoStop
{
my $self = shift;
my $stop_command = shift;
my $autostop = shift;
if( $stop_command && $autostop)
{
Debug( "Auto Stop" );
usleep( $autostop );
my $cmd = "decoder_control.cgi?command=".$stop_command;
$self->sendCmd( $cmd );
}
}
# Reset the Camera
sub reset
{
my $self = shift;
Debug( "Camera Reset" );
# Move to default position
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=home";
$self->sendCmd( $cmd );
# Reset all other values to default
$cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-image_type=1&-default=on";
$self->sendCmd( $cmd );
}
# Reboot Camera (on Sleep button)
sub sleep
{
my $self = shift;
Debug( "Camera Reboot" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=sysreboot";
$self->sendCmd( $cmd );
}
# Stop the Camera
sub moveStop
{
my $self = shift;
Debug( "Camera Stop" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-act=stop";
$self->sendCmd( $cmd );
}
#Up Arrow
sub moveConUp
{
my $self = shift;
my $stop_command = "1";
Debug( "Move Up" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=up&-speed=45";
$self->sendCmd( $cmd );
#$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Down Arrow
sub moveConDown
{
my $self = shift;
my $stop_command = "3";
Debug( "Move Down" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=down&-speed=45";
$self->sendCmd( $cmd );
#$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Left Arrow
sub moveConLeft
{
my $self = shift;
my $stop_command = "5";
Debug( "Move Left" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=left&-speed=45";
$self->sendCmd( $cmd );
#$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Right Arrow
sub moveConRight
{
my $self = shift;
my $stop_command = "7";
Debug( "Move Right" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=right&-speed=45";
$self->sendCmd( $cmd );
#$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
}
#Zoom In
sub zoomConTele
{
my $self = shift;
Debug( "Zoom Tele" );
my $cmd = "decoder_control.cgi?command=18";
$self->sendCmd( $cmd );
}
#Zoom Out
sub zoomConWide
{
my $self = shift;
Debug( "Zoom Wide" );
my $cmd = "decoder_control.cgi?command=16";
$self->sendCmd( $cmd );
}
#Diagonally Up Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpRight
{
my $self = shift;
Debug( "Move Diagonally Up Right" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=upright&-speed=45";
$self->sendCmd( $cmd );
}
#Diagonally Down Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownRight
{
my $self = shift;
Debug( "Move Diagonally Down Right" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=downright&-speed=45";
$self->sendCmd( $cmd );
}
#Diagonally Up Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpLeft
{
my $self = shift;
Debug( "Move Diagonally Up Left" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=upleft&-speed=45";
$self->sendCmd( $cmd );
}
#Diagonally Down Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownLeft
{
my $self = shift;
Debug( "Move Diagonally Down Left" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=downnleft&-speed=45";
$self->sendCmd( $cmd );
}
#Set Camera Preset
#Presets must be translated into values internal to the camera
#Those values are: 30,32,34,36,38,40,42,44 for presets 1-8 respectively
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
if (( $preset >= 1 ) && ( $preset <= 8 )) {
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=preset&-act=set&-number=".(($preset*2) + 28);
$self->sendCmd( $cmd );
}
}
#Recall Camera Preset
#Presets must be translated into values internal to the camera
#Those values are: 31,33,35,37,39,41,43,45 for presets 1-8 respectively
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
if (( $preset >= 1 ) && ( $preset <= 8 )) {
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=preset&-act=goto&-number=".(($preset*2) + 29);
$self->sendCmd( $cmd );
}
if ( $preset == 9 ) {
$self->horizontalPatrol();
}
if ( $preset == 10 ) {
$self->verticalPatrol();
}
}
#Horizontal Patrol
sub horizontalPatrol
{
my $self = shift;
Debug( "Horizontal Patrol" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=hscan";
$self->sendCmd( $cmd );
}
#Vertical Patrol
sub verticalPatrol
{
my $self = shift;
Debug( "Vertical Patrol" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-act=vscan";
$self->sendCmd( $cmd );
}
# Increase Brightness
sub irisAbsOpen
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'brightness'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'brightness'} += $step;
$CamParams{'brightness'} = 100 if ($CamParams{'brightness'} > 100);
Debug( "Increase Brightness" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-brightness=".$CamParams{'brightness'};
$self->sendCmd( $cmd );
}
# Decrease Brightness
sub irisAbsClose
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'brightness'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'brightness'} -= $step;
$CamParams{'brightness'} = 0 if ($CamParams{'brightness'} < 0);
Debug( "Decrease Brightness" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-brightness=".$CamParams{'brightness'};
$self->sendCmd( $cmd );
}
# Increase Contrast
sub whiteAbsIn
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'contrast'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'contrast'} += $step;
$CamParams{'contrast'} = 100 if ($CamParams{'contrast'} > 100);
Debug( "Increase Contrast" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-contrast=".$CamParams{'contrast'};
$self->sendCmd( $cmd );
}
# Decrease Contrast
sub whiteAbsOut
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'contrast'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'contrast'} -= $step;
$CamParams{'contrast'} = 0 if ($CamParams{'contrast'} < 0);
Debug( "Decrease Contrast" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-contrast=".$CamParams{'contrast'};
$self->sendCmd( $cmd );
}
#TODO Saturation cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=44 [0-255]
sub satIncrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'saturation'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'saturation'} += $step;
$CamParams{'saturation'} = 255 if ($CamParams{'saturation'} > 255);
Debug( "Increase Saturation" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=".$CamParams{'saturation'};
$self->sendCmd( $cmd );
}
sub satDecrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'saturation'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'saturation'} -= $step;
$CamParams{'saturation'} = 0 if ($CamParams{'saturation'} < 0);
Debug( "Decrease Saturation" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-saturation=".$CamParams{'saturation'};
$self->sendCmd( $cmd );
}
#TODO Sharpness cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=37 [0-100]
sub sharpIncrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'sharpness'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'sharpness'} += $step;
$CamParams{'sharpness'} = 100 if ($CamParams{'sharpness'} > 100);
Debug( "Increase Sharpness" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=".$CamParams{'sharpness'};
$self->sendCmd( $cmd );
}
sub sharpDecrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'sharpness'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'sharpness'} -= $step;
$CamParams{'sharpness'} = 0 if ($CamParams{'sharpness'} < 0);
Debug( "Decrease Sharpness" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-sharpness=".$CamParams{'sharpness'};
$self->sendCmd( $cmd );
}
#TODO Hue cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=37 [0-100]
sub hueIncrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'hue'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'hue'} += $step;
$CamParams{'hue'} = 100 if ($CamParams{'hue'} > 100);
Debug( "Increase Hue" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=".$CamParams{'hue'};
$self->sendCmd( $cmd );
}
sub hueDecrease
{
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'hue'});
my $step = $self->getParam( $params, 'step' );
$CamParams{'hue'} -= $step;
$CamParams{'hue'} = 0 if ($CamParams{'hue'} < 0);
Debug( "Decrease Hue" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setimageattr&-hue=".$CamParams{'hue'};
$self->sendCmd( $cmd );
}
1;

View File

@ -0,0 +1,326 @@
# ==========================================================================
#
# ZoneMinder iPhone Control Protocol Module, $Date: 2018-07-15 00:20:00 +0000 $, $Revision: 0003 $
# Copyright (C) 2001-2008 Philip Coombes
#
# Modified for iPhone ipcamera for IOS BY PETER ZARGLIS n 2018-06-09 13:45:00
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the iPhone ipcamera for IOS
# control protocol.
#
# ==========================================================================
package ZoneMinder::Control::IPCAMIOS;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# iPhone ipcamera for IOS Protocol
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
my $loopfactor=100000;
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
my $logindetails = "";
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent" );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = $res->decoded_content;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
}
return( $result );
}
sub getDisplayAttr
{
my $self = shift;
my $param = shift;
my $cmdget = "parameters?";
my $resp = $self->sendCmd( $cmdget );
my @fields = split(',',$resp);
my $response=$fields[$param];
my @buffer=split(':',$response);
my $response2=$buffer[1];
return ($response2);
}
sub sleep
{
}
# Flip image vertically -> Horz -> off
sub moveConUp
{
my $self = shift;
my $params = shift;
Debug( "Flip Image" );
my $dvalue=$self->getDisplayAttr(3);
if ( $dvalue == 2 )
{
$dvalue=0;
my $cmd = "parameters?flip=$dvalue";
$self->sendCmd( $cmd );
}
else
{
$dvalue=$dvalue+1;
my $cmd = "parameters?flip=$dvalue";
$self->sendCmd( $cmd );
}
}
# Change camera (front facing or back)
sub moveConDown
{
my $self = shift;
my $params = shift;
Debug( "Change Camera" );
my $dvalue=$self->getDisplayAttr(7);
if ( $dvalue == 0 )
{
my $cmd = "parameters?camera=1";
$self->sendCmd( $cmd );
}
else
{
my $cmd = "parameters?camera=0";
$self->sendCmd( $cmd );
}
}
# Picture Orientation Clockwise
sub moveConRight
{
my $self = shift;
my $params = shift;
Debug( "Orientation" );
my $dvalue=$self->getDisplayAttr(10);
if ( $dvalue == 1 )
{
$dvalue=4;
my $cmd = "parameters?rotation=$dvalue";
$self->sendCmd( $cmd );
}
else
{
$dvalue=$dvalue-1;
my $cmd = "parameters?rotation=$dvalue";
$self->sendCmd( $cmd );
}
}
# Picture Orientation Anti-Clockwise
sub moveConLeft
{
my $self = shift;
my $params = shift;
Debug( "Orientation" );
my $dvalue=$self->getDisplayAttr(10);
if ( $dvalue == 4 )
{
$dvalue=1;
my $cmd = "parameters?rotation=$dvalue";
$self->sendCmd( $cmd );
}
else
{
$dvalue=$dvalue+1;
my $cmd = "parameters?rotation=$dvalue";
$self->sendCmd( $cmd );
}
}
# presetHome is used to turn off Torch, unlock Focus, unlock Exposure, unlock white-balance, rotation, image flipping
# Just basically reset all the little variables and set it to medium quality
# Rotation = 0 means it will autoselect using built in detection
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "parameters?torch=0&focus=0&wb=0&exposure=0&rotation=0&flip=0&quality=0.5";
$self->sendCmd( $cmd );
}
sub focusAbsNear
# Focus Un/Lock
{
my $self = shift;
my $params = shift;
Debug( "Focus Un/Lock" );
my $dvalue=$self->getDisplayAttr(2);
if ( $dvalue == 0 )
{
my $cmd = "parameters?focus=1";
$self->sendCmd( $cmd );
}
else
{
my $cmd = "parameters?focus=0";
$self->sendCmd( $cmd );
}
}
sub focusAbsFar
# Exposure Un/Lock
{
my $self = shift;
my $params = shift;
Debug( "Exposure Un/Lock" );
my $dvalue=$self->getDisplayAttr(11);
if ( $dvalue == 0 )
{
my $cmd = "parameters?exposure=1";
$self->sendCmd( $cmd );
}
else
{
my $cmd = "parameters?exposure=0";
$self->sendCmd( $cmd );
}
}
# Increase stream Quality (from 0 to 10)
sub irisAbsOpen
{
my $self = shift;
my $params = shift;
Debug( "Quality" );
my $dvalue=$self->getDisplayAttr(8);
if ( $dvalue < 1 )
{
$dvalue=$dvalue+0.1;
my $cmd = "parameters?quality=$dvalue";
$self->sendCmd( $cmd );
}
}
# Decrease stream Quality (from 10 to 0)
sub irisAbsClose
{
my $self = shift;
my $params = shift;
Debug( "Quality" );
my $dvalue=$self->getDisplayAttr(8);
if ( $dvalue > 0 )
{
$dvalue=$dvalue-0.1;
my $cmd = "parameters?quality=$dvalue";
$self->sendCmd( $cmd );
}
}
# White Balance Un/Lock
sub whiteAbsIn
{
my $self = shift;
my $params = shift;
Debug( "White Balance" );
my $dvalue=$self->getDisplayAttr(9);
if ( $dvalue == 0 )
{
my $cmd = "parameters?wb=1";
$self->sendCmd( $cmd );
}
else
{
my $cmd = "parameters?wb=0";
$self->sendCmd( $cmd );
}
}
# Torch control on/off
sub whiteAbsOut
{
my $self = shift;
my $params = shift;
Debug( "Torch" );
my $dvalue=$self->getDisplayAttr(5);
if ( $dvalue == 0 )
{
my $cmd = "parameters?torch=1";
$self->sendCmd( $cmd );
}
else
{
my $cmd = "parameters?torch=0";
$self->sendCmd( $cmd );
}
}
1;

View File

@ -108,7 +108,7 @@ sub zmDbConnect {
, $Config{ZM_DB_PASS}
);
};
if ( !$dbh or $@ ) {
if ( !$dbh or $@ ) {
Error("Error reconnecting to db: errstr:$DBI::errstr error val:$@");
} else {
$dbh->{AutoCommit} = 1;

View File

@ -347,14 +347,14 @@ sub delete {
my $event = $_[0];
if ( ! ( $event->{Id} and $event->{MonitorId} and $event->{StartTime} ) ) {
my ( $caller, undef, $line ) = caller;
Warning( "Can't Delete event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime} from $caller:$line\n" );
Warning("Can't Delete event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime} from $caller:$line\n");
return;
}
if ( ! -e $event->Storage()->Path() ) {
Warning("Not deleting event because storage path doesn't exist");
return;
}
Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime}\n" );
Info("Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime}\n");
$ZoneMinder::Database::dbh->ping();
$ZoneMinder::Database::dbh->begin_work();
@ -362,9 +362,9 @@ sub delete {
{
my $sql = 'DELETE FROM Frames WHERE EventId=?';
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
or Error( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
my $res = $sth->execute($event->{Id})
or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
if ( $ZoneMinder::Database::dbh->errstr() ) {
@ -373,10 +373,10 @@ sub delete {
}
$sql = 'DELETE FROM Stats WHERE EventId=?';
$sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Error( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
$res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
or Error("Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr());
$res = $sth->execute($event->{Id})
or Error("Can't execute '$sql': ".$sth->errstr());
$sth->finish();
if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit();
@ -387,10 +387,10 @@ sub delete {
# Do it individually to avoid locking up the table for new events
{
my $sql = 'DELETE FROM Events WHERE Id=?';
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Error( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() );
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
or Error("Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr());
my $res = $sth->execute($event->{Id})
or Error("Can't execute '$sql': ".$sth->errstr());
$sth->finish();
}
$ZoneMinder::Database::dbh->commit();

View File

@ -307,7 +307,7 @@ sub Sql {
if ( $self->{AutoMessage} ) {
# Include all events, including events that are still ongoing
# and have no EndTime yet
$sql .= ' AND ( '.$self->{Sql}.' )';
$sql .= ' WHERE ( '.$self->{Sql}.' )';
} else {
# Only include closed events (events with valid EndTime)
$sql .= ' WHERE (E.EndTime IS NOT NULL) AND ( '.$self->{Sql}.' )';

View File

@ -557,8 +557,8 @@ our $hasJSONAny = 0;
sub _testJSON {
return if ( $testedJSON );
my $result = eval {
require JSON::Any;
JSON::Any->import();
require JSON::MaybeXS;
JSON::MaybeXS->import();
};
$testedJSON = 1;
$hasJSONAny = 1 if ( $result );
@ -581,7 +581,7 @@ sub jsonEncode {
_testJSON();
if ( $hasJSONAny ) {
my $string = eval { JSON::Any->objToJson( $value ) };
my $string = eval { JSON::MaybeXS->encode_json( $value ) };
Fatal( "Unable to encode object to JSON: $@" ) unless( $string );
return( $string );
}
@ -616,7 +616,7 @@ sub jsonDecode {
_testJSON();
if ( $hasJSONAny ) {
my $object = eval { JSON::Any->jsonToObj( $value ) };
my $object = eval { JSON::MaybeXS->decode_json( $value ) };
Fatal( "Unable to decode JSON string '$value': $@" ) unless( $object );
return( $object );
}

View File

@ -198,6 +198,7 @@ sub initialise( @ ) {
my $this = shift;
my %options = @_;
$this->{hasTerm} = -t STDERR;
$this->{id} = $options{id} if defined($options{id});
$this->{logPath} = $options{logPath} if defined($options{logPath});
@ -557,7 +558,7 @@ sub logPrint {
if ( ! ( $this->{dbh} and $this->{dbh}->ping() ) ) {
$this->{sth} = undef;
if ( ! ( $this->{dbh} = ZoneMinder::Database::zmDbConnect() ) ) {
print(STDERR "Can't log to database: ");
#print(STDERR "Can't log to database: ");
$this->{databaseLevel} = NOLOG;
return;
}

View File

@ -252,36 +252,37 @@ MAIN: while( $loop ) {
foreach my $day_dir ( @day_dirs ) {
Debug( "Checking day dir $day_dir" );
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
if ( ! chdir( $day_dir ) ) {
Error( "Can't chdir to '$$Storage{Path}/$day_dir': $!" );
if ( !chdir($day_dir) ) {
Error("Can't chdir to '$$Storage{Path}/$day_dir': $!");
next;
}
if ( ! opendir( DIR, '.' ) ) {
Error( "Can't open directory '$$Storage{Path}/$day_dir': $!" );
if ( ! opendir(DIR, '.') ) {
Error("Can't open directory '$$Storage{Path}/$day_dir': $!");
next;
}
my @event_links = sort { $b <=> $a } grep { -l $_ } readdir( DIR );
closedir( DIR );
Debug("Have " . @event_links . ' event links');
closedir(DIR);
my $count = 0;
foreach my $event_link ( @event_links ) {
if ( $event_link =~ /[^\d\.]/ ) {
Warning("Non-event link found $event_link in $day_dir, skipping");
next;
}
Debug( "Checking link $event_link" );
Debug("Checking link $event_link");
( my $event = $event_link ) =~ s/^.*\.//;
#Event path is hour/minute/sec
my $event_path = readlink( $event_link );
my $event_path = readlink($event_link);
if ( !($event_path and -e $event_path) ) {
aud_print( "Event link $day_dir/$event_link does not point to valid target" );
aud_print("Event link $day_dir/$event_link does not point to valid target");
if ( confirm() ) {
( $event_link ) = ( $event_link =~ /^(.*)$/ ); # De-taint
unlink( $event_link );
unlink($event_link);
$cleaned = 1;
}
} else {
Debug( "Checking link $event_link points to $event_path " );
Debug("Checking link $event_link points to $event_path ");
my $Event = $fs_events->{$event} = new ZoneMinder::Event();
$$Event{Id} = $event;
$$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path);
@ -292,6 +293,42 @@ MAIN: while( $loop ) {
$Event->DiskSpace( undef );
} # event path exists
} # end foreach event_link
# Now check for events that have lost their link
my @time_dirs = glob('[0-9][0-9]/[0-9][0-9]/[0-9][0-9]');
foreach my $event_dir ( @time_dirs ) {
Debug("Checking time dir $event_dir");
( $event_dir ) = ( $event_dir =~ /^(.*)$/ ); # De-taint
my $event_id = undef;
my @mp4_files = glob("$event_dir/[0-9]+\-video.mp4");
foreach my $mp4_file ( @mp4_files ) {
my ( $id ) = $mp4_file =~ /^([0-9]+)\-video\.mp4$/;
if ( $id ) {
$event_id = $id;
last;
}
}
if ( $event_id ) {
my $Event = $fs_events->{$event_id} = new ZoneMinder::Event();
$$Event{Id} = $event_id;
$$Event{Path} = join('/', $Storage->Path(), $day_dir, $event_dir);
$$Event{RelativePath} = join('/', $day_dir, $event_dir);
$$Event{Scheme} = 'Deep';
$Event->MonitorId( $monitor_dir );
$Event->StorageId( $Storage->Id() );
$Event->DiskSpace( undef );
} else {
aud_print("Deleting event directories with no event id information at $day_dir/$event_dir");
if ( confirm() ) {
my $command = "rm -rf $event_dir";
executeShellCommand( $command );
$cleaned = 1;
}
} # end if able to find id
} # end foreach event_dir without link
chdir( $Storage->Path() );
} # end foreach day dir
}
@ -701,17 +738,18 @@ FROM Frames WHERE EventId=?';
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^(.*)s$/ ) {
$Config{ZM_LOG_DATABASE_LIMIT} = $1;
}
my $deleteLogByTimeSql =
'DELETE low_priority FROM Logs
WHERE TimeKey < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.')';
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
$res = $deleteLogByTimeSth->execute()
or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() );
if ( $deleteLogByTimeSth->rows() ){
aud_print( 'Deleted '.$deleteLogByTimeSth->rows()
." log table entries by time\n" );
}
my $deleted_rows;
do {
my $deleteLogByTimeSql =
'DELETE FROM Logs
WHERE TimeKey < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.') LIMIT 10';
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
$res = $deleteLogByTimeSth->execute()
or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() );
$deleted_rows = $deleteLogByTimeSth->rows();
aud_print( "Deleted $deleted_rows log table entries by time\n" );
} while ( $deleted_rows );
}
} # end if ZM_LOG_DATABASE_LIMIT
$loop = $continuous;

View File

@ -172,7 +172,7 @@ if ( !$server_up ) {
exit();
} elsif ( $command ne 'startup' ) {
print("Unable to connect to server using socket at " . SOCK_FILE . "\n");
exit( -1 );
exit(-1);
}
# The server isn't there
@ -210,7 +210,7 @@ if ( ($command eq 'check') && !$daemon ) {
# The server is there, connect to it
CLIENT->autoflush();
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args);
print(CLIENT $message);
shutdown(CLIENT, 1);
while( my $line = <CLIENT> ) {
@ -242,6 +242,7 @@ use constant KILL_DELAY => 60; # seconds to wait between sending TERM and sendin
our %cmd_hash;
our %pid_hash;
our %terminating_processes;
our %pids_to_reap;
our $zm_terminate = 0;
sub run {
@ -282,7 +283,7 @@ sub run {
bind(SERVER, $saddr) or Fatal("Can't bind to " . main::SOCK_FILE . ": $!");
listen(SERVER, SOMAXCONN) or Fatal("Can't listen: $!");
$SIG{CHLD} = \&reaper;
$SIG{CHLD} = \&chld_sig_handler;
$SIG{INT} = \&shutdown_sig_handler;
$SIG{TERM} = \&shutdown_sig_handler;
$SIG{ABRT} = \&shutdown_sig_handler;
@ -336,7 +337,7 @@ sub run {
# Do nothing, this is all we're here for
dPrint(ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n");
} elsif ( $command eq 'shutdown' ) {
# Breka out of while loop
# Break out of while loop
last;
} elsif ( $command eq 'check' ) {
check($daemon, @args);
@ -370,8 +371,8 @@ sub run {
}
restartPending();
check_for_processes_to_kill();
check_for_processes_to_kill() if %terminating_processes;
reaper() if %pids_to_reap;
} # end while
dPrint(ZoneMinder::Logger::INFO, 'Server exiting at '
@ -388,6 +389,7 @@ sub run {
}
sub cPrint {
# One thought here, if no client exists to read these... does it block?
if ( fileno(CLIENT) ) {
print CLIENT @_
}
@ -396,10 +398,7 @@ sub cPrint {
# I think the purpose of this is to echo the logs to the client process so it can then display them.
sub dPrint {
my $logLevel = shift;
# One thought here, if no client exists to read these... does it block?
if ( fileno(CLIENT) ) {
print CLIENT @_
}
cPrint(@_);
if ( $logLevel == ZoneMinder::Logger::DEBUG ) {
Debug(@_);
} elsif ( $logLevel == ZoneMinder::Logger::INFO ) {
@ -434,7 +433,11 @@ sub start {
my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new(SIGCHLD);
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
# Apparently the child closing the db connection can affect the parent.
zmDbDisconnect();
if ( my $cpid = fork() ) {
$dbh = zmDbConnect(1);
# This logReinit is required. Not sure why.
#logReinit();
@ -450,7 +453,9 @@ sub start {
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
} elsif ( defined($cpid) ) {
# Force reconnection to the db.
# Child process
# Force reconnection to the db. $dbh got copied, but isn't really valid anymore.
$dbh = zmDbConnect(1);
logReinit();
@ -467,7 +472,7 @@ sub start {
my @good_args;
foreach my $arg ( @args ) {
# Detaint arguments, if they look ok
# Detaint arguments, if they look ok
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
push @good_args, $1;
} else {
@ -483,8 +488,8 @@ sub start {
POSIX::close($fd++);
}
# Child process
$SIG{CHLD} = 'DEFAULT';
$SIG{HUP} = 'DEFAULT';
$SIG{INT} = 'DEFAULT';
$SIG{TERM} = 'DEFAULT';
$SIG{ABRT} = 'DEFAULT';
@ -630,15 +635,24 @@ sub shutdown_sig_handler {
$zm_terminate = 1;
}
sub reaper {
sub chld_sig_handler {
my $saved_status = $!;
# Wait for a child to terminate
while ( (my $cpid = waitpid(-1, WNOHANG)) > 0 ) {
my $status = $?;
$pids_to_reap{$cpid} = { status=>$?, stopped=>time() };
} # end while waitpid
$SIG{CHLD} = \&chld_sig_handler;
$! = $saved_status;
}
sub reaper {
foreach my $cpid ( keys %pids_to_reap ) {
my $process = $pid_hash{$cpid};
delete $pid_hash{$cpid};
my $reap_info = $pids_to_reap{$cpid};
my ( $status, $stopped ) = @$reap_info{'status','stopped'};
delete $pids_to_reap{$cpid};
if ( !$process ) {
dPrint(ZoneMinder::Logger::INFO, "Can't find child with pid of '$cpid'\n");
@ -647,7 +661,7 @@ sub reaper {
delete $terminating_processes{$$process{command}};
delete $$process{term_sent_at};
$process->{stopped} = time();
$process->{stopped} = $stopped;
$process->{runtime} = ($process->{stopped}-$process->{started});
delete $process->{pid};
@ -700,10 +714,8 @@ sub reaper {
} else {
delete $cmd_hash{$$process{command}};
}
} # end while waitpid
$SIG{CHLD} = \&reaper;
$! = $saved_status;
}
} # end foreach pid_to_reap
} # end sub reaper
sub restartPending {
# Restart any pending processes, we list them first because cmd_hash may change in foreach
@ -723,6 +735,8 @@ sub shutdownAll {
send_stop(1, $pid_hash{$pid});
}
while ( keys %terminating_processes ) {
reaper() if %pids_to_reap;
check_for_processes_to_kill();
if ( %terminating_processes ) {
Debug("Still " . %terminating_processes . ' to die. sleeping');

View File

@ -77,11 +77,11 @@ my $version = 0;
my $zm_terminate = 0;
GetOptions(
'daemon' =>\$daemon,
'filter=s' =>\$filter_name,
'filter_id=s' =>\$filter_id,
'version' =>\$version
) or pod2usage(-exitstatus => -1);
daemon =>\$daemon,
'filter=s' =>\$filter_name,
'filter_id=s' =>\$filter_id,
version =>\$version
) or pod2usage(-exitstatus => -1);
if ( $version ) {
print ZoneMinder::Base::ZM_VERSION . "\n";
@ -98,15 +98,16 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)
logInit($filter_id?(id=>'zmfilter_'.$filter_id):());
sub HupHandler {
Info("Received HUP, reloading");
Info('Received HUP, reloading');
ZoneMinder::Object::init_cache();
&ZoneMinder::Logger::logHupHandler();
}
sub TermHandler {
Info("Received TERM, exiting");
Info('Received TERM, exiting');
$zm_terminate = 1;
}
sub Term {
exit( 0 );
exit(0);
}
$SIG{HUP} = \&HupHandler;
$SIG{TERM} = \&TermHandler;
@ -175,7 +176,7 @@ if ( $filter_name ) {
}
if ( ! ( $filter_name or $filter_id ) ) {
Debug("Sleeping due to start delay: " . START_DELAY . ' seconds...');
Debug('Sleeping due to start delay: ' . START_DELAY . ' seconds...');
sleep(START_DELAY);
}
@ -267,8 +268,7 @@ sub checkFilter {
Info(
join(' ',
'Checking filter', $filter->{Name},
join( ', ',
join(', ',
($filter->{AutoDelete}?'delete':()),
($filter->{AutoArchive}?'archive':()),
($filter->{AutoVideo}?'video':()),
@ -311,7 +311,7 @@ sub checkFilter {
}
if ( $Config{ZM_OPT_MESSAGE} && $filter->{AutoMessage} ) {
if ( !$event->{Messaged} ) {
$delete_ok = undef if !sendMessage($filter, $event);
$delete_ok = undef if !sendMessage($filter, $Event);
}
}
if ( $Config{ZM_OPT_UPLOAD} && $filter->{AutoUpload} ) {
@ -385,7 +385,7 @@ sub generateVideo {
$format = $ffmpeg_formats[0];
}
my $command = join( '',
my $command = join('',
$Config{ZM_PATH_BIN},
'/zmvideo.pl -e ',
$event->{Id},
@ -397,7 +397,7 @@ sub generateVideo {
$format,
);
my $output = qx($command);
chomp( $output );
chomp($output);
my $status = $? >> 8;
if ( $status || logDebugging() ) {
Debug("Output: $output\n");
@ -835,7 +835,7 @@ sub sendEmail {
sub sendMessage {
my $filter = shift;
my $event = shift;
my $Event = shift;
if ( ! $Config{ZM_FROM_EMAIL} ) {
Error('No from email address defined, not sending message');
@ -848,10 +848,10 @@ sub sendMessage {
Info('Creating notification message');
my $subject = substituteTags($Config{ZM_MESSAGE_SUBJECT}, $filter, $event);
my $subject = substituteTags($Config{ZM_MESSAGE_SUBJECT}, $filter, $Event);
return 0 if !$subject;
my @attachments;
my $body = substituteTags($Config{ZM_MESSAGE_BODY}, $filter, $event, \@attachments);
my $body = substituteTags($Config{ZM_MESSAGE_BODY}, $filter, $Event, \@attachments);
return 0 if !$body;
Info("Sending notification message '$subject'");
@ -932,11 +932,11 @@ sub sendMessage {
my $sql = 'UPDATE Events SET Messaged = 1 WHERE Id = ?';
my $sth = $dbh->prepare_cached($sql)
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
my $res = $sth->execute($event->{Id})
my $res = $sth->execute($Event->{Id})
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
return 1;
}
} # end sub sendMessage
sub executeCommand {
my $filter = shift;

View File

@ -173,6 +173,12 @@ my $cwd = getcwd;
my $video_name;
my @event_ids;
# Fail if the path to a valid ffmpeg binary is not set
if ( ! -x $Config{ZM_PATH_FFMPEG} ) {
Fatal("Ffmpeg binary not found or not executable. Verify ZM_PATH_FFMPEG points to ffmpeg, avconv, or a compatible binary.");
}
if ( $event_id ) {
@event_ids = ( $event_id );

View File

@ -85,7 +85,10 @@ public:
bool CanCapture() const { return( capture ); }
bool SupportsNativeVideo() const { return( (type == FFMPEG_SRC )||(type == REMOTE_SRC)); }
bool SupportsNativeVideo() const {
return (type == FFMPEG_SRC);
//return (type == FFMPEG_SRC )||(type == REMOTE_SRC);
}
virtual int PrimeCapture() { return( 0 ); }
virtual int PreCapture()=0;

View File

@ -685,14 +685,14 @@ int FfmpegCamera::Close() {
//Function to handle capture and store
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
if ( ! mCanCapture ) {
if ( !mCanCapture ) {
return -1;
}
int ret;
static char errbuf[AV_ERROR_MAX_STRING_SIZE];
int frameComplete = false;
while ( ! frameComplete ) {
while ( !frameComplete ) {
av_init_packet(&packet);
ret = av_read_frame(mFormatContext, &packet);
@ -874,18 +874,18 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
}
#if HAVE_AVUTIL_HWCONTEXT_H
if ( hwaccel ) {
ret = avcodec_receive_frame( mVideoCodecContext, hwFrame );
ret = avcodec_receive_frame(mVideoCodecContext, hwFrame);
if ( ret < 0 ) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
Error( "Unable to send packet at frame %d: %s, continuing", frameCount, errbuf );
zm_av_packet_unref( &packet );
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
Error("Unable to send packet at frame %d: %s, continuing", frameCount, errbuf);
zm_av_packet_unref(&packet);
continue;
}
ret = av_hwframe_transfer_data(mRawFrame, hwFrame, 0);
if (ret < 0) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
Error( "Unable to transfer frame at frame %d: %s, continuing", frameCount, errbuf );
zm_av_packet_unref( &packet );
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
Error("Unable to transfer frame at frame %d: %s, continuing", frameCount, errbuf);
zm_av_packet_unref(&packet);
continue;
}
} else {

View File

@ -609,16 +609,23 @@ bool Monitor::connect() {
next_buffer.image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
next_buffer.timestamp = new struct timeval;
}
if ( ( purpose == ANALYSIS ) && analysis_fps ) {
// Size of pre event buffer must be greater than pre_event_count
// if alarm_frame_count > 1, because in this case the buffer contains
// alarmed images that must be discarded when event is created
pre_event_buffer_count = pre_event_count + alarm_frame_count - 1;
pre_event_buffer = new Snapshot[pre_event_buffer_count];
for ( int i = 0; i < pre_event_buffer_count; i++ ) {
pre_event_buffer[i].timestamp = new struct timeval;
pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
}
if ( purpose == ANALYSIS ) {
if ( analysis_fps ) {
// Size of pre event buffer must be greater than pre_event_count
// if alarm_frame_count > 1, because in this case the buffer contains
// alarmed images that must be discarded when event is created
pre_event_buffer_count = pre_event_count + alarm_frame_count - 1;
pre_event_buffer = new Snapshot[pre_event_buffer_count];
for ( int i = 0; i < pre_event_buffer_count; i++ ) {
pre_event_buffer[i].timestamp = new struct timeval;
*pre_event_buffer[i].timestamp = {0,0};
pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
}
}
timestamps = new struct timeval *[pre_event_count];
images = new Image *[pre_event_count];
last_signal = shared_data->signal;
}
Debug(3, "Success connecting");
return true;
@ -1234,11 +1241,11 @@ bool Monitor::CheckSignal( const Image *image ) {
bool Monitor::Analyse() {
if ( shared_data->last_read_index == shared_data->last_write_index ) {
// I wonder how often this happens. Maybe if this happens we should sleep or something?
return( false );
return false;
}
struct timeval now;
gettimeofday( &now, NULL );
gettimeofday(&now, NULL);
if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) {
if ( now.tv_sec != last_fps_time ) {
@ -1261,6 +1268,7 @@ bool Monitor::Analyse() {
int index;
if ( adaptive_skip ) {
// I think the idea behind adaptive skip is if we are falling behind, then skip a bunch, but not all
int read_margin = shared_data->last_read_index - shared_data->last_write_index;
if ( read_margin < 0 ) read_margin += image_buffer_count;
@ -1274,7 +1282,10 @@ bool Monitor::Analyse() {
int pending_frames = shared_data->last_write_index - shared_data->last_read_index;
if ( pending_frames < 0 ) pending_frames += image_buffer_count;
Debug( 4, "ReadIndex:%d, WriteIndex: %d, PendingFrames = %d, ReadMargin = %d, Step = %d", shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step );
Debug(4,
"ReadIndex:%d, WriteIndex: %d, PendingFrames = %d, ReadMargin = %d, Step = %d",
shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step
);
if ( step <= pending_frames ) {
index = (shared_data->last_read_index+step)%image_buffer_count;
} else {
@ -1294,17 +1305,17 @@ bool Monitor::Analyse() {
if ( shared_data->action ) {
// Can there be more than 1 bit set in the action? Shouldn't these be elseifs?
if ( shared_data->action & RELOAD ) {
Info( "Received reload indication at count %d", image_count );
Info("Received reload indication at count %d", image_count);
shared_data->action &= ~RELOAD;
Reload();
}
if ( shared_data->action & SUSPEND ) {
if ( Active() ) {
Info( "Received suspend indication at count %d", image_count );
Info("Received suspend indication at count %d", image_count);
shared_data->active = false;
//closeEvent();
} else {
Info( "Received suspend indication at count %d, but wasn't active", image_count );
Info("Received suspend indication at count %d, but wasn't active", image_count);
}
if ( config.max_suspend_time ) {
auto_resume_time = now.tv_sec + config.max_suspend_time;
@ -1313,7 +1324,7 @@ bool Monitor::Analyse() {
}
if ( shared_data->action & RESUME ) {
if ( Enabled() && !Active() ) {
Info( "Received resume indication at count %d", image_count );
Info("Received resume indication at count %d", image_count);
shared_data->active = true;
ref_image = *snap_image;
ready_count = image_count+(warmup_count/2);
@ -1324,24 +1335,14 @@ bool Monitor::Analyse() {
} // end if shared_data->action
if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) {
Info( "Auto resuming at count %d", image_count );
Info("Auto resuming at count %d", image_count);
shared_data->active = true;
ref_image = *snap_image;
ready_count = image_count+(warmup_count/2);
auto_resume_time = 0;
}
static bool static_undef = true;
static int last_section_mod = 0;
static bool last_signal;
if ( static_undef ) {
// Sure would be nice to be able to assume that these were already initialized. It's just 1 compare/branch, but really not neccessary.
static_undef = false;
timestamps = new struct timeval *[pre_event_count];
images = new Image *[pre_event_count];
last_signal = shared_data->signal;
}
if ( Enabled() ) {
bool signal = shared_data->signal;
@ -1394,27 +1395,24 @@ bool Monitor::Analyse() {
} else if ( signal && Active() && (function == MODECT || function == MOCORD) ) {
Event::StringSet zoneSet;
int motion_score = last_motion_score;
if ( !(image_count % (motion_frame_skip+1) ) ) {
// Get new score.
motion_score = DetectMotion(*snap_image, zoneSet);
int new_motion_score = DetectMotion(*snap_image, zoneSet);
Debug(3,
"After motion detection, last_motion_score(%d), new motion score(%d)",
last_motion_score, motion_score
last_motion_score, new_motion_score
);
// Why are we updating the last_motion_score too?
last_motion_score = motion_score;
last_motion_score = new_motion_score;
}
//int motion_score = DetectBlack( *snap_image, zoneSet );
if ( motion_score ) {
if ( last_motion_score ) {
if ( !event ) {
score += motion_score;
score += last_motion_score;
if ( cause.length() )
cause += ", ";
cause += MOTION_CAUSE;
} else {
score += motion_score;
score += last_motion_score;
}
noteSetMap[MOTION_CAUSE] = zoneSet;
} // end if motion_score
@ -1436,7 +1434,7 @@ bool Monitor::Analyse() {
first_link = false;
}
}
noteSet.insert( linked_monitors[i]->Name() );
noteSet.insert(linked_monitors[i]->Name());
score += 50;
}
} else {
@ -1450,14 +1448,15 @@ bool Monitor::Analyse() {
//TODO: What happens is the event closes and sets recording to false then recording to true again so quickly that our capture daemon never picks it up. Maybe need a refresh flag?
if ( (!signal_change && signal) && (function == RECORD || function == MOCORD) ) {
if ( event ) {
//TODO: We shouldn't have to do this every time. Not sure why it clears itself if this isn't here??
//snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
Debug( 3, "Detected new event at (%d.%d)", timestamp->tv_sec,timestamp->tv_usec );
Debug(3, "Detected new event at (%d.%d)", timestamp->tv_sec, timestamp->tv_usec);
if ( section_length && ( timestamp->tv_sec >= section_length ) ) {
// TODO: Wouldn't this be clearer if we just did something like if now - event->start > section_length ?
int section_mod = timestamp->tv_sec % section_length;
Debug( 3, "Section length (%d) Last Section Mod(%d), new section mod(%d)", section_length, last_section_mod, section_mod );
Debug(3,
"Section length (%d) Last Section Mod(%d), new section mod(%d)",
section_length, last_section_mod, section_mod
);
if ( section_mod < last_section_mod ) {
//if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) {
//if ( state == TAPE ) {
@ -1480,7 +1479,7 @@ bool Monitor::Analyse() {
if ( ! event ) {
// Create event
event = new Event( this, *timestamp, "Continuous", noteSetMap, videoRecording );
event = new Event(this, *timestamp, "Continuous", noteSetMap, videoRecording);
shared_data->last_event = event->Id();
//set up video store data
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
@ -1547,13 +1546,17 @@ bool Monitor::Analyse() {
if ( score ) {
if ( state == IDLE || state == TAPE || state == PREALARM ) {
if ( (!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count) ) {
Info("%s: %03d - Gone into alarm state %u > %u",
Info("%s: %03d - Gone into alarm state PreAlarmCount: %u > AlarmFrameCount:%u",
name, image_count, Event::PreAlarmCount(), alarm_frame_count);
shared_data->state = state = ALARM;
if ( signal_change || (function != MOCORD && state != ALERT) ) {
int pre_index;
int pre_event_images = pre_event_count;
if ( event ) {
// SHouldn't be able to happen because
Error("Creating new event when one exists");
}
if ( analysis_fps && pre_event_count ) {
// If analysis fps is set,
// compute the index for pre event images in the dedicated buffer
@ -1576,6 +1579,9 @@ bool Monitor::Analyse() {
else
pre_index = ((index + image_buffer_count) - pre_event_count)%image_buffer_count;
Debug(4,"Resulting pre_index(%d) from index(%d) + image_buffer_count(%d) - pre_event_count(%d)",
pre_index, index, image_buffer_count, pre_event_count);
// Seek forward the next filled slot in to the buffer (oldest data)
// from the current position
while ( pre_event_images && !image_buffer[pre_index].timestamp->tv_sec ) {
@ -1619,7 +1625,6 @@ bool Monitor::Analyse() {
pre_index = (pre_index + 1)%image_buffer_count;
}
}
event->AddFrames( pre_event_images, images, timestamps );
}
if ( alarm_frame_count ) {
@ -2470,19 +2475,17 @@ int Monitor::Capture() {
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
Info("%s: images:%d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec", name, image_count, new_fps, new_capture_bandwidth);
last_fps_time = now;
if ( new_fps != fps ) {
fps = new_fps;
db_mutex.lock();
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql),
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth) VALUES (%d, %.2lf,%u) ON DUPLICATE KEY UPDATE CaptureFPS = %.2lf, CaptureBandwidth=%u",
id, fps, new_capture_bandwidth, fps, new_capture_bandwidth);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
}
db_mutex.unlock();
} // end if new_fps != fps
fps = new_fps;
db_mutex.lock();
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql),
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth) VALUES (%d, %.2lf,%u) ON DUPLICATE KEY UPDATE CaptureFPS = %.2lf, CaptureBandwidth=%u",
id, fps, new_capture_bandwidth, fps, new_capture_bandwidth);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
}
db_mutex.unlock();
Debug(4,sql);
} // end if time has changed since last update
} // end if it might be time to report the fps
} // end if captureResult

View File

@ -288,6 +288,8 @@ protected:
Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected
bool embed_exif; // Whether to embed Exif data into each image frame or not
bool last_signal;
double fps;
unsigned int last_camera_bytes;

View File

@ -58,7 +58,7 @@ public:
int Capture( Image &image );
int PostCapture();
int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) {return 0;};
int Close() { return 0; };
int Close() { Disconnect(); return 0; };
};
#endif // ZM_REMOTE_CAMERA_HTTP_H

View File

@ -533,7 +533,7 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
zm_av_packet_unref( &packet );
} // end while ! framecomplete and buffer.size()
if(frameComplete)
return (0);
return (1);
} /* getFrame() */
} // end while true

View File

@ -524,7 +524,10 @@ bool VideoStore::setup_resampler() {
audio_out_ctx->channels = audio_in_ctx->channels;
audio_out_ctx->channel_layout = audio_in_ctx->channel_layout;
audio_out_ctx->sample_fmt = audio_in_ctx->sample_fmt;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
#else
audio_out_ctx->refcounted_frames = 1;
#endif
if (audio_out_codec->supported_samplerates) {
int found = 0;

View File

@ -17,12 +17,15 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
#define __STDC_FORMAT_MACROS 1
#include <cinttypes>
#include "zm.h"
#include "zm_db.h"
#include "zm_zone.h"
#include "zm_image.h"
#include "zm_monitor.h"
void Zone::Setup(
Monitor *p_monitor,
int p_id,

View File

@ -46,7 +46,7 @@ bool ValidateAccess( User *user, int mon_id ) {
user->Id(), user->getUsername(), mon_id );
exit( -1 );
}
return( allowed );
return allowed;
}
int main( int argc, const char *argv[] ) {

View File

@ -257,11 +257,14 @@ execpackpack () {
fi
if [ "${TRAVIS}" == "true" ]; then
utils/packpack/heartbeat.sh &
mypid=$!
packpack/packpack $parms > buildlog.txt 2>&1
kill $mypid
tail -n 3000 buildlog.txt | grep -v ONVIF
# Travis will fail the build if the output gets too long
# To mitigate that, use grep to filter out some of the noise
if [ "${ARCH}" != "armhf" ]; then
packpack/packpack $parms | grep -Ev '^(-- Installing:|-- Up-to-date:|Skip blib|Manifying|Installing /build|cp lib|writing output...|copying images...|reading sources...|[Working])'
else
# Travis never ceases to amaze. For the case of arm emulation, Travis fails the build due to too little output over a 10 minute period. Facepalm.
packpack/packpack $parms | grep -Ev '^(-- Installing:|Skip blib|Manifying|Installing /build|cp lib|writing output...|copying images...|reading sources...|[Working])'
fi
else
packpack/packpack $parms
fi

View File

@ -82,7 +82,7 @@ fi
# Don't stare too closely. You will burn your eyes out.
sed -i '/.*'${variable}'.*/{
$!{ N
s/\(.*'${variable}'.*\n.*\)\"\(.*\)\"/\1\"'"${default}"'\"/
s/\(.*'${variable}'.*\n.*\)'\''\(.*\)'\''/\1'\'''"${default}"''\''/
t yes
P
D

View File

@ -1 +1 @@
1.31.44
1.31.45

View File

@ -1,40 +1,28 @@
<?php
define( "MSG_TIMEOUT", 2.0 );
define( "MSG_DATA_SIZE", 4+256 );
define("MSG_TIMEOUT", 2.0);
define("MSG_DATA_SIZE", 4+256);
if ( canEdit( 'Monitors' ) )
{
$zmuCommand = getZmuCommand( " -m ".validInt($_REQUEST['id']) );
if ( canEdit('Monitors') ) {
$zmuCommand = getZmuCommand(' -m '.validInt($_REQUEST['id']));
switch ( validJsStr($_REQUEST['command']) )
{
case "disableAlarms" :
{
$zmuCommand .= " -n";
switch ( validJsStr($_REQUEST['command']) ) {
case 'disableAlarms' :
$zmuCommand .= ' -n';
break;
}
case "enableAlarms" :
{
$zmuCommand .= " -c";
case 'enableAlarms' :
$zmuCommand .= ' -c';
break;
}
case "forceAlarm" :
{
$zmuCommand .= " -a";
case 'forceAlarm' :
$zmuCommand .= ' -a';
break;
}
case "cancelForcedAlarm" :
{
$zmuCommand .= " -c";
case 'cancelForcedAlarm' :
$zmuCommand .= ' -c';
break;
}
default :
{
ajaxError( "Unexpected command '".validJsStr($_REQUEST['command'])."'" );
}
ajaxError("Unexpected command '".validJsStr($_REQUEST['command'])."'");
}
ajaxResponse( exec( escapeshellcmd( $zmuCommand ) ) );
ajaxResponse(exec(escapeshellcmd($zmuCommand)));
} else {
ajaxError( 'Insufficient permissions' );
ajaxError('Insufficient permissions');
}
?>

View File

@ -1,28 +1,28 @@
<?php
if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) {
ajaxError( 'No event id(s) supplied' );
ajaxError('No event id(s) supplied');
}
if ( canView( 'Events' ) ) {
if ( canView('Events') ) {
switch ( $_REQUEST['action'] ) {
case 'video' :
{
if ( empty($_REQUEST['videoFormat']) ) {
ajaxError( 'Video Generation Failure, no format given' );
ajaxError('Video Generation Failure, no format given');
} elseif ( empty($_REQUEST['rate']) ) {
ajaxError( 'Video Generation Failure, no rate given' );
ajaxError('Video Generation Failure, no rate given');
} elseif ( empty($_REQUEST['scale']) ) {
ajaxError( 'Video Generation Failure, no scale given' );
ajaxError('Video Generation Failure, no scale given');
} else {
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'.monitorLimitSql();
if ( !($event = dbFetchOne( $sql, NULL, array( $_REQUEST['id'] ) )) )
ajaxError( 'Video Generation Failure, Unable to load event' );
else {
if ( $videoFile = createVideo( $event, $_REQUEST['videoFormat'], $_REQUEST['rate'], $_REQUEST['scale'], !empty($_REQUEST['overwrite']) ) )
ajaxResponse( array( 'response'=>$videoFile ) );
if ( !($event = dbFetchOne($sql, NULL, array( $_REQUEST['id']))) ) {
ajaxError('Video Generation Failure, Unable to load event');
} else {
if ( $videoFile = createVideo($event, $_REQUEST['videoFormat'], $_REQUEST['rate'], $_REQUEST['scale'], !empty($_REQUEST['overwrite'])) )
ajaxResponse(array('response'=>$videoFile));
else
ajaxError( 'Video Generation Failed' );
ajaxError('Video Generation Failed');
}
}
$ok = true;
@ -37,7 +37,7 @@ if ( canView( 'Events' ) ) {
}
case 'export' :
{
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' );
require_once(ZM_SKIN_PATH.'/includes/export_functions.php');
# We use session vars in here, so we need to restart the session because we stopped it in index.php to improve concurrency.
session_start();
@ -46,22 +46,27 @@ if ( canView( 'Events' ) ) {
$exportDetail = $_SESSION['export']['detail'] = $_REQUEST['exportDetail'];
else
$exportDetail = false;
if ( !empty($_REQUEST['exportFrames']) )
$exportFrames = $_SESSION['export']['frames'] = $_REQUEST['exportFrames'];
else
$exportFrames = false;
if ( !empty($_REQUEST['exportImages']) )
$exportImages = $_SESSION['export']['images'] = $_REQUEST['exportImages'];
else
$exportImages = false;
if ( !empty($_REQUEST['exportVideo']) )
$exportVideo = $_SESSION['export']['video'] = $_REQUEST['exportVideo'];
else
$exportVideo = false;
if ( !empty($_REQUEST['exportMisc']) )
$exportMisc = $_SESSION['export']['misc'] = $_REQUEST['exportMisc'];
else
$exportMisc = false;
if ( !empty($_REQUEST['exportFormat']) )
$exportFormat = $_SESSION['export']['format'] = $_REQUEST['exportFormat'];
else
@ -70,67 +75,84 @@ if ( canView( 'Events' ) ) {
session_write_close();
$exportIds = !empty($_REQUEST['eids'])?$_REQUEST['eids']:$_REQUEST['id'];
if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) );
if ( $exportFile = exportEvents(
$exportIds,
(isset($_REQUEST['connkey'])?$_REQUEST['connkey']:''),
$exportDetail,
$exportFrames,
$exportImages,
$exportVideo,
$exportMisc,
$exportFormat
) )
ajaxResponse(array('exportFile'=>$exportFile));
else
ajaxError( 'Export Failed' );
ajaxError('Export Failed');
break;
}
case 'download' :
{
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' );
require_once(ZM_SKIN_PATH.'/includes/export_functions.php');
$exportVideo = 1;
$exportFormat = $_REQUEST['exportFormat'];
$exportStructure = 'flat';
$exportIds = !empty($_REQUEST['eids'])?$_REQUEST['eids']:$_REQUEST['id'];
if ( $exportFile = exportEvents( $exportIds, false, false, false, $exportVideo, false, $exportFormat, $exportStructure ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) );
if ( $exportFile = exportEvents(
$exportIds,
(isset($_REQUEST['connkey'])?$_REQUEST['connkey']:''),
false,false, false, $exportVideo, false, $exportFormat, $exportStructure ) )
ajaxResponse(array('exportFile'=>$exportFile));
else
ajaxError( 'Export Failed' );
ajaxError('Export Failed');
break;
}
}
}
} // end if canView('Events')
if ( canEdit( 'Events' ) ) {
if ( canEdit('Events') ) {
switch ( $_REQUEST['action'] ) {
case 'rename' :
{
if ( !empty($_REQUEST['eventName']) )
dbQuery( 'UPDATE Events SET Name = ? WHERE Id = ?', array( $_REQUEST['eventName'], $_REQUEST['id'] ) );
dbQuery('UPDATE Events SET Name = ? WHERE Id = ?', array($_REQUEST['eventName'], $_REQUEST['id']));
else
ajaxError( 'No new event name supplied' );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
ajaxError('No new event name supplied');
ajaxResponse(array('refreshEvent'=>true, 'refreshParent'=>true));
break;
}
case 'eventdetail' :
{
dbQuery( 'UPDATE Events SET Cause = ?, Notes = ? WHERE Id = ?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['id'] ) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
dbQuery(
'UPDATE Events SET Cause = ?, Notes = ? WHERE Id = ?',
array($_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['id'])
);
ajaxResponse(array('refreshEvent'=>true, 'refreshParent'=>true));
break;
}
case 'archive' :
case 'unarchive' :
{
$archiveVal = ($_REQUEST['action'] == 'archive')?1:0;
dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) );
dbQuery(
'UPDATE Events SET Archived = ? WHERE Id = ?',
array($archiveVal, $_REQUEST['id'])
);
ajaxResponse(array('refreshEvent'=>true, 'refreshParent'=>false));
break;
}
case 'delete' :
{
$Event = new Event( $_REQUEST['id'] );
$Event = new Event($_REQUEST['id']);
if ( ! $Event->Id() ) {
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.' ) );
ajaxResponse(array('refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.'));
} else {
$Event->delete();
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) );
ajaxResponse(array('refreshEvent'=>false, 'refreshParent'=>true));
}
break;
}
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
} // end if canEdit('Events')
ajaxError('Unrecognised action or insufficient permissions');
?>

View File

@ -27,114 +27,63 @@ App::uses('CrudControllerTrait', 'Crud.Lib');
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
*/
class AppController extends Controller {
use CrudControllerTrait;
use CrudControllerTrait;
public $components = [
'Session', // We are going to use SessionHelper to check PHP session vars
'RequestHandler',
'Crud.Crud' => [
'actions' => [
'index' => 'Crud.Index',
'add' => 'Crud.Add',
'edit' => 'Crud.Edit',
'view' => 'Crud.View',
'keyvalue' => 'Crud.List',
'category' => 'Crud.Category'
],
'listeners' => ['Api', 'ApiTransformation']
#],
public $components = [
'Session', // We are going to use SessionHelper to check PHP session vars
'RequestHandler',
'Crud.Crud' => [
'actions' => [
'index' => 'Crud.Index',
'add' => 'Crud.Add',
'edit' => 'Crud.Edit',
'view' => 'Crud.View',
'keyvalue' => 'Crud.List',
'category' => 'Crud.Category'
],
'listeners' => ['Api', 'ApiTransformation']
#],
#'DebugKit.Toolbar' => [
# 'bootstrap' => true, 'routes' => true
]
];
];
// Global beforeFilter function
//Zoneminder sets the username session variable
// to the logged in user. If this variable is set
// then you are logged in
// its pretty simple to extend this to also check
// for role and deny API access in future
// Also checking to do this only if ZM_OPT_USE_AUTH is on
public function beforeFilter() {
$this->loadModel('Config');
// Global beforeFilter function
//Zoneminder sets the username session variable
// to the logged in user. If this variable is set
// then you are logged in
// its pretty simple to extend this to also check
// for role and deny API access in future
// Also checking to do this only if ZM_OPT_USE_AUTH is on
public function beforeFilter() {
$this->loadModel('Config');
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_API'));
$config = $this->Config->find('first', $options);
$zmOptApi = $config['Config']['Value'];
if ($zmOptApi !='1') {
if ( $zmOptApi != '1' ) {
throw new UnauthorizedException(__('API Disabled'));
return;
}
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
$config = $this->Config->find('first', $options);
$zmOptAuth = $config['Config']['Value'];
if ( $zmOptAuth == '1' ) {
require_once "../../../includes/auth.php";
$this->loadModel('User');
if ( isset($_REQUEST['user']) and isset($_REQUEST['pass']) ) {
$user = $this->User->find('first', array ('conditions' => array (
'User.Username' => $_REQUEST['user'],
'User.Password' => $_REQUEST['pass'],
)) );
if ( ! $user ) {
throw new UnauthorizedException(__('User not found'));
return;
} else {
$this->Session->Write( 'user.Username', $user['User']['Username'] );
$this->Session->Write( 'user.Enabled', $user['User']['Enabled'] );
}
}
if ( isset($_REQUEST['auth']) ) {
$user = getAuthUser($_REQUEST['auth']);
if ( ! $user ) {
throw new UnauthorizedException(__('User not found'));
return;
} else {
if ( ! $this->Session->Write('user.Username', $user['Username']) )
$this->log("Error writing session var user.Username");
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
$this->log("Error writing session var user.Enabled");
}
} # end if REQUEST['auth']
if ( ! $this->Session->read('user.Username') ) {
}
// We need to reject methods that are not authenticated
// besides login and logout
if (
strcasecmp($this->params->action, 'login')
&&
strcasecmp($this->params->action,"logout")
) {
if ( !$this->Session->read('user.Username') ) {
throw new UnauthorizedException(__('Not Authenticated'));
return;
} else if ( ! $this->Session->read('user.Enabled') ) {
} else if ( !$this->Session->read('user.Enabled') ) {
throw new UnauthorizedException(__('User is not enabled'));
return;
}
$options = array ('conditions' => array ('User.Username' => $this->Session->Read('user.Username')));
$userMonitors = $this->User->find('first', $options);
$this->Session->Write('allowedMonitors',$userMonitors['User']['MonitorIds']);
$this->Session->Write('streamPermission',$userMonitors['User']['Stream']);
$this->Session->Write('eventPermission',$userMonitors['User']['Events']);
$this->Session->Write('controlPermission',$userMonitors['User']['Control']);
$this->Session->Write('systemPermission',$userMonitors['User']['System']);
$this->Session->Write('monitorPermission',$userMonitors['User']['Monitors']);
} else {
// if auth is not on, you can do everything
//$userMonitors = $this->User->find('first', $options);
$this->Session->Write('allowedMonitors','');
$this->Session->Write('streamPermission','View');
$this->Session->Write('eventPermission','Edit');
$this->Session->Write('controlPermission','Edit');
$this->Session->Write('systemPermission','Edit');
$this->Session->Write('monitorPermission','Edit');
}
}
} # end function beforeFilter()
}

View File

@ -21,15 +21,18 @@ class ConfigsController extends AppController {
*
* @return void
*/
public function index() {
$this->Config->recursive = 0;
$configs = $this->Config->find('all');
$this->set(array(
'configs' => $configs,
'_serialize' => array('configs')
));
}
public function index() {
global $configvals;
$this->Config->recursive = 0;
$configs = $this->Config->find('all');
foreach ( $configvals as $k=>$v ) {
$configs[] = array( 'Config'=>array('Name'=>$k, 'Value'=>$v ) );
}
$this->set(array(
'configs' => $configs,
'_serialize' => array('configs')
));
}
/**
* view method
@ -53,8 +56,14 @@ class ConfigsController extends AppController {
public function viewByName($name = null) {
$config = $this->Config->findByName($name, array('fields' => 'Value'));
if (!$config) {
throw new NotFoundException(__('Invalid config'));
if ( !$config ) {
global $configvals;
if ( $configvals[$name] ) {
$config = array( 'Config'=>array('Value'=>$configvals[$name]) );
} else {
throw new NotFoundException(__('Invalid config'));
}
} else {
}
$this->set(array(

View File

@ -7,61 +7,61 @@ App::uses('AppController', 'Controller');
*/
class EventsController extends AppController {
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler', 'Scaler', 'Image', 'Paginator');
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler', 'Scaler', 'Image', 'Paginator');
public function beforeFilter() {
parent::beforeFilter();
$canView = $this->Session->Read('eventPermission');
if ($canView =='None') {
if ( $canView == 'None' ) {
throw new UnauthorizedException(__('Insufficient Privileges'));
return;
}
}
/**
* index method
*
* @return void
* This also creates a thumbnail for each event.
*/
public function index() {
$this->Event->recursive = -1;
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
/**
* index method
*
* @return void
* This also creates a thumbnail for each event.
*/
public function index() {
$this->Event->recursive = -1;
if (!empty($allowedMonitors)) {
$allowedMonitors = preg_split('@,@', $this->Session->Read('allowedMonitors'), NULL, PREG_SPLIT_NO_EMPTY);
if ( !empty($allowedMonitors) ) {
$mon_options = array('Event.MonitorId' => $allowedMonitors);
} else {
$mon_options='';
$mon_options = '';
}
if ($this->request->params['named']) {
//$this->FilterComponent = $this->Components->load('Filter');
//$conditions = $this->FilterComponent->buildFilter($this->request->params['named']);
if ( $this->request->params['named'] ) {
//$this->FilterComponent = $this->Components->load('Filter');
//$conditions = $this->FilterComponent->buildFilter($this->request->params['named']);
$conditions = $this->request->params['named'];
} else {
$conditions = array();
}
} else {
$conditions = array();
}
$settings = array(
// https://github.com/ZoneMinder/ZoneMinder/issues/995
// 'limit' => $limit['ZM_WEB_EVENTS_PER_PAGE'],
// 25 events per page which is what the above
// default is, is way too low for an API
// changing this to 100 so we don't kill ZM
// with many event APIs. In future, we can
// make a nice ZM_API_ITEMS_PER_PAGE for all pagination
// API
'limit' => '100',
'order' => array('StartTime'),
'paramType' => 'querystring',
// https://github.com/ZoneMinder/ZoneMinder/issues/995
// 'limit' => $limit['ZM_WEB_EVENTS_PER_PAGE'],
// 25 events per page which is what the above
// default is, is way too low for an API
// changing this to 100 so we don't kill ZM
// with many event APIs. In future, we can
// make a nice ZM_API_ITEMS_PER_PAGE for all pagination
// API
'limit' => '100',
'order' => array('StartTime'),
'paramType' => 'querystring',
);
if ( isset( $conditions['GroupId'] ) ) {
if ( isset($conditions['GroupId']) ) {
$settings['joins'] = array(
array(
'table' => 'Groups_Monitors',
@ -75,45 +75,45 @@ class EventsController extends AppController {
}
$settings['conditions'] = array($conditions, $mon_options);
// How many events to return
$this->loadModel('Config');
$limit = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_WEB_EVENTS_PER_PAGE'),
'fields' => array('Name', 'Value')
));
$this->Paginator->settings = $settings;
$events = $this->Paginator->paginate('Event');
// How many events to return
$this->loadModel('Config');
$limit = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_WEB_EVENTS_PER_PAGE'),
'fields' => array('Name', 'Value')
));
$this->Paginator->settings = $settings;
$events = $this->Paginator->paginate('Event');
// For each event, get the frameID which has the largest score
foreach ($events as $key => $value) {
$maxScoreFrameId = $this->getMaxScoreAlarmFrameId($value['Event']['Id']);
$events[$key]['Event']['MaxScoreFrameId'] = $maxScoreFrameId;
}
// For each event, get the frameID which has the largest score
foreach ($events as $key => $value) {
$maxScoreFrameId = $this->getMaxScoreAlarmFrameId($value['Event']['Id']);
$events[$key]['Event']['MaxScoreFrameId'] = $maxScoreFrameId;
}
$this->set(compact('events'));
}
$this->set(compact('events'));
}
/**
* view method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function view($id = null) {
/**
* view method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function view($id = null) {
$this->loadModel('Config');
$this->Event->recursive = 1;
if (!$this->Event->exists($id)) {
if ( !$this->Event->exists($id) ) {
throw new NotFoundException(__('Invalid event'));
}
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
$allowedMonitors = preg_split('@,@', $this->Session->Read('allowedMonitors'), NULL, PREG_SPLIT_NO_EMPTY);
if (!empty($allowedMonitors)) {
if ( !empty($allowedMonitors) ) {
$mon_options = array('Event.MonitorId' => $allowedMonitors);
} else {
$mon_options='';
$mon_options = '';
}
$options = array('conditions' => array(array('Event.' . $this->Event->primaryKey => $id), $mon_options));
@ -149,14 +149,14 @@ class EventsController extends AppController {
*/
public function add() {
if ($this->Session->Read('eventPermission') != 'Edit') {
if ( $this->Session->Read('eventPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
if ($this->request->is('post')) {
if ( $this->request->is('post') ) {
$this->Event->create();
if ($this->Event->save($this->request->data)) {
if ( $this->Event->save($this->request->data) ) {
return $this->flash(__('The event has been saved.'), array('action' => 'index'));
}
}
@ -173,18 +173,18 @@ class EventsController extends AppController {
*/
public function edit($id = null) {
if ($this->Session->Read('eventPermission') != 'Edit') {
if ( $this->Session->Read('eventPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
$this->Event->id = $id;
if (!$this->Event->exists($id)) {
if ( !$this->Event->exists($id) ) {
throw new NotFoundException(__('Invalid event'));
}
if ($this->Event->save($this->request->data)) {
if ( $this->Event->save($this->request->data) ) {
$message = 'Saved';
} else {
$message = 'Error';
@ -204,16 +204,16 @@ class EventsController extends AppController {
* @return void
*/
public function delete($id = null) {
if ($this->Session->Read('eventPermission') != 'Edit') {
if ( $this->Session->Read('eventPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
$this->Event->id = $id;
if (!$this->Event->exists()) {
if ( !$this->Event->exists() ) {
throw new NotFoundException(__('Invalid event'));
}
$this->request->allowMethod('post', 'delete');
if ($this->Event->delete()) {
if ( $this->Event->delete() ) {
//$this->loadModel('Frame');
//$this->Event->Frame->delete();
return $this->flash(__('The event has been deleted.'), array('action' => 'index'));
@ -228,7 +228,7 @@ class EventsController extends AppController {
foreach ($this->params['named'] as $param_name => $value) {
// Transform params into mysql
if (preg_match("/interval/i", $value, $matches)) {
if ( preg_match('/interval/i', $value, $matches) ) {
$condition = array("$param_name >= (date_sub(now(), $value))");
} else {
$condition = array($param_name => $value);
@ -254,9 +254,9 @@ class EventsController extends AppController {
$this->Event->recursive = -1;
$results = array();
$moreconditions ="";
$moreconditions = '';
foreach ($this->request->params['named'] as $name => $param) {
$moreconditions = $moreconditions . " AND ".$name.$param;
$moreconditions = $moreconditions . ' AND '.$name.$param;
}
$query = $this->Event->query("select MonitorId, COUNT(*) AS Count from Events WHERE (StartTime >= (DATE_SUB(NOW(), interval $interval)) $moreconditions) GROUP BY MonitorId;");
@ -275,7 +275,7 @@ class EventsController extends AppController {
public function createThumbnail($id = null) {
$this->Event->recursive = -1;
if (!$this->Event->exists($id)) {
if ( !$this->Event->exists($id) ) {
throw new NotFoundException(__('Invalid event'));
}
@ -285,13 +285,13 @@ class EventsController extends AppController {
// Find the max Frame for this Event. Error out otherwise.
$this->loadModel('Frame');
if (! $frame = $this->Frame->find('first', array(
if ( !( $frame = $this->Frame->find('first', array(
'conditions' => array(
'EventId' => $event['Event']['Id'],
'Score' => $event['Event']['MaxScore']
)
))) {
throw new NotFoundException(__("Can not find Frame for Event " . $event['Event']['Id']));
))) ) {
throw new NotFoundException(__('Can not find Frame for Event ' . $event['Event']['Id']));
}
$this->loadModel('Config');
@ -304,14 +304,15 @@ class EventsController extends AppController {
$config = $this->Config->find('list', array(
'conditions' => array('OR' => array(
'Name' => array('ZM_WEB_LIST_THUMB_WIDTH',
'ZM_WEB_LIST_THUMB_HEIGHT',
'ZM_EVENT_IMAGE_DIGITS',
'ZM_DIR_IMAGES',
$thumbs,
'ZM_DIR_EVENTS'
)
)),
'Name' => array(
'ZM_WEB_LIST_THUMB_WIDTH',
'ZM_WEB_LIST_THUMB_HEIGHT',
'ZM_EVENT_IMAGE_DIGITS',
'ZM_DIR_IMAGES',
$thumbs,
'ZM_DIR_EVENTS'
)
)),
'fields' => array('Name', 'Value')
));
$config['ZM_WEB_SCALE_THUMBS'] = $config[$thumbs];
@ -340,7 +341,7 @@ class EventsController extends AppController {
public function archive($id = null) {
$this->Event->recursive = -1;
if (!$this->Event->exists($id)) {
if ( !$this->Event->exists($id) ) {
throw new NotFoundException(__('Invalid event'));
}
@ -365,7 +366,7 @@ class EventsController extends AppController {
public function getMaxScoreAlarmFrameId($id = null) {
$this->Event->recursive = -1;
if (!$this->Event->exists($id)) {
if ( !$this->Event->exists($id) ) {
throw new NotFoundException(__('Invalid event'));
}
@ -382,7 +383,7 @@ class EventsController extends AppController {
'Score' => $event['Event']['MaxScore']
)
))) {
throw new NotFoundException(__("Can not find Frame for Event " . $event['Event']['Id']));
throw new NotFoundException(__('Can not find Frame for Event ' . $event['Event']['Id']));
}
return $frame['Frame']['Id'];
}

View File

@ -2,10 +2,10 @@
App::uses('AppController', 'Controller');
class HostController extends AppController {
public $components = array('RequestHandler');
public function daemonCheck($daemon=false, $args=false) {
public $components = array('RequestHandler', 'Session');
public function daemonCheck($daemon=false, $args=false) {
$string = Configure::read('ZM_PATH_BIN').'/zmdc.pl check';
if ( $daemon ) {
$string .= " $daemon";
@ -15,120 +15,241 @@ class HostController extends AppController {
$result = exec($string);
$result = preg_match('/running/', $result);
$this->set(array(
'result' => $result,
'_serialize' => array('result')
));
}
function getLoad() {
$load = sys_getloadavg();
$this->set(array(
'load' => $load,
'_serialize' => array('load')
));
}
function getCredentials() {
// ignore debug warnings from other functions
$this->view='Json';
$credentials = "";
$appendPassword = 0;
$this->loadModel('Config');
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
if ($isZmAuth) {
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
if ($zmAuthRelay == 'hashed') {
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
}
elseif ($zmAuthRelay == 'plain') {
// user will need to append the store password here
$credentials = "user=".$this->Session->read('user.Username')."&pass=";
$appendPassword = 1;
}
elseif ($zmAuthRelay == 'none') {
$credentials = "user=".$this->Session->read('user.Username');
}
}
$this->set(array(
'credentials'=> $credentials,
'append_password'=>$appendPassword,
'result' => $result,
'_serialize' => array('result')
));
}
function getLoad() {
$load = sys_getloadavg();
$this->set(array(
'load' => $load,
'_serialize' => array('load')
));
}
function login() {
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
$config = $this->Config->find('first', $options);
$zmOptAuth = $config['Config']['Value'];
if ( $zmOptAuth == '1' ) {
require_once "../../../includes/auth.php";
global $user;
$user = $this->Session->read('user');
$mUser = $this->request->data('user');
$mPassword = $this->request->data('pass');
$mAuth = $this->request->data('auth');
if ( $mUser and $mPassword) {
$user = userLogin($mUser, $mPassword);
if ( !$user ) {
throw new UnauthorizedException(__('User not found or incorrect password'));
return;
}
}
elseif ( $mAuth ) {
$user = getAuthUser($mAuth);
if ( ! $user ) {
throw new UnauthorizedException(__('User not found or incorrect password'));
return;
}
}
else {
throw new UnauthorizedException(__('missing credentials'));
}
if ( 0 and $user ) {
# We have to redo the session variables because cakephp's Session code will overwrite the normal php session
# Actually I'm not sure that is true. Getting indeterminate behaviour
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
if ( ! $this->Session->Write('user', $user) )
$this->log("Error writing session var user");
Logger::Debug("user.Username: " . $this->Session->read('user.Username'));
if ( ! $this->Session->Write('user.Username', $user['Username']) )
$this->log("Error writing session var user.Username");
if ( ! $this->Session->Write('password', $user['Password']) )
$this->log("Error writing session var user.Username");
if ( ! $this->Session->Write('user.Enabled', $user['Enabled']) )
$this->log("Error writing session var user.Enabled");
if ( ! $this->Session->Write('remoteAddr', $_SERVER['REMOTE_ADDR']) )
$this->log("Error writing session var remoteAddr");
}
// I don't think this is really needed - the Username part
// Enabled check is ok
if ( !$user['Username'] ) {
throw new UnauthorizedException(__('Not Authenticated'));
return;
} else if ( !$user['Enabled'] ) {
throw new UnauthorizedException(__('User is not enabled'));
return;
}
$this->Session->Write('allowedMonitors',$user['MonitorIds']);
$this->Session->Write('streamPermission',$user['Stream']);
$this->Session->Write('eventPermission',$user['Events']);
$this->Session->Write('controlPermission',$user['Control']);
$this->Session->Write('systemPermission',$user['System']);
$this->Session->Write('monitorPermission',$user['Monitors']);
} else {
// if auth is not on, you can do everything
//$userMonitors = $this->User->find('first', $options);
$this->Session->Write('allowedMonitors','');
$this->Session->Write('streamPermission','View');
$this->Session->Write('eventPermission','Edit');
$this->Session->Write('controlPermission','Edit');
$this->Session->Write('systemPermission','Edit');
$this->Session->Write('monitorPermission','Edit');
}
$cred = $this->_getCredentials();
$ver = $this->_getVersion();
$this->set(array(
'credentials' => $cred[0],
'append_password'=>$cred[1],
'version' => $ver[0],
'apiversion' => $ver[1],
'_serialize' => array('credentials',
'append_password',
'version',
'apiversion'
)));
}
// clears out session
function logout() {
global $user;
$this->Session->Write('user', null);
$this->set(array(
'result' => 'ok',
'_serialize' => array('result')
));
}
private function _getCredentials() {
$credentials = '';
$appendPassword = 0;
$this->loadModel('Config');
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
if ( $isZmAuth ) {
require_once "../../../includes/auth.php"; # in the event we directly call getCredentials.json
$this->Session->read('user'); # this is needed for command line/curl to recognize a session
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
if ( $zmAuthRelay == 'hashed' ) {
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
} else if ( $zmAuthRelay == 'plain' ) {
// user will need to append the store password here
$credentials = 'user='.$this->Session->read('user.Username').'&pass=';
$appendPassword = 1;
} else if ( $zmAuthRelay == 'none' ) {
$credentials = 'user='.$this->Session->read('user.Username');
}
}
return array($credentials, $appendPassword);
}
function getCredentials() {
// ignore debug warnings from other functions
$this->view='Json';
$val = $this->_getCredentials();
$this->set(array(
'credentials'=> $val[0],
'append_password'=>$val[1],
'_serialize' => array('credentials', 'append_password')
) );
}
}
// If $mid is set, only return disk usage for that monitor
// If $mid is set, only return disk usage for that monitor
// Else, return an array of total disk usage, and per-monitor
// usage.
function getDiskPercent($mid = null) {
$this->loadModel('Config');
$this->loadModel('Monitor');
function getDiskPercent($mid = null) {
$this->loadModel('Config');
$this->loadModel('Monitor');
// If $mid is passed, see if it is valid
if ($mid) {
if (!$this->Monitor->exists($mid)) {
throw new NotFoundException(__('Invalid monitor'));
}
}
// If $mid is passed, see if it is valid
if ($mid) {
if (!$this->Monitor->exists($mid)) {
throw new NotFoundException(__('Invalid monitor'));
}
}
$zm_dir_events = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_DIR_EVENTS'),
'fields' => array('Name', 'Value')
));
$zm_dir_events = $zm_dir_events['ZM_DIR_EVENTS' ];
$zm_dir_events = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_DIR_EVENTS'),
'fields' => array('Name', 'Value')
));
$zm_dir_events = $zm_dir_events['ZM_DIR_EVENTS' ];
// Test to see if $zm_dir_events is relative or absolute
if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
// relative - so add the full path
$zm_dir_events = Configure::read('ZM_PATH_WEB') . '/' . $zm_dir_events;
}
// Test to see if $zm_dir_events is relative or absolute
if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
// relative - so add the full path
$zm_dir_events = Configure::read('ZM_PATH_WEB') . '/' . $zm_dir_events;
}
if ($mid) {
// Get disk usage for $mid
$usage = shell_exec ("du -sh0 $zm_dir_events/$mid | awk '{print $1}'");
} else {
$monitors = $this->Monitor->find('all', array(
'fields' => array('Id', 'Name', 'WebColour')
));
$usage = array();
if ($mid) {
// Get disk usage for $mid
$usage = shell_exec ("du -sh0 $zm_dir_events/$mid | awk '{print $1}'");
} else {
$monitors = $this->Monitor->find('all', array(
'fields' => array('Id', 'Name', 'WebColour')
));
$usage = array();
// Add each monitor's usage to array
foreach ($monitors as $key => $value) {
$id = $value['Monitor']['Id'];
$name = $value['Monitor']['Name'];
$color = $value['Monitor']['WebColour'];
// Add each monitor's usage to array
foreach ($monitors as $key => $value) {
$id = $value['Monitor']['Id'];
$name = $value['Monitor']['Name'];
$color = $value['Monitor']['WebColour'];
$space = shell_exec ("du -s0 $zm_dir_events/$id | awk '{print $1}'");
if ($space == null) {
$space = 0;
}
$space = $space/1024/1024;
$space = shell_exec ("du -s0 $zm_dir_events/$id | awk '{print $1}'");
if ($space == null) {
$space = 0;
}
$space = $space/1024/1024;
$usage[$name] = array(
'space' => rtrim($space),
'color' => $color
);
}
$usage[$name] = array(
'space' => rtrim($space),
'color' => $color
);
}
// Add total usage to array
$space = shell_exec( "df $zm_dir_events |tail -n1 | awk '{print $3 }'");
$space = $space/1024/1024;
$usage['Total'] = array(
'space' => rtrim($space),
'color' => '#F7464A'
);
}
// Add total usage to array
$space = shell_exec( "df $zm_dir_events |tail -n1 | awk '{print $3 }'");
$space = $space/1024/1024;
$usage['Total'] = array(
'space' => rtrim($space),
'color' => '#F7464A'
);
}
$this->set(array(
'usage' => $usage,
'_serialize' => array('usage')
));
}
$this->set(array(
'usage' => $usage,
'_serialize' => array('usage')
));
}
function getTimeZone() {
//http://php.net/manual/en/function.date-default-timezone-get.php
@ -139,18 +260,18 @@ class HostController extends AppController {
));
}
function getVersion() {
//throw new UnauthorizedException(__('API Disabled'));
$version = Configure::read('ZM_VERSION');
// not going to use the ZM_API_VERSION
// requires recompilation and dependency on ZM upgrade
//$apiversion = Configure::read('ZM_API_VERSION');
$apiversion = '1.0';
private function _getVersion() {
$version = Configure::read('ZM_VERSION');
$apiversion = '1.0';
return array($version, $apiversion);
}
$this->set(array(
'version' => $version,
'apiversion' => $apiversion,
'_serialize' => array('version', 'apiversion')
));
}
function getVersion() {
$val = $this->_getVersion();
$this->set(array(
'version' => $val[0],
'apiversion' => $val[1],
'_serialize' => array('version', 'apiversion')
));
}
}

View File

@ -18,6 +18,7 @@ class MonitorsController extends AppController {
public function beforeRender() {
$this->set($this->Monitor->enumValues());
}
public function beforeFilter() {
parent::beforeFilter();
$canView = $this->Session->Read('monitorPermission');
@ -35,7 +36,7 @@ class MonitorsController extends AppController {
public function index() {
$this->Monitor->recursive = 0;
if ($this->request->params['named']) {
if ( $this->request->params['named'] ) {
$this->FilterComponent = $this->Components->load('Filter');
//$conditions = $this->FilterComponent->buildFilter($this->request->params['named']);
$conditions = $this->request->params['named'];
@ -49,7 +50,7 @@ class MonitorsController extends AppController {
}
$find_array = array('conditions'=>$conditions,'contain'=>array('Group'));
if ( isset( $conditions['GroupId'] ) ) {
if ( isset($conditions['GroupId']) ) {
$find_array['joins'] = array(
array(
'table' => 'Groups_Monitors',
@ -84,11 +85,11 @@ class MonitorsController extends AppController {
*/
public function view($id = null) {
$this->Monitor->recursive = 0;
if (!$this->Monitor->exists($id)) {
if ( !$this->Monitor->exists($id) ) {
throw new NotFoundException(__('Invalid monitor'));
}
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
if (!empty($allowedMonitors)) {
$allowedMonitors=preg_split('@,@', $this->Session->Read('allowedMonitors'), NULL, PREG_SPLIT_NO_EMPTY);
if ( !empty($allowedMonitors) ) {
$restricted = array('Monitor.' . $this->Monitor->primaryKey => $allowedMonitors);
} else {
$restricted = '';
@ -115,12 +116,12 @@ class MonitorsController extends AppController {
if ( $this->request->is('post') ) {
if ( $this->Session->Read('systemPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
$this->Monitor->create();
if ($this->Monitor->save($this->request->data)) {
if ( $this->Monitor->save($this->request->data) ) {
$this->daemonControl($this->Monitor->id, 'start');
//return $this->flash(__('The monitor has been saved.'), array('action' => 'index'));
$message = 'Saved';
@ -144,10 +145,10 @@ class MonitorsController extends AppController {
public function edit($id = null) {
$this->Monitor->id = $id;
if (!$this->Monitor->exists($id)) {
if ( !$this->Monitor->exists($id) ) {
throw new NotFoundException(__('Invalid monitor'));
}
if ($this->Session->Read('monitorPermission') != 'Edit') {
if ( $this->Session->Read('monitorPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
@ -163,9 +164,17 @@ class MonitorsController extends AppController {
// - restart or stop this monitor after change
$func = $Monitor['Function'];
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
$this->daemonControl( $this->Monitor->id, 'stop' );
if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID')) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) {
$this->daemonControl( $this->Monitor->id, 'start' );
$this->daemonControl($this->Monitor->id, 'stop');
if (
( $func != 'None' )
and
(
(!defined('ZM_SERVER_ID'))
or
($Monitor['ServerId']==ZM_SERVER_ID)
)
) {
$this->daemonControl($this->Monitor->id, 'start');
}
} else {
$message = 'Error ' . print_r($this->Monitor->invalidFields(), true);
@ -187,10 +196,10 @@ class MonitorsController extends AppController {
*/
public function delete($id = null) {
$this->Monitor->id = $id;
if (!$this->Monitor->exists()) {
if ( !$this->Monitor->exists() ) {
throw new NotFoundException(__('Invalid monitor'));
}
if ($this->Session->Read('systemPermission') != 'Edit') {
if ( $this->Session->Read('systemPermission') != 'Edit' ) {
throw new UnauthorizedException(__('Insufficient privileges'));
return;
}
@ -198,7 +207,7 @@ class MonitorsController extends AppController {
$this->daemonControl($this->Monitor->id, 'stop');
if ($this->Monitor->delete()) {
if ( $this->Monitor->delete() ) {
return $this->flash(__('The monitor has been deleted.'), array('action' => 'index'));
} else {
return $this->flash(__('The monitor could not be deleted. Please, try again.'), array('action' => 'index'));
@ -226,7 +235,7 @@ class MonitorsController extends AppController {
public function alarm() {
$id = $this->request->params['named']['id'];
$cmd = strtolower($this->request->params['named']['command']);
if (!$this->Monitor->exists($id)) {
if ( !$this->Monitor->exists($id) ) {
throw new NotFoundException(__('Invalid monitor'));
}
if ( $cmd != 'on' && $cmd != 'off' && $cmd != 'status' ) {
@ -252,19 +261,19 @@ class MonitorsController extends AppController {
// form auth key based on auth credentials
$this->loadModel('Config');
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
$config = $this->Config->find('first', $options);
$config = $this->Config->find('first', $options);
$zmOptAuth = $config['Config']['Value'];
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY'));
$config = $this->Config->find('first', $options);
$config = $this->Config->find('first', $options);
$zmAuthRelay = $config['Config']['Value'];
$auth='';
$auth = '';
if ( $zmOptAuth ) {
if ( $zmAuthRelay == 'hashed' ) {
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
$config = $this->Config->find('first', $options);
$config = $this->Config->find('first', $options);
$zmAuthHashSecret = $config['Config']['Value'];
$time = localtime();
@ -293,7 +302,7 @@ class MonitorsController extends AppController {
$id = $this->request->params['named']['id'];
$daemon = $this->request->params['named']['daemon'];
if (!$this->Monitor->exists($id)) {
if ( !$this->Monitor->exists($id) ) {
throw new NotFoundException(__('Invalid monitor'));
}

View File

@ -0,0 +1,172 @@
<?php
App::uses('AppController', 'Controller');
/**
* Users Controller
*
* @property User $User
*/
class UsersController extends AppController {
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler', 'Paginator');
/**
* index method
*
* @return void
* This also creates a thumbnail for each user.
*/
public function index() {
$this->User->recursive = 0;
$users = $this->Paginator->paginate('User');
$this->set(compact('users'));
}
/**
* view method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function view($id = null) {
$this->loadModel('Config');
$configs = $this->Config->find('list', array(
'fields' => array('Name', 'Value'),
'conditions' => array('Name' => array('ZM_DIR_EVENTS'))
));
$this->User->recursive = 1;
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$user = $this->User->find('first', $options);
$this->set(array(
'user' => $user,
'_serialize' => array('user')
));
}
/**
* add method
*
* @return void
*/
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
return $this->flash(__('The user has been saved.'), array('action' => 'index'));
}
$this->Session->setFlash(
__('The user could not be saved. Please, try again.')
);
}
}
/**
* edit method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
} else {
$this->request->data = $this->User->read(null, $id);
unset($this->request->data['User']['password']);
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
/**
* delete method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function delete($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
$this->request->allowMethod('post', 'delete');
if ($this->User->delete()) {
$message = 'The user has been deleted.';
} else {
$message = 'The user could not be deleted. Please, try again.';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
public function beforeFilter() {
parent::beforeFilter();
$this->loadModel('Config');
$configs = $this->Config->find('list', array(
'fields' => array('Name', 'Value'),
'conditions' => array('Name' => array('ZM_OPT_USE_AUTH'))
));
if ( $configs['ZM_OPT_USE_AUTH'] ) {
$this->Auth->allow('add','logout');
} else {
$this->Auth->allow();
}
}
public function login() {
$this->loadModel('Config');
$configs = $this->Config->find('list', array(
'fields' => array('Name', 'Value'),
'conditions' => array('Name' => array('ZM_OPT_USE_AUTH'))
));
if ( ! $configs['ZM_OPT_USE_AUTH'] ) {
$this->set(array(
'message' => 'Login is not required.',
'_serialize' => array('message')
));
return;
}
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}

View File

@ -8,92 +8,93 @@ App::uses('AppController', 'Controller');
*/
class ZonePresetsController extends AppController {
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler');
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler');
/**
* index method
*
* @return void
*/
public function index() {
$zonePresets = $this->ZonePreset->find('all');
$this->set(array(
'zonePresets' => $zonePresets,
'_serialize' => array('zonePresets')
));
}
/**
* index method
*
* @return void
*/
public function index() {
$zonePresets = $this->ZonePreset->find('all');
$this->set(array(
'zonePresets' => $zonePresets,
'_serialize' => array('zonePresets')
));
}
/**
* view method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function view($id = null) {
if (!$this->ZonePreset->exists($id)) {
throw new NotFoundException(__('Invalid zone preset'));
}
$options = array('conditions' => array('ZonePreset.' . $this->ZonePreset->primaryKey => $id));
$this->set('zonePreset', $this->ZonePreset->find('first', $options));
}
/**
* view method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function view($id = null) {
if ( !$this->ZonePreset->exists($id) ) {
throw new NotFoundException(__('Invalid zone preset'));
}
$options = array('conditions' => array('ZonePreset.' . $this->ZonePreset->primaryKey => $id));
$this->set('zonePreset', $this->ZonePreset->find('first', $options));
}
/**
* add method
*
* @return void
*/
public function add() {
if ($this->request->is('post')) {
$this->ZonePreset->create();
if ($this->ZonePreset->save($this->request->data)) {
return $this->flash(__('The zone preset has been saved.'), array('action' => 'index'));
}
}
}
/**
* add method
*
* @return void
*/
public function add() {
if ( $this->request->is('post') ) {
$this->ZonePreset->create();
if ( $this->ZonePreset->save($this->request->data) ) {
return $this->flash(__('The zone preset has been saved.'), array('action' => 'index'));
}
}
}
/**
* edit method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function edit($id = null) {
if (!$this->ZonePreset->exists($id)) {
throw new NotFoundException(__('Invalid zone preset'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->ZonePreset->save($this->request->data)) {
return $this->flash(__('The zone preset has been saved.'), array('action' => 'index'));
}
} else {
$options = array('conditions' => array('ZonePreset.' . $this->ZonePreset->primaryKey => $id));
$this->request->data = $this->ZonePreset->find('first', $options);
}
}
/**
* edit method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function edit($id = null) {
if ( !$this->ZonePreset->exists($id) ) {
throw new NotFoundException(__('Invalid zone preset'));
}
if ( $this->request->is(array('post', 'put')) ) {
if ( $this->ZonePreset->save($this->request->data) ) {
return $this->flash(__('The zone preset has been saved.'), array('action' => 'index'));
}
} else {
$options = array('conditions' => array('ZonePreset.' . $this->ZonePreset->primaryKey => $id));
$this->request->data = $this->ZonePreset->find('first', $options);
}
}
/**
* delete method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function delete($id = null) {
$this->ZonePreset->id = $id;
if (!$this->ZonePreset->exists()) {
throw new NotFoundException(__('Invalid zone preset'));
}
$this->request->allowMethod('post', 'delete');
if ($this->ZonePreset->delete()) {
return $this->flash(__('The zone preset has been deleted.'), array('action' => 'index'));
} else {
return $this->flash(__('The zone preset could not be deleted. Please, try again.'), array('action' => 'index'));
}
}}
/**
* delete method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function delete($id = null) {
$this->ZonePreset->id = $id;
if ( !$this->ZonePreset->exists() ) {
throw new NotFoundException(__('Invalid zone preset'));
}
$this->request->allowMethod('post', 'delete');
if ( $this->ZonePreset->delete() ) {
return $this->flash(__('The zone preset has been deleted.'), array('action' => 'index'));
} else {
return $this->flash(__('The zone preset could not be deleted. Please, try again.'), array('action' => 'index'));
}
}
} // end class ZonePresetsController

View File

@ -7,148 +7,141 @@ App::uses('AppController', 'Controller');
*/
class ZonesController extends AppController {
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler');
/**
* Components
*
* @var array
*/
public $components = array('RequestHandler');
public function beforeFilter() {
parent::beforeFilter();
$canView = $this->Session->Read('monitorPermission');
if ($canView =='None')
{
throw new UnauthorizedException(__('Insufficient Privileges'));
return;
}
public function beforeFilter() {
parent::beforeFilter();
$canView = $this->Session->Read('monitorPermission');
if ( $canView =='None' ) {
throw new UnauthorizedException(__('Insufficient Privileges'));
return;
}
}
}
// Find all zones which belong to a MonitorId
public function forMonitor($id = null) {
// Find all zones which belong to a MonitorId
public function forMonitor($id = null) {
$this->loadModel('Monitor');
if (!$this->Monitor->exists($id)) {
throw new NotFoundException(__('Invalid monitor'));
if ( !$this->Monitor->exists($id) ) {
throw new NotFoundException(__('Invalid monitor'));
}
$this->Zone->recursive = -1;
$zones = $this->Zone->find('all', array(
'conditions' => array('MonitorId' => $id)
'conditions' => array('MonitorId' => $id)
));
$this->set(array(
'zones' => $zones,
'_serialize' => array('zones')
'zones' => $zones,
'_serialize' => array('zones')
));
}
public function index() {
}
public function index() {
$this->Zone->recursive = -1;
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
if (!empty($allowedMonitors))
{
$mon_options = array('Zones.MonitorId' => $allowedMonitors);
}
else
{
$mon_options='';
$allowedMonitors = preg_split('@,@', $this->Session->Read('allowedMonitors'), NULL, PREG_SPLIT_NO_EMPTY);
if ( !empty($allowedMonitors) ) {
$mon_options = array('Zones.MonitorId' => $allowedMonitors);
} else {
$mon_options = '';
}
$zones = $this->Zone->find('all',$mon_options);
$this->set(array(
'zones' => $zones,
'_serialize' => array('zones')
'zones' => $zones,
'_serialize' => array('zones')
));
}
/**
* add method
*
* @return void
*/
public function add() {
if ($this->request->is('post')) {
$this->Zone->create();
if ($this->Zone->save($this->request->data)) {
return $this->flash(__('The zone has been saved.'), array('action' => 'index'));
}
}
$monitors = $this->Zone->Monitor->find('list');
$this->set(compact('monitors'));
}
/**
* edit method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function edit($id = null) {
$this->Zone->id = $id;
if (!$this->Zone->exists($id)) {
throw new NotFoundException(__('Invalid zone'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->Zone->save($this->request->data)) {
return $this->flash(__('The zone has been saved.'), array('action' => 'index'));
}
} else {
$options = array('conditions' => array('Zone.' . $this->Zone->primaryKey => $id));
$this->request->data = $this->Zone->find('first', $options);
}
$monitors = $this->Zone->Monitor->find('list');
$this->set(compact('monitors'));
}
/**
* delete method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function delete($id = null) {
$this->Zone->id = $id;
if (!$this->Zone->exists()) {
throw new NotFoundException(__('Invalid zone'));
}
$this->request->allowMethod('post', 'delete');
if ($this->Zone->delete()) {
return $this->flash(__('The zone has been deleted.'), array('action' => 'index'));
} else {
return $this->flash(__('The zone could not be deleted. Please, try again.'), array('action' => 'index'));
}
}
public function createZoneImage( $id = null ) {
$this->loadModel('Monitor');
$this->Monitor->id = $id;
if (!$this->Monitor->exists()) {
throw new NotFoundException(__('Invalid zone'));
}
$this->loadModel('Config');
$zm_dir_images = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_DIR_IMAGES'),
'fields' => array('Name', 'Value')
));
$zm_dir_images = $zm_dir_images['ZM_DIR_IMAGES'];
$zm_path_web = Configure::read('ZM_PATH_WEB');
$zm_path_bin = Configure::read('ZM_PATH_BIN');
$images_path = "$zm_path_web/$zm_dir_images";
chdir($images_path);
$command = escapeshellcmd("$zm_path_bin/zmu -z -m $id");
system( $command, $status );
$this->set(array(
'status' => $status,
'_serialize' => array('status')
));
}
}
/**
* add method
*
* @return void
*/
public function add() {
if ( $this->request->is('post') ) {
$this->Zone->create();
if ( $this->Zone->save($this->request->data) ) {
return $this->flash(__('The zone has been saved.'), array('action' => 'index'));
}
}
$monitors = $this->Zone->Monitor->find('list');
$this->set(compact('monitors'));
}
/**
* edit method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function edit($id = null) {
$this->Zone->id = $id;
if ( !$this->Zone->exists($id) ) {
throw new NotFoundException(__('Invalid zone'));
}
if ( $this->request->is(array('post', 'put')) ) {
if ( $this->Zone->save($this->request->data) ) {
return $this->flash(__('The zone has been saved.'), array('action' => 'index'));
}
} else {
$options = array('conditions' => array('Zone.' . $this->Zone->primaryKey => $id));
$this->request->data = $this->Zone->find('first', $options);
}
$monitors = $this->Zone->Monitor->find('list');
$this->set(compact('monitors'));
}
/**
* delete method
*
* @throws NotFoundException
* @param string $id
* @return void
*/
public function delete($id = null) {
$this->Zone->id = $id;
if ( !$this->Zone->exists() ) {
throw new NotFoundException(__('Invalid zone'));
}
$this->request->allowMethod('post', 'delete');
if ( $this->Zone->delete() ) {
return $this->flash(__('The zone has been deleted.'), array('action' => 'index'));
} else {
return $this->flash(__('The zone could not be deleted. Please, try again.'), array('action' => 'index'));
}
}
public function createZoneImage($id = null) {
$this->loadModel('Monitor');
$this->Monitor->id = $id;
if ( !$this->Monitor->exists() ) {
throw new NotFoundException(__('Invalid zone'));
}
$this->loadModel('Config');
$zm_dir_images = $this->Config->find('list', array(
'conditions' => array('Name' => 'ZM_DIR_IMAGES'),
'fields' => array('Name', 'Value')
));
$zm_dir_images = $zm_dir_images['ZM_DIR_IMAGES'];
$zm_path_web = Configure::read('ZM_PATH_WEB');
$zm_path_bin = Configure::read('ZM_PATH_BIN');
$images_path = "$zm_path_web/$zm_dir_images";
chdir($images_path);
$command = escapeshellcmd("$zm_path_bin/zmu -z -m $id");
system($command, $status);
$this->set(array(
'status' => $status,
'_serialize' => array('status')
));
}
}

View File

@ -1,12 +1,28 @@
<?php
App::uses('AppModel', 'Model');
/**
* User Model
*
* @property Monitor $Monitor
* @property Frame $Frame
*/
class User extends AppModel {
public $validate = array(
'Username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
)
),
'Password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
)
);
/**
* Use table
*
@ -26,6 +42,48 @@ class User extends AppModel {
*
* @var string
*/
public $displayField = 'Name';
public $displayField = 'Username';
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* belongsTo associations
*
* @var array
*/
public $belongsTo = array(
/*'Monitor' => array(
'className' => 'Monitor',
'foreignKey' => 'MonitorId',
'conditions' => '',
'fields' => '',
'order' => ''
)
*/
);
/**
* hasMany associations
*
* @var array
*/
public $hasMany = array(
/*
'Frame' => array(
'className' => 'Frame',
'foreignKey' => 'UserId',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
*/
);
}

View File

@ -0,0 +1,15 @@
<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend><?php echo __('Add User'); ?></legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('role', array(
'options' => array('admin' => 'Admin', 'author' => 'Author')
));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

View File

@ -0,0 +1,5 @@
<?php
$array['users'] = $users;
$array['pagination'] = $this->Paginator->params();
echo json_encode($array);
?>

View File

@ -0,0 +1 @@
echo json_encode($user);

View File

@ -0,0 +1,13 @@
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>

View File

@ -0,0 +1,2 @@
$xml = Xml::fromArray(array('response' => $events));
echo $xml->asXML();

View File

@ -0,0 +1,2 @@
$xml = Xml::fromArray(array('response' => $event));
echo $xml->asXML();

View File

@ -12,6 +12,9 @@ private $defaults = array(
'CanMoveRel' => 0,
'CanMoveCon' => 0,
'CanPan' => 0,
'CanReset' => 0,
'CanSleep' => 0,
'CanWake' => 0,
'MinPanRange' => NULL,
'MaxPanRange' => NULL,
'MinPanStep' => NULL,
@ -103,7 +106,7 @@ private $defaults = array(
if ( $IdOrRow ) {
$row = NULL;
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
$row = dbFetchOne( 'SELECT * FROM Control WHERE Id=?', NULL, array( $IdOrRow ) );
$row = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $IdOrRow ) );
if ( ! $row ) {
Error("Unable to load Control record for Id=" . $IdOrRow );
}

View File

@ -246,7 +246,7 @@ class Event {
if ( is_null($new) or ( $new != '' ) ) {
$this->{'DiskSpace'} = $new;
}
if ( null === $this->{'DiskSpace'} ) {
if ( (!array_key_exists('DiskSpace',$this)) or (null === $this->{'DiskSpace'}) ) {
$this->{'DiskSpace'} = folder_size($this->Path());
dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'}));
}

View File

@ -9,17 +9,19 @@ private $defaults = array(
'Name' => '',
'StorageId' => 0,
'ServerId' => 0,
'Type' => 'Ffmpeg',
'Function' => 'None',
'Enabled' => 1,
'LinkedMonitors' => null,
'Width' => null,
'Height' => null,
'Orientation' => null,
'AnalysisFPSLimit' => null,
'ZoneCount' => 0,
'Triggers' => null,
'Type' => 'Ffmpeg',
'MaxFPS' => null,
'AlarmMaxFPS' => null,
'Refresh' => null,
);
private $status_fields = array(
'AnalysisFPS' => null,
@ -215,7 +217,7 @@ private $control_fields = array(
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
$args['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
$args['auth'] = generateAuthHash(ZM_AUTH_HASH_IPS);
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
$args['user'] = $_SESSION['username'];
$args['pass'] = $_SESSION['password'];
@ -335,13 +337,13 @@ private $control_fields = array(
}
if ( $mode == 'stop' ) {
daemonControl( 'stop', 'zmc', $zmcArgs );
daemonControl('stop', 'zmc', $zmcArgs);
} else {
if ( $mode == 'restart' ) {
daemonControl( 'stop', 'zmc', $zmcArgs );
daemonControl('stop', 'zmc', $zmcArgs);
}
if ( $this->{'Function'} != 'None' ) {
daemonControl( 'start', 'zmc', $zmcArgs );
daemonControl('start', 'zmc', $zmcArgs);
}
}
} else if ( $this->ServerId() ) {
@ -378,6 +380,8 @@ private $control_fields = array(
} catch ( Exception $e ) {
Error("Except $e thrown trying to restart zmc");
}
} else {
Error("Server not assigned to Monitor in a multi-server setup. Please assign a server to the Monitor.");
}
} // end function zmcControl
@ -385,9 +389,9 @@ private $control_fields = array(
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
if ( ZM_OPT_CONTROL ) {
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'});
}
daemonControl( 'stop', 'zma', '-m '.$this->{'Id'} );
daemonControl('stop', 'zma', '-m '.$this->{'Id'});
} else {
if ( $mode == 'restart' ) {
if ( ZM_OPT_CONTROL ) {
@ -404,7 +408,8 @@ private $control_fields = array(
}
}
} // end if we are on the recording server
}
} // end public function zmaControl
public function GroupIds( $new='') {
if ( $new != '' ) {
if(!is_array($new)) {
@ -484,14 +489,20 @@ private $control_fields = array(
$source = preg_replace( '/^.*\//', '', $this->{'Path'} );
} elseif ( $this->{'Type'} == 'Ffmpeg' || $this->{'Type'} == 'Libvlc' || $this->{'Type'} == 'WebSite' ) {
$url_parts = parse_url( $this->{'Path'} );
unset($url_parts['user']);
unset($url_parts['pass']);
#unset($url_parts['scheme']);
unset($url_parts['query']);
#unset($url_parts['path']);
if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) )
unset($url_parts['port']);
$source = unparse_url($url_parts);
if ( ZM_WEB_FILTER_SOURCE == "Hostname" ) { # Filter out everything but the hostname
$source = $url_parts['host'];
} elseif ( ZM_WEB_FILTER_SOURCE == "NoCredentials" ) { # Filter out sensitive and common items
unset($url_parts['user']);
unset($url_parts['pass']);
#unset($url_parts['scheme']);
unset($url_parts['query']);
#unset($url_parts['path']);
if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) )
unset($url_parts['port']);
$source = unparse_url($url_parts);
} else { # Don't filter anything
$source = $this->{'Path'};
}
}
if ( $source == '' ) {
$source = 'Monitor ' . $this->{'Id'};

View File

@ -1,5 +1,5 @@
<?php
require_once( 'database.php' );
require_once('database.php');
class Server {
private $defaults = array(

View File

@ -140,20 +140,31 @@ class Storage {
return $usage;
}
public function disk_total_space() {
if ( ! array_key_exists('disk_total_space', $this) ) {
$this->{'disk_total_space'} = disk_total_space($this->Path());
if ( !array_key_exists('disk_total_space', $this) ) {
$path = $this->Path();
if ( file_exists($path) ) {
$this->{'disk_total_space'} = disk_total_space($path);
} else {
Error("Path $path does not exist.");
$this->{'disk_total_space'} = 0;
}
}
return $this->{'disk_total_space'};
}
public function disk_used_space() {
# This isn't a function like this in php, so we have to add up the space used in each event.
if ( (! array_key_exists('disk_used_space', $this)) or (!$this->{'disk_used_space'}) ) {
if ( ( !array_key_exists('disk_used_space', $this)) or !$this->{'disk_used_space'} ) {
if ( $this->{'Type'} == 's3fs' ) {
$this->{'disk_used_space'} = $this->disk_event_space();
} else {
$path = $this->Path();
$this->{'disk_used_space'} = disk_total_space($path) - disk_free_space($path);
if ( file_exists($path) ) {
$this->{'disk_used_space'} = disk_total_space($path) - disk_free_space($path);
} else {
Error("Path $path does not exist.");
$this->{'disk_used_space'} = 0;
}
}
}
return $this->{'disk_used_space'};

View File

@ -114,23 +114,23 @@ if ( $action == 'login' && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 're
// as it produces the same error as when you don't answer a recaptcha
if (isset($responseData['error-codes']) && is_array($responseData['error-codes'])) {
if (!in_array('invalid-input-secret',$responseData['error-codes'])) {
Error ('reCaptcha authentication failed');
Error('reCaptcha authentication failed');
userLogout();
$view='login';
$refreshParent = true;
return;
} else {
//Let them login but show an error
echo '<script type="text/javascript">alert("'.translate('RecaptchaWarning').'"); </script>';
Error ('Invalid recaptcha secret detected');
Error('Invalid recaptcha secret detected');
}
}
} // end if success==false
} // end if using reCaptcha
$username = validStr( $_REQUEST['username'] );
$username = validStr($_REQUEST['username']);
$password = isset($_REQUEST['password'])?validStr($_REQUEST['password']):'';
userLogin( $username, $password );
userLogin($username, $password);
$refreshParent = true;
$view = 'console';
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=console';
@ -492,8 +492,8 @@ if ( canEdit( 'Monitors' ) ) {
# If we change anything that changes the shared mem size, zma can complain. So let's stop first.
if ( $monitor['Type'] != 'WebSite' ) {
zmaControl( $monitor, 'stop' );
zmcControl( $monitor, 'stop' );
zmaControl($monitor, 'stop');
zmcControl($monitor, 'stop');
}
dbQuery( 'UPDATE Monitors SET '.implode( ', ', $changes ).' WHERE Id=?', array($mid) );
// Groups will be added below
@ -567,6 +567,8 @@ if ( canEdit( 'Monitors' ) ) {
}
$restart = true;
} else {
Logger::Debug("No action due to no changes to Monitor");
} # end if count(changes)
if (
@ -730,7 +732,7 @@ if ( canEdit( 'System' ) ) {
$_SESSION['zmMontageLayout'] = $Layout->Id();
setcookie('zmMontageLayout', $Layout->Id(), 1 );
session_write_close();
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=montagereview';
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=montage';
} // end if save
} else if ( $_REQUEST['object'] == 'server' ) {

View File

@ -19,7 +19,7 @@
//
function userLogin($username, $password='', $passwordHashed=false) {
global $user, $cookies;
global $user;
$sql = 'SELECT * FROM Users WHERE Enabled=1';
$sql_values = NULL;
@ -34,7 +34,12 @@ function userLogin($username, $password='', $passwordHashed=false) {
$sql .= ' AND Username=?';
$sql_values = array($username);
}
session_start();
$close_session = 0;
if ( !is_session_started() ) {
Logger::Debug("Starting session in userLogin");
session_start();
$close_session = 1;
}
$_SESSION['username'] = $username;
if ( ZM_AUTH_RELAY == 'plain' ) {
// Need to save this in session
@ -54,7 +59,9 @@ function userLogin($username, $password='', $passwordHashed=false) {
$_SESSION['loginFailed'] = true;
unset($user);
}
session_write_close();
if ( $close_session )
session_write_close();
return isset($user) ? $user: null;
} # end function userLogin
function userLogout() {
@ -103,13 +110,13 @@ function getAuthUser($auth) {
return false;
} // end getAuthUser($auth)
function generateAuthHash($useRemoteAddr) {
function generateAuthHash($useRemoteAddr, $force=false) {
if ( ZM_OPT_USE_AUTH and ZM_AUTH_RELAY == 'hashed' and isset($_SESSION['username']) and $_SESSION['passwordHash'] ) {
# regenerate a hash at half the liftetime of a hash, an hour is 3600 so half is 1800
$time = time();
$mintime = $time - ( ZM_AUTH_HASH_TTL * 1800 );
if ( ( !isset($_SESSION['AuthHash']) ) or ( $_SESSION['AuthHashGeneratedAt'] < $mintime ) ) {
if ( $force or ( !isset($_SESSION['AuthHash']) ) or ( $_SESSION['AuthHashGeneratedAt'] < $mintime ) ) {
# Don't both regenerating Auth Hash if an hour hasn't gone by yet
$local_time = localtime();
$authKey = '';
@ -120,19 +127,25 @@ function generateAuthHash($useRemoteAddr) {
}
#Logger::Debug("Generated using hour:".$local_time[2] . ' mday:' . $local_time[3] . ' month:'.$local_time[4] . ' year: ' . $local_time[5] );
$auth = md5($authKey);
session_start();
$_SESSION['AuthHash'] = $auth;
$_SESSION['AuthHashGeneratedAt'] = $time;
session_write_close();
if ( !$force ) {
$close_session = 0;
if ( !is_session_started() ) {
session_start();
$close_session = 1;
}
$_SESSION['AuthHash'] = $auth;
$_SESSION['AuthHashGeneratedAt'] = $time;
session_write_close();
} else {
return $auth;
}
#Logger::Debug("Generated new auth $auth at " . $_SESSION['AuthHashGeneratedAt']. " using $authKey" );
#} else {
#} else {
#Logger::Debug("Using cached auth " . $_SESSION['AuthHash'] ." beacuse generatedat:" . $_SESSION['AuthHashGeneratedAt'] . ' < now:'. $time . ' - ' . ZM_AUTH_HASH_TTL . ' * 1800 = '. $mintime);
} # end if AuthHash is not cached
return $_SESSION['AuthHash'];
} else {
$auth = '';
}
return $auth;
} # end if using AUTH and AUTH_RELAY
return '';
}
function visibleMonitor($mid) {
@ -153,4 +166,17 @@ function canEdit($area, $mid=false) {
return ( $user[$area] == 'Edit' && ( !$mid || visibleMonitor($mid) ));
}
function is_session_started() {
if ( php_sapi_name() !== 'cli' ) {
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
} else {
return session_id() === '' ? FALSE : TRUE;
}
} else {
Warning("php_sapi_name === 'cli'");
}
return FALSE;
}
?>

View File

@ -227,7 +227,7 @@ function getImageStreamHTML( $id, $src, $width, $height, $title='' ) {
if ( canStreamIframe() ) {
return '<iframe id="'.$id.'" src="'.$src.'" alt="'. validHtmlStr($title) .'" '.($width? ' width="'. validInt($width).'"' : '').($height?' height="'.validInt($height).'"' : '' ).'/>';
} else {
return '<img id="'.$id.'" src="'.$src.'" alt="'. validHtmlStr($title) .'" style="'.($width? ' width:'.$width.';' : '' ).($height ? ' height:'. $height.';' : '' ).'"/>';
return '<img id="'.$id.'" src="'.$src.'" alt="'. validHtmlStr($title) .'" style="'.($width? ' width:'.$width.'px;' : '' ).($height ? ' height:'. $height.'px;' : '' ).'"/>';
}
}
@ -334,11 +334,11 @@ function getZmuCommand( $args ) {
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
$zmuCommand .= ' -A '.generateAuthHash( false );
$zmuCommand .= ' -A '.generateAuthHash(false, true);
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
$zmuCommand .= ' -U ' .escapeshellarg($_SESSION['username']).' -P '.escapeshellarg($_SESSION['password']);
} elseif ( ZM_AUTH_RELAY == 'none' ) {
$zmuCommand .= " -U ".escapeshellarg($_SESSION['username']);
$zmuCommand .= ' -U '.escapeshellarg($_SESSION['username']);
}
}
@ -2063,7 +2063,7 @@ function cache_bust( $file ) {
global $css;
$dirname = preg_replace( '/\//', '_', $parts['dirname'] );
$cacheFile = $dirname.'_'.$parts['filename'].'-'.$css.'-'.filemtime($file).'.'.$parts['extension'];
if ( file_exists( ZM_DIR_CACHE.'/'.$cacheFile ) or symlink( ZM_PATH_WEB.'/'.$file, ZM_DIR_CACHE.'/'.$cacheFile ) ) {
if ( file_exists(ZM_DIR_CACHE.'/'.$cacheFile) or symlink(ZM_PATH_WEB.'/'.$file, ZM_DIR_CACHE.'/'.$cacheFile) ) {
return 'cache/'.$cacheFile;
} else {
Warning("Failed linking $file to $cacheFile");
@ -2137,15 +2137,15 @@ function getStreamHTML( $monitor, $options = array() ) {
if ( isset($options['scale']) and $options['scale'] and ( $options['scale'] != 100 ) ) {
//Warning("Scale to " . $options['scale'] );
$options['width'] = reScale( $monitor->Width(), $options['scale'] ) . 'px';
$options['height'] = reScale( $monitor->Height(), $options['scale'] ) . 'px';
$options['width'] = reScale( $monitor->Width(), $options['scale'] );
$options['height'] = reScale( $monitor->Height(), $options['scale'] );
} else {
# scale is empty or 100
# There may be a fixed width applied though, in which case we need to leave the height empty
if ( ! ( isset($options['width']) and $options['width'] ) ) {
$options['width'] = $monitor->Width() . 'px';
$options['width'] = $monitor->Width();
if ( ! ( isset($options['height']) and $options['height'] ) ) {
$options['height'] = $monitor->Height() . 'px';
$options['height'] = $monitor->Height();
}
} else if ( ! isset($options['height']) ) {
$options['height'] = '';
@ -2159,12 +2159,13 @@ function getStreamHTML( $monitor, $options = array() ) {
$options['buffer'] = $monitor->StreamReplayBuffer();
//Warning("width: " . $options['width'] . ' height: ' . $options['height']. ' scale: ' . $options['scale'] );
if ( $monitor->Type() == "WebSite" ) {
return getWebSiteUrl( 'liveStream'.$monitor->Id(), $monitor->Path(),
( isset($options['width']) ? $options['width'] : NULL ),
( isset($options['height']) ? $options['height'] : NULL ),
$monitor->Name()
);
if ( $monitor->Type() == 'WebSite' ) {
return getWebSiteUrl(
'liveStream'.$monitor->Id(), $monitor->Path(),
( isset($options['width']) ? $options['width'] : NULL ),
( isset($options['height']) ? $options['height'] : NULL ),
$monitor->Name()
);
//FIXME, the width and height of the image need to be scaled.
} else if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
$streamSrc = $monitor->getStreamSrc( array(
@ -2177,7 +2178,7 @@ function getStreamHTML( $monitor, $options = array() ) {
return getVideoStreamHTML( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], ZM_MPEG_LIVE_FORMAT, $monitor->Name() );
} else if ( $options['mode'] == 'stream' and canStream() ) {
$options['mode'] = 'jpeg';
$streamSrc = $monitor->getStreamSrc( $options );
$streamSrc = $monitor->getStreamSrc($options);
if ( canStreamNative() )
return getImageStreamHTML( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], $monitor->Name());

View File

@ -51,7 +51,12 @@ require_once( 'includes/Event.php' );
require_once( 'includes/Group.php' );
require_once( 'includes/Monitor.php' );
if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) {
if (
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
or
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
) {
$protocol = 'https';
} else {
$protocol = 'http';

View File

@ -324,6 +324,7 @@ $SLANG = array(
'Exclude' => 'Exclude',
'Execute' => 'Execute',
'ExportDetails' => 'Export Event Details',
'ExportMatches' => 'Export Matches',
'Exif' => 'Embed EXIF data into image',
'Export' => 'Export',
'DownloadVideo' => 'Download Video',
@ -662,6 +663,7 @@ $SLANG = array(
'ShowFilterWindow' => 'Show Filter Window',
'ShowTimeline' => 'Show Timeline',
'SignalCheckColour' => 'Signal Check Colour',
'SignalCheckPoints' => 'Signal Check Points',
'Size' => 'Size',
'SkinDescription' => 'Change the skin for this session',
'CSSDescription' => 'Change the css for this session',
@ -696,6 +698,7 @@ $SLANG = array(
'Stills' => 'Stills',
'Stopped' => 'Stopped',
'Stop' => 'Stop',
'StorageArea' => 'Storage Area',
'StorageScheme' => 'Scheme',
'StreamReplayBuffer' => 'Stream Replay Image Buffer',
'Stream' => 'Stream',

View File

@ -60,10 +60,10 @@ $SLANG = array(
'AttrDateTime' => 'Fecha/Hora',
'AttrDiskBlocks' => 'Disk Blocks',
'AttrDiskPercent' => 'Disk Percent',
'AttrDuration' => 'Duración',
'AttrDuration' => 'Duración',
'AttrFrames' => 'Cuadros',
'AttrId' => 'Id',
'AttrMaxScore' => 'Puntaje Máximo',
'AttrMaxScore' => 'Puntaje Máximo',
'AttrMonitorId' => 'Monitor Id',
'AttrMonitorName' => 'Nombre Monitor',
'AttrName' => 'Name',
@ -71,7 +71,7 @@ $SLANG = array(
'AttrSystemLoad' => 'System Load',
'AttrTime' => 'Hora',
'AttrTotalScore' => 'Puntaje Total',
'AttrWeekday' => 'Día Semana',
'AttrWeekday' => 'Día Semana',
'Auto' => 'Auto',
'AutoStopTimeout' => 'Auto Stop Timeout',
'Available' => 'Available', // Added - 2009-03-31
@ -95,7 +95,7 @@ $SLANG = array(
'BadLabelY' => 'Label Y co-ordinate must be set to an integer of zero or more',
'BadMaxFPS' => 'Maximum FPS must be a positive integer or floating point value',
'BadMotionFrameSkip' => 'Motion Frame skip count must be an integer of zero or more',
'BadNameChars' => 'Los nombres pueden contener solamente caracteres alfanuméricos más el guión y la raya',
'BadNameChars' => 'Los nombres pueden contener solamente caracteres alfanuméricos más el guión y la raya',
'BadPalette' => 'Palette must be set to a valid value', // Added - 2009-03-31
'BadPath' => 'Path must be set to a valid value',
'BadPort' => 'Port must be set to a valid number',
@ -177,7 +177,7 @@ $SLANG = array(
'Config' => 'Config.',
'ConfiguredFor' => 'Configurado Para',
'ConfirmDeleteEvents' => 'Are you sure you wish to delete the selected events?',
'ConfirmPassword' => 'Confirmar Contraseña',
'ConfirmPassword' => 'Confirmar Contraseña',
'ConjAnd' => 'y',
'ConjOr' => 'o',
'Console' => 'Console',
@ -195,7 +195,7 @@ $SLANG = array(
'Cycle' => 'Cycle',
'CycleWatch' => 'Cycle Watch',
'DateTime' => 'Date/Time', // Added - 2011-06-16
'Day' => 'Día',
'Day' => 'Día',
'Debug' => 'Debug',
'DefaultRate' => 'Default Rate',
'DefaultScale' => 'Default Scale',
@ -203,15 +203,15 @@ $SLANG = array(
'Deinterlacing' => 'Deinterlacing', // Added - 2015-04-18
'Delay' => 'Delay', // Added - 2015-04-18
'Delete' => 'Borrar',
'DeleteAndNext' => 'Borrar &amp; Próximo',
'DeleteAndNext' => 'Borrar &amp; Próximo',
'DeleteAndPrev' => 'Borrar &amp; Anterior',
'DeleteSavedFilter' => 'Borrar Filtro Guardado',
'Description' => 'Descripción',
'Description' => 'Descripción',
'DetectedCameras' => 'Detected Cameras', // Added - 2009-03-31
'DetectedProfiles' => 'Detected Profiles', // Added - 2015-04-18
'Device' => 'Device', // Added - 2009-02-08
'DeviceChannel' => 'Canal',
'DeviceFormat' => 'Señal',
'DeviceFormat' => 'Señal',
'DeviceNumber' => 'Fuente',
'DevicePath' => 'Device Path',
'Devices' => 'Devices',
@ -232,15 +232,15 @@ $SLANG = array(
'DonateYes' => 'Yes, I\'d like to donate now',
'Download' => 'Download',
'DuplicateMonitorName' => 'Duplicate Monitor Name', // Added - 2009-03-31
'Duration' => 'Duración',
'Duration' => 'Duración',
'Edit' => 'Editar',
'Email' => 'Email',
'EnableAlarms' => 'Enable Alarms',
'Enabled' => 'Habilitado',
'EnterNewFilterName' => 'Ingresar Nuevo Nombre De Filtro',
'Error' => 'Error',
'ErrorBrackets' => 'Error, Revisar si tiene la misma cantidad de paréntesis de apertura',
'ErrorValidValue' => 'Error, Revisar si los términos tienen nombres validos',
'ErrorBrackets' => 'Error, Revisar si tiene la misma cantidad de paréntesis de apertura',
'ErrorValidValue' => 'Error, Revisar si los términos tienen nombres validos',
'Etc' => 'etc',
'Event' => 'Evento',
'EventFilter' => 'Filtro de Evento',
@ -302,7 +302,7 @@ $SLANG = array(
'FrameSkip' => 'Saltear Cuadro',
'Frames' => 'Cuadros',
'Func' => 'Func',
'Function' => 'Función',
'Function' => 'Función',
'Gain' => 'Gain',
'General' => 'General',
'GenerateVideo' => 'Crear Video',
@ -326,12 +326,12 @@ $SLANG = array(
'HighBW' => 'Alta&nbsp;B/W',
'Home' => 'Home',
'Hour' => 'Hora',
'Hue' => 'Saturación',
'Hue' => 'Saturación',
'Id' => 'Id',
'Idle' => 'Pasivo',
'Ignore' => 'Ignorar',
'Image' => 'Imagen',
'ImageBufferSize' => 'Tamaño del Buffer de Imagen',
'ImageBufferSize' => 'Tamaño del Buffer de Imagen',
'Images' => 'Images',
'In' => 'In',
'Include' => 'Incluir',
@ -434,7 +434,7 @@ $SLANG = array(
'MonitorProbe' => 'Monitor Probe', // Added - 2009-03-31
'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2009-03-31
'Monitors' => 'Monitores',
'Montage' => 'Cámara Múltiple',
'Montage' => 'Cámara Múltiple',
'Month' => 'Mes',
'More' => 'More', // Added - 2011-06-16
'MotionFrameSkip' => 'Motion Frame Skip',
@ -446,8 +446,8 @@ $SLANG = array(
'MtgDefault' => 'Default', // Added 2013.08.15.
'MustBeGe' => 'Debe ser mayor o igual que',
'MustBeLe' => 'Debe ser menor o igual que',
'MustConfirmPassword' => 'Debe confirmar la contraseña',
'MustSupplyPassword' => 'Debe ingresar una contraseña',
'MustConfirmPassword' => 'Debe confirmar la contraseña',
'MustSupplyPassword' => 'Debe ingresar una contraseña',
'MustSupplyUsername' => 'You must supply a username', // Added - 2009-02-08
'Name' => 'Nombre',
'Near' => 'Near',
@ -455,7 +455,7 @@ $SLANG = array(
'New' => 'Nuevo',
'NewGroup' => 'New Group',
'NewLabel' => 'New Label',
'NewPassword' => 'Nueva Contraseña',
'NewPassword' => 'Nueva Contraseña',
'NewState' => 'Nuevo Estado',
'NewUser' => 'Nuevo Usuario',
'Next' => 'Siguiente',
@ -491,7 +491,7 @@ $SLANG = array(
'Options' => 'Opciones',
'OrEnterNewName' => 'o agregue nombre',
'Order' => 'Order',
'Orientation' => 'Orientación',
'Orientation' => 'Orientación',
'Out' => 'Out',
'OverwriteExisting' => 'Sobreescribir Exitente',
'Paged' => 'Paged',
@ -500,8 +500,8 @@ $SLANG = array(
'PanRight' => 'Pan Right',
'PanTilt' => 'Pan/Tilt',
'Parameter' => 'Parametro',
'Password' => 'Contraseña',
'PasswordsDifferent' => 'Las contraseñas nueva y de confirmacion son diferentes',
'Password' => 'Contraseña',
'PasswordsDifferent' => 'Las contraseñas nueva y de confirmacion son diferentes',
'Paths' => 'Enlaces',
'Pause' => 'Pause',
'Phone' => 'Phone',
@ -556,7 +556,7 @@ $SLANG = array(
'RotateRight' => 'Rotar a la izquierda',
'RunLocalUpdate' => 'Please run zmupdate.pl to update', // Added - 2011-05-25
'RunMode' => 'Metodo Ejecucion',
'RunState' => 'Estado de Ejecución',
'RunState' => 'Estado de Ejecución',
'Running' => 'Ejecutando',
'Save' => 'Guardar',
'SaveAs' => 'Guardar Como',
@ -564,7 +564,7 @@ $SLANG = array(
'Scale' => 'Escala',
'Score' => 'Res.',
'Secs' => 'Seg',
'Sectionlength' => 'Longitud Sección',
'Sectionlength' => 'Longitud Sección',
'Select' => 'Select',
'SelectFormat' => 'Select Format', // Added - 2011-06-17
'SelectLog' => 'Select Log', // Added - 2011-06-17
@ -630,7 +630,7 @@ $SLANG = array(
'Today' => 'Today',
'Tools' => 'Herra.',
'Total' => 'Total', // Added - 2011-06-16
'TotalBrScore' => 'Total<br/>puntuación',
'TotalBrScore' => 'Total<br/>puntuación',
'TrackDelay' => 'Track Delay',
'TrackMotion' => 'Track Motion',
'Triggers' => 'Gatillos',
@ -642,8 +642,8 @@ $SLANG = array(
'Units' => 'Unidades',
'Unknown' => 'Desconocido',
'Update' => 'Update',
'UpdateAvailable' => 'Una Actualización a ZoneMinder esta disponible',
'UpdateNotNecessary' => 'No se requiere Actualización',
'UpdateAvailable' => 'Una Actualización a ZoneMinder esta disponible',
'UpdateNotNecessary' => 'No se requiere Actualización',
'Updated' => 'Updated', // Added - 2011-06-16
'Upload' => 'Upload', // Added - 2011-08-23
'UseFilter' => 'Usar Filtro',
@ -657,9 +657,9 @@ $SLANG = array(
'V4LCapturesPerFrame' => 'Captures Per Frame', // Added - 2015-04-18
'V4LMultiBuffer' => 'Multi Buffering', // Added - 2015-04-18
'Value' => 'Valor',
'Version' => 'Versión',
'VersionIgnore' => 'Ignore esta versión',
'VersionRemindDay' => 'Recordar en 1 día',
'Version' => 'Versión',
'VersionIgnore' => 'Ignore esta versión',
'VersionRemindDay' => 'Recordar en 1 día',
'VersionRemindHour' => 'Recordar en 1 hora',
'VersionRemindNever' => 'No avizar de nuevas versiones',
'VersionRemindWeek' => 'Recordar en 1 semana',
@ -670,7 +670,7 @@ $SLANG = array(
'VideoGenNoFiles' => 'No Video Files Found',
'VideoGenParms' => 'Parametros Generacion Video',
'VideoGenSucceeded' => 'Video Generation Succeeded!',
'VideoSize' => 'Tamaño Video',
'VideoSize' => 'Tamaño Video',
'View' => 'Ver',
'ViewAll' => 'Ver Todo',
'ViewEvent' => 'View Event',
@ -686,7 +686,7 @@ $SLANG = array(
'Wide' => 'Wide',
'X' => 'X',
'X10' => 'X10',
'X10ActivationString' => 'X10 Comando Activación',
'X10ActivationString' => 'X10 Comando Activación',
'X10InputAlarmString' => 'X10 Comando Entrada Alarma',
'X10OutputAlarmString' => 'X10 Output Alarm String',
'Y' => 'Y',

View File

@ -71,62 +71,62 @@ setlocale( LC_ALL, 'he_IL' ); //All locale settings 4.3.0 and after
// Simple String Replacements
$SLANG = array(
'24BitColour' => 'צבע 24 ביט',
'32BitColour' => 'צבע 32 ביט', // Added - 2011-06-15
'8BitGrey' => 'גווני אפור 8 ביט',
'Action' => 'פעולה',
'Actual' => 'מקורי',
'AddNewControl' => 'הוסף קונטרול חדש',
'AddNewMonitor' => 'הוסף מוניטור חדש',
'AddNewUser' => 'הוסף משתמש חדש',
'AddNewZone' => 'הוסף איזור חדש',
'Alarm' => 'אזעקה',
'AlarmBrFrames' => 'אזעקת<br/>פריימים',
'AlarmFrame' => 'אזעקת פריימים',
'AlarmFrameCount' => 'ספירת אזעקות פריימים',
'AlarmLimits' => 'הגבלות אזעקה',
'24BitColour' => 'öáò 24 áéè',
'32BitColour' => 'öáò 32 áéè', // Added - 2011-06-15
'8BitGrey' => 'âååðé àôåø 8 áéè',
'Action' => 'ôòåìä',
'Actual' => 'î÷åøé',
'AddNewControl' => 'äåñó ÷åðèøåì çãù',
'AddNewMonitor' => 'äåñó îåðéèåø çãù',
'AddNewUser' => 'äåñó îùúîù çãù',
'AddNewZone' => 'äåñó àéæåø çãù',
'Alarm' => 'àæò÷ä',
'AlarmBrFrames' => 'àæò÷ú<br/>ôøééîéí',
'AlarmFrame' => 'àæò÷ú ôøééîéí',
'AlarmFrameCount' => 'ñôéøú àæò÷åú ôøééîéí',
'AlarmLimits' => 'äâáìåú àæò÷ä',
'AlarmMaximumFPS' => 'Alarm Maximum FPS',
'AlarmPx' => 'אזעקת Px',
'AlarmRGBUnset' => 'הינך חייב לאתחל אזעקת צבע',
'AlarmPx' => 'àæò÷ú Px',
'AlarmRGBUnset' => 'äéðê çééá ìàúçì àæò÷ú öáò',
'AlarmRefImageBlendPct'=> 'Alarm Reference Image Blend %ge', // Added - 2015-04-18
'Alert' => 'התראה',
'All' => 'הכל',
'Alert' => 'äúøàä',
'All' => 'äëì',
'AnalysisFPS' => 'Analysis FPS', // Added - 2015-07-22
'AnalysisUpdateDelay' => 'Analysis Update Delay', // Added - 2015-07-23
'Apply' => 'החל',
'ApplyingStateChange' => 'החל שינוי מצב',
'ArchArchived' => 'ארכיב בלבד',
'ArchUnarchived' => 'לא לארכיב בלבד',
'Archive' => 'ארכיב',
'Archived' => 'אורכב',
'Area' => 'אזור',
'AreaUnits' => 'אזור (px/%)',
'Apply' => 'äçì',
'ApplyingStateChange' => 'äçì ùéðåé îöá',
'ArchArchived' => 'àøëéá áìáã',
'ArchUnarchived' => 'ìà ìàøëéá áìáã',
'Archive' => 'àøëéá',
'Archived' => 'àåøëá',
'Area' => 'àæåø',
'AreaUnits' => 'àæåø (px/%)',
'AttrAlarmFrames' => 'Alarm Frames',
'AttrArchiveStatus' => 'Archive Status',
'AttrAvgScore' => 'ניקוד ממוצע',
'AttrCause' => 'סיבה',
'AttrDate' => 'תאריך',
'AttrDateTime' => 'תאריך/שעה',
'AttrAvgScore' => 'ðé÷åã îîåöò',
'AttrCause' => 'ñéáä',
'AttrDate' => 'úàøéê',
'AttrDateTime' => 'úàøéê/ùòä',
'AttrDiskBlocks' => 'Disk Blocks',
'AttrDiskPercent' => 'Disk Percent',
'AttrDuration' => 'משך זמן',
'AttrFrames' => 'פריימים',
'AttrDuration' => 'îùê æîï',
'AttrFrames' => 'ôøééîéí',
'AttrId' => 'Id',
'AttrMaxScore' => 'ניקוד מקסימלי',
'AttrMaxScore' => 'ðé÷åã î÷ñéîìé',
'AttrMonitorId' => 'Monitor Id',
'AttrMonitorName' => 'שם מוניטור',
'AttrName' => 'שם',
'AttrNotes' => 'הערות',
'AttrMonitorName' => 'ùí îåðéèåø',
'AttrName' => 'ùí',
'AttrNotes' => 'äòøåú',
'AttrSystemLoad' => 'System Load',
'AttrTime' => 'שעה',
'AttrTotalScore' => 'סך סכום',
'AttrWeekday' => 'יום בשבוע',
'Auto' => 'אוטו',
'AutoStopTimeout' => 'פסק זמן עצירה אוטו',
'AttrTime' => 'ùòä',
'AttrTotalScore' => 'ñê ñëåí',
'AttrWeekday' => 'éåí áùáåò',
'Auto' => 'àåèå',
'AutoStopTimeout' => 'ôñ÷ æîï òöéøä àåèå',
'Available' => 'Available', // Added - 2009-03-31
'AvgBrScore' => 'ניקוד<br/>ממוצע',
'Background' => 'רקע',
'BackgroundFilter' => 'הרץ מסנן ברקע',
'AvgBrScore' => 'ðé÷åã<br/>îîåöò',
'Background' => 'ø÷ò',
'BackgroundFilter' => 'äøõ îñðï áø÷ò',
'BadAlarmFrameCount' => 'Alarm frame count must be an integer of one or more',
'BadAlarmMaxFPS' => 'Alarm Maximum FPS must be a positive integer or floating point value',
'BadAnalysisFPS' => 'Analysis FPS must be a positive integer or floating point value', // Added - 2015-07-22
@ -157,24 +157,24 @@ $SLANG = array(
'BadWarmupCount' => 'Warmup frames must be an integer of zero or more',
'BadWebColour' => 'Web colour must be a valid web colour string',
'BadWidth' => 'Width must be set to a valid value',
'Bandwidth' => 'רוחב פס',
'Bandwidth' => 'øåçá ôñ',
'BandwidthHead' => 'Bandwidth', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing
'BlobPx' => 'Blob Px',
'BlobSizes' => 'Blob Sizes',
'Blobs' => 'Blobs',
'Brightness' => 'בהירות',
'Brightness' => 'áäéøåú',
'Buffer' => 'Buffer', // Added - 2015-04-18
'Buffers' => 'Buffers',
'CSSDescription' => 'Change the default css for this computer', // Added - 2015-04-18
'CanAutoFocus' => 'אפשר התמקדות אוטומטי',
'CanAutoFocus' => 'àôùø äúî÷ãåú àåèåîèé',
'CanAutoGain' => 'Can Auto Gain',
'CanAutoIris' => 'Can Auto Iris',
'CanAutoWhite' => 'Can Auto White Bal.',
'CanAutoZoom' => 'אפשר זום אוטומטי',
'CanFocus' => 'אפשר התמקדות',
'CanFocusAbs' => 'אפשר התמקדות אבסולוטי',
'CanFocusCon' => 'אפשר התמקדות מתמשך',
'CanFocusRel' => 'אפשר התמקדות יחסי',
'CanAutoZoom' => 'àôùø æåí àåèåîèé',
'CanFocus' => 'àôùø äúî÷ãåú',
'CanFocusAbs' => 'àôùø äúî÷ãåú àáñåìåèé',
'CanFocusCon' => 'àôùø äúî÷ãåú îúîùê',
'CanFocusRel' => 'àôùø äúî÷ãåú éçñé',
'CanGain' => 'Can Gain ',
'CanGainAbs' => 'Can Gain Absolute',
'CanGainCon' => 'Can Gain Continuous',
@ -183,136 +183,136 @@ $SLANG = array(
'CanIrisAbs' => 'Can Iris Absolute',
'CanIrisCon' => 'Can Iris Continuous',
'CanIrisRel' => 'Can Iris Relative',
'CanMove' => 'אפשר תנועה',
'CanMoveAbs' => 'אפשר תנועה אבסולוטית',
'CanMoveCon' => 'אפשר תזוזה מתמשכת',
'CanMove' => 'àôùø úðåòä',
'CanMoveAbs' => 'àôùø úðåòä àáñåìåèéú',
'CanMoveCon' => 'àôùø úæåæä îúîùëú',
'CanMoveDiag' => 'Can Move Diagonally',
'CanMoveMap' => 'Can Move Mapped',
'CanMoveRel' => 'אפשר תזוזה יחסית',
'CanMoveRel' => 'àôùø úæåæä éçñéú',
'CanPan' => 'Can Pan' ,
'CanReset' => 'אפשר אתחול',
'CanReset' => 'àôùø àúçåì',
'CanSetPresets' => 'Can Set Presets',
'CanSleep' => 'אפשר מצב שינה',
'CanTilt' => 'אפשר זעזוע',
'CanWake' => 'אפשר יציאה ממצב שינה',
'CanSleep' => 'àôùø îöá ùéðä',
'CanTilt' => 'àôùø æòæåò',
'CanWake' => 'àôùø éöéàä îîöá ùéðä',
'CanWhite' => 'Can White Balance',
'CanWhiteAbs' => 'Can White Bal. Absolute',
'CanWhiteBal' => 'Can White Bal.',
'CanWhiteCon' => 'Can White Bal. Continuous',
'CanWhiteRel' => 'Can White Bal. Relative',
'CanZoom' => 'אפשר זום',
'CanZoomAbs' => 'אפשר זום אבסולוטי',
'CanZoomCon' => 'אפשר זום מתמשך',
'CanZoomRel' => 'אפשר זום יחסי',
'Cancel' => 'בטל',
'CanZoom' => 'àôùø æåí',
'CanZoomAbs' => 'àôùø æåí àáñåìåèé',
'CanZoomCon' => 'àôùø æåí îúîùê',
'CanZoomRel' => 'àôùø æåí éçñé',
'Cancel' => 'áèì',
'CancelForcedAlarm' => 'Cancel Forced Alarm',
'CaptureHeight' => 'Capture Height',
'CaptureMethod' => 'Capture Method', // Added - 2009-02-08
'CapturePalette' => 'Capture Palette',
'CaptureResolution' => 'Capture Resolution', // Added - 2015-04-18
'CaptureWidth' => 'Capture Width',
'Cause' => 'סיבה',
'Cause' => 'ñéáä',
'CheckMethod' => 'Alarm Check Method',
'ChooseDetectedCamera' => 'Choose Detected Camera', // Added - 2009-03-31
'ChooseFilter' => 'בחר מסנן',
'ChooseFilter' => 'áçø îñðï',
'ChooseLogFormat' => 'Choose a log format', // Added - 2011-06-17
'ChooseLogSelection' => 'Choose a log selection', // Added - 2011-06-17
'ChoosePreset' => 'Choose Preset',
'Clear' => 'Clear', // Added - 2011-06-16
'Close' => 'סגור',
'Colour' => 'צבע',
'Command' => 'פקודה',
'Close' => 'ñâåø',
'Colour' => 'öáò',
'Command' => 'ô÷åãä',
'Component' => 'Component', // Added - 2011-06-16
'Config' => 'תצורה',
'ConfiguredFor' => 'תצורה עבור',
'Config' => 'úöåøä',
'ConfiguredFor' => 'úöåøä òáåø',
'ConfirmDeleteEvents' => 'Are you sure you wish to delete the selected events?',
'ConfirmPassword' => 'אשר סיסמא',
'ConjAnd' => 'ו',
'ConjOr' => 'או',
'Console' => 'קונסול',
'ContactAdmin' => 'צור קשר עם מנהל המערכת בשביל פרטים נוספים.',
'Continue' => 'המשך',
'Contrast' => 'ניגודיות',
'Control' => 'קונטרול',
'ControlAddress' => 'כתובת הקונטרול',
'ControlCap' => 'יכולת הקונטרול',
'ControlCaps' => 'יכולות הקונטרול',
'ControlDevice' => 'התקן הקונטרול',
'ControlType' => 'סוג הקונטרול',
'ConfirmPassword' => 'àùø ñéñîà',
'ConjAnd' => 'å',
'ConjOr' => 'àå',
'Console' => '÷åðñåì',
'ContactAdmin' => 'öåø ÷ùø òí îðäì äîòøëú áùáéì ôøèéí ðåñôéí.',
'Continue' => 'äîùê',
'Contrast' => 'ðéâåãéåú',
'Control' => '÷åðèøåì',
'ControlAddress' => 'ëúåáú ä÷åðèøåì',
'ControlCap' => 'éëåìú ä÷åðèøåì',
'ControlCaps' => 'éëåìåú ä÷åðèøåì',
'ControlDevice' => 'äú÷ï ä÷åðèøåì',
'ControlType' => 'ñåâ ä÷åðèøåì',
'Controllable' => 'Controllable',
'Current' => 'Current', // Added - 2015-04-18
'Cycle' => 'מחזורי',
'CycleWatch' => 'צפייה מחזורית',
'Cycle' => 'îçæåøé',
'CycleWatch' => 'öôééä îçæåøéú',
'DateTime' => 'Date/Time', // Added - 2011-06-16
'Day' => 'יום',
'Day' => 'éåí',
'Debug' => 'Debug',
'DefaultRate' => 'Default Rate',
'DefaultScale' => 'Default Scale',
'DefaultView' => 'Default View',
'Deinterlacing' => 'Deinterlacing', // Added - 2015-04-18
'Delay' => 'Delay', // Added - 2015-04-18
'Delete' => 'מחק',
'DeleteAndNext' => 'מחק &amp; הבא',
'DeleteAndPrev' => 'מחק &amp; הקודם',
'DeleteSavedFilter' => 'מחק מסנן שמור',
'Description' => 'תיאור',
'Delete' => 'îç÷',
'DeleteAndNext' => 'îç÷ &amp; äáà',
'DeleteAndPrev' => 'îç÷ &amp; ä÷åãí',
'DeleteSavedFilter' => 'îç÷ îñðï ùîåø',
'Description' => 'úéàåø',
'DetectedCameras' => 'Detected Cameras', // Added - 2009-03-31
'DetectedProfiles' => 'Detected Profiles', // Added - 2015-04-18
'Device' => 'Device', // Added - 2009-02-08
'DeviceChannel' => 'ערוץ ההתקן',
'DeviceFormat' => 'תבנית ההתקן',
'DeviceNumber' => 'מספר ההתקן',
'DevicePath' => 'נתיב ההתקן',
'Devices' => 'התקנים',
'Dimensions' => 'מימדים',
'DisableAlarms' => 'נטרל אזעקות',
'Disk' => 'דיסק',
'DeviceChannel' => 'òøåõ ääú÷ï',
'DeviceFormat' => 'úáðéú ääú÷ï',
'DeviceNumber' => 'îñôø ääú÷ï',
'DevicePath' => 'ðúéá ääú÷ï',
'Devices' => 'äú÷ðéí',
'Dimensions' => 'îéîãéí',
'DisableAlarms' => 'ðèøì àæò÷åú',
'Disk' => 'ãéñ÷',
'Display' => 'Display', // Added - 2011-01-30
'Displaying' => 'Displaying', // Added - 2011-06-16
'DoNativeMotionDetection'=> 'Do Native Motion Detection',
'Donate' => 'תרום בבקשה',
'DonateAlready' => 'לא, תרמתי כבר',
'Donate' => 'úøåí áá÷ùä',
'DonateAlready' => 'ìà, úøîúé ëáø',
'DonateEnticement' => 'You\'ve been running ZoneMinder for a while now and hopefully are finding it a useful addition to your home or workplace security. Although ZoneMinder is, and will remain, free and open source, it costs money to develop and support. If you would like to help support future development and new features then please consider donating. Donating is, of course, optional but very much appreciated and you can donate as much or as little as you like.<br><br>If you would like to donate please select the option below or go to http://www.zoneminder.com/donate.html in your browser.<br><br>Thank you for using ZoneMinder and don\'t forget to visit the forums on ZoneMinder.com for support or suggestions about how to make your ZoneMinder experience even better.',
'DonateRemindDay' => 'עדיין לא, הזכר לא בעוד יום אחד',
'DonateRemindHour' => 'עדיין לא, הזכר לי בעוד שעה אחת',
'DonateRemindMonth' => 'עדיין לא, הזכר לי בעוד חודש אחד',
'DonateRemindNever' => 'לא, אני לא רוצה לתרום, אל תתזכר אותי',
'DonateRemindWeek' => 'עדיין לא, הזכר לי בעוד שבוע אחד',
'DonateYes' => 'כן, אני מעוניין לתרום עכשיו',
'Download' => 'הורד',
'DonateRemindDay' => 'òãééï ìà, äæëø ìà áòåã éåí àçã',
'DonateRemindHour' => 'òãééï ìà, äæëø ìé áòåã ùòä àçú',
'DonateRemindMonth' => 'òãééï ìà, äæëø ìé áòåã çåãù àçã',
'DonateRemindNever' => 'ìà, àðé ìà øåöä ìúøåí, àì úúæëø àåúé',
'DonateRemindWeek' => 'òãééï ìà, äæëø ìé áòåã ùáåò àçã',
'DonateYes' => 'ëï, àðé îòåðééï ìúøåí òëùéå',
'Download' => 'äåøã',
'DuplicateMonitorName' => 'Duplicate Monitor Name', // Added - 2009-03-31
'Duration' => 'משך זמן',
'Edit' => 'ערוך',
'Email' => 'דוא"ל',
'EnableAlarms' => 'אפשר אזעקות',
'Enabled' => 'אפשר',
'EnterNewFilterName' => 'הזן מסנן חדש',
'Error' => 'שגיאה',
'Duration' => 'îùê æîï',
'Edit' => 'òøåê',
'Email' => 'ãåà"ì',
'EnableAlarms' => 'àôùø àæò÷åú',
'Enabled' => 'àôùø',
'EnterNewFilterName' => 'äæï îñðï çãù',
'Error' => 'ùâéàä',
'ErrorBrackets' => 'Error, please check you have an equal number of opening and closing brackets',
'ErrorValidValue' => 'Error, please check that all terms have a valid value',
'Etc' => 'וכו\'',
'Event' => 'אירוע',
'EventFilter' => 'מסנן אירוע',
'EventId' => 'זיהוי אירוע',
'EventName' => 'שם אירוע',
'Etc' => 'åëå\'',
'Event' => 'àéøåò',
'EventFilter' => 'îñðï àéøåò',
'EventId' => 'æéäåé àéøåò',
'EventName' => 'ùí àéøåò',
'EventPrefix' => 'Event Prefix',
'Events' => 'אירועים',
'Exclude' => 'ללא',
'Execute' => 'בצע',
'Export' => 'יצא',
'ExportDetails' => 'יצא פרטי אירוע',
'ExportFailed' => 'יצוא נכשל',
'ExportFormat' => 'יצא תבנית קובץ',
'Events' => 'àéøåòéí',
'Exclude' => 'ììà',
'Execute' => 'áöò',
'Export' => 'éöà',
'ExportDetails' => 'éöà ôøèé àéøåò',
'ExportFailed' => 'éöåà ðëùì',
'ExportFormat' => 'éöà úáðéú ÷åáõ',
'ExportFormatTar' => 'Tar',
'ExportFormatZip' => 'Zip',
'ExportFrames' => 'Export Frame Details',
'ExportImageFiles' => 'יצא קבצי תמונה',
'ExportImageFiles' => 'éöà ÷áöé úîåðä',
'ExportLog' => 'Export Log', // Added - 2011-06-17
'ExportMiscFiles' => 'יצא קבצים אחרים (אם ישנם)',
'ExportOptions' => 'יצא אפשרויות',
'ExportMiscFiles' => 'éöà ÷áöéí àçøéí (àí éùðí)',
'ExportOptions' => 'éöà àôùøåéåú',
'ExportSucceeded' => 'Export Succeeded', // Added - 2009-02-08
'ExportVideoFiles' => 'Export Video Files (if present)',
'Exporting' => 'מייצא',
'Exporting' => 'îééöà',
'FPS' => 'fps',
'FPSReportInterval' => 'FPS Report Interval',
'FTP' => 'FTP',
@ -320,20 +320,20 @@ $SLANG = array(
'FastForward' => 'Fast Forward',
'Feed' => 'Feed',
'Ffmpeg' => 'Ffmpeg', // Added - 2009-02-08
'File' => 'קובץ',
'File' => '÷åáõ',
'Filter' => 'Filter', // Added - 2015-04-18
'FilterArchiveEvents' => 'ארכב תואמים',
'FilterDeleteEvents' => 'מחק תואמים',
'FilterEmailEvents' => 'שלח דואר של כל התואמים',
'FilterArchiveEvents' => 'àøëá úåàîéí',
'FilterDeleteEvents' => 'îç÷ úåàîéí',
'FilterEmailEvents' => 'ùìç ãåàø ùì ëì äúåàîéí',
'FilterExecuteEvents' => 'Execute command on all matches',
'FilterLog' => 'Filter log', // Added - 2015-04-18
'FilterMessageEvents' => 'Message details of all matches',
'FilterPx' => 'Filter Px',
'FilterUnset' => 'עליך לציין רוחב וגובה מסנן',
'FilterUploadEvents' => 'עלה את כל התואמים',
'FilterVideoEvents' => 'צור וידאו לכל התואמים',
'Filters' => 'מסננים',
'First' => 'הראשון',
'FilterUnset' => 'òìéê ìöééï øåçá åâåáä îñðï',
'FilterUploadEvents' => 'òìä àú ëì äúåàîéí',
'FilterVideoEvents' => 'öåø åéãàå ìëì äúåàîéí',
'Filters' => 'îñððéí',
'First' => 'äøàùåï',
'FlippedHori' => 'Flipped Horizontally',
'FlippedVert' => 'Flipped Vertically',
'FnMocord' => 'Mocord', // Added 2013.08.16.
@ -342,24 +342,24 @@ $SLANG = array(
'FnNodect' => 'Nodect', // Added 2013.08.16.
'FnNone' => 'None', // Added 2013.08.16.
'FnRecord' => 'Record', // Added 2013.08.16.
'Focus' => 'התמקד',
'ForceAlarm' => 'הכרח אזעקה',
'Format' => 'תבנית',
'Frame' => 'פריים',
'Focus' => 'äúî÷ã',
'ForceAlarm' => 'äëøç àæò÷ä',
'Format' => 'úáðéú',
'Frame' => 'ôøééí',
'FrameId' => 'Frame Id',
'FrameRate' => 'Frame Rate',
'FrameSkip' => 'דלג פריים',
'Frames' => 'פריימים',
'Func' => 'פונק',
'Function' => 'פונקציה',
'FrameSkip' => 'ãìâ ôøééí',
'Frames' => 'ôøééîéí',
'Func' => 'ôåð÷',
'Function' => 'ôåð÷öéä',
'Gain' => 'Gain',
'General' => 'כללי',
'GenerateVideo' => 'צור וידאו',
'GeneratingVideo' => 'מייצר וידאו',
'GoToZoneMinder' => 'בקר ZoneMinder.com',
'Grey' => 'אפור',
'Group' => 'קבוצה',
'Groups' => 'קבוצות',
'General' => 'ëììé',
'GenerateVideo' => 'öåø åéãàå',
'GeneratingVideo' => 'îééöø åéãàå',
'GoToZoneMinder' => 'á÷ø ZoneMinder.com',
'Grey' => 'àôåø',
'Group' => '÷áåöä',
'Groups' => '÷áåöåú',
'HasFocusSpeed' => 'Has Focus Speed',
'HasGainSpeed' => 'Has Gain Speed',
'HasHomePreset' => 'Has Home Preset',
@ -371,51 +371,51 @@ $SLANG = array(
'HasTurboTilt' => 'Has Turbo Tilt',
'HasWhiteSpeed' => 'Has White Bal. Speed',
'HasZoomSpeed' => 'Has Zoom Speed',
'High' => 'גבוה',
'HighBW' => 'גבוה&nbsp;ר/פ',
'Home' => 'בית',
'Hour' => 'שעה',
'High' => 'âáåä',
'HighBW' => 'âáåä&nbsp;ø/ô',
'Home' => 'áéú',
'Hour' => 'ùòä',
'Hue' => 'Hue',
'Id' => 'זיהוי',
'Idle' => 'המתנה',
'Ignore' => 'התעלם',
'Image' => 'תמונה',
'Id' => 'æéäåé',
'Idle' => 'äîúðä',
'Ignore' => 'äúòìí',
'Image' => 'úîåðä',
'ImageBufferSize' => 'Image Buffer Size (frames)',
'Images' => 'תמונות',
'In' => 'בתוך',
'Include' => 'כלול',
'Inverted' => 'הפוך',
'Images' => 'úîåðåú',
'In' => 'áúåê',
'Include' => 'ëìåì',
'Inverted' => 'äôåê',
'Iris' => 'Iris',
'KeyString' => 'מחרוזת תוים',
'Label' => 'תווית',
'Language' => 'שפה',
'Last' => 'אחרון',
'KeyString' => 'îçøåæú úåéí',
'Label' => 'úååéú',
'Language' => 'ùôä',
'Last' => 'àçøåï',
'Layout' => 'Layout', // Added - 2009-02-08
'Level' => 'Level', // Added - 2011-06-16
'Libvlc' => 'Libvlc',
'LimitResultsPost' => 'תוצאות בלבד;', // This is used at the end of the phrase 'Limit to first N results only'
'LimitResultsPre' => 'הגבל לראשון', // This is used at the beginning of the phrase 'Limit to first N results only'
'LimitResultsPost' => 'úåöàåú áìáã;', // This is used at the end of the phrase 'Limit to first N results only'
'LimitResultsPre' => 'äâáì ìøàùåï', // This is used at the beginning of the phrase 'Limit to first N results only'
'Line' => 'Line', // Added - 2011-06-16
'LinkedMonitors' => 'מוניטורים מקושרים',
'List' => 'רשימה',
'Load' => 'טען',
'Local' => 'מקומי',
'LinkedMonitors' => 'îåðéèåøéí î÷åùøéí',
'List' => 'øùéîä',
'Load' => 'èòï',
'Local' => 'î÷åîé',
'Log' => 'Log', // Added - 2011-06-16
'LoggedInAs' => 'התחבר כ',
'LoggedInAs' => 'äúçáø ë',
'Logging' => 'Logging', // Added - 2011-06-16
'LoggingIn' => 'מתחבר',
'Login' => 'התחבר',
'Logout' => 'התנתק',
'LoggingIn' => 'îúçáø',
'Login' => 'äúçáø',
'Logout' => 'äúðú÷',
'Logs' => 'Logs', // Added - 2011-06-17
'Low' => 'נמוך',
'LowBW' => 'נמוך&nbsp;ר/פ',
'Main' => 'מרכזי',
'Man' => 'מדריך',
'Manual' => 'מדריך',
'Mark' => 'סמן',
'Max' => 'מקס',
'MaxBandwidth' => 'רוחב פס מקס',
'MaxBrScore' => 'ניקוד<br/>מקסימלי',
'Low' => 'ðîåê',
'LowBW' => 'ðîåê&nbsp;ø/ô',
'Main' => 'îøëæé',
'Man' => 'îãøéê',
'Manual' => 'îãøéê',
'Mark' => 'ñîï',
'Max' => 'î÷ñ',
'MaxBandwidth' => 'øåçá ôñ î÷ñ',
'MaxBrScore' => 'ðé÷åã<br/>î÷ñéîìé',
'MaxFocusRange' => 'Max Focus Range',
'MaxFocusSpeed' => 'Max Focus Speed',
'MaxFocusStep' => 'Max Focus Step',
@ -438,7 +438,7 @@ $SLANG = array(
'MaxZoomSpeed' => 'Max Zoom Speed',
'MaxZoomStep' => 'Max Zoom Step',
'MaximumFPS' => 'Maximum FPS',
'Medium' => 'בינוני',
'Medium' => 'áéðåðé',
'MediumBW' => 'Medium&nbsp;B/W',
'Message' => 'Message', // Added - 2011-06-16
'MinAlarmAreaLtMax' => 'Minimum alarm area should be less than maximum',
@ -476,18 +476,18 @@ $SLANG = array(
'MinZoomStep' => 'Min Zoom Step',
'Misc' => 'Misc',
'Mode' => 'Mode', // Added - 2015-04-18
'Monitor' => 'מוניטור',
'Monitor' => 'îåðéèåø',
'MonitorIds' => 'Monitor&nbsp;Ids',
'MonitorPreset' => 'Monitor Preset',
'MonitorPresetIntro' => 'Select an appropriate preset from the list below.<br><br>Please note that this may overwrite any values you already have configured for this monitor.<br><br>',
'MonitorProbe' => 'Monitor Probe', // Added - 2009-03-31
'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2009-03-31
'Monitors' => 'מוניטורים',
'Monitors' => 'îåðéèåøéí',
'Montage' => 'Montage',
'Month' => 'חודש',
'Month' => 'çåãù',
'More' => 'More', // Added - 2011-06-16
'MotionFrameSkip' => 'Motion Frame Skip',
'Move' => 'הזז',
'Move' => 'äææ',
'Mtg2widgrd' => '2-wide grid', // Added 2013.08.15.
'Mtg3widgrd' => '3-wide grid', // Added 2013.08.15.
'Mtg3widgrx' => '3-wide grid, scaled, enlarge on alarm', // Added 2013.08.15.
@ -498,48 +498,48 @@ $SLANG = array(
'MustConfirmPassword' => 'You must confirm the password',
'MustSupplyPassword' => 'You must supply a password',
'MustSupplyUsername' => 'You must supply a username',
'Name' => 'שם',
'Near' => 'ליד',
'Network' => 'רשת',
'New' => 'חדש',
'NewGroup' => 'קבוצה חדשה',
'NewLabel' => 'תווית חדשה',
'NewPassword' => 'סיסמא חדשה',
'NewState' => 'מצב חדש',
'NewUser' => 'משתמש חדש',
'Next' => 'הבא',
'No' => 'לא',
'Name' => 'ùí',
'Near' => 'ìéã',
'Network' => 'øùú',
'New' => 'çãù',
'NewGroup' => '÷áåöä çãùä',
'NewLabel' => 'úååéú çãùä',
'NewPassword' => 'ñéñîà çãùä',
'NewState' => 'îöá çãù',
'NewUser' => 'îùúîù çãù',
'Next' => 'äáà',
'No' => 'ìà',
'NoDetectedCameras' => 'No Detected Cameras', // Added - 2009-03-31
'NoFramesRecorded' => 'There are no frames recorded for this event',
'NoGroup' => 'ללא קבוצה',
'NoGroup' => 'ììà ÷áåöä',
'NoSavedFilters' => 'NoSavedFilters',
'NoStatisticsRecorded' => 'There are no statistics recorded for this event/frame',
'None' => 'ריק',
'NoneAvailable' => 'בלתי זמין',
'Normal' => 'נורמלי',
'None' => 'øé÷',
'NoneAvailable' => 'áìúé æîéï',
'Normal' => 'ðåøîìé',
'Notes' => 'Notes',
'NumPresets' => 'Num Presets',
'Off' => 'כבוי',
'On' => 'דלוק',
'Off' => 'ëáåé',
'On' => 'ãìå÷',
'OnvifCredentialsIntro'=> 'Please supply user name and password for the selected camera.<br/>If no user has been created for the camera then the user given here will be created with the given password.<br/><br/>', // Added - 2015-04-18
'OnvifProbe' => 'ONVIF', // Added - 2015-04-18
'OnvifProbeIntro' => 'The list below shows detected ONVIF cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
'OpEq' => 'שווה ל',
'OpGt' => 'גדול מ',
'OpEq' => 'ùååä ì',
'OpGt' => 'âãåì î',
'OpGtEq' => 'greater than or equal to',
'OpIn' => 'in set',
'OpLt' => 'פחות מ',
'OpLt' => 'ôçåú î',
'OpLtEq' => 'less than or equal to',
'OpMatches' => 'matches',
'OpNe' => 'אינו שווה',
'OpNe' => 'àéðå ùååä',
'OpNotIn' => 'not in set',
'OpNotMatches' => 'אינו תואם',
'Open' => 'פתח',
'OpNotMatches' => 'àéðå úåàí',
'Open' => 'ôúç',
'OptionHelp' => 'OptionHelp',
'OptionRestartWarning' => 'These changes may not come into effect fully\nwhile the system is running. When you have\nfinished making your changes please ensure that\nyou restart ZoneMinder.',
'Options' => 'אפשרויות',
'Options' => 'àôùøåéåú',
'OrEnterNewName' => 'or enter new name',
'Order' => 'מיון',
'Order' => 'îéåï',
'Orientation' => 'Orientation',
'Out' => 'Out',
'OverwriteExisting' => 'Overwrite Existing',
@ -548,200 +548,200 @@ $SLANG = array(
'PanLeft' => 'Pan Left',
'PanRight' => 'Pan Right',
'PanTilt' => 'Pan/Tilt',
'Parameter' => 'פרמטר',
'Password' => 'סיסמא',
'Parameter' => 'ôøîèø',
'Password' => 'ñéñîà',
'PasswordsDifferent' => 'The new and confirm passwords are different',
'Paths' => 'נתיבים',
'Paths' => 'ðúéáéí',
'Pause' => 'Pause',
'Phone' => 'טלפון',
'PhoneBW' => 'ר/פ&nbsp;טלפון',
'Phone' => 'èìôåï',
'PhoneBW' => 'ø/ô&nbsp;èìôåï',
'Pid' => 'PID', // Added - 2011-06-16
'PixelDiff' => 'Pixel Diff',
'Pixels' => 'פיקסלים',
'Pixels' => 'ôé÷ñìéí',
'Play' => 'Play',
'PlayAll' => 'נגן הכל',
'PleaseWait' => 'המתן בבקשה',
'PlayAll' => 'ðâï äëì',
'PleaseWait' => 'äîúï áá÷ùä',
'Plugins' => 'Plugins',
'Point' => 'נקודה',
'Point' => 'ð÷åãä',
'PostEventImageBuffer' => 'Post Event Image Count',
'PreEventImageBuffer' => 'Pre Event Image Count',
'PreserveAspect' => 'Preserve Aspect Ratio',
'Preset' => 'Preset',
'Presets' => 'Presets',
'Prev' => 'הקודם',
'Prev' => 'ä÷åãí',
'Probe' => 'Probe', // Added - 2009-03-31
'ProfileProbe' => 'Stream Probe', // Added - 2015-04-18
'ProfileProbeIntro' => 'The list below shows the existing stream profiles of the selected camera .<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that ZoneMinder cannot configure additional profiles and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
'Progress' => 'Progress', // Added - 2015-04-18
'Protocol' => 'Protocol',
'Rate' => 'דירוג',
'Real' => 'אמיתי',
'Record' => 'הקלטה',
'Rate' => 'ãéøåâ',
'Real' => 'àîéúé',
'Record' => 'ä÷ìèä',
'RefImageBlendPct' => 'Reference Image Blend %ge',
'Refresh' => 'רענון',
'Remote' => 'מרוחק',
'RemoteHostName' => 'שם מארח מרוחק',
'RemoteHostPath' => 'נתיב מארח מרוחק',
'RemoteHostPort' => 'פורט מארח מרוחק',
'Refresh' => 'øòðåï',
'Remote' => 'îøåç÷',
'RemoteHostName' => 'ùí îàøç îøåç÷',
'RemoteHostPath' => 'ðúéá îàøç îøåç÷',
'RemoteHostPort' => 'ôåøè îàøç îøåç÷',
'RemoteHostSubPath' => 'Remote Host SubPath', // Added - 2009-02-08
'RemoteImageColours' => 'Remote Image Colours',
'RemoteMethod' => 'Remote Method', // Added - 2009-02-08
'RemoteProtocol' => 'Remote Protocol', // Added - 2009-02-08
'Rename' => 'שנה שם',
'Rename' => 'ùðä ùí',
'Replay' => 'Replay',
'ReplayAll' => 'All Events',
'ReplayGapless' => 'Gapless Events',
'ReplaySingle' => 'Single Event',
'Reset' => 'אפס',
'Reset' => 'àôñ',
'ResetEventCounts' => 'Reset Event Counts',
'Restart' => 'אתחל',
'Restarting' => 'מאתחל',
'Restart' => 'àúçì',
'Restarting' => 'îàúçì',
'RestrictedCameraIds' => 'Restricted Camera Ids',
'RestrictedMonitors' => 'Restricted Monitors',
'ReturnDelay' => 'חזרה מהשהיה',
'ReturnLocation' => 'מיקום חזרה',
'ReturnDelay' => 'çæøä îäùäéä',
'ReturnLocation' => 'îé÷åí çæøä',
'Rewind' => 'Rewind',
'RotateLeft' => 'סובב שמאלה',
'RotateRight' => 'סובב ימינה',
'RotateLeft' => 'ñåáá ùîàìä',
'RotateRight' => 'ñåáá éîéðä',
'RunLocalUpdate' => 'Please run zmupdate.pl to update', // Added - 2011-05-25
'RunMode' => 'צורת ריצה',
'RunState' => 'מצב ריצה',
'Running' => 'מריץ',
'Save' => 'שמור',
'SaveAs' => 'שמור בשם',
'SaveFilter' => 'שמור מסנן',
'Scale' => 'סקאלה',
'Score' => 'ניקוד',
'Secs' => 'שניות',
'Sectionlength' => 'אורך קטע',
'Select' => 'בחר',
'RunMode' => 'öåøú øéöä',
'RunState' => 'îöá øéöä',
'Running' => 'îøéõ',
'Save' => 'ùîåø',
'SaveAs' => 'ùîåø áùí',
'SaveFilter' => 'ùîåø îñðï',
'Scale' => 'ñ÷àìä',
'Score' => 'ðé÷åã',
'Secs' => 'ùðéåú',
'Sectionlength' => 'àåøê ÷èò',
'Select' => 'áçø',
'SelectFormat' => 'Select Format', // Added - 2011-06-17
'SelectLog' => 'Select Log', // Added - 2011-06-17
'SelectMonitors' => 'בחר מוניטורים',
'SelectMonitors' => 'áçø îåðéèåøéí',
'SelfIntersecting' => 'Polygon edges must not intersect',
'Set' => 'קבע',
'Set' => '÷áò',
'SetNewBandwidth' => 'Set New Bandwidth',
'SetPreset' => 'Set Preset',
'Settings' => 'הגדרות',
'Settings' => 'äâãøåú',
'ShowFilterWindow' => 'Show Filter Window',
'ShowTimeline' => 'Show Timeline',
'SignalCheckColour' => 'Signal Check Colour',
'Size' => 'גודל',
'Size' => 'âåãì',
'SkinDescription' => 'Change the default skin for this computer', // Added - 2011-01-30
'Sleep' => 'שינה',
'Sleep' => 'ùéðä',
'SortAsc' => 'Asc',
'SortBy' => 'Sort by',
'SortDesc' => 'Desc',
'Source' => 'מקור',
'Source' => 'î÷åø',
'SourceColours' => 'Source Colours', // Added - 2009-02-08
'SourcePath' => 'Source Path', // Added - 2009-02-08
'SourceType' => 'סוג מקור',
'Speed' => 'מהירות',
'SpeedHigh' => 'מהירות גבוהה',
'SpeedLow' => 'מהירות נמוכה',
'SpeedMedium' => 'מצלמה בינונית',
'SpeedTurbo' => 'מהירות טורבו',
'Start' => 'התחל',
'State' => 'מצב',
'Stats' => 'מצבים',
'Status' => 'סטטוס',
'Step' => 'צעד',
'SourceType' => 'ñåâ î÷åø',
'Speed' => 'îäéøåú',
'SpeedHigh' => 'îäéøåú âáåää',
'SpeedLow' => 'îäéøåú ðîåëä',
'SpeedMedium' => 'îöìîä áéðåðéú',
'SpeedTurbo' => 'îäéøåú èåøáå',
'Start' => 'äúçì',
'State' => 'îöá',
'Stats' => 'îöáéí',
'Status' => 'ñèèåñ',
'Step' => 'öòã',
'StepBack' => 'Step Back',
'StepForward' => 'Step Forward',
'StepLarge' => 'צעד גדול',
'StepMedium' => 'צעד בינוני',
'StepNone' => 'אל תצעד',
'StepSmall' => 'צעד קטן',
'Stills' => 'סטילס',
'Stop' => 'עצור',
'Stopped' => 'נעצר',
'Stream' => 'סטרים',
'StepLarge' => 'öòã âãåì',
'StepMedium' => 'öòã áéðåðé',
'StepNone' => 'àì úöòã',
'StepSmall' => 'öòã ÷èï',
'Stills' => 'ñèéìñ',
'Stop' => 'òöåø',
'Stopped' => 'ðòöø',
'Stream' => 'ñèøéí',
'StreamReplayBuffer' => 'Stream Replay Image Buffer',
'Submit' => 'Submit',
'System' => 'מערכת',
'System' => 'îòøëú',
'SystemLog' => 'System Log', // Added - 2011-06-16
'TargetColorspace' => 'Target colorspace', // Added - 2015-04-18
'Tele' => 'טל',
'Tele' => 'èì',
'Thumbnail' => 'Thumbnail',
'Tilt' => 'Tilt',
'Time' => 'זמן',
'TimeDelta' => 'שינוי בזמן',
'TimeStamp' => 'חותמת זמן',
'Timeline' => 'קו זמן',
'Time' => 'æîï',
'TimeDelta' => 'ùéðåé áæîï',
'TimeStamp' => 'çåúîú æîï',
'Timeline' => '÷å æîï',
'TimelineTip1' => 'Pass your mouse over the graph to view a snapshot image and event details.', // Added 2013.08.15.
'TimelineTip2' => 'Click on the coloured sections of the graph, or the image, to view the event.', // Added 2013.08.15.
'TimelineTip3' => 'Click on the background to zoom in to a smaller time period based around your click.', // Added 2013.08.15.
'TimelineTip4' => 'Use the controls below to zoom out or navigate back and forward through the time range.', // Added 2013.08.15.
'Timestamp' => 'חותמת זמן',
'Timestamp' => 'çåúîú æîï',
'TimestampLabelFormat' => 'Timestamp Label Format',
'TimestampLabelX' => 'Timestamp Label X',
'TimestampLabelY' => 'Timestamp Label Y',
'Today' => 'היום',
'Tools' => 'כלים',
'Today' => 'äéåí',
'Tools' => 'ëìéí',
'Total' => 'Total', // Added - 2011-06-16
'TotalBrScore' => 'סך<br/>ניקוד',
'TotalBrScore' => 'ñê<br/>ðé÷åã',
'TrackDelay' => 'Track Delay',
'TrackMotion' => 'Track Motion',
'Triggers' => 'טריגרים',
'Triggers' => 'èøéâøéí',
'TurboPanSpeed' => 'Turbo Pan Speed',
'TurboTiltSpeed' => 'Turbo Tilt Speed',
'Type' => 'סוג',
'Unarchive' => 'בלתי ארכיב',
'Type' => 'ñåâ',
'Unarchive' => 'áìúé àøëéá',
'Undefined' => 'Undefined', // Added - 2009-02-08
'Units' => 'יחידות',
'Unknown' => 'בלתי ידוע',
'Update' => 'עדכון',
'UpdateAvailable' => 'עדכון לזון-מינדר אפשרי.',
'UpdateNotNecessary' => 'עדכון אינו הכרחי.',
'Units' => 'éçéãåú',
'Unknown' => 'áìúé éãåò',
'Update' => 'òãëåï',
'UpdateAvailable' => 'òãëåï ìæåï-îéðãø àôùøé.',
'UpdateNotNecessary' => 'òãëåï àéðå äëøçé.',
'Updated' => 'Updated', // Added - 2011-06-16
'Upload' => 'Upload', // Added - 2011-08-23
'UseFilter' => 'שימוש במסנן',
'UseFilter' => 'ùéîåù áîñðï',
'UseFilterExprsPost' => '&nbsp;filter&nbsp;expressions', // This is used at the end of the phrase 'use N filter expressions'
'UseFilterExprsPre' => 'שימוש&nbsp;', // This is used at the beginning of the phrase 'use N filter expressions'
'UseFilterExprsPre' => 'ùéîåù&nbsp;', // This is used at the beginning of the phrase 'use N filter expressions'
'UsedPlugins' => 'Used Plugins',
'User' => 'משתמש',
'Username' => 'שם משתמש',
'Users' => 'משתמשים',
'User' => 'îùúîù',
'Username' => 'ùí îùúîù',
'Users' => 'îùúîùéí',
'V4L' => 'V4L', // Added - 2015-04-18
'V4LCapturesPerFrame' => 'Captures Per Frame', // Added - 2015-04-18
'V4LMultiBuffer' => 'Multi Buffering', // Added - 2015-04-18
'Value' => 'ערך',
'Version' => 'גירסה',
'VersionIgnore' => 'התעלם מגירסה זו',
'VersionRemindDay' => 'הזכר לי בעוד יום אחד',
'VersionRemindHour' => 'הזכר לי בעוד שעה אחת',
'Value' => 'òøê',
'Version' => 'âéøñä',
'VersionIgnore' => 'äúòìí îâéøñä æå',
'VersionRemindDay' => 'äæëø ìé áòåã éåí àçã',
'VersionRemindHour' => 'äæëø ìé áòåã ùòä àçú',
'VersionRemindNever' => 'Don\'t remind about new versions',
'VersionRemindWeek' => 'Remind again in 1 week',
'Video' => 'וידאו',
'VideoFormat' => 'תבנית וידאו',
'Video' => 'åéãàå',
'VideoFormat' => 'úáðéú åéãàå',
'VideoGenFailed' => 'Video Generation Failed!',
'VideoGenFiles' => 'Existing Video Files',
'VideoGenNoFiles' => 'No Video Files Found',
'VideoGenParms' => 'Video Generation Parameters',
'VideoGenSucceeded' => 'Video Generation Succeeded!',
'VideoSize' => 'גודל וידאו',
'View' => 'הצג',
'ViewAll' => 'הצג הכל',
'ViewEvent' => 'הצג אירוע',
'VideoSize' => 'âåãì åéãàå',
'View' => 'äöâ',
'ViewAll' => 'äöâ äëì',
'ViewEvent' => 'äöâ àéøåò',
'ViewPaged' => 'View Paged',
'Wake' => 'הער',
'Wake' => 'äòø',
'WarmupFrames' => 'Warmup Frames',
'Watch' => 'צפה',
'Web' => 'אינטרנט',
'WebColour' => 'צבע אינטרנט',
'Week' => 'שבוע',
'White' => 'לבן',
'Watch' => 'öôä',
'Web' => 'àéðèøðè',
'WebColour' => 'öáò àéðèøðè',
'Week' => 'ùáåò',
'White' => 'ìáï',
'WhiteBalance' => 'White Balance',
'Wide' => 'רחב',
'Wide' => 'øçá',
'X' => 'X',
'X10' => 'X10',
'X10ActivationString' => 'X10 Activation String',
'X10InputAlarmString' => 'X10 Input Alarm String',
'X10OutputAlarmString' => 'X10 Output Alarm String',
'Y' => 'Y',
'Yes' => 'כן',
'YouNoPerms' => 'אין לך הרשאה להיכנס למקור זה.',
'Zone' => 'אזור',
'Yes' => 'ëï',
'YouNoPerms' => 'àéï ìê äøùàä ìäéëðñ ìî÷åø æä.',
'Zone' => 'àæåø',
'ZoneAlarmColour' => 'Alarm Colour (Red/Green/Blue)',
'ZoneArea' => 'Zone Area',
'ZoneExtendAlarmFrames' => 'Extend Alarm Frame Count',
@ -753,10 +753,10 @@ $SLANG = array(
'ZoneMinMaxPixelThres' => 'Min/Max Pixel Threshold (0-255)',
'ZoneMinderLog' => 'ZoneMinder Log', // Added - 2011-06-17
'ZoneOverloadFrames' => 'Overload Frame Ignore Count',
'Zones' => 'אזורים',
'Zoom' => 'זום',
'ZoomIn' => 'זום פנימה',
'ZoomOut' => 'זום החוצה',
'Zones' => 'àæåøéí',
'Zoom' => 'æåí',
'ZoomIn' => 'æåí ôðéîä',
'ZoomOut' => 'æåí äçåöä',
);
// Complex replacements with formatting and/or placements, must be passed through sprintf

View File

@ -4,7 +4,7 @@
//
// Feel Free to contact Me at illuminati@linuxmail.org
//
// Tradução Para Português do Brasil do Zoneminder
// Tradução Para Português do Brasil do Zoneminder
//
// Sinta-se Livre para me contactar em illuminati@linuxmail.org
@ -18,7 +18,7 @@ $SLANG = array(
'Actual' => 'Atual',
'AddNewControl' => 'Add New Control',
'AddNewMonitor' => 'Adicionar Monitor',
'AddNewUser' => 'Adicionar Usuário',
'AddNewUser' => 'Adicionar Usuário',
'AddNewZone' => 'Adicionar Zona',
'Alarm' => 'Alarme',
'AlarmBrFrames' => 'Imagens<br/>Alarmadas',
@ -34,7 +34,7 @@ $SLANG = array(
'AnalysisFPS' => 'Analysis FPS', // Added - 2015-07-22
'AnalysisUpdateDelay' => 'Analysis Update Delay', // Added - 2015-07-23
'Apply' => 'Aplicar',
'ApplyingStateChange' => 'Aplicando mudança de estado',
'ApplyingStateChange' => 'Aplicando mudança de estado',
'ArchArchived' => 'Somente Arquivados',
'ArchUnarchived' => 'Somente Nao Arquivados',
'Archive' => 'Arquivar',
@ -49,7 +49,7 @@ $SLANG = array(
'AttrDateTime' => 'Data/Horario',
'AttrDiskBlocks' => 'Blocos de Disco',
'AttrDiskPercent' => 'Porcentagem de Disco',
'AttrDuration' => 'Duração',
'AttrDuration' => 'Duração',
'AttrFrames' => 'Imagens',
'AttrId' => 'Id',
'AttrMaxScore' => 'Max. Score',
@ -58,7 +58,7 @@ $SLANG = array(
'AttrName' => 'Nome',
'AttrNotes' => 'Notes',
'AttrSystemLoad' => 'System Load',
'AttrTime' => 'Horário',
'AttrTime' => 'Horário',
'AttrTotalScore' => 'Score Total',
'AttrWeekday' => 'Dia/Semana',
'Auto' => 'Auto',
@ -84,7 +84,7 @@ $SLANG = array(
'BadLabelY' => 'Label Y co-ordinate must be set to an integer of zero or more',
'BadMaxFPS' => 'Maximum FPS must be a positive integer or floating point value',
'BadMotionFrameSkip' => 'Motion Frame skip count must be an integer of zero or more',
'BadNameChars' => 'Nomes devem ser caracteres alfanuméricos mais hífen e underscore',
'BadNameChars' => 'Nomes devem ser caracteres alfanuméricos mais hífen e underscore',
'BadPalette' => 'Palette must be set to a valid value', // Added - 2009-03-31
'BadPath' => 'Path must be set to a valid value',
'BadPort' => 'Port must be set to a valid number',
@ -145,7 +145,7 @@ $SLANG = array(
'CanZoomCon' => 'Can Zoom Continuous',
'CanZoomRel' => 'Can Zoom Relative',
'Cancel' => 'Cancelar',
'CancelForcedAlarm' => 'Cancelar Alarme Forçado',
'CancelForcedAlarm' => 'Cancelar Alarme Forçado',
'CaptureHeight' => 'Altura da Captura',
'CaptureMethod' => 'Capture Method', // Added - 2009-02-08
'CapturePalette' => 'Paleta de Captura',
@ -192,10 +192,10 @@ $SLANG = array(
'Deinterlacing' => 'Deinterlacing', // Added - 2015-04-18
'Delay' => 'Delay', // Added - 2015-04-18
'Delete' => 'Deletar',
'DeleteAndNext' => 'Deletar &amp; Próx',
'DeleteAndNext' => 'Deletar &amp; Próx',
'DeleteAndPrev' => 'Deletar &amp; Ant',
'DeleteSavedFilter' => 'Deletar Filtros Salvos',
'Description' => 'Descrição',
'Description' => 'Descrição',
'DetectedCameras' => 'Detected Cameras', // Added - 2009-03-31
'DetectedProfiles' => 'Detected Profiles', // Added - 2015-04-18
'Device' => 'Device', // Added - 2009-02-08
@ -204,7 +204,7 @@ $SLANG = array(
'DeviceNumber' => 'Num. do Dispos.',
'DevicePath' => 'Device Path',
'Devices' => 'Devices',
'Dimensions' => 'Dimensões',
'Dimensions' => 'Dimensões',
'DisableAlarms' => 'Disable Alarms',
'Disk' => 'Disco',
'Display' => 'Display', // Added - 2011-01-30
@ -221,15 +221,15 @@ $SLANG = array(
'DonateYes' => 'Yes, I\'d like to donate now',
'Download' => 'Download',
'DuplicateMonitorName' => 'Duplicate Monitor Name', // Added - 2009-03-31
'Duration' => 'Duração',
'Duration' => 'Duração',
'Edit' => 'Editar',
'Email' => 'Email',
'EnableAlarms' => 'Enable Alarms',
'Enabled' => 'Habilitado',
'EnterNewFilterName' => 'Digite nome do novo filtro',
'Error' => 'Erro',
'ErrorBrackets' => 'Por favor cheque se você tem o mesmo numero de chaves abertas e fechadas',
'ErrorValidValue' => 'Erro, por favor cheque se os campos estão corretos',
'ErrorBrackets' => 'Por favor cheque se você tem o mesmo numero de chaves abertas e fechadas',
'ErrorValidValue' => 'Erro, por favor cheque se os campos estão corretos',
'Etc' => 'etc',
'Event' => 'Evento',
'EventFilter' => 'Filtro de Evento',
@ -283,7 +283,7 @@ $SLANG = array(
'FnNone' => 'None', // Added 2013.08.16.
'FnRecord' => 'Record', // Added 2013.08.16.
'Focus' => 'Focus',
'ForceAlarm' => 'Forçar Alarme',
'ForceAlarm' => 'Forçar Alarme',
'Format' => 'Format',
'Frame' => 'Imagem',
'FrameId' => 'Id de Imagem',
@ -291,7 +291,7 @@ $SLANG = array(
'FrameSkip' => 'Salto de Imagem',
'Frames' => 'Imagens',
'Func' => 'Func',
'Function' => 'Função',
'Function' => 'Função',
'Gain' => 'Gain',
'General' => 'General',
'GenerateVideo' => 'Gerar Video',
@ -315,7 +315,7 @@ $SLANG = array(
'HighBW' => 'Alta&nbsp;L/B',
'Home' => 'Home',
'Hour' => 'Hora',
'Hue' => 'Saturação',
'Hue' => 'Saturação',
'Id' => 'Id',
'Idle' => 'Parado',
'Ignore' => 'Ignorar',
@ -329,7 +329,7 @@ $SLANG = array(
'KeyString' => 'Key String',
'Label' => 'Label',
'Language' => 'Linguagem',
'Last' => 'Último',
'Last' => 'Último',
'Layout' => 'Layout', // Added - 2009-02-08
'Level' => 'Level', // Added - 2011-06-16
'Libvlc' => 'Libvlc',
@ -383,7 +383,7 @@ $SLANG = array(
'Message' => 'Message', // Added - 2011-06-16
'MinAlarmAreaLtMax' => 'Minimum alarm area should be less than maximum',
'MinAlarmAreaUnset' => 'You must specify the minimum alarm pixel count',
'MinBlobAreaLtMax' => 'A area minima de blob deve ser menor do que a area máxima de blob',
'MinBlobAreaLtMax' => 'A area minima de blob deve ser menor do que a area máxima de blob',
'MinBlobAreaUnset' => 'You must specify the minimum blob pixel count',
'MinBlobLtMinFilter' => 'Minimum blob area should be less than or equal to minimum filter area',
'MinBlobsLtMax' => 'O minimo de Blobs deve ser menor que o maximo de blobs',
@ -424,7 +424,7 @@ $SLANG = array(
'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2009-03-31
'Monitors' => 'Monitores',
'Montage' => 'Montagem',
'Month' => 'Mês',
'Month' => 'Mês',
'More' => 'More', // Added - 2011-06-16
'MotionFrameSkip' => 'Motion Frame Skip',
'Move' => 'Move',
@ -437,7 +437,7 @@ $SLANG = array(
'MustBeLe' => 'deve ser menor ou igual a',
'MustConfirmPassword' => 'Voce deve Confirmar a senha',
'MustSupplyPassword' => 'Voce deve informar a senha',
'MustSupplyUsername' => 'Voce deve informar nome de usuário',
'MustSupplyUsername' => 'Voce deve informar nome de usuário',
'Name' => 'Nome',
'Near' => 'Near',
'Network' => 'Rede',
@ -446,16 +446,16 @@ $SLANG = array(
'NewLabel' => 'New Label',
'NewPassword' => 'Nova Senha',
'NewState' => 'Novo Estado',
'NewUser' => 'Novo Usuário',
'Next' => 'Próx',
'No' => 'Não',
'NewUser' => 'Novo Usuário',
'Next' => 'Próx',
'No' => 'Não',
'NoDetectedCameras' => 'No Detected Cameras', // Added - 2009-03-31
'NoFramesRecorded' => 'Não há imagens gravadas neste evento',
'NoFramesRecorded' => 'Não há imagens gravadas neste evento',
'NoGroup' => 'No Group',
'NoSavedFilters' => 'SemFiltrosSalvos',
'NoStatisticsRecorded' => 'Não há estatísticas gravadas neste evento/imagem',
'NoStatisticsRecorded' => 'Não há estatísticas gravadas neste evento/imagem',
'None' => 'Nada',
'NoneAvailable' => 'Nada disponível',
'NoneAvailable' => 'Nada disponível',
'Normal' => 'Normal',
'Notes' => 'Notes',
'NumPresets' => 'Num Presets',
@ -472,15 +472,15 @@ $SLANG = array(
'OpLtEq' => 'menor que ou igual a',
'OpMatches' => 'combina',
'OpNe' => 'diferente de',
'OpNotIn' => 'não no set',
'OpNotMatches' => 'não combina',
'OpNotIn' => 'não no set',
'OpNotMatches' => 'não combina',
'Open' => 'Open',
'OptionHelp' => 'OpçãoAjuda',
'OptionRestartWarning' => 'Reinicie o Zoneminder para que as mudanças tenham efeito',
'Options' => 'Opções',
'OptionHelp' => 'OpçãoAjuda',
'OptionRestartWarning' => 'Reinicie o Zoneminder para que as mudanças tenham efeito',
'Options' => 'Opções',
'OrEnterNewName' => 'ou defina novo nome',
'Order' => 'Order',
'Orientation' => 'Orientação',
'Orientation' => 'Orientação',
'Out' => 'Out',
'OverwriteExisting' => 'Sobrescrever Existente',
'Paged' => 'Paginado',
@ -490,7 +490,7 @@ $SLANG = array(
'PanTilt' => 'Pan/Tilt',
'Parameter' => 'Parametro',
'Password' => 'Senha',
'PasswordsDifferent' => 'A nova senha e a de confirmação são diferentes',
'PasswordsDifferent' => 'A nova senha e a de confirmação são diferentes',
'Paths' => 'Caminhos',
'Pause' => 'Pause',
'Phone' => 'Phone',
@ -503,8 +503,8 @@ $SLANG = array(
'PleaseWait' => 'Por Favor Espere',
'Plugins' => 'Plugins',
'Point' => 'Point',
'PostEventImageBuffer' => 'Buffer de imagem pós evento',
'PreEventImageBuffer' => 'Buffer de imagem pré evento',
'PostEventImageBuffer' => 'Buffer de imagem pós evento',
'PreEventImageBuffer' => 'Buffer de imagem pré evento',
'PreserveAspect' => 'Preserve Aspect Ratio',
'Preset' => 'Preset',
'Presets' => 'Presets',
@ -517,7 +517,7 @@ $SLANG = array(
'Rate' => 'Vel.',
'Real' => 'Real',
'Record' => 'Gravar',
'RefImageBlendPct' => 'Referência de imagem Blend %ge',
'RefImageBlendPct' => 'Referência de imagem Blend %ge',
'Refresh' => 'Atualizar',
'Remote' => 'Remoto',
'RemoteHostName' => 'Nome do host remoto',
@ -536,16 +536,16 @@ $SLANG = array(
'ResetEventCounts' => 'Resetar contagem de eventos',
'Restart' => 'Reiniciar',
'Restarting' => 'Reiniciando',
'RestrictedCameraIds' => 'Ids de camera proibídos',
'RestrictedCameraIds' => 'Ids de camera proibídos',
'RestrictedMonitors' => 'Restricted Monitors',
'ReturnDelay' => 'Return Delay',
'ReturnLocation' => 'Return Location',
'Rewind' => 'Rewind',
'RotateLeft' => 'Rotacionar à esquerda ',
'RotateRight' => 'Rotacionar à direita',
'RotateLeft' => 'Rotacionar à esquerda ',
'RotateRight' => 'Rotacionar à direita',
'RunLocalUpdate' => 'Please run zmupdate.pl to update', // Added - 2011-05-25
'RunMode' => 'Modo de Execução',
'RunState' => 'Estado de Execução',
'RunMode' => 'Modo de Execução',
'RunState' => 'Estado de Execução',
'Running' => 'Rodando',
'Save' => 'Salvar',
'SaveAs' => 'Salvar Como',
@ -562,7 +562,7 @@ $SLANG = array(
'Set' => 'Set',
'SetNewBandwidth' => 'Defina Nova L/B',
'SetPreset' => 'Set Preset',
'Settings' => 'Configurações',
'Settings' => 'Configurações',
'ShowFilterWindow' => 'MostrarJanelaDeFiltros',
'ShowTimeline' => 'Show Timeline',
'SignalCheckColour' => 'Signal Check Colour',
@ -595,7 +595,7 @@ $SLANG = array(
'Stills' => 'Imagens',
'Stop' => 'Parar',
'Stopped' => 'Parado',
'Stream' => 'Contínuo',
'Stream' => 'Contínuo',
'StreamReplayBuffer' => 'Stream Replay Image Buffer',
'Submit' => 'Submit',
'System' => 'Sistema',
@ -614,8 +614,8 @@ $SLANG = array(
'TimelineTip4' => 'Use the controls below to zoom out or navigate back and forward through the time range.', // Added 2013.08.15.
'Timestamp' => 'Tempo',
'TimestampLabelFormat' => 'Formato de etiqueta de tempo',
'TimestampLabelX' => 'posição de etiqueta X',
'TimestampLabelY' => 'posição de etiqueta Y',
'TimestampLabelX' => 'posição de etiqueta X',
'TimestampLabelY' => 'posição de etiqueta Y',
'Today' => 'Today',
'Tools' => 'Ferramentas',
'Total' => 'Total', // Added - 2011-06-16
@ -631,35 +631,35 @@ $SLANG = array(
'Units' => 'Unidades',
'Unknown' => 'Desconhecido',
'Update' => 'Update',
'UpdateAvailable' => 'Um update ao zoneminder está disponível.',
'UpdateNotNecessary' => 'Não é necessário update.',
'UpdateAvailable' => 'Um update ao zoneminder está disponível.',
'UpdateNotNecessary' => 'Não é necessário update.',
'Updated' => 'Updated', // Added - 2011-06-16
'Upload' => 'Upload', // Added - 2011-08-23
'UseFilter' => 'Use Filtro',
'UseFilterExprsPost' => '&nbsp;expressões&nbsp;de&nbsp;filtragem', // This is used at the end of the phrase 'use N filter expressions'
'UseFilterExprsPost' => '&nbsp;expressões&nbsp;de&nbsp;filtragem', // This is used at the end of the phrase 'use N filter expressions'
'UseFilterExprsPre' => 'Use&nbsp;', // This is used at the beginning of the phrase 'use N filter expressions'
'UsedPlugins' => 'Used Plugins',
'User' => 'Usuário',
'Username' => 'Nome de Usuário',
'Users' => 'Usuários',
'User' => 'Usuário',
'Username' => 'Nome de Usuário',
'Users' => 'Usuários',
'V4L' => 'V4L', // Added - 2015-04-18
'V4LCapturesPerFrame' => 'Captures Per Frame', // Added - 2015-04-18
'V4LMultiBuffer' => 'Multi Buffering', // Added - 2015-04-18
'Value' => 'Valor',
'Version' => 'Versão',
'VersionIgnore' => 'Ignorar esta versão',
'Version' => 'Versão',
'VersionIgnore' => 'Ignorar esta versão',
'VersionRemindDay' => 'Lembre novamente em 1 dia',
'VersionRemindHour' => 'Lembre novamente em 1 hora',
'VersionRemindNever' => 'Nao lembrar novas versões',
'VersionRemindNever' => 'Nao lembrar novas versões',
'VersionRemindWeek' => 'Lembrar novamente em 1 semana',
'Video' => 'Video',
'VideoFormat' => 'Video Format',
'VideoGenFailed' => 'Geração de Vídeo falhou!',
'VideoGenFailed' => 'Geração de Vídeo falhou!',
'VideoGenFiles' => 'Existing Video Files',
'VideoGenNoFiles' => 'No Video Files Found',
'VideoGenParms' => 'Parametros de geração de vídeo',
'VideoGenParms' => 'Parametros de geração de vídeo',
'VideoGenSucceeded' => 'Video Generation Succeeded!',
'VideoSize' => 'Tamanho do vídeo',
'VideoSize' => 'Tamanho do vídeo',
'View' => 'Ver',
'ViewAll' => 'Ver Tudo',
'ViewEvent' => 'View Event',
@ -675,12 +675,12 @@ $SLANG = array(
'Wide' => 'Wide',
'X' => 'X',
'X10' => 'X10',
'X10ActivationString' => 'String de Ativação X10',
'X10ActivationString' => 'String de Ativação X10',
'X10InputAlarmString' => 'String de Entrada de alarme X10',
'X10OutputAlarmString' => 'String de Saída de Alarme X10',
'X10OutputAlarmString' => 'String de Saída de Alarme X10',
'Y' => 'Y',
'Yes' => 'Sim',
'YouNoPerms' => 'Você não tem permissões para acessar este recurso.',
'YouNoPerms' => 'Você não tem permissões para acessar este recurso.',
'Zone' => 'Zona',
'ZoneAlarmColour' => 'Cor de Alarme (Red/Green/Blue)',
'ZoneArea' => 'Zone Area',
@ -701,13 +701,13 @@ $SLANG = array(
// Complex replacements with formatting and/or placements, must be passed through sprintf
$CLANG = array(
'CurrentLogin' => 'Login atual é \'%1$s\'',
'CurrentLogin' => 'Login atual é \'%1$s\'',
'EventCount' => '%1$s %2$s', // For example '37 Events' (from Vlang below)
'LastEvents' => 'Últimos %1$s %2$s', // For example 'Last 37 Events' (from Vlang below)
'LatestRelease' => 'A Última versão é v%1$s, você tem v%2$s.',
'LastEvents' => 'Últimos %1$s %2$s', // For example 'Last 37 Events' (from Vlang below)
'LatestRelease' => 'A Última versão é v%1$s, você tem v%2$s.',
'MonitorCount' => '%1$s %2$s', // For example '4 Monitors' (from Vlang below)
'MonitorFunction' => 'Monitor %1$s Funcção',
'RunningRecentVer' => 'Você está usando a versão mais recente do ZoneMinder, v%s.',
'MonitorFunction' => 'Monitor %1$s Funcção',
'RunningRecentVer' => 'Você está usando a versão mais recente do ZoneMinder, v%s.',
'VersionMismatch' => 'Version mismatch, system is version %1$s, database is %2$s.', // Added - 2011-05-25
);

View File

@ -72,92 +72,92 @@
// Simple String Replacements
$SLANG = array(
'24BitColour' => '24 bitars färg',
'32BitColour' => '32 bitars färg', // Added - 2011-06-15
'8BitGrey' => '8 bit gråskala',
'24BitColour' => '24 bitars färg',
'32BitColour' => '32 bitars färg', // Added - 2011-06-15
'8BitGrey' => '8 bit gråskala',
'Action' => 'Action',
'Actual' => 'Verklig',
'AddNewControl' => 'Ny kontroll',
'AddNewMonitor' => 'Ny bevakare',
'AddNewUser' => 'Ny användare',
'AddNewUser' => 'Ny användare',
'AddNewZone' => 'Ny zon',
'Alarm' => 'Larm',
'AlarmBrFrames' => 'Larm<br/>ramar',
'AlarmFrame' => 'Larmram',
'AlarmFrameCount' => 'Larmramsräknare',
'AlarmLimits' => 'Larmgränser',
'AlarmMaximumFPS' => 'Max. ramar/s för larm',
'AlarmFrameCount' => 'Larmramsräknare',
'AlarmLimits' => 'Larmgränser',
'AlarmMaximumFPS' => 'Max. ramar/s för larm',
'AlarmPx' => 'Larmpunkter',
'AlarmRGBUnset' => 'Du måste sätta en färg för RGB-larm',
'AlarmRGBUnset' => 'Du måste sätta en färg för RGB-larm',
'AlarmRefImageBlendPct'=> 'Alarm Reference Image Blend %ge', // Added - 2015-04-18
'Alert' => 'Varning',
'All' => 'Alla',
'AnalysisFPS' => 'Analysis FPS', // Added - 2015-07-22
'AnalysisUpdateDelay' => 'Analysis Update Delay', // Added - 2015-07-23
'Apply' => 'Lägg till',
'ApplyingStateChange' => 'Aktivera statusändring',
'Apply' => 'Lägg till',
'ApplyingStateChange' => 'Aktivera statusändring',
'ArchArchived' => 'Arkivera endast',
'ArchUnarchived' => 'Endast ej arkiverade',
'Archive' => 'Arkiv',
'Archived' => 'Arkiverad',
'Area' => 'Område',
'AreaUnits' => 'Område (px/%)',
'Area' => 'Område',
'AreaUnits' => 'Område (px/%)',
'AttrAlarmFrames' => 'Larmramar',
'AttrArchiveStatus' => 'Arkivstatus',
'AttrAvgScore' => 'Ung. värde',
'AttrAvgScore' => 'Ung. värde',
'AttrCause' => 'Orsak',
'AttrDate' => 'Datum',
'AttrDateTime' => 'Datum/Tid',
'AttrDiskBlocks' => 'Diskblock',
'AttrDiskPercent' => 'Diskprocent',
'AttrDuration' => 'Längd',
'AttrDuration' => 'Längd',
'AttrFrames' => 'Ramar',
'AttrId' => 'Id',
'AttrMaxScore' => 'Max. värde',
'AttrMaxScore' => 'Max. värde',
'AttrMonitorId' => 'Bevakningsid',
'AttrMonitorName' => 'Bevakningsnamn',
'AttrName' => 'Namn',
'AttrNotes' => 'Notering',
'AttrSystemLoad' => 'Systemlast',
'AttrTime' => 'Tid',
'AttrTotalScore' => 'Totalvärde',
'AttrTotalScore' => 'Totalvärde',
'AttrWeekday' => 'Veckodag',
'Auto' => 'Automatik',
'AutoStopTimeout' => 'Tidsutlösning för automatstop',
'AutoStopTimeout' => 'Tidsutlösning för automatstop',
'Available' => 'Available', // Added - 2009-03-31
'AvgBrScore' => 'Ung.<br/>träff',
'AvgBrScore' => 'Ung.<br/>träff',
'Background' => 'Bakgrund',
'BackgroundFilter' => 'Kör filter i bakgrunden',
'BadAlarmFrameCount' => 'Ramantalet för larm måste vara ett heltal, minsta värdet är 1',
'BadAlarmMaxFPS' => 'Larm för bilder/s måste vara ett positivt heltal eller ett flyttal',
'BackgroundFilter' => 'Kör filter i bakgrunden',
'BadAlarmFrameCount' => 'Ramantalet för larm måste vara ett heltal, minsta värdet är 1',
'BadAlarmMaxFPS' => 'Larm för bilder/s måste vara ett positivt heltal eller ett flyttal',
'BadAnalysisFPS' => 'Analysis FPS must be a positive integer or floating point value', // Added - 2015-07-22
'BadAnalysisUpdateDelay'=> 'Analysis update delay must be set to an integer of zero or more', // Added - 2015-07-23
'BadChannel' => 'Kanalen måste vara ett heltal, noll eller högre',
'BadChannel' => 'Kanalen måste vara ett heltal, noll eller högre',
'BadColours' => 'Target colour must be set to a valid value', // Added - 2011-06-15
'BadDevice' => 'Enheten måste sättas till ett giltigt värde',
'BadFPSReportInterval' => 'Buffern för ramintervallrapporten måste vara ett heltal på minst 0 eller högre',
'BadFormat' => 'Formatet måste vara ett heltal, noll eller högre',
'BadFrameSkip' => 'Värdet för ramöverhopp måste vara ett heltal på 0 eller högre',
'BadHeight' => 'Höjden måste sättas till ett giltigt värde',
'BadHost' => 'Detta fält ska innehålla en giltig ip-adress eller värdnamn, inkludera inte http://',
'BadImageBufferCount' => 'Bufferstorleken för avbilden måste vara ett heltal på minst 10 eller högre',
'BadLabelX' => 'Etiketten för X koordinaten måste sättas till ett heltal, 0 eller högre',
'BadLabelY' => 'Etiketten för Y koordinaten måste sättas till ett heltal, 0 eller högre',
'BadMaxFPS' => 'Max. ramar/s måste vara ett positivt heltal eller ett flyttal',
'BadDevice' => 'Enheten måste sättas till ett giltigt värde',
'BadFPSReportInterval' => 'Buffern för ramintervallrapporten måste vara ett heltal på minst 0 eller högre',
'BadFormat' => 'Formatet måste vara ett heltal, noll eller högre',
'BadFrameSkip' => 'Värdet för ramöverhopp måste vara ett heltal på 0 eller högre',
'BadHeight' => 'Höjden måste sättas till ett giltigt värde',
'BadHost' => 'Detta fält ska innehålla en giltig ip-adress eller värdnamn, inkludera inte http://',
'BadImageBufferCount' => 'Bufferstorleken för avbilden måste vara ett heltal på minst 10 eller högre',
'BadLabelX' => 'Etiketten för X koordinaten måste sättas till ett heltal, 0 eller högre',
'BadLabelY' => 'Etiketten för Y koordinaten måste sättas till ett heltal, 0 eller högre',
'BadMaxFPS' => 'Max. ramar/s måste vara ett positivt heltal eller ett flyttal',
'BadMotionFrameSkip' => 'Motion Frame skip count must be an integer of zero or more',
'BadNameChars' => 'Namn kan endast innehålla alfanumeriska tecken, utrymmen, bindestreck och understreck',
'BadNameChars' => 'Namn kan endast innehålla alfanumeriska tecken, utrymmen, bindestreck och understreck',
'BadPalette' => 'Palette must be set to a valid value', // Added - 2009-03-31
'BadPath' => 'Sökvägen måste innehålla ett giltigt värde',
'BadPort' => 'Porten måste innehålla ett giltigt nummer',
'BadPostEventCount' => 'Räknaren för efterhändelsen måste vara ett heltal på 0 eller högre',
'BadPreEventCount' => 'Räknaren för för-händelsen måste vara ett heltal på 0 eller högre, och mindre än bufferstorleken på avbilden',
'BadRefBlendPerc' => 'Mixprocenten för referensen måste hara ett positivt heltal',
'BadSectionLength' => 'Sektionslängden måste vara ett heltal på minst 30 eller högre',
'BadSignalCheckColour' => 'Kontrollfärgen på signalen måste vara en giltig RGB färgsträng',
'BadStreamReplayBuffer'=> 'Buffern för strömmande uppspelning måste vara ett heltal på 0 eller högre',
'BadWarmupCount' => 'Uppvärmingsramen måste vara ett heltal på 0 eller högre',
'BadWebColour' => 'Webbfärgen måste vara en giltig sträng för webbfärg',
'BadWidth' => 'Bredden måste sättas til ett giltigt värde',
'BadPath' => 'Sökvägen måste innehålla ett giltigt värde',
'BadPort' => 'Porten måste innehålla ett giltigt nummer',
'BadPostEventCount' => 'Räknaren för efterhändelsen måste vara ett heltal på 0 eller högre',
'BadPreEventCount' => 'Räknaren för för-händelsen måste vara ett heltal på 0 eller högre, och mindre än bufferstorleken på avbilden',
'BadRefBlendPerc' => 'Mixprocenten för referensen måste hara ett positivt heltal',
'BadSectionLength' => 'Sektionslängden måste vara ett heltal på minst 30 eller högre',
'BadSignalCheckColour' => 'Kontrollfärgen på signalen måste vara en giltig RGB färgsträng',
'BadStreamReplayBuffer'=> 'Buffern för strömmande uppspelning måste vara ett heltal på 0 eller högre',
'BadWarmupCount' => 'Uppvärmingsramen måste vara ett heltal på 0 eller högre',
'BadWebColour' => 'Webbfärgen måste vara en giltig sträng för webbfärg',
'BadWidth' => 'Bredden måste sättas til ett giltigt värde',
'Bandwidth' => 'Bandbredd',
'BandwidthHead' => 'Bandwidth', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing
'BlobPx' => 'Blob Px',
@ -168,7 +168,7 @@ $SLANG = array(
'Buffers' => 'Buffrar',
'CSSDescription' => 'Change the default css for this computer', // Added - 2015-04-18
'CanAutoFocus' => 'Har autofokus',
'CanAutoGain' => 'Har autonivå',
'CanAutoGain' => 'Har autonivå',
'CanAutoIris' => 'Har autoiris',
'CanAutoWhite' => 'Har autovitbalans.',
'CanAutoZoom' => 'Har autozoom',
@ -176,23 +176,23 @@ $SLANG = array(
'CanFocusAbs' => 'Har absolut fokus',
'CanFocusCon' => 'Har kontinuerlig fokus',
'CanFocusRel' => 'Har relativ fokus',
'CanGain' => 'Har nivå',
'CanGainAbs' => 'Har absolut nivå',
'CanGainCon' => 'Har kontinuerlig nivå',
'CanGainRel' => 'Har relativ nivå',
'CanGain' => 'Har nivå',
'CanGainAbs' => 'Har absolut nivå',
'CanGainCon' => 'Har kontinuerlig nivå',
'CanGainRel' => 'Har relativ nivå',
'CanIris' => 'Har iris',
'CanIrisAbs' => 'Har absolut iris',
'CanIrisCon' => 'Har kontinuerlig iris',
'CanIrisRel' => 'Har relativ iris',
'CanMove' => 'Har förflyttning',
'CanMoveAbs' => 'Har absolut förflyttning',
'CanMoveCon' => 'Har kontinuerlig förflyttning',
'CanMoveDiag' => 'Har diagonal förflyttning',
'CanMoveMap' => 'Har mappad förflyttning',
'CanMoveRel' => 'Har relativ förflyttning',
'CanMove' => 'Har förflyttning',
'CanMoveAbs' => 'Har absolut förflyttning',
'CanMoveCon' => 'Har kontinuerlig förflyttning',
'CanMoveDiag' => 'Har diagonal förflyttning',
'CanMoveMap' => 'Har mappad förflyttning',
'CanMoveRel' => 'Har relativ förflyttning',
'CanPan' => 'Har panorering',
'CanReset' => 'Har återställning',
'CanSetPresets' => 'Har förinställningar',
'CanReset' => 'Har återställning',
'CanSetPresets' => 'Har förinställningar',
'CanSleep' => 'Kan vila',
'CanTilt' => 'Kan tilta',
'CanWake' => 'Kan vakna',
@ -205,39 +205,39 @@ $SLANG = array(
'CanZoomAbs' => 'Kan zooma absolut',
'CanZoomCon' => 'Kan zooma kontinuerligt',
'CanZoomRel' => 'Kan zooma realativt',
'Cancel' => 'Ångra',
'CancelForcedAlarm' => 'Ångra tvingande larm',
'CaptureHeight' => 'Fångsthöjd',
'Cancel' => 'Ångra',
'CancelForcedAlarm' => 'Ångra tvingande larm',
'CaptureHeight' => 'Fångsthöjd',
'CaptureMethod' => 'Capture Method', // Added - 2009-02-08
'CapturePalette' => 'Fångstpalett',
'CapturePalette' => 'Fångstpalett',
'CaptureResolution' => 'Capture Resolution', // Added - 2015-04-18
'CaptureWidth' => 'Fångstbredd',
'CaptureWidth' => 'Fångstbredd',
'Cause' => 'Orsak',
'CheckMethod' => 'Larmkontrollmetod',
'ChooseDetectedCamera' => 'Choose Detected Camera', // Added - 2009-03-31
'ChooseFilter' => 'Välj filter',
'ChooseFilter' => 'Välj filter',
'ChooseLogFormat' => 'Choose a log format', // Added - 2011-06-17
'ChooseLogSelection' => 'Choose a log selection', // Added - 2011-06-17
'ChoosePreset' => 'Välj standard',
'ChoosePreset' => 'Välj standard',
'Clear' => 'Clear', // Added - 2011-06-16
'Close' => 'Stäng',
'Colour' => 'Färg',
'Close' => 'Stäng',
'Colour' => 'Färg',
'Command' => 'Kommando',
'Component' => 'Component', // Added - 2011-06-16
'Config' => 'Konfigurera',
'ConfiguredFor' => 'Konfigurerad för',
'ConfirmDeleteEvents' => 'Är du säker på att du vill ta bort dom valda händelserna?',
'ConfirmPassword' => 'Bekräfta lösenord',
'ConfiguredFor' => 'Konfigurerad för',
'ConfirmDeleteEvents' => 'Är du säker på att du vill ta bort dom valda händelserna?',
'ConfirmPassword' => 'Bekräfta lösenord',
'ConjAnd' => 'och',
'ConjOr' => 'eller',
'Console' => 'Konsoll',
'ContactAdmin' => 'Kontakta din administratör för detaljer.',
'Continue' => 'Fortsätt',
'ContactAdmin' => 'Kontakta din administratör för detaljer.',
'Continue' => 'Fortsätt',
'Contrast' => 'Kontrast',
'Control' => 'Kontroll',
'ControlAddress' => 'Kontrolladress',
'ControlCap' => 'Kontrollförmåga',
'ControlCaps' => 'Kontrollförmågor',
'ControlCap' => 'Kontrollförmåga',
'ControlCaps' => 'Kontrollförmågor',
'ControlDevice' => 'Kontrollenhet',
'ControlType' => 'Kontrolltyp',
'Controllable' => 'Kontrollerbar',
@ -253,8 +253,8 @@ $SLANG = array(
'Deinterlacing' => 'Deinterlacing', // Added - 2015-04-18
'Delay' => 'Delay', // Added - 2015-04-18
'Delete' => 'Radera',
'DeleteAndNext' => 'Radera &amp; Nästa',
'DeleteAndPrev' => 'Radera &amp; Föreg.',
'DeleteAndNext' => 'Radera &amp; Nästa',
'DeleteAndPrev' => 'Radera &amp; Föreg.',
'DeleteSavedFilter' => 'Radera sparade filter',
'Description' => 'Beskrivning',
'DetectedCameras' => 'Detected Cameras', // Added - 2009-03-31
@ -263,7 +263,7 @@ $SLANG = array(
'DeviceChannel' => 'Enhetskanal',
'DeviceFormat' => 'Enhetsformat',
'DeviceNumber' => 'Enhetsnummer',
'DevicePath' => 'Enhetssökväg',
'DevicePath' => 'Enhetssökväg',
'Devices' => 'Enheter',
'Dimensions' => 'Dimensioner',
'DisableAlarms' => 'Avaktivera larm',
@ -271,39 +271,39 @@ $SLANG = array(
'Display' => 'Display', // Added - 2011-01-30
'Displaying' => 'Displaying', // Added - 2011-06-16
'DoNativeMotionDetection'=> 'Do Native Motion Detection',
'Donate' => 'Var vänlig och donera',
'Donate' => 'Var vänlig och donera',
'DonateAlready' => 'Nej, Jag har redan donerat',
'DonateEnticement' => 'Du har kört ZoneMinder ett tag nu och förhoppningsvis har du sett att det fungerar bra hemma eller på ditt företag. Även om ZoneMinder är, och kommer att vara, fri programvara och öppen kallkod, så kostar det pengar att utveckla och underhålla. Om du vill hjälpa till med framtida utveckling och nya funktioner så var vanlig och bidrag med en slant. Bidragen är naturligtvis en option men mycket uppskattade och du kan bidra med precis hur mycket du vill.<br><br>Om du vill ge ett bidrag väljer du nedan eller surfar till http://www.zoneminder.com/donate.html.<br><br>Tack för att du använder ZoneMinder, glöm inte att besöka forumen på ZoneMinder.com för support och förslag om hur du får din ZoneMinder att fungera lite bättre.',
'DonateRemindDay' => 'Inte än, påminn om 1 dag',
'DonateRemindHour' => 'Inte än, påminn om en 1 timme',
'DonateRemindMonth' => 'Inte än, påminn om 1 månad',
'DonateRemindNever' => 'Nej, Jag vill inte donera, påminn mig inte mer',
'DonateRemindWeek' => 'Inte än, påminn om 1 vecka',
'DonateYes' => 'Ja, jag vill gärna donera nu',
'DonateEnticement' => 'Du har kört ZoneMinder ett tag nu och förhoppningsvis har du sett att det fungerar bra hemma eller på ditt företag. Även om ZoneMinder är, och kommer att vara, fri programvara och öppen kallkod, så kostar det pengar att utveckla och underhålla. Om du vill hjälpa till med framtida utveckling och nya funktioner så var vanlig och bidrag med en slant. Bidragen är naturligtvis en option men mycket uppskattade och du kan bidra med precis hur mycket du vill.<br><br>Om du vill ge ett bidrag väljer du nedan eller surfar till http://www.zoneminder.com/donate.html.<br><br>Tack för att du använder ZoneMinder, glöm inte att besöka forumen på ZoneMinder.com för support och förslag om hur du får din ZoneMinder att fungera lite bättre.',
'DonateRemindDay' => 'Inte än, påminn om 1 dag',
'DonateRemindHour' => 'Inte än, påminn om en 1 timme',
'DonateRemindMonth' => 'Inte än, påminn om 1 månad',
'DonateRemindNever' => 'Nej, Jag vill inte donera, påminn mig inte mer',
'DonateRemindWeek' => 'Inte än, påminn om 1 vecka',
'DonateYes' => 'Ja, jag vill gärna donera nu',
'Download' => 'Ladda ner',
'DuplicateMonitorName' => 'Duplicate Monitor Name', // Added - 2009-03-31
'Duration' => 'Längd',
'Duration' => 'Längd',
'Edit' => 'Redigera',
'Email' => 'E-post',
'EnableAlarms' => 'Aktivera larm',
'Enabled' => 'Aktiverad',
'EnterNewFilterName' => 'Mata in nytt filternamn',
'Error' => 'Fel',
'ErrorBrackets' => 'Fel, kontrollera att du har samma antal vänster som höger-hakar',
'ErrorValidValue' => 'Fel, kontrollera att alla parametrar har giltligt värde',
'ErrorBrackets' => 'Fel, kontrollera att du har samma antal vänster som höger-hakar',
'ErrorValidValue' => 'Fel, kontrollera att alla parametrar har giltligt värde',
'Etc' => 'etc',
'Event' => 'Händelse',
'EventFilter' => 'Händelsefilter',
'EventId' => 'Händelse nr',
'EventName' => 'Händelsenamn',
'EventPrefix' => 'Händelseprefix',
'Events' => 'Händelser',
'Event' => 'Händelse',
'EventFilter' => 'Händelsefilter',
'EventId' => 'Händelse nr',
'EventName' => 'Händelsenamn',
'EventPrefix' => 'Händelseprefix',
'Events' => 'Händelser',
'Exclude' => 'Exkludera',
'Execute' => 'Utför',
'Execute' => 'Utför',
'Export' => 'Exportera',
'ExportDetails' => 'Exportera händelsedetaljer',
'ExportDetails' => 'Exportera händelsedetaljer',
'ExportFailed' => 'Exporten misslyckades',
'ExportFormat' => 'Filformat för exporter',
'ExportFormat' => 'Filformat för exporter',
'ExportFormatTar' => 'Tar',
'ExportFormatZip' => 'Zip',
'ExportFrames' => 'Exportera ramdetaljer',
@ -323,20 +323,20 @@ $SLANG = array(
'Ffmpeg' => 'Ffmpeg', // Added - 2009-02-08
'File' => 'Fil',
'Filter' => 'Filter', // Added - 2015-04-18
'FilterArchiveEvents' => 'Arkivera alla träffar',
'FilterDeleteEvents' => 'Radera alla träffar',
'FilterEmailEvents' => 'Skicka e-post med detaljer om alla träffar',
'FilterExecuteEvents' => 'Utför kommando på alla träffar',
'FilterArchiveEvents' => 'Arkivera alla träffar',
'FilterDeleteEvents' => 'Radera alla träffar',
'FilterEmailEvents' => 'Skicka e-post med detaljer om alla träffar',
'FilterExecuteEvents' => 'Utför kommando på alla träffar',
'FilterLog' => 'Filter log', // Added - 2015-04-18
'FilterMessageEvents' => 'Meddela detaljer om alla träffar',
'FilterMessageEvents' => 'Meddela detaljer om alla träffar',
'FilterPx' => 'Filter Px',
'FilterUnset' => 'Du måste specificera filtrets bredd och höjd',
'FilterUploadEvents' => 'Ladda upp alla träffar',
'FilterVideoEvents' => 'Skapa video för alla träffar',
'FilterUnset' => 'Du måste specificera filtrets bredd och höjd',
'FilterUploadEvents' => 'Ladda upp alla träffar',
'FilterVideoEvents' => 'Skapa video för alla träffar',
'Filters' => 'Filter',
'First' => 'Först',
'FlippedHori' => 'Vänd horisontellt',
'FlippedVert' => 'Vänd vertikalt',
'First' => 'Först',
'FlippedHori' => 'Vänd horisontellt',
'FlippedVert' => 'Vänd vertikalt',
'FnMocord' => 'Mocord', // Added 2013.08.16.
'FnModect' => 'Modect', // Added 2013.08.16.
'FnMonitor' => 'Monitor', // Added 2013.08.16.
@ -349,31 +349,31 @@ $SLANG = array(
'Frame' => 'Ram',
'FrameId' => 'Ram id',
'FrameRate' => 'Ram hastighet',
'FrameSkip' => 'Hoppa över ram',
'FrameSkip' => 'Hoppa över ram',
'Frames' => 'Ramar',
'Func' => 'Funk',
'Function' => 'Funktion',
'Gain' => 'Nivå',
'Gain' => 'Nivå',
'General' => 'Generell',
'GenerateVideo' => 'Skapa video',
'GeneratingVideo' => 'Skapar video',
'GoToZoneMinder' => 'Gå till ZoneMinder.com',
'Grey' => 'Grå',
'GoToZoneMinder' => 'Gå till ZoneMinder.com',
'Grey' => 'Grå',
'Group' => 'Grupp',
'Groups' => 'Grupper',
'HasFocusSpeed' => 'Har focushastighet',
'HasGainSpeed' => 'Har nivåhastighet',
'HasHomePreset' => 'Har normalinställning',
'HasGainSpeed' => 'Har nivåhastighet',
'HasHomePreset' => 'Har normalinställning',
'HasIrisSpeed' => 'Har irishastighet',
'HasPanSpeed' => 'Har panoramahastighet',
'HasPresets' => 'Har förinställningar',
'HasPresets' => 'Har förinställningar',
'HasTiltSpeed' => 'Har tilthastighet',
'HasTurboPan' => 'Har turbopanorering',
'HasTurboTilt' => 'Har turbotilt',
'HasWhiteSpeed' => 'Har vitbalanshastighet',
'HasZoomSpeed' => 'Har Zoomhastighet',
'High' => 'Hög',
'HighBW' => 'Hög bandbredd',
'High' => 'Hög',
'HighBW' => 'Hög bandbredd',
'Home' => 'Hem',
'Hour' => 'Timme',
'Hue' => 'Hue',
@ -387,17 +387,17 @@ $SLANG = array(
'Include' => 'Inkludera',
'Inverted' => 'Inverterad',
'Iris' => 'Iris',
'KeyString' => 'Nyckelsträng',
'KeyString' => 'Nyckelsträng',
'Label' => 'Etikett',
'Language' => 'Språk',
'Language' => 'Språk',
'Last' => 'Sist',
'Layout' => 'Layout', // Added - 2009-02-08
'Level' => 'Level', // Added - 2011-06-16
'Libvlc' => 'Libvlc',
'LimitResultsPost' => 'resultaten;', // This is used at the end of the phrase 'Limit to first N results only'
'LimitResultsPre' => 'Begränsa till första', // This is used at the beginning of the phrase 'Limit to first N results only'
'LimitResultsPre' => 'Begränsa till första', // This is used at the beginning of the phrase 'Limit to first N results only'
'Line' => 'Line', // Added - 2011-06-16
'LinkedMonitors' => 'Länkade övervakare',
'LinkedMonitors' => 'Länkade övervakare',
'List' => 'Lista',
'Load' => 'Belastning',
'Local' => 'Lokal',
@ -408,8 +408,8 @@ $SLANG = array(
'Login' => 'Logga in',
'Logout' => 'Logga ut',
'Logs' => 'Logs', // Added - 2011-06-17
'Low' => 'Låg',
'LowBW' => 'Låg bandbredd',
'Low' => 'Låg',
'LowBW' => 'Låg bandbredd',
'Main' => 'Huvudmeny',
'Man' => 'Man',
'Manual' => 'Manuell',
@ -417,75 +417,75 @@ $SLANG = array(
'Max' => 'Max',
'MaxBandwidth' => 'Max bandbredd',
'MaxBrScore' => 'Max.<br/>Score',
'MaxFocusRange' => 'Max fokusområde',
'MaxFocusRange' => 'Max fokusområde',
'MaxFocusSpeed' => 'Max fokushastighet',
'MaxFocusStep' => 'Max fokussteg',
'MaxGainRange' => 'Max nivåområde',
'MaxGainSpeed' => 'Max nivåhastighet',
'MaxGainStep' => 'Max nivåsteg',
'MaxIrisRange' => 'Max irsiområde',
'MaxGainRange' => 'Max nivåområde',
'MaxGainSpeed' => 'Max nivåhastighet',
'MaxGainStep' => 'Max nivåsteg',
'MaxIrisRange' => 'Max irsiområde',
'MaxIrisSpeed' => 'Max irishastighet',
'MaxIrisStep' => 'Max irissteg',
'MaxPanRange' => 'Max panoramaområde',
'MaxPanRange' => 'Max panoramaområde',
'MaxPanSpeed' => 'Max panoramahastighet',
'MaxPanStep' => 'Max panoramasteg',
'MaxTiltRange' => 'Max tiltområde',
'MaxTiltRange' => 'Max tiltområde',
'MaxTiltSpeed' => 'Max tilthastighet',
'MaxTiltStep' => 'Max tiltsteg',
'MaxWhiteRange' => 'Max vitbalansområde',
'MaxWhiteRange' => 'Max vitbalansområde',
'MaxWhiteSpeed' => 'Max vitbalanshastighet',
'MaxWhiteStep' => 'Max vitbalanssteg',
'MaxZoomRange' => 'Max zoomområde',
'MaxZoomRange' => 'Max zoomområde',
'MaxZoomSpeed' => 'Max zoomhastighet',
'MaxZoomStep' => 'Max zoomsteg',
'MaximumFPS' => 'Max ramar/s',
'Medium' => 'Mellan',
'MediumBW' => 'Mellan bandbredd',
'Message' => 'Message', // Added - 2011-06-16
'MinAlarmAreaLtMax' => 'Minsta larmarean skall vara mindre än största',
'MinAlarmAreaUnset' => 'Du måste ange minsta antal larmbildpunkter',
'MinBlobAreaLtMax' => 'Minsta blobarean skall vara mindre än högsta',
'MinBlobAreaUnset' => 'Du måste ange minsta antalet blobpixlar',
'MinBlobLtMinFilter' => 'Minsta blobarean skall vara mindre än eller lika med minsta filterarean',
'MinBlobsLtMax' => 'Minsta antalet blobbar skall vara mindre än största',
'MinBlobsUnset' => 'Du måste ange minsta antalet blobbar',
'MinFilterAreaLtMax' => 'Minsta filterarean skall vara mindre än högsta',
'MinFilterAreaUnset' => 'Du måste ange minsta antal filterbildpunkter',
'MinFilterLtMinAlarm' => 'Minsta filterarean skall vara mindre än eller lika med minsta larmarean',
'MinFocusRange' => 'Min fokusområde',
'MinAlarmAreaLtMax' => 'Minsta larmarean skall vara mindre än största',
'MinAlarmAreaUnset' => 'Du måste ange minsta antal larmbildpunkter',
'MinBlobAreaLtMax' => 'Minsta blobarean skall vara mindre än högsta',
'MinBlobAreaUnset' => 'Du måste ange minsta antalet blobpixlar',
'MinBlobLtMinFilter' => 'Minsta blobarean skall vara mindre än eller lika med minsta filterarean',
'MinBlobsLtMax' => 'Minsta antalet blobbar skall vara mindre än största',
'MinBlobsUnset' => 'Du måste ange minsta antalet blobbar',
'MinFilterAreaLtMax' => 'Minsta filterarean skall vara mindre än högsta',
'MinFilterAreaUnset' => 'Du måste ange minsta antal filterbildpunkter',
'MinFilterLtMinAlarm' => 'Minsta filterarean skall vara mindre än eller lika med minsta larmarean',
'MinFocusRange' => 'Min fokusområde',
'MinFocusSpeed' => 'Min fokushastighet',
'MinFocusStep' => 'Min fokussteg',
'MinGainRange' => 'Min nivåområde',
'MinGainSpeed' => 'Min nivåhastighet',
'MinGainStep' => 'Min nivåsteg',
'MinIrisRange' => 'Min irisområde',
'MinGainRange' => 'Min nivåområde',
'MinGainSpeed' => 'Min nivåhastighet',
'MinGainStep' => 'Min nivåsteg',
'MinIrisRange' => 'Min irisområde',
'MinIrisSpeed' => 'Min irishastighet',
'MinIrisStep' => 'Min irissteg',
'MinPanRange' => 'Min panoramaområde',
'MinPanRange' => 'Min panoramaområde',
'MinPanSpeed' => 'Min panoramahastighet',
'MinPanStep' => 'Min panoramasteg',
'MinPixelThresLtMax' => 'Minsta tröskelvärde för bildpunkter ska vara mindre än högsta',
'MinPixelThresUnset' => 'Du måste ange minsta tröskelvärde för bildpunkter',
'MinTiltRange' => 'Min tiltområde',
'MinPixelThresLtMax' => 'Minsta tröskelvärde för bildpunkter ska vara mindre än högsta',
'MinPixelThresUnset' => 'Du måste ange minsta tröskelvärde för bildpunkter',
'MinTiltRange' => 'Min tiltområde',
'MinTiltSpeed' => 'Min tilthastighet',
'MinTiltStep' => 'Min tiltsteg',
'MinWhiteRange' => 'Min vitbalansområde',
'MinWhiteRange' => 'Min vitbalansområde',
'MinWhiteSpeed' => 'Min vitbalanshastighet',
'MinWhiteStep' => 'Min vitbalanssteg',
'MinZoomRange' => 'Min zoomområde',
'MinZoomRange' => 'Min zoomområde',
'MinZoomSpeed' => 'Min zoomhastighet',
'MinZoomStep' => 'Min zoomsteg',
'Misc' => 'Övrigt',
'Misc' => 'Övrigt',
'Mode' => 'Mode', // Added - 2015-04-18
'Monitor' => 'Bevakning',
'MonitorIds' => 'Bevakningsnr',
'MonitorPreset' => 'Förinställd bevakning',
'MonitorPresetIntro' => 'Välj en förinställning från listan.<br><br>Var medveten om att detta kan skriva över inställningar du redan gjort för denna bevakare.<br><br>',
'MonitorPreset' => 'Förinställd bevakning',
'MonitorPresetIntro' => 'Välj en förinställning från listan.<br><br>Var medveten om att detta kan skriva över inställningar du redan gjort för denna bevakare.<br><br>',
'MonitorProbe' => 'Monitor Probe', // Added - 2009-03-31
'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2009-03-31
'Monitors' => 'Bevakare',
'Montage' => 'Montera',
'Month' => 'Månad',
'Month' => 'Månad',
'More' => 'More', // Added - 2011-06-16
'MotionFrameSkip' => 'Motion Frame Skip',
'Move' => 'Flytta',
@ -494,65 +494,65 @@ $SLANG = array(
'Mtg3widgrx' => '3-wide grid, scaled, enlarge on alarm', // Added 2013.08.15.
'Mtg4widgrd' => '4-wide grid', // Added 2013.08.15.
'MtgDefault' => 'Default', // Added 2013.08.15.
'MustBeGe' => 'måste vara större än eller lika med',
'MustBeLe' => 'måste vara mindre än eller lika med',
'MustConfirmPassword' => 'Du måste bekräfta lösenordet',
'MustSupplyPassword' => 'Du måste ange ett lösenord',
'MustSupplyUsername' => 'Du måste ange ett användarnamn',
'MustBeGe' => 'måste vara större än eller lika med',
'MustBeLe' => 'måste vara mindre än eller lika med',
'MustConfirmPassword' => 'Du måste bekräfta lösenordet',
'MustSupplyPassword' => 'Du måste ange ett lösenord',
'MustSupplyUsername' => 'Du måste ange ett användarnamn',
'Name' => 'Namn',
'Near' => 'Nära',
'Network' => 'Nätverk',
'Near' => 'Nära',
'Network' => 'Nätverk',
'New' => 'Ny',
'NewGroup' => 'Ny grupp',
'NewLabel' => 'Ny etikett',
'NewPassword' => 'Nytt lösenord',
'NewState' => 'Nytt läge',
'NewUser' => 'Ny användare',
'Next' => 'Nästa',
'NewPassword' => 'Nytt lösenord',
'NewState' => 'Nytt läge',
'NewUser' => 'Ny användare',
'Next' => 'Nästa',
'No' => 'Nej',
'NoDetectedCameras' => 'No Detected Cameras', // Added - 2009-03-31
'NoFramesRecorded' => 'Det finns inga ramar inspelade för denna händelse',
'NoFramesRecorded' => 'Det finns inga ramar inspelade för denna händelse',
'NoGroup' => 'Ingen grupp',
'NoSavedFilters' => 'Inga sparade filter',
'NoStatisticsRecorded' => 'Det finns ingen statistik inspelad för denna händelse/ram',
'NoStatisticsRecorded' => 'Det finns ingen statistik inspelad för denna händelse/ram',
'None' => 'Ingen',
'NoneAvailable' => 'Ingen tillgänglig',
'NoneAvailable' => 'Ingen tillgänglig',
'Normal' => 'Normal',
'Notes' => 'Not.',
'NumPresets' => 'Antal förinställningar',
'NumPresets' => 'Antal förinställningar',
'Off' => 'Av',
'On' => 'På',
'On' => 'På',
'OnvifCredentialsIntro'=> 'Please supply user name and password for the selected camera.<br/>If no user has been created for the camera then the user given here will be created with the given password.<br/><br/>', // Added - 2015-04-18
'OnvifProbe' => 'ONVIF', // Added - 2015-04-18
'OnvifProbeIntro' => 'The list below shows detected ONVIF cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
'OpEq' => 'lika med',
'OpGt' => 'större än',
'OpGtEq' => 'större än eller lika med',
'OpGt' => 'större än',
'OpGtEq' => 'större än eller lika med',
'OpIn' => 'in set',
'OpLt' => 'mindre än',
'OpLtEq' => 'mindre än eller lika med',
'OpLt' => 'mindre än',
'OpLtEq' => 'mindre än eller lika med',
'OpMatches' => 'matchar',
'OpNe' => 'inte lika med',
'OpNotIn' => 'inte i set',
'OpNotMatches' => 'matchar inte',
'Open' => 'Öppna',
'OptionHelp' => 'Optionhjälp',
'OptionRestartWarning' => 'Dessa ändringar kommer inte att vara implementerade\nnär systemet körs. När du är klar starta om\n ZoneMinder.',
'Open' => 'Öppna',
'OptionHelp' => 'Optionhjälp',
'OptionRestartWarning' => 'Dessa ändringar kommer inte att vara implementerade\nnär systemet körs. När du är klar starta om\n ZoneMinder.',
'Options' => 'Alternativ',
'OrEnterNewName' => 'eller skriv in nytt namn',
'Order' => 'Sortera',
'Orientation' => 'Orientation',
'Out' => 'Ut',
'OverwriteExisting' => 'Skriv över',
'OverwriteExisting' => 'Skriv över',
'Paged' => 'Paged',
'Pan' => 'Panorera',
'PanLeft' => 'Panorera vänster',
'PanRight' => 'Panorera höger',
'PanLeft' => 'Panorera vänster',
'PanRight' => 'Panorera höger',
'PanTilt' => 'Pan/Tilt',
'Parameter' => 'Parameter',
'Password' => 'Lösenord',
'PasswordsDifferent' => 'Lösenorden skiljer sig åt',
'Paths' => 'Sökvägar',
'Password' => 'Lösenord',
'PasswordsDifferent' => 'Lösenorden skiljer sig åt',
'Paths' => 'Sökvägar',
'Pause' => 'Paus',
'Phone' => 'Mobil',
'PhoneBW' => 'Mobil bandbredd',
@ -561,15 +561,15 @@ $SLANG = array(
'Pixels' => 'bildpunkter',
'Play' => 'Spela',
'PlayAll' => 'Visa alla',
'PleaseWait' => 'Vänta...',
'PleaseWait' => 'Vänta...',
'Plugins' => 'Plugins',
'Point' => 'Punkt',
'PostEventImageBuffer' => 'Post Event Image Count',
'PreEventImageBuffer' => 'Pre Event Image Count',
'PreserveAspect' => 'Bevara lägesförhållande',
'Preset' => 'Förinställning',
'Presets' => 'Förinställningar',
'Prev' => 'Föreg.',
'PreserveAspect' => 'Bevara lägesförhållande',
'Preset' => 'Förinställning',
'Presets' => 'Förinställningar',
'Prev' => 'Föreg.',
'Probe' => 'Probe', // Added - 2009-03-31
'ProfileProbe' => 'Stream Probe', // Added - 2015-04-18
'ProfileProbeIntro' => 'The list below shows the existing stream profiles of the selected camera .<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that ZoneMinder cannot configure additional profiles and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
@ -580,51 +580,51 @@ $SLANG = array(
'Record' => 'Spela in',
'RefImageBlendPct' => 'Reference Image Blend %ge',
'Refresh' => 'Uppdatera',
'Remote' => 'Fjärr',
'RemoteHostName' => 'Fjärrnamn',
'RemoteHostPath' => 'Fjärrsökväg',
'RemoteHostPort' => 'Fjärrport',
'Remote' => 'Fjärr',
'RemoteHostName' => 'Fjärrnamn',
'RemoteHostPath' => 'Fjärrsökväg',
'RemoteHostPort' => 'Fjärrport',
'RemoteHostSubPath' => 'Remote Host SubPath', // Added - 2009-02-08
'RemoteImageColours' => 'Fjärrbildfärger',
'RemoteImageColours' => 'Fjärrbildfärger',
'RemoteMethod' => 'Remote Method', // Added - 2009-02-08
'RemoteProtocol' => 'Remote Protocol', // Added - 2009-02-08
'Rename' => 'Byt namn',
'Replay' => 'Repris',
'ReplayAll' => 'Alla händelser',
'ReplayAll' => 'Alla händelser',
'ReplayGapless' => 'Gapless Events',
'ReplaySingle' => 'Ensam händelse',
'Reset' => 'Återställ',
'ResetEventCounts' => 'Återställ händelseräknare',
'Restart' => 'Återstart',
'Restarting' => 'Återstartar',
'RestrictedCameraIds' => 'Begränsade kameranr.',
'RestrictedMonitors' => 'Begränsade bevakare',
'ReturnDelay' => 'Fördröjd retur',
'ReturnLocation' => 'Återvänd till position',
'ReplaySingle' => 'Ensam händelse',
'Reset' => 'Återställ',
'ResetEventCounts' => 'Återställ händelseräknare',
'Restart' => 'Återstart',
'Restarting' => 'Återstartar',
'RestrictedCameraIds' => 'Begränsade kameranr.',
'RestrictedMonitors' => 'Begränsade bevakare',
'ReturnDelay' => 'Fördröjd retur',
'ReturnLocation' => 'Återvänd till position',
'Rewind' => 'Backa',
'RotateLeft' => 'Rotera vänster',
'RotateRight' => 'Rotera höger',
'RotateLeft' => 'Rotera vänster',
'RotateRight' => 'Rotera höger',
'RunLocalUpdate' => 'Please run zmupdate.pl to update', // Added - 2011-05-25
'RunMode' => 'Körläge',
'RunState' => 'Körläge',
'Running' => 'Körs',
'RunMode' => 'Körläge',
'RunState' => 'Körläge',
'Running' => 'Körs',
'Save' => 'Spara',
'SaveAs' => 'Spara som',
'SaveFilter' => 'Spara filter',
'Scale' => 'Skala',
'Score' => 'Resultat',
'Secs' => 'Sek',
'Sectionlength' => 'Sektionslängd',
'Select' => 'Välj',
'Sectionlength' => 'Sektionslängd',
'Select' => 'Välj',
'SelectFormat' => 'Select Format', // Added - 2011-06-17
'SelectLog' => 'Select Log', // Added - 2011-06-17
'SelectMonitors' => 'Välj bevakare',
'SelfIntersecting' => 'Polygonändarna får inte överlappa',
'Set' => 'Ställ in',
'SetNewBandwidth' => 'Ställ in ny bandbredd',
'SetPreset' => 'Ställ in förinställning',
'Settings' => 'Inställningar',
'ShowFilterWindow' => 'Visa fönsterfilter',
'SelectMonitors' => 'Välj bevakare',
'SelfIntersecting' => 'Polygonändarna får inte överlappa',
'Set' => 'Ställ in',
'SetNewBandwidth' => 'Ställ in ny bandbredd',
'SetPreset' => 'Ställ in förinställning',
'Settings' => 'Inställningar',
'ShowFilterWindow' => 'Visa fönsterfilter',
'ShowTimeline' => 'Visa tidslinje',
'SignalCheckColour' => 'Signal Check Colour',
'Size' => 'Storlek',
@ -633,31 +633,31 @@ $SLANG = array(
'SortAsc' => 'Stigande',
'SortBy' => 'Sortera',
'SortDesc' => 'Fallande',
'Source' => 'Källa',
'Source' => 'Källa',
'SourceColours' => 'Source Colours', // Added - 2009-02-08
'SourcePath' => 'Source Path', // Added - 2009-02-08
'SourceType' => 'Källtyp',
'SourceType' => 'Källtyp',
'Speed' => 'Hastighet',
'SpeedHigh' => 'Höghastighet',
'SpeedLow' => 'Låghastighet',
'SpeedHigh' => 'Höghastighet',
'SpeedLow' => 'Låghastighet',
'SpeedMedium' => 'Normalhastighet',
'SpeedTurbo' => 'Turbohastighet',
'Start' => 'Start',
'State' => 'Läge',
'State' => 'Läge',
'Stats' => 'Statistik',
'Status' => 'Status',
'Step' => 'Steg',
'StepBack' => 'Stepga bakåt',
'StepForward' => 'Stega framåt',
'StepBack' => 'Stepga bakåt',
'StepForward' => 'Stega framåt',
'StepLarge' => 'Stora steg',
'StepMedium' => 'Normalsteg',
'StepNone' => 'Inga steg',
'StepSmall' => 'Små steg',
'StepSmall' => 'Små steg',
'Stills' => 'Stillbilder',
'Stop' => 'Stopp',
'Stopped' => 'Stoppad',
'Stream' => 'Strömmande',
'StreamReplayBuffer' => 'Buffert för strömmande uppspelning',
'Stream' => 'Strömmande',
'StreamReplayBuffer' => 'Buffert för strömmande uppspelning',
'Submit' => 'Skicka',
'System' => 'System',
'SystemLog' => 'System Log', // Added - 2011-06-16
@ -667,22 +667,22 @@ $SLANG = array(
'Tilt' => 'Tilt',
'Time' => 'Tid',
'TimeDelta' => 'tidsdelta',
'TimeStamp' => 'Tidsstämpel',
'TimeStamp' => 'Tidsstämpel',
'Timeline' => 'Tidslinje',
'TimelineTip1' => 'Pass your mouse over the graph to view a snapshot image and event details.', // Added 2013.08.15.
'TimelineTip2' => 'Click on the coloured sections of the graph, or the image, to view the event.', // Added 2013.08.15.
'TimelineTip3' => 'Click on the background to zoom in to a smaller time period based around your click.', // Added 2013.08.15.
'TimelineTip4' => 'Use the controls below to zoom out or navigate back and forward through the time range.', // Added 2013.08.15.
'Timestamp' => 'Tidsstämpel',
'TimestampLabelFormat' => 'Format på tidsstämpel',
'TimestampLabelX' => 'Värde på tidsstämpel X',
'TimestampLabelY' => 'Värde på tidsstämpel Y',
'Timestamp' => 'Tidsstämpel',
'TimestampLabelFormat' => 'Format på tidsstämpel',
'TimestampLabelX' => 'Värde på tidsstämpel X',
'TimestampLabelY' => 'Värde på tidsstämpel Y',
'Today' => 'Idag',
'Tools' => 'Verktyg',
'Total' => 'Total', // Added - 2011-06-16
'TotalBrScore' => 'Total<br/>Score',
'TrackDelay' => 'Spårfördröjning',
'TrackMotion' => 'Spåra rörelse',
'TrackDelay' => 'Spårfördröjning',
'TrackMotion' => 'Spåra rörelse',
'Triggers' => 'Triggers',
'TurboPanSpeed' => 'Turbo panoramahastighet',
'TurboTiltSpeed' => 'Turbo tilthastighet',
@ -690,63 +690,63 @@ $SLANG = array(
'Unarchive' => 'Packa upp',
'Undefined' => 'Undefined', // Added - 2009-02-08
'Units' => 'Enheter',
'Unknown' => 'Okänd',
'Unknown' => 'Okänd',
'Update' => 'Uppdatera',
'UpdateAvailable' => 'En uppdatering till ZoneMinder finns tillgänglig.',
'UpdateNotNecessary' => 'Ingen uppdatering behövs.',
'UpdateAvailable' => 'En uppdatering till ZoneMinder finns tillgänglig.',
'UpdateNotNecessary' => 'Ingen uppdatering behövs.',
'Updated' => 'Updated', // Added - 2011-06-16
'Upload' => 'Upload', // Added - 2011-08-23
'UseFilter' => 'Använd filter',
'UseFilter' => 'Använd filter',
'UseFilterExprsPost' => '&nbsp;filter&nbsp;expressions', // This is used at the end of the phrase 'use N filter expressions'
'UseFilterExprsPre' => 'Använd&nbsp;', // This is used at the beginning of the phrase 'use N filter expressions'
'UseFilterExprsPre' => 'Använd&nbsp;', // This is used at the beginning of the phrase 'use N filter expressions'
'UsedPlugins' => 'Used Plugins',
'User' => 'Användare',
'Username' => 'Användarnamn',
'Users' => 'Användare',
'User' => 'Användare',
'Username' => 'Användarnamn',
'Users' => 'Användare',
'V4L' => 'V4L', // Added - 2015-04-18
'V4LCapturesPerFrame' => 'Captures Per Frame', // Added - 2015-04-18
'V4LMultiBuffer' => 'Multi Buffering', // Added - 2015-04-18
'Value' => 'Värde',
'Value' => 'Värde',
'Version' => 'Version',
'VersionIgnore' => 'Ignorera denna version',
'VersionRemindDay' => 'Påminn om 1 dag',
'VersionRemindHour' => 'Påminn om 1 timme',
'VersionRemindNever' => 'Påminn inte om nya versioner',
'VersionRemindWeek' => 'Påminn om en 1 vecka',
'VersionRemindDay' => 'Påminn om 1 dag',
'VersionRemindHour' => 'Påminn om 1 timme',
'VersionRemindNever' => 'Påminn inte om nya versioner',
'VersionRemindWeek' => 'Påminn om en 1 vecka',
'Video' => 'Video',
'VideoFormat' => 'Videoformat',
'VideoGenFailed' => 'Videogenereringen misslyckades!',
'VideoGenFiles' => 'Befintliga videofiler',
'VideoGenNoFiles' => 'Inga videofiler',
'VideoGenParms' => 'Inställningar för videogenerering',
'VideoGenParms' => 'Inställningar för videogenerering',
'VideoGenSucceeded' => 'Videogenereringen lyckades!',
'VideoSize' => 'Videostorlek',
'View' => 'Visa',
'ViewAll' => 'Visa alla',
'ViewEvent' => 'Visa händelse',
'ViewEvent' => 'Visa händelse',
'ViewPaged' => 'Visa Paged',
'Wake' => 'Vakna',
'WarmupFrames' => 'Värm upp ramar',
'WarmupFrames' => 'Värm upp ramar',
'Watch' => 'Se',
'Web' => 'Webb',
'WebColour' => 'Webbfärg',
'WebColour' => 'Webbfärg',
'Week' => 'Vecka',
'White' => 'Vit',
'WhiteBalance' => 'Vitbalans',
'Wide' => 'Vid',
'X' => 'X',
'X10' => 'X10',
'X10ActivationString' => 'X10 aktiveringssträng',
'X10InputAlarmString' => 'X10 larmingångssträng',
'X10OutputAlarmString' => 'X10 larmutgångssträng',
'X10ActivationString' => 'X10 aktiveringssträng',
'X10InputAlarmString' => 'X10 larmingångssträng',
'X10OutputAlarmString' => 'X10 larmutgångssträng',
'Y' => 'J',
'Yes' => 'Ja',
'YouNoPerms' => 'Du har inte tillstånd till denna resurs.',
'YouNoPerms' => 'Du har inte tillstånd till denna resurs.',
'Zone' => 'Zon',
'ZoneAlarmColour' => 'Larmfärg (Röd/Grön/Blå)',
'ZoneAlarmColour' => 'Larmfärg (Röd/Grön/Blå)',
'ZoneArea' => 'Zonarea',
'ZoneExtendAlarmFrames' => 'Extend Alarm Frame Count',
'ZoneFilterSize' => 'Filterbredd/höjd (pixlar)',
'ZoneFilterSize' => 'Filterbredd/höjd (pixlar)',
'ZoneMinMaxAlarmArea' => 'Min/Max larmarea',
'ZoneMinMaxBlobArea' => 'Min/Max blobbarea',
'ZoneMinMaxBlobs' => 'Min/Max blobbar',
@ -762,13 +762,13 @@ $SLANG = array(
// Complex replacements with formatting and/or placements, must be passed through sprintf
$CLANG = array(
'CurrentLogin' => 'Aktuell inloggning är \'%1$s\'',
'CurrentLogin' => 'Aktuell inloggning är \'%1$s\'',
'EventCount' => '%1$s %2$s', // For example '37 Events' (from Vlang below)
'LastEvents' => 'Senaste %1$s %2$s', // For example 'Last 37 Events' (from Vlang below)
'LatestRelease' => 'Aktuell version är v%1$s, du har v%2$s.',
'LatestRelease' => 'Aktuell version är v%1$s, du har v%2$s.',
'MonitorCount' => '%1$s %2$s', // For example '4 Monitors' (from Vlang below)
'MonitorFunction' => 'Bevakare %1$s funktion',
'RunningRecentVer' => 'Du använder den senaste versionen av ZoneMinder, v%s.',
'RunningRecentVer' => 'Du använder den senaste versionen av ZoneMinder, v%s.',
'VersionMismatch' => 'Version mismatch, system is version %1$s, database is %2$s.', // Added - 2011-05-25
);
@ -806,7 +806,7 @@ $CLANG = array(
// Variable arrays expressing plurality, see the zmVlang description above
$VLANG = array(
'Event' => array( 0=>'Händelser', 1=>'Händelsen', 2=>'Händelserna' ),
'Event' => array( 0=>'Händelser', 1=>'Händelsen', 2=>'Händelserna' ),
'Monitor' => array( 0=>'Bevakare', 1=>'Bevakare', 2=>'Bevakare' ),
);
@ -826,7 +826,7 @@ function zmVlang( $langVarArray, $count )
return( $value );
}
}
die( 'Fel, kan inte relatera variabel språksträng' );
die( 'Fel, kan inte relatera variabel språksträng' );
}
// This is an version that could be used in the Russian example above
@ -886,8 +886,8 @@ function zmVlang( $langVarArray, $count )
// These overrides are in the form show below where the array key represents the option name minus the initial ZM_
$OLANG = array(
'LANG_DEFAULT' => array(
'Prompt' => "Välj språk för ZoneMinder",
'Help' => "ZoneMinder kan använda annat språk än engelska i menyer och texter. Välj här det språk du vill använda till ZoneMinder."
'Prompt' => "Välj språk för ZoneMinder",
'Help' => "ZoneMinder kan använda annat språk än engelska i menyer och texter. Välj här det språk du vill använda till ZoneMinder."
),
'OPTIONS_FFMPEG' => array(
'Help' => "Parameters in this field are passed on to FFmpeg. Multiple parameters can be separated by ,~~ ".

View File

@ -0,0 +1,3 @@
input[type="text"] {
width: 100%;
}

View File

@ -18,21 +18,19 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
function exportHeader( $title )
{
function exportHeader($title) {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php echo $title ?></title>
<style type="text/css">
<!--
<?php include( ZM_SKIN_PATH.'/css/'.ZM_SKIN_NAME.'/export.css' ); ?>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?php echo $title ?></title>
<style type="text/css">
<!--
<?php include(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/css/'.ZM_SKIN_NAME.'/export.css'); ?>
ul.tabs {
margin: 0;
margin-bottom: -1px;
margin-bottom: -1px;
padding: 0;
float: left;
list-style: none;
@ -70,50 +68,46 @@ html ul.tabs li.active, html ul.tabs li.active a:hover {
border-bottom: 1px solid #e0e0e0;
}
-->
</style>
<script type="text/javascript">
<?php include(ZM_SKIN_PATH.'/js/jquery.js') ?>
</script>
<script type="text/javascript" language="javascript" charset="utf-8">
</style>
<script type="text/javascript" src="<?php echo ($title == translate('Images').' Master' ? '' : '../') ?>jquery.js"></script>
<!--<script type="text/javascript" src="<?php echo ($title == translate('Images').' Master' ? '' : '../') ?>video.js"></script>-->
<script type="text/javascript">
/*==========[tab code]==========*/
$(document).ready(function() {
/*==========[tab code]==========*/
$(document).ready(function() {
//When page loads...
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//When page loads...
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//On Click Event
$("ul.tabs li").click(function() {
//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
// ]]>
</script>
</head>
});
// ]]>
</script>
</head>
<?php
}
function exportEventDetail( $event, $exportFrames, $exportImages )
{
ob_start();
exportHeader( translate('Event')." ".$event->Id() );
function exportEventDetail($event, $exportFrames, $exportImages) {
ob_start();
exportHeader(translate('Event').' '.$event->Id());
$otherlinks = '';
if( $exportFrames ) $otherlinks .= '<a href="zmEventFrames.html">'.translate('Frames').'</a>,';
if( $exportImages ) $otherlinks .= '<a href="zmEventImages.html">'.translate('Images').'</a>,';
$otherlinks = substr($otherlinks,0,-1);
?>
<body>
<div id="page">
@ -139,22 +133,20 @@ function exportEventDetail( $event, $exportFrames, $exportImages )
</body>
</html>
<?php
return( ob_get_clean() );
return ob_get_clean();
}
function exportEventFrames( $event, $exportDetail, $exportImages )
{
$sql = "SELECT *, unix_timestamp( TimeStamp ) AS UnixTimeStamp FROM Frames WHERE EventID = ? ORDER BY FrameId";
$frames = dbFetchAll( $sql, NULL, array( $event->Id() ) );
function exportEventFrames($event, $exportDetail, $exportImages) {
$sql = 'SELECT *, unix_timestamp( TimeStamp ) AS UnixTimeStamp FROM Frames WHERE EventID = ? ORDER BY FrameId';
$frames = dbFetchAll($sql, NULL, array($event->Id()));
ob_start();
exportHeader( translate('Frames')." ".$event->Id() );
ob_start();
exportHeader(translate('Frames').' '.$event->Id());
$otherlinks = '';
if( $exportDetail ) $otherlinks .= '<a href="zmEventDetail.html">'.translate('Event').'</a>,';
if( $exportImages ) $otherlinks .= '<a href="zmEventImages.html">'.translate('Images').'</a>,';
$otherlinks = substr($otherlinks,0,-1);
?>
<body>
<div id="page">
@ -168,56 +160,49 @@ function exportEventFrames( $event, $exportDetail, $exportImages )
<th><?php echo translate('TimeDelta') ?></th>
<th><?php echo translate('Score') ?></th>
<?php
if ( $exportImages )
{
if ( $exportImages ) {
?>
<th><?php echo translate('Image') ?></th>
<?php
}
}
?>
</tr>
<?php
if ( count($frames) )
{
$eventPath = $event->Path();
foreach ( $frames as $frame )
{
$imageFile = sprintf( "%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", $frame['FrameId'] );
$imagePath = $eventPath."/".$imageFile;
$analImage = preg_replace( "/capture/", "analyse", $imagePath );
if ( file_exists( $analImage ) )
{
$imageFile = preg_replace( "/capture/", "analyse", $imageFile );
}
if ( count($frames) ) {
$eventPath = $event->Path();
foreach ( $frames as $frame ) {
$imageFile = sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId']);
$imagePath = $eventPath.'/'.$imageFile;
$analImage = preg_replace('/capture/', 'analyse', $imagePath);
if ( file_exists($analImage) ) {
$imageFile = preg_replace('/capture/', 'analyse', $imageFile);
}
$class = strtolower($frame['Type']);
$class = strtolower($frame['Type']);
?>
<tr class="<?php echo $class ?>">
<td><?php echo $frame['FrameId'] ?></td>
<td><?php echo $frame['Type'] ?></td>
<td><?php echo strftime( STRF_FMT_TIME, $frame['UnixTimeStamp'] ) ?></td>
<td><?php echo number_format( $frame['Delta'], 2 ) ?></td>
<td><?php echo strftime(STRF_FMT_TIME, $frame['UnixTimeStamp']) ?></td>
<td><?php echo number_format($frame['Delta'], 2) ?></td>
<td><?php echo $frame['Score'] ?></td>
<?php
if ( $exportImages )
{
if ( $exportImages ) {
?>
<td><a href="<?php echo $imageFile ?>" target="zmExportImage"><img src="<?php echo $imageFile ?>" border="0" class="thumb" alt="Frame <?php echo $frame['FrameId'] ?>"/></a></td>
<td><a href="<?php echo $imageFile ?>" target="zmExportImage"><img src="<?php echo $imageFile ?>" class="thumb" alt="Frame <?php echo $frame['FrameId'] ?>"/></a></td>
<?php
}
}
?>
</tr>
<?php
}
}
else
{
} # end foreach frame
} else {
?>
<tr>
<td class="monoRow" colspan="<?php echo $exportImages?6:5 ?>"><?php echo translate('NoFramesRecorded') ?></td>
</tr>
<?php
}
} # end if count($frames)
?>
</table>
</div>
@ -225,13 +210,12 @@ function exportEventFrames( $event, $exportDetail, $exportImages )
</body>
</html>
<?php
return( ob_get_clean() );
return ob_get_clean();
}
function exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist )
{
ob_start();
exportHeader( translate('Images')." ".$event->Id() );
function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
ob_start();
exportHeader(translate('Images').' '.$event->Id());
$otherlinks = '';
if( $exportDetail ) $otherlinks .= '<a href="zmEventDetail.html">'.translate('Event').'</a>,';
@ -257,28 +241,54 @@ function exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist )
<h2><?php echo translate('Images') ?>: <?php echo validHtmlStr($event->Name()) ?><?php if(!empty($otherlinks)) { ?> (<?php echo$otherlinks?>) <?php } ?></h2>
<?php
if ( $event->DefaultVideo() ) {
// videojs zoomrotate only when direct recording
$Zoom = 1;
$Rotation = 0;
$Monitor = $event->Monitor();
if ( $Monitor->VideoWriter() == '2' ) {
# Passthrough
$Rotation = $event->Orientation();
if ( in_array($event->Orientation(),array('90','270')) )
$Zoom = $event->Height()/$event->Width();
}
?>
<div id="videoFeed">
<video id="videoobj" class="video-js vjs-default-skin" style="transform: matrix(1, 0, 0, 1, 0, 0)"
width="<?php echo $event->Width() ?>"
height="<?php echo $event->Height() ?>"
data-setup='{ "controls": true, "autoplay": true, "preload": "auto", "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'>
<source src="<?php echo $event->getStreamSrc(array('mode'=>'mpeg','format'=>'h264')); ?>" type="video/mp4">
<track id="monitorCaption" kind="captions" label="English" srclang="en" src='data:plain/text;charset=utf-8,"WEBVTT\n\n 00:00:00.000 --> 00:00:01.000 ZoneMinder"' default>
Your browser does not support the video tag.
</video>
</div><!--videoFeed-->
<?php
} else { // end if DefaultVideo
?>
<ilayer id="slidensmain" width=&{slidewidth}; height=&{slideheight}; bgColor=&{slidebgcolor}; visibility=hide>
<layer id="slidenssub" width=&{slidewidth}; left=auto top=auto></layer>
<layer id="slidenssub" width="&{slidewidth};" left="auto" top="auto"></layer>
</ilayer>
<div id="imagevideo" align="center"></div>
<br>
<div align="center">
<button onclick="stepbackward()">< Step</button><button
id="btnrwd" onclick="rewind()" >Rwd</button><button
id="btnplay" onclick="playstop()">Stop</button><button
onclick="stepforward()">Step ></button><button
id="btnspeedup" onclick="speedup()">speedup</button><button
id="btnspeeddown" onclick="speeddown()">slowdown</button>
<button type="button" onclick="stepbackward()">&lt; Step</button>
<button type="button" id="btnrwd" onclick="rewind()" >Rwd</button>
<button type="button" id="btnplay" onclick="playstop()">Stop</button>
<button type="button" onclick="stepforward()">Step &gt;</button>
<button type="button" id="btnspeedup" onclick="speedup()">speedup</button>
<button type="button" id="btnspeeddown" onclick="speeddown()">slowdown</button>
</div>
<div align="center"><div class="horizontal_track" >
<div class="horizontal_slit" >&nbsp;</div>
<div class="horizontal_slider" id="imageslider_id" style="left: 0px;"
onmousedown="slide(event,'horizontal', <?php echo($event->Width()-20)?>, 1, <?php echo$listcount?>, <?php echo$listcount?>,0, 'imageslider_display_id');" >&nbsp;</div>
</div></div>
<div align="center"><div class="display_holder" ><input id="imageslider_display_id" class="value_display" type="text" value="0" onfocus="blur(this);" /></div></div>
onmousedown="slide(event,'horizontal', <?php echo($event->Width()-20)?>, 1, <?php echo$listcount?>, <?php echo$listcount?>,0, 'imageslider_display_id');">&nbsp;</div>
</div>
</div>
<div align="center"><div class="display_holder"><input id="imageslider_display_id" class="value_display" type="text" value="0" onfocus="blur(this);"/></div></div>
<script language="JavaScript1.2">
<script type="text/javascript">
/***********************************************
* Flexi Slideshow- © Dynamic Drive (www.dynamicdrive.com)
@ -286,15 +296,15 @@ function exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist )
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
var eventWidth = <?php echo$event->Width()?>;
var eventHeight = <?php echo$event->Height()?>;
var variableslide=[<?php echo$slides?>];
var eventWidth = <?php echo $event->Width()?>;
var eventHeight = <?php echo $event->Height()?>;
var variableslide=[<?php echo $slides?>];
//configure the below 3 variables to set the dimension/background color of the slideshow
var slidewidth=eventWidth+'px' //set to width of LARGEST image in your slideshow
var slideheight=eventHeight+'px' //set to height of LARGEST iamge in your slideshow, plus any text description
var slidebgcolor='#ffffff'
var slidewidth=eventWidth+'px'; //set to width of LARGEST image in your slideshow
var slideheight=eventHeight+'px'; //set to height of LARGEST image in your slideshow, plus any text description
var slidebgcolor='#ffffff';
//configure the below variable to determine the delay between image rotations (in miliseconds)
var origslidedelay=100;
@ -306,15 +316,15 @@ var ie=document.all;
var dom=document.getElementById;
for (i=0;i<variableslide.length;i++){
var cacheimage=new Image()
cacheimage.src=variableslide[i]
var cacheimage = new Image();
cacheimage.src = variableslide[i];
}
var currentslide=-1
var currentslide = -1;
var mytimer = null;
//if (ie||dom) document.write('<div id="slidedom" style="width:'+slidewidth+'px;height:'+slideheight+'; background-color:'+slidebgcolor+'"></div>');
if (ie||dom) document.getElementById('imagevideo').innerHTML = '<div id="slidedom" style="width:'+slidewidth+'px;height:'+slideheight+'; background-color:'+slidebgcolor+'"><img src="" name="imageslideframe"></div>';
if (ie||dom) document.getElementById('imagevideo').innerHTML = '<div id="slidedom" style="width:'+slidewidth+';height:'+slideheight+'; background-color:'+slidebgcolor+'"><img src="" name="imageslideframe"></div>';
function rotateimages(){
if (currentslide==variableslide.length-1) currentslide=0;
@ -337,14 +347,12 @@ function changeimage() {
slideManual(currentslide+1,eventWidth-20, 1, variableslide.length);
}
function start_slider(){
crossrotateobj=dom? document.getElementById("slidedom") : ie? document.all.slidedom : document.slidensmain.document.slidenssub;
crossrotateobj = dom ? document.getElementById("slidedom") : ie ? document.all.slidedom : document.slidensmain.document.slidenssub;
if (document.layers) document.slidensmain.visibility="show";
rotateimages();
}
// seyi_code
function rotateimagesrewind(){
if (currentslide==0) currentslide=variableslide.length-1;
@ -366,12 +374,12 @@ function stepforward() {
document.getElementById('btnspeedup').disabled = true;
document.getElementById('btnspeeddown').disabled = true;
if (currentslide==variableslide.length-1) currentslide=0;
if ( currentslide == variableslide.length-1 ) currentslide=0;
else currentslide++;
changeimage();
}
function stepbackward() {
clearTimeout(mytimer);
// document.getElementById('btnrwd').style.borderTop='2px solid #ffffff';
@ -383,11 +391,10 @@ function stepbackward() {
document.getElementById('btnspeedup').disabled = true;
document.getElementById('btnspeeddown').disabled = true;
if (currentslide==0) currentslide=variableslide.length-1;
if ( currentslide == 0 ) currentslide = variableslide.length-1;
else currentslide--;
changeimage();
}
function speedup() { slidedelay = slidedelay/2; }
function speeddown() { slidedelay = slidedelay*2; }
@ -430,7 +437,6 @@ function rewind() {
document.getElementById('btnspeedup').disabled = true;
document.getElementById('btnspeeddown').disabled = true;
}
}
//---------------------------------+
@ -501,65 +507,63 @@ function moveSlider(evnt) {
// seyi_code
currentslide = v-1;
changeimage();
return false
return false;
}
return
}
// moveSlider: Handles the start of a slider move.
function slide(evnt, orientation, length, from, to, count, decimals, display) {
if (!evnt) evnt = window.event;
sliderObj = (evnt.target) ? evnt.target : evnt.srcElement; // Get the activated slider element.
sliderObj.pxLen = length // The allowed slider movement in pixels.
sliderObj.valCount = count ? count - 1 : length // Allowed number of values in the interval.
displayObj = carpeGetElementById(display) // Get the associated display element.\
displayObj.dec = decimals // Number of decimals to be displayed.
sliderObj.scale = (to - from) / length // Slider-display scale [value-change per pixel of movement].
sliderObj.pxLen = length; // The allowed slider movement in pixels.
sliderObj.valCount = count ? count - 1 : length; // Allowed number of values in the interval.
displayObj = carpeGetElementById(display); // Get the associated display element.\
displayObj.dec = decimals; // Number of decimals to be displayed.
sliderObj.scale = (to - from) / length; // Slider-display scale [value-change per pixel of movement].
if (orientation == 'horizontal') { // Set limits for horizontal sliders.
sliderObj.fromVal = from
xMax = length
yMax = 0
sliderObj.fromVal = from;
xMax = length;
yMax = 0;
} else if (orientation == 'vertical') { // Set limits and scale for vertical sliders.
sliderObj.fromVal = to;
xMax = 0;
yMax = length;
sliderObj.scale = -sliderObj.scale; // Invert scale for vertical sliders. "Higher is more."
}
if (orientation == 'vertical') { // Set limits and scale for vertical sliders.
sliderObj.fromVal = to
xMax = 0
yMax = length
sliderObj.scale = -sliderObj.scale // Invert scale for vertical sliders. "Higher is more."
}
pxLeft = carpeLeft(sliderObj.id) // Sliders horizontal position at start of slide.
pxTop = carpeTop(sliderObj.id) // Sliders vertical position at start of slide.
xCoord = evnt.screenX // Horizontal mouse position at start of slide.
yCoord = evnt.screenY // Vertical mouse position at start of slide.
mouseover = true
document.onmousemove = moveSlider // Start the action if the mouse is dragged.
document.onmouseup = sliderMouseUp // Stop sliding.
pxLeft = carpeLeft(sliderObj.id); // Sliders horizontal position at start of slide.
pxTop = carpeTop(sliderObj.id); // Sliders vertical position at start of slide.
xCoord = evnt.screenX; // Horizontal mouse position at start of slide.
yCoord = evnt.screenY; // Vertical mouse position at start of slide.
mouseover = true;
document.onmousemove = moveSlider; // Start the action if the mouse is dragged.
document.onmouseup = sliderMouseUp; // Stop sliding.
}
// sliderMouseup: Handles the mouseup event after moving a slider.
// Snaps the slider position to allowed/displayed value.
function sliderMouseUp() {
mouseover = false // Stop the sliding.
v = (displayObj.value) ? displayObj.value : 0 // Find last display value.
pos = (v - sliderObj.fromVal)/(sliderObj.scale) // Calculate slider position (regardless of orientation).
if (yMax == 0) carpeLeft(sliderObj.id, pos) // Snap horizontal slider to corresponding display position.
if (xMax == 0) carpeTop(sliderObj.id, pos) // Snap vertical slider to corresponding display position.
mouseover = false; // Stop the sliding.
v = (displayObj.value) ? displayObj.value : 0; // Find last display value.
pos = (v - sliderObj.fromVal)/(sliderObj.scale); // Calculate slider position (regardless of orientation).
if (yMax == 0) carpeLeft(sliderObj.id, pos); // Snap horizontal slider to corresponding display position.
if (xMax == 0) carpeTop(sliderObj.id, pos); // Snap vertical slider to corresponding display position.
if (document.removeEventListener) { // Remove event listeners from 'document' (Moz&co).
document.removeEventListener('mousemove', moveSlider)
document.removeEventListener('mouseup', sliderMouseUp)
document.removeEventListener('mousemove', moveSlider);
document.removeEventListener('mouseup', sliderMouseUp);
}
else if (document.detachEvent) { // Remove event listeners from 'document' (IE&co).
document.detachEvent('onmousemove', moveSlider)
document.detachEvent('onmouseup', sliderMouseUp)
document.detachEvent('onmousemove', moveSlider);
document.detachEvent('onmouseup', sliderMouseUp);
}
}
//seyi_code
// seyi_code
//slide(event,'horizontal', 300, 1, 22, 22,0, 'imageslider_display_id');
//slide(evnt, orientation, length, from, to, count, decimals, display) {
function slideManual(val,length,from,to) {
scale = (to - from) / length // Slider-display scale [value-change per pixel of movement].
fromVal = from
xMax = length
yMax = 0
scale = (to - from) / length; // Slider-display scale [value-change per pixel of movement].
fromVal = from;
xMax = length;
yMax = 0;
sliderid = 'imageslider_id';
@ -574,24 +578,26 @@ if (ie||dom) start_slider();
else if (document.layers) window.onload=start_slider;
</script>
<?php
} # end if defaultvideo
?>
</body>
</html>
<?php
return( ob_get_clean() );
return ob_get_clean();
}
function exportEventImagesMaster( $eids ) {
function exportEventImagesMaster($eids) {
ob_start();
exportHeader( translate('Images').' Master' );
exportHeader(translate('Images').' Master');
?>
<body>
<h2><?php echo translate('Images') ?> Master</h2>
<?php
// TODO: SHould use find to make this 1 db query
// TODO: Should use find to make this 1 db query
foreach ($eids as $eid) {
//get monitor id and event id
$event = new Event( $eid );
$event = new Event($eid);
$eventMonitorId[$eid] = $event->MonitorId();
$eventPath[$eid] = $event->Relative_Path();
}
@ -600,70 +606,66 @@ function exportEventImagesMaster( $eids ) {
$monitorNames = array();
//*
if(!empty($monitors)) {
$tmp = dbFetchAll("SELECT Id,Name FROM Monitors WHERE Id IN (".implode(',', $monitors).") ");
if ( !empty($monitors) ) {
$tmp = dbFetchAll('SELECT Id,Name FROM Monitors WHERE Id IN ('.implode(',', $monitors).') ');
foreach ( $tmp as $row ) { $monitorNames[$row['Id']] = $row['Name']; }
}
//*/
//trigger_error(print_r($monitorNames,1));
?>
<div id="tabs">
<ul class="tabs">
<li class="active"><a href="#all"> All </a></li>
<?php
foreach ($monitors as $monitor) {
# code...
echo "<li><a href='#tab$monitor'>" . $monitorNames[$monitor] . '</a></li>';
echo "<li><a href=\"#tab$monitor\">" . $monitorNames[$monitor] . '</a></li>';
}
?>
</ul>
</div>
<table width="100%" height="100%" ><tr>
<td valign="top" bgcolor="#dddddd" style="padding:10px;">
<div class='tab_content' id='all'>
<h2> All </h2>
<?php
if (!is_array($eids)) {
echo "<div><a href=\"javascript:switchevent('$eids/zm/EventImages.html');\"> $eids </div>";
}
?>
<?php foreach($eids as $eid) {
?>
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
<?php
}
?>
<table width="100%" height="100%">
<tr>
<td valign="top" bgcolor="#dddddd" style="padding:10px;">
<div class="tab_content" id="all">
<h2> All </h2>
<?php
foreach($eids as $eid) {
$Event = new Event($eid);
if ( $Event->SaveJPEGs() ) {
?>
<div><a href="#" onclick="switchevent('<?php echo $eid; ?>/zmEventImages.html');return false;"><?php echo $eid; ?></a></div>
<?php
} # end if saveJPEGs
} # end foreach event id
?>
</div>
<?php
foreach ($monitors as $monitor) {
echo "<div class='tab_content' id='tab$monitor'>";
echo "<h2>Monitor: " . $monitorNames[$monitor] . " </h2>";
foreach ($eids as $eid) {
if ($eventMonitorId[$eid] == $monitor) {
?>
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
<?php
}
<?php
foreach ($monitors as $monitor) {
echo "<div class=\"tab_content\" id=\"tab$monitor\">";
echo '<h2>Monitor: ' . $monitorNames[$monitor] . ' </h2>';
foreach ( $eids as $eid ) {
if ( $eventMonitorId[$eid] == $monitor ) {
?>
<div><a href="#" onclick="switchevent('<?php echo $eid; ?>/zmEventImages.html');return false;"><?php echo $eid; ?></a></div>
<?php
}
echo'</div>';
}
?>
</td><td>
<iframe id="myframe" onload="resizeCaller();" name="myframe" src="#"
scrolling="no" marginwidth="0" marginheight="0" frameborder="0"
vspace="0" hspace="0" style="overflow:visible; width:100%; display:none">
</iframe>
</td>
</tr></table>
echo '</div>';
} # end foreach monitor
?>
</td><td>
<iframe id="myframe" onload="resizeCaller();" name="myframe" src="#"
scrolling="no" marginwidth="0" marginheight="0" frameborder="0"
vspace="0" hspace="0" style="overflow:visible; width:100%; display:none">
</iframe>
</td>
</tr>
</table>
<script type="text/javascript">
function switchevent(src) {
if(document.all) document.all.myframe.src = src;
else window.frames['myframe'].location.href = src;
$('#myframe').attr('src',src);
$('#myframe').show();
}
/***********************************************
@ -674,72 +676,72 @@ function switchevent(src) {
//Input the IDs of the IFRAMES you wish to dynamically resize to match its content height:
//Separate each ID with a comma. Examples: ["myframe1", "myframe2"] or ["myframe"] or [] for none:
var iframeids=["myframe"]
var iframeids=["myframe"];
//Should script hide iframe from browsers that don't support this script (non IE5+/NS6+ browsers. Recommended):
var iframehide="yes"
var iframehide="yes";
var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1]
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0 //extra height in px to add to iframe in FireFox 1.0+ browsers
var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1];
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0; //extra height in px to add to iframe in FireFox 1.0+ browsers
function resizeCaller() {
var dyniframe=new Array()
var dyniframe=new Array();
for (i=0; i<iframeids.length; i++){
if (document.getElementById) resizeIframe(iframeids[i]);
//reveal iframe for lower end browsers? (see var above):
if ((document.all || document.getElementById) && iframehide=="no"){
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i])
tempobj.style.display="block"
if ( (document.all || document.getElementById) && iframehide=="no" ) {
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i]);
tempobj.style.display="block";
}
}
}
function resizeIframe(frameid){
var currentfr=document.getElementById(frameid)
if (currentfr && !window.opera){
currentfr.style.display="block"
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
function resizeIframe(frameid) {
var currentfr = document.getElementById(frameid);
if ( currentfr && !window.opera ) {
currentfr.style.display = "block";
if ( currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight ) //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight;
else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
else if ( currentfr.Document && currentfr.Document.body.scrollHeight ) //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight;
if (currentfr.addEventListener) currentfr.addEventListener("load", readjustIframe, false);
else if (currentfr.attachEvent){
currentfr.detachEvent("onload", readjustIframe) // Bug fix line
currentfr.attachEvent("onload", readjustIframe)
if ( currentfr.addEventListener ) {
currentfr.addEventListener("load", readjustIframe, false);
} else if ( currentfr.attachEvent ) {
currentfr.detachEvent("onload", readjustIframe); // Bug fix line
currentfr.attachEvent("onload", readjustIframe);
}
}
}
function readjustIframe(loadevt) {
var crossevt=(window.event)? event : loadevt;
var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement
var crossevt = window.event ? event : loadevt;
var iframeroot = crossevt.currentTarget ? crossevt.currentTarget : crossevt.srcElement;
if (iframeroot) resizeIframe(iframeroot.id);
}
function loadintoIframe(iframeid, url){
function loadintoIframe(iframeid, url) {
if (document.getElementById) document.getElementById(iframeid).src=url;
}
//if (window.addEventListener) window.addEventListener("load", resizeCaller, false)
//else if (window.attachEvent) window.attachEvent("onload", resizeCaller)
//else window.onload=resizeCaller
</script>
</body>
</script>
</body>
</html>
<?php
return( ob_get_clean() );
return ob_get_clean();
}
function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) {
function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc) {
if ( (!canView('Events')) or ! $eid ) {
if ( !canView('Events') or !$event ) {
return;
}
$event = new Event($eid);
$eventPath = $event->Path();
$eventPath = $event->Path();
$eventRelativePath = $event->Relative_Path();
$files = array();
if ( $dir = opendir($eventPath) ) {
while ( ($file = readdir($dir)) !== false ) {
@ -754,29 +756,29 @@ function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exp
if ( $exportDetail ) {
$file = 'zmEventDetail.html';
if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
Fatal( "Can't open event detail export file '$file'" );
if ( !($fp = fopen($eventPath.'/'.$file, 'w')) ) {
Fatal("Can't open event detail export file '$file'");
}
fwrite( $fp, exportEventDetail( $event, $exportFrames, $exportImages ) );
fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file;
fwrite($fp, exportEventDetail($event, $exportFrames, $exportImages));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
}
if ( $exportFrames ) {
$file = 'zmEventFrames.html';
if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
Fatal( "Can't open event frames export file '$file'" );
if ( !($fp = fopen($eventPath.'/'.$file, 'w')) ) {
Fatal("Can't open event frames export file '$file'");
}
fwrite( $fp, exportEventFrames( $event, $exportDetail, $exportImages ) );
fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file;
fwrite($fp, exportEventFrames($event, $exportDetail, $exportImages));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
}
if ( $exportImages ) {
$filesLeft = array();
$myfilelist = array();
foreach ( $files as $file ) {
if ( preg_match( '/-(?:capture|analyse).jpg$/', $file ) ) {
$exportFileList[$file] = $eventPath."/".$file;
$myfilelist[$file] = $eventPath."/".$file;
if ( preg_match('/-(?:capture|analyse).jpg$/', $file ) ) {
$myfilelist[$file] = $exportFileList[$file] = $event->Id().'/'.$file;
} else {
$filesLeft[$file] = $file;
}
@ -785,109 +787,160 @@ function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exp
// create an image slider
if ( !empty($myfilelist) ) {
$file = 'zmEventImages.html';
if ( !($fp = fopen($eventPath.'/'.$file, 'w')) ) Fatal( "Can't open event images export file '$file'" );
fwrite( $fp, exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist ) );
fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file;
$file = $event->Id().'/zmEventImages.html';
if ( !($fp = fopen($file, 'w')) )
Fatal("Can't open event images export file '$file'");
fwrite($fp, exportEventImages($event, $exportDetail, $exportFrames, $myfilelist));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
}
} # end if exportImages
if ( $exportVideo ) {
$filesLeft = array();
foreach ( $files as $file ) {
if ( preg_match( '/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file ) ) {
$exportFileList[$file] = $eventPath.'/'.$file;
if ( preg_match('/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file) ) {
$exportFileList[$file] = $event->Id().'/'.$file;
} else {
$filesLeft[$file] = $file;
}
}
$files = $filesLeft;
} # end if exportVideo
} # end if exportVideo
if ( $exportMisc ) {
foreach ( $files as $file ) {
$exportFileList[$file] = $eventPath.'/'.$file;
$exportFileList[$file] = $event->Id().'/'.$file;
}
$files = array();
}
return array_values($exportFileList);
}
} # end exportFileList()
function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false ) {
function exportEvents(
$eids,
$connkey,
$exportDetail,
$exportFrames,
$exportImages,
$exportVideo,
$exportMisc,
$exportFormat,
$exportStructure = false
) {
if ( (!canView('Events')) || empty($eids) ) {
if ( !canView('Events') ) {
Error("You do not have permission to view events.");
return false;
} else if ( empty($eids) ) {
Error("Attempt to export an empty list of events.");
return false;
}
# Ensure that we are going to be able to do this.
if ( ! file_exists(ZM_DIR_EXPORTS) ) {
if ( ! mkdir(ZM_DIR_EXPORTS) ) {
Fatal("Can't create exports dir at '".ZM_DIR_EXPORTS."'");
}
}
$export_dir = ZM_DIR_EXPORTS.'/zmExport_'.$connkey;
# Ensure that we are going to be able to do this.
if ( ! file_exists($export_dir) ) {
if ( ! mkdir($export_dir) ) {
Fatal("Can't create exports dir at '$export_dir'");
} else {
Logger::Debug("Successfully created dir '$export_dir'");
}
}
if ( !chdir($export_dir) )
Fatal("Can't chdir to $export_dir");
$export_root = 'zmExport';
$export_listFile = 'zmFileList.txt';
$exportFileList = array();
$html_eventMaster = '';
if ( is_array($eids) ) {
foreach ( $eids as $eid ) {
$exportFileList = array_merge( $exportFileList, exportFileList( $eid , $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) );
}
} else {
$eid = $eids;
$exportFileList = exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc );
if ( !is_array($eids) ) {
$eids = array($eids);
}
// create an master image slider
if ( $exportImages ) {
if ( !is_array($eids) ) {
$eids = array($eids);
foreach ( $eids as $eid ) {
$event = new Event($eid);
$event_dir = $export_dir.'/'.$event->Id();
if ( !mkdir($event_dir) )
Error("Can't mkdir $event_dir");
$event_exportFileList = exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc);
$exportFileList = array_merge($exportFileList,$event_exportFileList);
foreach ( $event_exportFileList as $file ) {
if ( preg_match('/\.html$/', $file ) )
continue;
Logger::Debug('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
}
$monitorPath = ZM_DIR_EVENTS.'/';
$html_eventMaster = 'zmEventImagesMaster_'.date('Ymd_His'). '.html';
if ( !($fp = fopen( $monitorPath.'/'.$html_eventMaster, 'w' )) ) Fatal( "Can't open event images export file '$html_eventMaster'" );
fwrite($fp, exportEventImagesMaster($eids));
fclose($fp);
$exportFileList[] = $monitorPath.'/'.$html_eventMaster;
}
$listFile = ZM_DIR_EXPORTS.'/'.$export_listFile;
// create an master image
if ( $exportImages ) {
if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/jquery.js', $export_dir.'/jquery.js') )
Error("Failed linking jquery.js");
//if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/video.js', $export_dir.'/video.js') )
//Error("Failed linking video.js");
$html_eventMaster_file = 'zmEventImagesMaster_'.date('Ymd_His'). '.html';
$html_eventMaster_path = $export_dir.'/'.$html_eventMaster_file;
if ( ($fp = fopen($html_eventMaster_path, 'w')) ) {
fwrite($fp, exportEventImagesMaster($eids));
fclose($fp);
$exportFileList[] = $html_eventMaster_file;
} else {
Error("Can't open event images export file '$html_eventMaster_path'");
}
}
$listFile = $export_dir.'/'.$export_listFile;
if ( !($fp = fopen($listFile, 'w')) ) {
Fatal( "Can't open event export list file '$listFile'" );
Fatal("Can't open event export list file '$listFile'");
}
foreach ( $exportFileList as $exportFile ) {
fwrite( $fp, "$exportFile\n" );
$exportFile = 'zmExport'.$connkey.'/'.$exportFile;
fwrite($fp, "$exportFile\n");
}
fclose( $fp );
fwrite($fp, "$listFile\n");
fclose($fp);
chdir(ZM_DIR_EXPORTS);
$archive = '';
if ( $exportFormat == 'tar' ) {
$archive = ZM_DIR_EXPORTS.'/'.$export_root.'.tar.gz';
@unlink( $archive );
if ( $exportStructure == 'flat' ) { //strip file paths if we choose
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile)." --xform='s#^.+/##x'";
} else {
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile);
}
exec( $command, $output, $status );
if ( $status ) {
Error( "Command '$command' returned with status $status" );
if ( $output[0] )
Error( "First line of output is '".$output[0]."'" );
return( false );
$archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.tar.gz';
@unlink($archive);
$command = 'nice -10 tar --create --gzip --dereference --file='.escapeshellarg($archive).' zmExport_'.$connkey.'/';
#$command = 'nice -10 tar --create --gzip --file='.escapeshellarg($archive).' --files-from='.escapeshellarg($listFile);
if ( $exportStructure == 'flat' ) {
//strip file paths if we
$command .= " --xform='s#^.+/##x'";
}
} elseif ( $exportFormat == 'zip' ) {
$archive = ZM_DIR_EXPORTS.'/'.$export_root.'.zip';
@unlink( $archive );
if ($exportStructure == 'flat') {
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q -j ".escapeshellarg($archive)." -@";
$archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.zip';
@unlink($archive);
if ( $exportStructure == 'flat' ) {
$command = 'nice -10 zip -j '.escapeshellarg($archive).' zmExport_'.$connkey.'/';
#$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q -j '.escapeshellarg($archive).' -@';
} else {
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q ".escapeshellarg($archive)." -@";
}
//cat zmFileList.txt | zip -q zm_export.zip -@
//-bash: zip: command not found
exec( $command, $output, $status );
if ( $status ) {
Error("Command '$command' returned with status $status");
if ( $output[0] )
Error("First line of output is '".$output[0]."'");
return false;
$command = 'nice -10 zip -r '.escapeshellarg($archive).' zmExport_' . $connkey.'/';
#$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q '.escapeshellarg($archive).' -@';
}
} else {
Error("No exportFormat specified.");
return false;
} // if $exportFormat
Logger::Debug("Command is $command");
exec($command, $output, $status);
if ( $status ) {
Error("Command '$command' returned with status $status");
if ( isset($output[0]) )
Error("First line of output is '".$output[0]."'");
return false;
}
//clean up temporary files
@ -895,5 +948,5 @@ function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $expo
unlink($monitorPath.'/'.$html_eventMaster);
}
return '?view=archive%26type='.$exportFormat;
return '?view=archive%26type='.$exportFormat.'%26connkey='.$connkey;
}

View File

@ -317,9 +317,6 @@ if ($reload == 'reload') ob_start();
</div>
<div id="Version" class="pull-right">
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
<h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3>
<?php } ?>
</div>
<ul class="list-inline">
<li class="Load"><i class="material-icons md-18">trending_up</i>&nbsp;<?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
@ -359,6 +356,9 @@ if ($reload == 'reload') ob_start();
echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%';
?></li>
</ul>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
<h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3>
<?php } ?>
<!-- End .footer/reload --></div>
<?php
if ($reload == 'reload') return( ob_get_clean() );

View File

@ -41,7 +41,7 @@ var popupSizes = {
'filter': { 'width': 900, 'height': 700 },
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 200 },
'frames': { 'width': 600, 'height': 600 },
'function': { 'width': 350, 'height': 160 },
'function': { 'width': 350, 'height': 260 },
'group': { 'width': 760, 'height': 600 },
'groups': { 'width': 540, 'height': 420 },
'image': { 'addWidth': 48, 'addHeight': 80 },
@ -54,7 +54,7 @@ var popupSizes = {
'monitorselect':{ 'width': 160, 'height': 200 },
'montage': { 'width': -1, 'height': -1 },
'onvifprobe': { 'width': 700, 'height': 550 },
'optionhelp': { 'width': 400, 'height': 320 },
'optionhelp': { 'width': 400, 'height': 400 },
'options': { 'width': 1000, 'height': 660 },
'preset': { 'width': 300, 'height': 220 },
'server': { 'width': 600, 'height': 405 },

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
https://github.com/twbs/bootstrap/releases/download/v3.3.6/bootstrap-3.3.6-dist.zip

View File

@ -1,42 +0,0 @@
{
"name": "chosen",
"description": "Chosen is a JavaScript plugin that makes select boxes user-friendly. It is currently available in both jQuery and Prototype flavors.",
"keywords": [
"select",
"multiselect",
"dropdown",
"form",
"input",
"ui"
],
"homepage": "https://harvesthq.github.io/chosen/",
"license": "https://github.com/harvesthq/chosen/blob/master/LICENSE.md",
"authors": [
{
"name": "Patrick Filler",
"url": "https://github.com/pfiller"
},
{
"name": "Christophe Coevoet",
"url": "https://github.com/stof"
},
{
"name": "Ken Earley",
"url": "https://github.com/kenearley"
},
{
"name": "Koen Punt",
"url": "https://github.com/koenpunt"
}
],
"dependencies": {},
"main": [
"chosen.jquery.js",
"chosen.css"
],
"ignore": [],
"repository": {
"type": "git",
"url": "https://github.com/harvesthq/chosen.git"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,11 +0,0 @@
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : { allow_single_deselect: true },
'.chosen-select-no-single' : { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-rtl' : { rtl: true },
'.chosen-select-width' : { width: '95%' }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}

View File

@ -1,16 +0,0 @@
document.observe('dom:loaded', function(evt) {
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : { allow_single_deselect: true },
'.chosen-select-no-single' : { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-rtl' : { rtl: true },
'.chosen-select-width' : { width: '95%' }
}
for (var selector in config) {
$$(selector).each(function(element) {
new Chosen(element, config[selector]);
});
}
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -1,108 +0,0 @@
/**
* okaidia theme for JavaScript, CSS and HTML
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
* @author ocodia
*/
code[class*="language-"],
pre[class*="language-"] {
color: #f8f8f2;
text-shadow: 0 1px rgba(0,0,0,0.3);
font-family: Consolas, Monaco, 'Andale Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: 0.3em;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #272822;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #f8f8f2;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag {
color: #f92672;
}
.token.boolean,
.token.number{
color: #ae81ff;
}
.token.selector,
.token.attr-name,
.token.string {
color: #a6e22e;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #f8f8f2;
}
.token.atrule,
.token.attr-value
{
color: #e6db74;
}
.token.keyword{
color: #66d9ef;
}
.token.regex,
.token.important {
color: #fd971f;
}
.token.important {
font-weight: bold;
}
.token.entity {
cursor: help;
}

View File

@ -1,9 +0,0 @@
/**
* Prism: Lightweight, robust, elegant syntax highlighting
* MIT license http://www.opensource.org/licenses/mit-license.php/
* @author Lea Verou http://lea.verou.me
*/(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){return n.stringify(t.tokenize(e,r),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u],f=a.inside,l=!!a.lookbehind,c=0;a=a.pattern||a;for(var h=0;h<s.length;h++){var p=s[h];if(s.length>e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+"</"+s.tag+">"};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();;
Prism.languages.markup={comment:/&lt;!--[\w\W]*?-->/g,prolog:/&lt;\?.+?\?>/,doctype:/&lt;!DOCTYPE.+?>/,cdata:/&lt;!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/&lt;\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^&lt;\/?[\w:-]+/i,inside:{punctuation:/^&lt;\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&amp;#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&amp;/,"&"))});;
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/ig,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\{\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/(&lt;|<)style[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/style(>|&gt;)/ig,inside:{tag:{pattern:/(&lt;|<)style[\w\W]*?(>|&gt;)|(&lt;|<)\/style(>|&gt;)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});;
Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}}, number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|&lt;=?|>=?|={1,3}|(&amp;){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(&lt;|<)script[\w\W]*?(>|&gt;)[\w\W]*?(&lt;|<)\/script(>|&gt;)/ig,inside:{tag:{pattern:/(&lt;|<)script[\w\W]*?(>|&gt;)|(&lt;|<)\/script(>|&gt;)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});;

View File

@ -1,219 +0,0 @@
/* Reset */
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; }
ins { background-color: #ff9; color: #000; text-decoration: none; }
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
del { text-decoration: line-through; }
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
table { border-collapse: collapse; border-spacing: 0; }
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
input, select { vertical-align: middle; }
body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
select, input, textarea, button { font:99% sans-serif; }
pre, code, kbd, samp { font-family: monospace, sans-serif; }
body { background: #EEE; color: #444; line-height: 1.4em; }
header h1 { color: black; font-size: 2em; line-height: 1.1em; display: inline-block; height: 27px; margin: 20px 0 25px; }
header h1 small { font-size: 0.6em; }
div#content { background: white; border: 1px solid #ccc; border-width: 0 1px 1px; margin: 0 auto; padding: 40px 50px 40px; width: 738px; }
footer { color: #999; padding-top: 40px; font-size: 0.8em; text-align: center; }
body { font-family: sans-serif; font-size: 1em; }
p { margin: 0 0 .7em; max-width: 700px; }
table+p { margin-top: 1em; }
h2 { border-bottom: 1px solid #ccc; font-size: 1.2em; margin: 3em 0 1em 0; font-weight: bold;}
h3 { font-weight: bold; }
h2.intro { border-bottom: none; font-size: 1em; font-weight: normal; margin-top:0; }
ul li { list-style: disc; margin-left: 1em; margin-bottom: 1.25em; }
ol li { margin-left: 1.25em; }
ol ul, ul ul { margin: .25em 0 0; }
ol ul li, ul ul li { list-style-type: circle; margin: 0 0 .25em 1em; }
li > p { margin-top: .25em; }
div.side-by-side { width: 100%; margin-bottom: 1em; }
div.side-by-side > div { float: left; width: 49%; }
div.side-by-side > div > em { margin-bottom: 10px; display: block; }
.faqs em { display: block; }
.clearfix:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
a { color: #F36C00; outline: none; text-decoration: none; }
a:hover { text-decoration: underline; }
ul.credits li { margin-bottom: .25em; }
strong { font-weight: bold; }
i { font-style: italic; }
.button {
background: #fafafa;
background: -webkit-linear-gradient(top, #ffffff, #eeeeee);
background: -moz-linear-gradient(top, #ffffff, #eeeeee);
background: -o-linear-gradient(top, #ffffff, #eeeeee);
background: linear-gradient(to bottom, #ffffff, #eeeeee);
border: 1px solid #bbbbbb;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.2);
color: #555555;
cursor: pointer;
display: inline-block;
font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif;
font-size: 13px;
font-weight: 500;
height: 31px;
line-height: 28px;
outline: none;
padding: 0 13px;
text-shadow: 0 1px 0 white;
text-decoration: none;
vertical-align: middle;
white-space: nowrap;
-webkit-font-smoothing: antialiased;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.button-blue {
background: #1385e5;
background: -webkit-linear-gradient(top, #53b2fc, #1385e5);
background: -moz-linear-gradient(top, #53b2fc, #1385e5);
background: -o-linear-gradient(top, #53b2fc, #1385e5);
background: linear-gradient(to bottom, #53b2fc, #1385e5);
border-color: #075fa9;
color: white;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
}
/* Tweak navbar brand link to be super sleek
-------------------------------------------------- */
.oss-bar {
top: 0;
right: 20px;
position: fixed;
z-index: 1030;
}
.oss-bar ul {
float: right;
margin: 0;
list-style: none;
}
.oss-bar ul li {
list-style: none;
float: left;
line-height: 0;
margin: 0;
}
.oss-bar ul li a {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
border: 0;
margin-top: -10px;
display: block;
height: 58px;
background: #F36C00 url(oss-credit.png) no-repeat 20px 22px;
padding: 22px 20px 12px 20px;
text-indent: 120%; /* stupid padding */
white-space: nowrap;
overflow: hidden;
-webkit-transition: all 0.10s ease-in-out;
-moz-transition: all 0.10s ease-in-out;
transition: all 0.15s ease-in-out;
}
.oss-bar ul li a:hover {
margin-top: 0px;
}
.oss-bar a.harvest {
width: 196px;
background-color: #F36C00;
background-position: -142px 22px;
padding-right: 22px; /* optical illusion */
}
.oss-bar a.fork {
width: 162px;
background-color: #333333;
}
.docs-table th, .docs-table td {
border: 1px solid #000;
padding: 4px 6px;
white-space: nowrap;
}
.docs-table td:last-child {
white-space: normal;
}
.docs-table th {
font-weight: bold;
text-align: left;
}
#content pre[class*=language-] {
font-size: 14px;
margin-bottom: 20px;
}
#content pre[class*=language-] code {
font-size: 14px;
padding: 0;
}
#content code[class*=language-] {
font-size: 12px;
padding: 2px 4px;
}
.anchor {
color: inherit;
position: relative;
}
.anchor:hover {
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSI3Ij48ZyBmaWxsPSIjNDE0MDQyIj48cGF0aCBkPSJNOS44IDdoLS45bC0uOS0uMWMtLjctLjMtMS40LS43LTEuOC0xLjMtLjItLjEtLjMtLjMtLjMtLjVsLS4zLS40Yy0uMS0uNC0uMi0uOC0uMi0xLjIgMC0uNC4xLS44LjItMS4yaDEuN2MtLjMuNC0uNC44LS40IDEuMiAwIC40LjEuOC4zIDEuMS4xLjIuMi4zLjQuNC4xLjEuMi4yLjQuMy4zLjIuNy4zIDEgLjNoMy40YzEuMiAwIDIuMi0uOSAyLjItMi4xcy0xLTIuMS0yLjItMi4xaC0xLjRjLS4zLS42LS43LTEtMS4yLTEuNGgyLjZjMiAwIDMuNiAxLjYgMy42IDMuNXMtMS42IDMuNS0zLjYgMy41aC0yLjZ6TTguNCAyYy0uMS0uMS0uMi0uMy0uNC0uMy0uMy0uMi0uNy0uMy0xLS4zaC0zLjRjLTEuMiAwLTIuMi45LTIuMiAyLjEgMCAxLjIgMSAyLjEgMi4yIDIuMWgxLjRjLjMuNS43IDEgMS4yIDEuNGgtMi42Yy0yIDAtMy42LTEuNi0zLjYtMy41czEuNi0zLjUgMy42LTMuNWgzLjUwMDAwMDAwMDAwMDAwMDRsLjkuMWMuNy4yIDEuNC43IDEuOCAxLjMuMS4xLjIuMy4zLjUuMS4xLjIuMy4yLjUuMS40LjIuOC4yIDEuMiAwIC40LS4xLjgtLjIgMS4yaC0xLjZjLjMtLjUuNC0uOS40LTEuM3MtLjEtLjgtLjMtMS4xYy0uMS0uMi0uMi0uMy0uNC0uNHoiLz48L2c+PC9zdmc+) 0 50% no-repeat;
background-size: 21px 9px;
margin-left: -27px;
padding-left: 27px;
text-decoration: none;
}
.select,
.chosen-select,
.chosen-select-no-single,
.chosen-select-no-results,
.chosen-select-deselect,
.chosen-select-rtl,
.chosen-select-width {
width: 350px;
}
.jquery-version-refer {
margin-top: 40px;
font-style: italic;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,306 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes</title>
<link rel="stylesheet" href="docsupport/style.css">
<link rel="stylesheet" href="docsupport/prism.css">
<link rel="stylesheet" href="chosen.css">
<style type="text/css" media="all">
/* fix rtl for demo */
.chosen-rtl .chosen-drop { left: -9000px; }
</style>
</head>
<body>
<div id="container">
<div id="content">
<header>
<h1>Chosen <small>(<span id="latest-version">v1.8.2</span>)</small></h1>
</header>
<p>Chosen has a number of options and attributes that allow you to have full control of your select boxes.</p>
<h2><a name="options" class="anchor" href="#options">Options</a></h2>
<p>The following options are available to pass into Chosen on instantiation.</p>
<h3>Example:</h3>
<pre>
<code class="language-javascript">$(".my_select_box").chosen({
disable_search_threshold: 10,
no_results_text: "Oops, nothing found!",
width: "95%"
});</code>
</pre>
<table class="docs-table">
<tr>
<th>Option</th><th>Default</th><th>Description</th>
</tr>
<tr>
<td>allow_single_deselect</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code> on a single select, Chosen adds a UI element which selects the first element (if it is blank).</td>
</tr>
<tr>
<td>disable_search</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code>, Chosen will not display the search field (single selects only).</td>
</tr>
<tr>
<td>disable_search_threshold</td>
<td>0</td>
<td>Hide the search input on single selects if there are <i>n</i> or fewer options.</td>
</tr>
<tr>
<td>enable_split_word_search</td>
<td>true</td>
<td>By default, searching will match on any word within an option tag. Set this option to <code class="language-javascript">false</code> if you want to only match on the entire text of an option tag.</td>
</tr>
<tr>
<td>inherit_select_classes</td>
<td>false</td>
<td>When set to <code class="language-javascript">true</code>, Chosen will grab any classes on the original select field and add them to Chosens container div.</td>
</tr>
<tr>
<td>max_selected_options</td>
<td>Infinity</td>
<td>Limits how many options the user can select. When the limit is reached, the <code class="language-javascript">chosen:maxselected</code> event is triggered.</td>
</tr>
<tr>
<td>no_results_text</td>
<td>"No results match"</td>
<td>The text to be displayed when no matching results are found. The current search is shown at the end of the text (<i>e.g.</i>,
No results match "Bad Search").</td>
</tr>
<tr>
<td>placeholder_text_multiple</td>
<td>"Select Some Options"</td>
<td>The text to be displayed as a placeholder when no options are selected for a multiple select.</td>
</tr>
<tr>
<td>placeholder_text_single</td>
<td>"Select an Option"</td>
<td>The text to be displayed as a placeholder when no options are selected for a single select.</td>
</tr>
<tr>
<td>search_contains</td>
<td>false</td>
<td>By default, Chosens search matches starting at the beginning of a word. Setting this option to <code class="language-javascript">true</code> allows matches starting from anywhere within a word. This is especially useful for options that include a lot of special characters or phrases in ()s and []s.</td>
</tr>
<tr>
<td>single_backstroke_delete</td>
<td>true</td>
<td>By default, pressing delete/backspace on multiple selects will remove a selected choice. When <code class="language-javascript">false</code>, pressing delete/backspace will highlight the last choice, and a second press deselects it.</td>
</tr>
<tr>
<td>width</td>
<td>Original select width.</td>
<td>The width of the Chosen select box. By default, Chosen attempts to match the width of the select box you are replacing. If your select is hidden when Chosen is instantiated, you must specify a width or the select will show up with a width of 0.</td>
</tr>
<tr>
<td>display_disabled_options</td>
<td>true</td>
<td>By default, Chosen includes disabled options in search results with a special styling. Setting this option to false will hide disabled results and exclude them from searches.</td>
</tr>
<tr>
<td>display_selected_options</td>
<td>true</td>
<td>
<p>By default, Chosen includes selected options in search results with a special styling. Setting this option to false will hide selected results and exclude them from searches.</p>
<p><strong>Note:</strong> this is for multiple selects only. In single selects, the selected result will always be displayed.</p>
</td>
</tr>
<tr>
<td>include_group_label_in_selected</td>
<td>false</td>
<td>
<p>By default, Chosen only shows the text of a selected option. Setting this option to <code class="language-javascript">true</code> will show the text and group (if any) of the selected option.</p>
</td>
</tr>
<tr>
<td>max_shown_results</td>
<td>Infinity</td>
<td>
<p>Only show the first (n) matching options in the results. This can be used to increase performance for selects with very many options.</p>
</td>
</tr>
<tr>
<td>case_sensitive_search</td>
<td>false</td>
<td>
<p>By default Chosen's search is case-insensitive. Setting this option to <code class="language-javascript">true</code> makes the search case-sensitive.</p>
</td>
</tr>
<tr>
<td>hide_results_on_select</td>
<td>true</td>
<td>
<p>By default Chosen's results are hidden after a option is selected. Setting this option to <code class="language-javascript">false</code> will keep the results open after selection. This only applies to multiple selects.</p>
</td>
</tr>
<tr>
<td>rtl</td>
<td>false</td>
<td>
<p>Chosen supports right-to-left text in select boxes. Set this option to <code class="language-javascript">true</code> to support right-to-left text options.</p>
<p><strong>Note:</strong> <a href="#classes">the <code class="language-javascript">chosen-rtl</code> class</a> on the select has precedence over this option. However, the classname approach is deprecated and will be removed in future versions of Chosen.</p>
</td>
</tr>
</table>
<h2><a name="attributes" class="anchor" href="#attributes">Attributes</a></h2>
<p>Certain attributes placed on the select tag or its options can be used to configure Chosen.</p>
<h3>Example:</h3>
<pre>
<code class="language-markup">&lt;select class="my_select_box" data-placeholder="Select Your Options"&gt;
&lt;option value="1"&gt;Option 1&lt;/option&gt;
&lt;option value="2" selected&gt;Option 2&lt;/option&gt;
&lt;option value="3" disabled&gt;Option 3&lt;/option&gt;
&lt;/select&gt;</code>
</pre>
<table class="docs-table">
<tr>
<th>Attribute</th><th>Description</th>
</tr>
<tr>
<td>data-placeholder</td>
<td>
<p>The text to be displayed as a placeholder when no options are selected for a select. Defaults to "Select an Option" for single selects or "Select Some Options" for multiple selects.</p>
<p><strong>Note:</strong>This attribute overrides anything set in the <code class="language-javascript">placeholder_text_multiple</code> or <code class="language-javascript">placeholder_text_single</code> options.</p>
</td>
</tr>
<tr>
<td>multiple</td>
<td>The attribute <code class="language-html">multiple</code> on your select box dictates whether Chosen will render a multiple or single select.</td>
</tr>
<tr>
<td>selected, disabled</td>
<td>Chosen automatically highlights selected options and disables disabled options.</td>
</tr>
</table>
<h2><a name="classes" class="anchor" href="#classes">Classes</a></h2>
<p>Classes placed on the select tag can be used to configure Chosen.</p>
<h3>Example:</h3>
<pre>
<code class="language-markup">&lt;select class="my_select_box chosen-rtl"&gt;
&lt;option value="1"&gt;Option 1&lt;/option&gt;
&lt;option value="2"&gt;Option 2&lt;/option&gt;
&lt;option value="3"&gt;Option 3&lt;/option&gt;
&lt;/select&gt;</code>
</pre>
<table class="docs-table">
<tr>
<th>Classname</th>
<th>Description</th>
</tr>
<tr>
<td>chosen-rtl</td>
<td>
<p>Chosen supports right-to-left text in select boxes. Add the class <code class="language-html">chosen-rtl</code> to your select tag to support right-to-left text options.</p>
<p><strong>Note:</strong> The <code class="language-html">chosen-rtl</code> class will pass through to the Chosen select even when the <code class="language-javascript">inherit_select_classes</code> option is set to <code class="language-javascript">false</code>.</p>
<p><strong>Note:</strong> This is deprecated in favor of using the <code class="language-javascript">rtl: true</code> option (see the <a href="#options">Options section</a>).</p>
</td>
</tr>
</table>
<h2><a name="triggered-events" class="anchor" href="#triggered-events">Triggered Events</a></h2>
<p>Chosen triggers a number of standard and custom events on the original select field.</p>
<h3>Example:</h3>
<pre>
<code class="language-javascript">$('.my_select_box').on('change', function(evt, params) {
do_something(evt, params);
});</code>
</pre>
<table class="docs-table">
<tr>
<th>Event</th><th>Description</th>
</tr>
<tr>
<td>change</td>
<td>
<p>Chosen triggers the standard DOM event whenever a selection is made (it also sends a <code class="language-javascript">selected</code> or <code class="language-javascript">deselected</code> parameter that tells you which option was changed).</p>
<p><strong>Note:</strong> The selected and deselected parameters are not available for Prototype.</p>
</td>
</tr>
<tr>
<td>chosen:ready</td>
<td>Triggered after Chosen has been fully instantiated.</td>
</tr>
<tr>
<td>chosen:maxselected</td>
<td>Triggered if <code class="language-javascript">max_selected_options</code> is set and that total is broken.</td>
</tr>
<tr>
<td>chosen:showing_dropdown</td>
<td>Triggered when Chosens dropdown is opened.</td>
</tr>
<tr>
<td>chosen:hiding_dropdown</td>
<td>Triggered when Chosens dropdown is closed.</td>
</tr>
<tr>
<td>chosen:no_results</td>
<td>Triggered when a search returns no matching results.</td>
</tr>
</table>
<p>
<strong>Note:</strong> all custom Chosen events (those that begin with <code class="language-javascript">chosen:</code>) also include the <code class="language-javascript">chosen</code> object as a parameter.
</p>
<h2><a name="triggerable-events" class="anchor" href="#triggerable-events">Triggerable Events</a></h2>
<p>You can trigger several events on the original select field to invoke a behavior in Chosen.</p>
<h3>Example:</h3>
<pre>
<code class="language-javascript">// tell Chosen that a select has changed
$('.my_select_box').trigger('chosen:updated');</code>
</pre>
<table class="docs-table">
<tr>
<th>Event</th><th>Description</th>
</tr>
<tr>
<td>chosen:updated</td>
<td>This event should be triggered whenever Chosens underlying select element changes (such as a change in selected options).</td>
</tr>
<tr>
<td>chosen:activate</td>
<td>This is the equivalant of focusing a standard HTML select field. When activated, Chosen will capure keypress events as if you had clicked the field directly.</td>
</tr>
<tr>
<td>chosen:open</td>
<td>This event activates Chosen and also displays the search results.</td>
</tr>
<tr>
<td>chosen:close</td>
<td>This event deactivates Chosen and hides the search results.</td>
</tr>
</table>
<footer>
&copy; 2011&ndash;2016 <a href="http://www.getharvest.com/">Harvest</a>. Chosen is licensed under the <a href="https://github.com/harvesthq/chosen/blob/master/LICENSE.md">MIT license</a>.
</footer>
</div>
</div>
<div class="oss-bar">
<ul>
<li><a class="fork" href="https://github.com/harvesthq/chosen">Fork on Github</a></li>
<li><a class="harvest" href="http://www.getharvest.com/">Built by Harvest</a></li>
</ul>
</div>
<script src="docsupport/prism.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

View File

@ -1,50 +0,0 @@
{
"name": "chosen-js",
"version": "1.8.1",
"description": "Chosen is a JavaScript plugin that makes select boxes user-friendly. It is currently available in both jQuery and Prototype flavors.",
"keywords": [
"select",
"multiselect",
"dropdown",
"form",
"input",
"ui"
],
"homepage": "https://harvesthq.github.io/chosen/",
"bugs": "https://github.com/harvesthq/chosen/issues",
"license": "MIT",
"contributors": [
{
"name": "Patrick Filler",
"url": "https://github.com/pfiller"
},
{
"name": "Christophe Coevoet",
"url": "https://github.com/stof"
},
{
"name": "Ken Earley",
"url": "https://github.com/kenearley"
},
{
"name": "Koen Punt",
"url": "https://github.com/koenpunt"
}
],
"dependencies": {},
"files": [
"chosen.jquery.js",
"chosen.jquery.min.js",
"chosen.proto.js",
"chosen.proto.min.js",
"chosen.css",
"chosen.min.css",
"chosen-sprite@2x.png",
"chosen-sprite.png"
],
"main": "chosen.jquery.js",
"repository": {
"type": "git",
"url": "https://github.com/harvesthq/chosen.git"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
jquery-ui-1.11.3.js
jquery-ui-1.12.1/jquery-ui.js

Some files were not shown because too many files have changed in this diff Show More