Start trimming dump1090-mutability down for use in piaware.
This commit is contained in:
parent
9479a5c9be
commit
b433a521bf
10
debian/changelog
vendored
10
debian/changelog
vendored
|
@ -1,4 +1,10 @@
|
||||||
dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium
|
dump1090-fa (2.2.0~dev) UNRELEASE; urgency=medium
|
||||||
|
|
||||||
|
* testing, testing.
|
||||||
|
|
||||||
|
-- Oliver Jowett <oliver@mutability.co.uk> Mon, 11 Jan 2016 17:20:05 +0000
|
||||||
|
|
||||||
|
dump1090-mutability (1.15~devubuntu1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* In development.
|
* In development.
|
||||||
* Validate that the username given to debconf is syntactically OK and
|
* Validate that the username given to debconf is syntactically OK and
|
||||||
|
@ -22,7 +28,7 @@ dump1090-mutability (1.15~dev) UNRELEASED; urgency=medium
|
||||||
timestamp value. If they arrive, tag the derived data as mlat-derived.
|
timestamp value. If they arrive, tag the derived data as mlat-derived.
|
||||||
Don't include mlat-derived output in FATSV output to avoid loops.
|
Don't include mlat-derived output in FATSV output to avoid loops.
|
||||||
|
|
||||||
-- Oliver Jowett <oliver@mutability.co.uk> Thu, 19 Feb 2015 22:39:19 +0000
|
-- Oliver Jowett <oliver@mutability.co.uk> Mon, 11 Jan 2016 17:20:05 +0000
|
||||||
|
|
||||||
dump1090-mutability (1.14) unstable; urgency=medium
|
dump1090-mutability (1.14) unstable; urgency=medium
|
||||||
|
|
||||||
|
|
2
debian/compat
vendored
2
debian/compat
vendored
|
@ -1 +1 @@
|
||||||
8
|
9
|
127
debian/config-template
vendored
127
debian/config-template
vendored
|
@ -1,128 +1,21 @@
|
||||||
## TEMPLATE FILE - This is used to create /etc/default/dump1090-mutability ##
|
# dump1090-fa configuration
|
||||||
## The first three lines will be discarded ##
|
# This is read by the systemd service file as environment vars,
|
||||||
|
# and evaluated by some scripts as a POSIX shell fragment.
|
||||||
|
|
||||||
# dump1090-mutability configuration file
|
# User to run as.
|
||||||
# This is a POSIX shell fragment.
|
DUMP1090_USER=dump1090
|
||||||
# You can edit this file directly, or use
|
|
||||||
# "dpkg-reconfigure dump1090-mutability"
|
|
||||||
|
|
||||||
# Set to "yes" to start dump1090 on boot.
|
# Where to log to. (See also /etc/logrotate.d/dump1090-fa.conf)
|
||||||
START_DUMP1090=
|
LOGFILE=/var/log/dump1090-fa.log
|
||||||
|
|
||||||
# User to run dump1090 as.
|
|
||||||
DUMP1090_USER=
|
|
||||||
|
|
||||||
# Logfile to log to
|
|
||||||
LOGFILE=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Receiver options
|
|
||||||
#
|
|
||||||
|
|
||||||
# RTLSDR device index or serial number to use
|
# RTLSDR device index or serial number to use
|
||||||
# If set to "none", dump1090 will be started in --net-only mode
|
# If set to "none", dump1090 will be started in --net-only mode
|
||||||
DEVICE=
|
DEVICE=0
|
||||||
|
|
||||||
# RTLSDR gain in dB.
|
# RTLSDR gain in dB.
|
||||||
# If set to "max" (the default) the maximum supported gain is used.
|
# If set to "max" (the default) the maximum supported gain is used.
|
||||||
# If set to "agc", the tuner AGC is used to set the gain.
|
# If set to "agc", the tuner AGC is used to set the gain.
|
||||||
GAIN=
|
GAIN=agc
|
||||||
|
|
||||||
# RTLSDR frequency correction in PPM
|
# RTLSDR frequency correction in PPM
|
||||||
PPM=
|
PPM=0
|
||||||
|
|
||||||
# If yes, enable sampling at 2.4MHz. Otherwise, 2.0MHz is used.
|
|
||||||
OVERSAMPLE=
|
|
||||||
|
|
||||||
# If yes, enables phase-enhancement of messages
|
|
||||||
PHASE_ENHANCE=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Decoding options
|
|
||||||
#
|
|
||||||
|
|
||||||
# If yes, fixes messages with correctable CRC errors.
|
|
||||||
FIX_CRC=
|
|
||||||
|
|
||||||
# If yes, enables aggressive fixes to damaged messages.
|
|
||||||
# Use with caution - it can increase the rate of undetected errors.
|
|
||||||
AGGRESSIVE=
|
|
||||||
|
|
||||||
# If set, supplies a reference location for local position decoding.
|
|
||||||
LAT=
|
|
||||||
LON=
|
|
||||||
|
|
||||||
# If set, provides the absolute maximum receiver range used to
|
|
||||||
# filter bad position reports, and to determine when local position
|
|
||||||
# decoding is safe to use. Specify this in nautical miles (NM).
|
|
||||||
MAX_RANGE=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Networking options
|
|
||||||
#
|
|
||||||
|
|
||||||
# Port to listen on for HTTP connections. 0 disables.
|
|
||||||
# HTTP defaults to being disabled unless you specify something here. I
|
|
||||||
# that you do not enable this, and instead serve the contents of
|
|
||||||
# /usr/share/dump1090-mutability and JSON_DIR (below) using a proper
|
|
||||||
# webserver. See /etc/lighttpd/conf-available/90-dump1090.conf
|
|
||||||
# for an example configuration ("sudo lighty-enable-mod dump1090" to enable)
|
|
||||||
HTTP_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for raw (AVR-format) input connections. 0 disables.
|
|
||||||
RAW_INPUT_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for raw (AVR-format) output connections. 0 disables.
|
|
||||||
RAW_OUTPUT_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for SBS-format output connections. 0 disables.
|
|
||||||
SBS_OUTPUT_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for Beast-format input connections. 0 disables.
|
|
||||||
BEAST_INPUT_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for Beast-format output connections. 0 disables.
|
|
||||||
BEAST_OUTPUT_PORT=
|
|
||||||
|
|
||||||
# Port to listen on for FATSV-format output connections. 0 disables.
|
|
||||||
FATSV_OUTPUT_PORT=
|
|
||||||
|
|
||||||
# TCP heartbeat interval in seconds. 0 disables.
|
|
||||||
NET_HEARTBEAT=
|
|
||||||
|
|
||||||
# Minimum output buffer size per write, in bytes.
|
|
||||||
NET_OUTPUT_SIZE=
|
|
||||||
|
|
||||||
# Maximum buffering time before writing, in seconds.
|
|
||||||
NET_OUTPUT_INTERVAL=
|
|
||||||
|
|
||||||
# TCP buffer size, in bytes
|
|
||||||
NET_BUFFER=
|
|
||||||
|
|
||||||
# Bind ports on a particular address. If unset, binds to all interfaces.
|
|
||||||
# This defaults to binding to localhost. If you need to allow remote
|
|
||||||
# connections, change this.
|
|
||||||
NET_BIND_ADDRESS=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Misc options
|
|
||||||
#
|
|
||||||
|
|
||||||
# Interval (in seconds) between logging stats to the logfile. 0 disables.
|
|
||||||
STATS_INTERVAL=
|
|
||||||
|
|
||||||
# Path to write json state to (for use with an external webserver). Blank disables.
|
|
||||||
JSON_DIR=
|
|
||||||
|
|
||||||
# Interval between writing json state (in seconds). 0 disables.
|
|
||||||
JSON_INTERVAL=
|
|
||||||
|
|
||||||
# Accuracy of receiver location to write to json state, one of "exact" / "approximate" / "none"
|
|
||||||
JSON_LOCATION_ACCURACY=
|
|
||||||
|
|
||||||
# Set to yes to log all decoded messages
|
|
||||||
# This can get large fast!
|
|
||||||
LOG_DECODED_MESSAGES=
|
|
||||||
|
|
||||||
# Additional options that are passed to the Daemon.
|
|
||||||
EXTRA_ARGS=
|
|
||||||
|
|
15
debian/control
vendored
15
debian/control
vendored
|
@ -1,21 +1,18 @@
|
||||||
Source: dump1090-mutability
|
Source: dump1090-fa
|
||||||
Section: embedded
|
Section: embedded
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Oliver Jowett <oliver@mutability.co.uk>
|
Maintainer: Oliver Jowett <oliver@mutability.co.uk>
|
||||||
Build-Depends: debhelper(>=8), librtlsdr-dev, libusb-1.0-0-dev, pkg-config
|
Build-Depends: debhelper(>=9), librtlsdr-dev, libusb-1.0-0-dev, pkg-config, dh-systemd
|
||||||
Standards-Version: 3.9.3
|
Standards-Version: 3.9.3
|
||||||
Homepage: https://github.com/mutability/dump1090
|
Homepage: https://github.com/mutability/dump1090
|
||||||
Vcs-Git: https://github.com/mutability/dump1090.git
|
Vcs-Git: https://github.com/mutability/dump1090.git
|
||||||
|
|
||||||
Package: dump1090-mutability
|
Package: dump1090-fa
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
|
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, python(>=2.5), cron | cron-daemon, curl, lighttpd
|
||||||
Recommends: python(>=2.5), cron | cron-daemon, curl
|
|
||||||
Suggests: lighttpd
|
|
||||||
Provides: fatsv-data-source
|
|
||||||
Description: ADS-B Ground Station System for RTL-SDR
|
Description: ADS-B Ground Station System for RTL-SDR
|
||||||
Networked Aviation Mode S / ADS-B decoder/translator with RTL-SDR software
|
Networked Aviation Mode S / ADS-B decoder/translator with RTL-SDR software
|
||||||
defined radio USB device support.
|
defined radio USB device support.
|
||||||
.
|
.
|
||||||
This is a packaging of the "mutability" fork of dump1090 that includes
|
This is FlightAware's packaging of dump1090-mutability, customized for use
|
||||||
sampling at 2.4MHz and other improvements.
|
in the piaware sdcard images.
|
||||||
|
|
2
debian/cron-template
vendored
2
debian/cron-template
vendored
|
@ -9,4 +9,4 @@
|
||||||
# all installs hitting the server at the same time.
|
# all installs hitting the server at the same time.
|
||||||
|
|
||||||
# m h dom mon dow user command
|
# m h dom mon dow user command
|
||||||
@MIN@ 5 * * * @USER@ test -x /usr/share/dump1090-mutability/update-aircraft-database.sh && /usr/share/dump1090-mutability/update-aircraft-database.sh --log-to-file
|
@MIN@ 5 @DOM@ * * @USER@ test -x /usr/share/dump1090-fa/update-aircraft-database.sh && /usr/share/dump1090-fa/update-aircraft-database.sh --log-to-file
|
||||||
|
|
11
debian/dump1090-fa.default
vendored
Normal file
11
debian/dump1090-fa.default
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# dump1090-fa configuration
|
||||||
|
# This is read by the systemd service file as an environment file,
|
||||||
|
# and evaluated by some scripts as a POSIX shell fragment.
|
||||||
|
|
||||||
|
# TODO: This needs to be generated from piaware-config.txt
|
||||||
|
|
||||||
|
#RECEIVER_OPTIONS="--device-index 0 --gain -10 --ppm 0 --oversample --phase-enhance --net-bo-port 30005 --fix"
|
||||||
|
RECEIVER_OPTIONS="--net-only --net-bo-port 0"
|
||||||
|
DECODER_OPTIONS="--max-range 300"
|
||||||
|
NET_OPTIONS="--net --net-heartbeat 60 --net-ro-size 1000 --net-ro-interval 1 --net-http-port 0 --net-ri-port 0 --net-ro-port 30002 --net-sbs-port 30003 --net-bi-port 30104 --net-fatsv-port 0"
|
||||||
|
JSON_OPTIONS="--json-location-accuracy 1"
|
5
debian/dump1090-fa.install
vendored
Normal file
5
debian/dump1090-fa.install
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
public_html/* usr/share/dump1090-fa/html
|
||||||
|
debian/lighttpd/* etc/lighttpd/conf-available
|
||||||
|
debian/cron-template usr/share/dump1090-fa
|
||||||
|
tools/vrs-basicaircraft-to-json.py usr/share/dump1090-fa
|
||||||
|
tools/update-aircraft-database.sh usr/share/dump1090-fa
|
70
debian/dump1090-fa.postinst
vendored
Normal file
70
debian/dump1090-fa.postinst
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# postinst script for dump1090
|
||||||
|
#
|
||||||
|
# see: dh_installdeb(1)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# summary of how this script can be called:
|
||||||
|
# * <postinst> `configure' <most-recently-configured-version>
|
||||||
|
# * <old-postinst> `abort-upgrade' <new version>
|
||||||
|
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||||
|
# <new-version>
|
||||||
|
# * <postinst> `abort-remove'
|
||||||
|
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||||
|
# <failed-install-package> <version> `removing'
|
||||||
|
# <conflicting-package> <version>
|
||||||
|
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||||
|
# the debian-policy package
|
||||||
|
|
||||||
|
NAME=dump1090-fa
|
||||||
|
RUNAS=dump1090
|
||||||
|
CRONFILE=/etc/cron.d/$NAME
|
||||||
|
TEMPLATECRON=/usr/share/$NAME/cron-template
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
. /usr/share/debconf/confmodule
|
||||||
|
|
||||||
|
if ! getent passwd "$RUNAS" >/dev/null
|
||||||
|
then
|
||||||
|
adduser --system --home /usr/share/$NAME --no-create-home --quiet "$RUNAS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create cronjob
|
||||||
|
if ! test -e $CRONFILE; then
|
||||||
|
echo "Creating cronjob in $CRONFILE to periodically update the aircraft database.." >&2
|
||||||
|
MIN=$(($RANDOM % 60))
|
||||||
|
DOM=$(( ($RANDOM % 28) + 1 ))
|
||||||
|
tail -n +4 $TEMPLATECRON | sed -e "s/@USER@/$RUNAS/g" -e "s/@MIN@/$MIN/g" -e "s/@DOM@/$DOM/g" >$CRONFILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
# update the DB
|
||||||
|
echo "Updating aircraft database now.."
|
||||||
|
mkdir -m 0755 -p /var/cache/$NAME
|
||||||
|
chown $RUNAS /var/cache/$NAME
|
||||||
|
su $RUNAS -s /bin/bash -c /usr/share/$NAME/update-aircraft-database.sh || true
|
||||||
|
|
||||||
|
# set up lighttpd
|
||||||
|
echo "Enabling lighttpd integration.." >&2
|
||||||
|
lighty-enable-mod dump1090-fa || true
|
||||||
|
echo "Restarting lighttpd.." >&2
|
||||||
|
invoke-rc.d lighttpd force-reload || true
|
||||||
|
;;
|
||||||
|
|
||||||
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "postinst called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then db_stop; fi
|
||||||
|
exit 0
|
|
@ -20,10 +20,16 @@ set -e
|
||||||
|
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
remove)
|
||||||
|
echo "Disabling dump1090-fa lighttpd integration.." >&2
|
||||||
|
lighty-disable-mod dump1090-fa || echo "warning: failed to disable lighttpd module" >&2
|
||||||
|
invoke-rc.d lighttpd restart || echo "warning: failed to restart lighttpd" >&2
|
||||||
|
;;
|
||||||
|
|
||||||
purge)
|
purge)
|
||||||
rm -f /etc/default/dump1090-mutability
|
rm -f /etc/default/dump1090-fa
|
||||||
rm -f /etc/cron.d/dump1090-mutability
|
rm -f /etc/cron.d/dump1090-fa
|
||||||
rm -rf /var/cache/dump1090-mutability
|
rm -rf /var/cache/dump1090-fa
|
||||||
;;
|
;;
|
||||||
|
|
||||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
24
debian/dump1090-fa.service
vendored
Normal file
24
debian/dump1090-fa.service
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# dump1090-fa service for systemd
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=dump1090 ADS-B receiver (FlightAware customization)
|
||||||
|
Documentation=https://flightaware.com/adsb/piaware/
|
||||||
|
Wants=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=/etc/default/dump1090-fa
|
||||||
|
EnvironmentFile=-/var/cache/piaware/location.env
|
||||||
|
User=dump1090
|
||||||
|
RuntimeDirectory=dump1090-fa
|
||||||
|
RuntimeDirectoryMode=0755
|
||||||
|
ExecStart=/usr/bin/dump1090-fa \
|
||||||
|
$RECEIVER_OPTIONS $DECODER_OPTIONS $NET_OPTIONS $JSON_OPTIONS $PIAWARE_DUMP1090_LOCATION_OPTIONS \
|
||||||
|
--write-json /run/dump1090-fa --quiet --stats-every 86400
|
||||||
|
Type=simple
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=30
|
||||||
|
Nice=-5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
8
debian/dump1090-mutability.conffiles
vendored
8
debian/dump1090-mutability.conffiles
vendored
|
@ -1,8 +0,0 @@
|
||||||
/usr/share/dump1090-mutability/html/config.js
|
|
||||||
/usr/share/dump1090-mutability/html/gmap.html
|
|
||||||
/usr/share/dump1090-mutability/html/script.js
|
|
||||||
/usr/share/dump1090-mutability/html/planeObject.js
|
|
||||||
/usr/share/dump1090-mutability/html/style.css
|
|
||||||
/usr/share/dump1090-mutability/html/markers.js
|
|
||||||
/usr/share/dump1090-mutability/html/formatter.js
|
|
||||||
/usr/share/dump1090-mutability/html/dbloader.js
|
|
237
debian/dump1090-mutability.config
vendored
237
debian/dump1090-mutability.config
vendored
|
@ -1,237 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
NAME=dump1090-mutability
|
|
||||||
CONFIGFILE=/etc/default/$NAME
|
|
||||||
set -e
|
|
||||||
. /usr/share/debconf/confmodule
|
|
||||||
|
|
||||||
db_set_yn() {
|
|
||||||
if [ "x$2" = "xyes" ]; then db_set $1 true; else db_set $1 false; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load config file, if it exists.
|
|
||||||
if [ -e $CONFIGFILE ]; then
|
|
||||||
. $CONFIGFILE || true
|
|
||||||
|
|
||||||
# Store values from config file into
|
|
||||||
# debconf db.
|
|
||||||
|
|
||||||
db_set_yn $NAME/auto-start "$START_DUMP1090"
|
|
||||||
db_set $NAME/run-as-user "$DUMP1090_USER"
|
|
||||||
db_set $NAME/log-file "$LOGFILE"
|
|
||||||
|
|
||||||
db_set $NAME/rtlsdr-device "$DEVICE"
|
|
||||||
db_set $NAME/rtlsdr-gain "$GAIN"
|
|
||||||
db_set $NAME/rtlsdr-ppm "$PPM"
|
|
||||||
db_set_yn $NAME/rtlsdr-oversample "$OVERSAMPLE"
|
|
||||||
|
|
||||||
db_set_yn $NAME/decode-fixcrc "$FIX_CRC"
|
|
||||||
db_set_yn $NAME/decode-phase-enhance "$PHASE_ENHANCE"
|
|
||||||
db_set_yn $NAME/decode-aggressive "$AGGRESSIVE"
|
|
||||||
db_set $NAME/decode-lat "$LAT"
|
|
||||||
db_set $NAME/decode-lon "$LON"
|
|
||||||
db_set $NAME/decode-max-range "$MAX_RANGE"
|
|
||||||
|
|
||||||
db_set $NAME/net-http-port "$HTTP_PORT"
|
|
||||||
db_set $NAME/net-ri-port "$RAW_INPUT_PORT"
|
|
||||||
db_set $NAME/net-ro-port "$RAW_OUTPUT_PORT"
|
|
||||||
db_set $NAME/net-bi-port "$BEAST_INPUT_PORT"
|
|
||||||
db_set $NAME/net-bo-port "$BEAST_OUTPUT_PORT"
|
|
||||||
db_set $NAME/net-sbs-port "$SBS_OUTPUT_PORT"
|
|
||||||
db_set $NAME/net-fatsv-port "$FATSV_OUTPUT_PORT"
|
|
||||||
db_set $NAME/net-heartbeat "$NET_HEARTBEAT"
|
|
||||||
db_set $NAME/net-out-size "$NET_OUTPUT_SIZE"
|
|
||||||
db_set $NAME/net-out-interval "$NET_OUTPUT_INTERVAL"
|
|
||||||
db_set $NAME/net-buffer "$NET_BUFFER"
|
|
||||||
db_set $NAME/net-bind-address "$NET_BIND_ADDRESS"
|
|
||||||
|
|
||||||
db_set $NAME/stats-interval "$STATS_INTERVAL"
|
|
||||||
db_set $NAME/json-dir "$JSON_DIR"
|
|
||||||
db_set $NAME/json-interval "$JSON_INTERVAL"
|
|
||||||
db_set $NAME/json-location-accuracy "$JSON_LOCATION_ACCURACY"
|
|
||||||
db_set_yn $NAME/log-decoded-messages "$LOG_DECODED_MESSAGES"
|
|
||||||
db_set $NAME/extra-args "$EXTRA_ARGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ask questions.
|
|
||||||
|
|
||||||
db_input_verify() {
|
|
||||||
# $1 = priority
|
|
||||||
# $2 = db key
|
|
||||||
# $3 = verification function, should return 0 if OK
|
|
||||||
PRI=$1; KEY=$2; VERIFY=$3
|
|
||||||
|
|
||||||
set +e
|
|
||||||
db_input $PRI $KEY; RESULT=$?
|
|
||||||
db_go
|
|
||||||
set -e
|
|
||||||
ASKED=0
|
|
||||||
while :
|
|
||||||
do
|
|
||||||
db_get $KEY
|
|
||||||
if $VERIFY "$RET"; then return 0; fi
|
|
||||||
if [ $RESULT -ne 0 ]; then
|
|
||||||
# db_input failed, and the existing value does not validate
|
|
||||||
if [ $RESULT = 30 ] && [ $ASKED = 0 ]
|
|
||||||
then
|
|
||||||
# question was skipped, but existing value is invalid
|
|
||||||
# bump priority and try again (once)
|
|
||||||
PRI=high
|
|
||||||
ASKED=1
|
|
||||||
else
|
|
||||||
# give up, use the default value
|
|
||||||
db_reset $KEY
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# db_input was OK, but the value did not verify.
|
|
||||||
# show an error message
|
|
||||||
db_input high dump1090-mutability/invalid-$VERIFY || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# try again
|
|
||||||
set +e
|
|
||||||
db_fset $KEY seen false
|
|
||||||
db_input high $KEY; RESULT=$?
|
|
||||||
db_go
|
|
||||||
set -e
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
is_unsigned_int() {
|
|
||||||
if echo "$1" | grep -Eq '^(0|+?[1-9][0-9]*)$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_unsigned_int_or_empty() {
|
|
||||||
if [ -z "$1" ]; then return 0
|
|
||||||
elif is_unsigned_int "$1"; then return 0
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_positive_int() {
|
|
||||||
if echo "$1" | grep -Eq '^(+?[1-9][0-9]*)$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_signed_int() {
|
|
||||||
if echo "$1" | grep -Eq '^(0|[+-]?[1-9][0-9]*)$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_signed_int_or_empty() {
|
|
||||||
if [ -z "$1" ]; then return 0
|
|
||||||
elif is_signed_int "$1"; then return 0
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_ipaddrish() {
|
|
||||||
if echo "$1" | grep -Eq '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_ipaddrish_or_empty() {
|
|
||||||
if [ -z "$1" ]; then return 0
|
|
||||||
elif is_ipaddrish "$1"; then return 0
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_number() {
|
|
||||||
if echo "$1" | grep -Eq '^([+-]?[0-9][0-9]*)(\.[0-9]+)?$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_unsigned_number() {
|
|
||||||
if echo "$1" | grep -Eq '^([+]?[0-9][0-9]*)(\.[0-9]+)?$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_positive_number() {
|
|
||||||
if echo "$1" | grep -Eq '^(([+]?0\.[0-9]*[1-9]+[0-9]*)|([+]?[1-9][0-9]*)(\.[0-9]+)?)$'; then return 0; else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_number_or_empty() {
|
|
||||||
if [ -z "$1" ]; then return 0
|
|
||||||
elif is_number "$1"; then return 0;
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_valid_gain() {
|
|
||||||
if is_number "$1"; then return 0;
|
|
||||||
elif [ "$1" = "max" ]; then return 0;
|
|
||||||
elif [ "$1" = "agc" ]; then return 0;
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_not_empty() {
|
|
||||||
if [ -z "$1" ]; then return 1; else return 0; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# "adduser: To avoid problems, the username should consist only of
|
|
||||||
# letters, digits, underscores, full stops, at signs and dashes, and not start with
|
|
||||||
# a dash (as defined by IEEE Std 1003.1-2001). For compatibility with Samba
|
|
||||||
# machine accounts $ is also supported at the end of the username"
|
|
||||||
is_non_root_user() {
|
|
||||||
if [ -z "$1" ]; then return 1;
|
|
||||||
elif [ "$1" = "root" ]; then return 1;
|
|
||||||
elif echo "$1" | grep -Eq '^[a-zA-Z0-9_.@-]+\$?$'; then return 0;
|
|
||||||
else return 1; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_port_number() {
|
|
||||||
if is_unsigned_int "$1"; then
|
|
||||||
if [ "$1" -eq 0 ]; then return 0; fi
|
|
||||||
if [ "$1" -lt 1024 ]; then return 1; fi
|
|
||||||
if [ "$1" -gt 65535 ]; then return 1; fi
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
db_input high $NAME/auto-start || true
|
|
||||||
db_input_verify low $NAME/run-as-user is_non_root_user || true
|
|
||||||
db_input_verify low $NAME/log-file is_not_empty || true
|
|
||||||
|
|
||||||
db_go || true; db_get $NAME/auto-start; if [ "$RET" = "true" ]; then
|
|
||||||
# all of these are only relevant if the init script is enabled
|
|
||||||
db_input medium $NAME/rtlsdr-device || true
|
|
||||||
|
|
||||||
db_go || true; db_get $NAME/rtlsdr-device; if [ "x$RET" != "xnone" ]; then
|
|
||||||
# only if a real device was chosen:
|
|
||||||
db_input_verify medium $NAME/rtlsdr-gain is_valid_gain || true
|
|
||||||
db_input_verify medium $NAME/rtlsdr-ppm is_signed_int || true
|
|
||||||
db_input low $NAME/rtlsdr-oversample || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
db_input low $NAME/decode-fix-crc || true
|
|
||||||
db_input low $NAME/decode-aggressive || true
|
|
||||||
db_input_verify medium $NAME/decode-max-range is_number || true
|
|
||||||
db_input_verify medium $NAME/decode-lat is_number_or_empty || true
|
|
||||||
|
|
||||||
db_go || true; db_get $NAME/decode-lat; if [ -n "$RET" ]; then
|
|
||||||
# only if latitude was given:
|
|
||||||
db_input_verify medium $NAME/decode-lon is_number_or_empty || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
db_input_verify medium $NAME/net-http-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-ri-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-ro-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-bi-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-bo-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-sbs-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-fatsv-port is_port_number || true
|
|
||||||
db_input_verify low $NAME/net-heartbeat is_unsigned_number || true
|
|
||||||
db_input_verify low $NAME/net-out-size is_unsigned_int || true
|
|
||||||
db_input_verify low $NAME/net-out-interval is_unsigned_number || true
|
|
||||||
db_input_verify low $NAME/net-buffer is_unsigned_int || true
|
|
||||||
db_input_verify medium $NAME/net-bind-address is_ipaddrish_or_empty || true
|
|
||||||
|
|
||||||
db_input_verify low $NAME/stats-interval is_unsigned_int || true
|
|
||||||
|
|
||||||
db_input_verify low $NAME/json-interval is_positive_number || true
|
|
||||||
db_input low $NAME/json-location-accuracy || true
|
|
||||||
db_input low $NAME/json-dir || true
|
|
||||||
|
|
||||||
db_input low $NAME/log-decoded-messages || true
|
|
||||||
db_input low $NAME/extra-args || true
|
|
||||||
|
|
||||||
db_go || True
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Done.
|
|
||||||
db_stop
|
|
207
debian/dump1090-mutability.init
vendored
207
debian/dump1090-mutability.init
vendored
|
@ -1,207 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: dump1090-mutability
|
|
||||||
# Required-Start: $remote_fs
|
|
||||||
# Required-Stop: $remote_fs
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: dump1090 daemon (mutability variant)
|
|
||||||
# Description: Receives ADS-B messages from a RTLSDR dongle
|
|
||||||
# and makes them available to other applications via
|
|
||||||
# a variety of network protocols.
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
# Do NOT "set -e"
|
|
||||||
|
|
||||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|
||||||
DESC="dump1090-mutability daemon"
|
|
||||||
NAME=dump1090-mutability
|
|
||||||
DAEMON=/usr/bin/$NAME
|
|
||||||
ARGS=""
|
|
||||||
PIDFILE=/var/run/$NAME.pid
|
|
||||||
SCRIPTNAME=/etc/init.d/$NAME
|
|
||||||
|
|
||||||
# Exit if the package is not installed
|
|
||||||
[ -x "$DAEMON" ] || exit 0
|
|
||||||
|
|
||||||
# Read configuration variable file if it is present
|
|
||||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
|
||||||
|
|
||||||
# work out daemon args
|
|
||||||
|
|
||||||
# sanitize missing settings
|
|
||||||
[ -z "$START_DUMP1090" ] && START_DUMP1090=no
|
|
||||||
[ -z "$DUMP1090_USER" ] && DUMP1090_USER="missing-DUMP1090_USER-setting-in-config"
|
|
||||||
[ -z "$HTTP_PORT" ] && HTTP_PORT=0
|
|
||||||
[ -z "$RAW_INPUT_PORT" ] && RAW_INPUT_PORT=0
|
|
||||||
[ -z "$RAW_OUTPUT_PORT" ] && RAW_OUTPUT_PORT=0
|
|
||||||
[ -z "$SBS_OUTPUT_PORT" ] && SBS_OUTPUT_PORT=0
|
|
||||||
[ -z "$BEAST_INPUT_PORT" ] && BEAST_INPUT_PORT=0
|
|
||||||
[ -z "$BEAST_OUTPUT_PORT" ] && BEAST_OUTPUT_PORT=0
|
|
||||||
[ -z "$FATSV_OUTPUT_PORT" ] && FATSV_OUTPUT_PORT=0
|
|
||||||
[ -z "$NET_BUFFER" ] && NET_BUFFER=0
|
|
||||||
[ -z "$JSON_INTERVAL" ] && JSON_INTERVAL=0
|
|
||||||
[ -z "$MAX_RANGE" ] && MAX_RANGE=300
|
|
||||||
|
|
||||||
# receiver:
|
|
||||||
NICELEVEL="--nicelevel -5"
|
|
||||||
case "x$DEVICE" in
|
|
||||||
x|x0) ARGS="$ARGS --net" ;;
|
|
||||||
xnone) ARGS="$ARGS --net-only"; NICELEVEL="" ;;
|
|
||||||
*) ARGS="$ARGS --net --device-index $DEVICE" ;;
|
|
||||||
esac
|
|
||||||
case "x$GAIN" in
|
|
||||||
x|xmax) ;;
|
|
||||||
xagc) ARGS="$ARGS --gain -10" ;;
|
|
||||||
*) ARGS="$ARGS --gain $GAIN" ;;
|
|
||||||
esac
|
|
||||||
if [ -n "$PPM" ]; then ARGS="$ARGS --ppm $PPM"; fi
|
|
||||||
if [ "x$OVERSAMPLE" = "xyes" ]; then ARGS="$ARGS --oversample"; fi
|
|
||||||
|
|
||||||
# decoder:
|
|
||||||
if [ "x$FIX_CRC" = "xyes" ]; then ARGS="$ARGS --fix"; fi
|
|
||||||
if [ "x$PHASE_ENHANCE" = "xyes" ]; then ARGS="$ARGS --phase-enhance"; fi
|
|
||||||
if [ "x$AGGRESSIVE" = "xyes" ]; then ARGS="$ARGS --aggressive"; fi
|
|
||||||
if [ -n "$LAT" ]; then ARGS="$ARGS --lat $LAT"; fi
|
|
||||||
if [ -n "$LON" ]; then ARGS="$ARGS --lon $LON"; fi
|
|
||||||
ARGS="$ARGS --max-range $MAX_RANGE"; fi
|
|
||||||
|
|
||||||
# net:
|
|
||||||
|
|
||||||
ARGS="$ARGS --net-http-port $HTTP_PORT \
|
|
||||||
--net-ri-port $RAW_INPUT_PORT --net-ro-port $RAW_OUTPUT_PORT \
|
|
||||||
--net-bi-port $BEAST_INPUT_PORT --net-bo-port $BEAST_OUTPUT_PORT \
|
|
||||||
--net-sbs-port $SBS_OUTPUT_PORT --net-fatsv-port $FATSV_OUTPUT_PORT"
|
|
||||||
if [ -n "$NET_HEARTBEAT" ]; then ARGS="$ARGS --net-heartbeat $NET_HEARTBEAT"; fi
|
|
||||||
if [ -n "$NET_OUTPUT_SIZE" ]; then ARGS="$ARGS --net-ro-size $NET_OUTPUT_SIZE"; fi
|
|
||||||
if [ -n "$NET_OUTPUT_INTERVAL" ]; then ARGS="$ARGS --net-ro-interval $NET_OUTPUT_INTERVAL"; fi
|
|
||||||
if [ "$NET_BUFFER" -le "65536" ]; then ARGS="$ARGS --net-buffer 0"
|
|
||||||
elif [ "$NET_BUFFER" -le "131072" ]; then ARGS="$ARGS --net-buffer 1"
|
|
||||||
elif [ "$NET_BUFFER" -le "262144" ]; then ARGS="$ARGS --net-buffer 2"
|
|
||||||
else ARGS="$ARGS --net-buffer 3"; fi
|
|
||||||
if [ -n "$NET_BIND_ADDRESS" ]; then ARGS="$ARGS --net-bind-address $NET_BIND_ADDRESS"; fi
|
|
||||||
|
|
||||||
# misc:
|
|
||||||
if [ -n "$STATS_INTERVAL" ]; then ARGS="$ARGS --stats-every $STATS_INTERVAL"; fi
|
|
||||||
if [ -n "$JSON_DIR" ]; then ARGS="$ARGS --write-json $JSON_DIR"; fi
|
|
||||||
if [ -n "$JSON_INTERVAL" ]; then ARGS="$ARGS --write-json-every $JSON_INTERVAL"; fi
|
|
||||||
case "x$JSON_LOCATION_ACCURACY" in
|
|
||||||
xexact) ARGS="$ARGS --json-location-accuracy 2" ;;
|
|
||||||
xapproximate) ARGS="$ARGS --json-location-accuracy 1" ;;
|
|
||||||
*) ARGS="$ARGS --json-location-accuracy 0" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ "x$LOG_DECODED_MESSAGES" != "xyes" ]; then ARGS="$ARGS --quiet"; fi
|
|
||||||
|
|
||||||
if [ -n "$EXTRA_ARGS" ]; then ARGS="$ARGS $EXTRA_ARGS"; fi
|
|
||||||
|
|
||||||
# Load the VERBOSE setting and other rcS variables
|
|
||||||
. /lib/init/vars.sh
|
|
||||||
|
|
||||||
# Define LSB log_* functions.
|
|
||||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
|
||||||
# and status_of_proc is working.
|
|
||||||
. /lib/lsb/init-functions
|
|
||||||
|
|
||||||
#
|
|
||||||
# Function that starts the daemon/service
|
|
||||||
#
|
|
||||||
do_start()
|
|
||||||
{
|
|
||||||
# Return
|
|
||||||
# 0 if daemon has been started
|
|
||||||
# 1 if daemon was already running
|
|
||||||
# 2 if daemon could not be started
|
|
||||||
|
|
||||||
if [ "x$START_DUMP1090" != "xyes" ]; then
|
|
||||||
log_warning_msg "Not starting $NAME daemon, disabled via /etc/default/$NAME"
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --user "$DUMP1090_USER" --exec $DAEMON --test > /dev/null \
|
|
||||||
|| return 1
|
|
||||||
|
|
||||||
# create JSON_DIR with the appropriate permissions
|
|
||||||
# (it is on /run by default, so will be lost on reboot)
|
|
||||||
if [ "x$JSON_DIR" != "x" ]; then
|
|
||||||
if [ ! -e $JSON_DIR ]; then
|
|
||||||
(mkdir $JSON_DIR && chmod 0755 $JSON_DIR && chown $DUMP1090_USER $JSON_DIR) || log_warning_msg "Failed to create $JSON_DIR"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create logfile with the appropriate permissions if not already there
|
|
||||||
# (the cronjob running as DUMP1090_USER wants to append to it)
|
|
||||||
touch $LOGFILE
|
|
||||||
chown "$DUMP1090_USER":root $LOGFILE
|
|
||||||
|
|
||||||
start-stop-daemon --start $NICELEVEL --quiet --pidfile $PIDFILE --user "$DUMP1090_USER" --chuid "$DUMP1090_USER" --make-pidfile --background --no-close --exec $DAEMON -- \
|
|
||||||
$ARGS >>$LOGFILE 2>&1 \
|
|
||||||
|| return 2
|
|
||||||
sleep 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Function that stops the daemon/service
|
|
||||||
#
|
|
||||||
do_stop()
|
|
||||||
{
|
|
||||||
# Return
|
|
||||||
# 0 if daemon has been stopped
|
|
||||||
# 1 if daemon was already stopped
|
|
||||||
# 2 if daemon could not be stopped
|
|
||||||
# other if a failure occurred
|
|
||||||
start-stop-daemon --stop --retry=TERM/30/KILL/5 --pidfile $PIDFILE --user "$DUMP1090_USER" --exec $DAEMON
|
|
||||||
RETVAL="$?"
|
|
||||||
[ "$RETVAL" = 2 ] && return 2
|
|
||||||
sleep 1
|
|
||||||
# Many daemons don't delete their pidfiles when they exit.
|
|
||||||
rm -f $PIDFILE
|
|
||||||
return "$RETVAL"
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
|
||||||
do_start
|
|
||||||
case "$?" in
|
|
||||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
|
||||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
|
||||||
do_stop
|
|
||||||
case "$?" in
|
|
||||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
|
||||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
|
||||||
;;
|
|
||||||
restart|force-reload)
|
|
||||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
|
||||||
do_stop
|
|
||||||
case "$?" in
|
|
||||||
0|1)
|
|
||||||
do_start
|
|
||||||
case "$?" in
|
|
||||||
0) log_end_msg 0 ;;
|
|
||||||
1) log_end_msg 1 ;; # Old process is still running
|
|
||||||
*) log_end_msg 1 ;; # Failed to start
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Failed to stop
|
|
||||||
log_end_msg 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
|
||||||
exit 3
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
:
|
|
7
debian/dump1090-mutability.install
vendored
7
debian/dump1090-mutability.install
vendored
|
@ -1,7 +0,0 @@
|
||||||
public_html/* usr/share/dump1090-mutability/html
|
|
||||||
debian/lighttpd/* etc/lighttpd/conf-available
|
|
||||||
debian/nginx/* etc/nginx/sites-available
|
|
||||||
debian/config-template usr/share/dump1090-mutability
|
|
||||||
debian/cron-template usr/share/dump1090-mutability
|
|
||||||
tools/vrs-basicaircraft-to-json.py usr/share/dump1090-mutability
|
|
||||||
tools/update-aircraft-database.sh usr/share/dump1090-mutability
|
|
5
debian/dump1090-mutability.logrotate
vendored
5
debian/dump1090-mutability.logrotate
vendored
|
@ -1,5 +0,0 @@
|
||||||
/var/log/dump1090-mutability.log {
|
|
||||||
weekly
|
|
||||||
rotate 4
|
|
||||||
copytruncate
|
|
||||||
}
|
|
149
debian/dump1090-mutability.postinst
vendored
149
debian/dump1090-mutability.postinst
vendored
|
@ -1,149 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# postinst script for dump1090
|
|
||||||
#
|
|
||||||
# see: dh_installdeb(1)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# summary of how this script can be called:
|
|
||||||
# * <postinst> `configure' <most-recently-configured-version>
|
|
||||||
# * <old-postinst> `abort-upgrade' <new version>
|
|
||||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
|
||||||
# <new-version>
|
|
||||||
# * <postinst> `abort-remove'
|
|
||||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
|
||||||
# <failed-install-package> <version> `removing'
|
|
||||||
# <conflicting-package> <version>
|
|
||||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
|
||||||
# the debian-policy package
|
|
||||||
|
|
||||||
NAME=dump1090-mutability
|
|
||||||
CONFIGFILE=/etc/default/$NAME
|
|
||||||
TEMPLATECONFIG=/usr/share/$NAME/config-template
|
|
||||||
CRONFILE=/etc/cron.d/$NAME
|
|
||||||
TEMPLATECRON=/usr/share/$NAME/cron-template
|
|
||||||
SEDSCRIPT=$CONFIGFILE.sed.tmp
|
|
||||||
|
|
||||||
subvar_raw() {
|
|
||||||
# $1 = db var value
|
|
||||||
# $2 = config var name
|
|
||||||
|
|
||||||
# if not present in the config file, add it
|
|
||||||
test -z "$1" || grep -Eq "^ *$2=" $CONFIGFILE || echo "$2=" >> $CONFIGFILE
|
|
||||||
# add to the sedscript
|
|
||||||
echo "s@^ *$2=.*@$2=\"$1\"@" >>$SEDSCRIPT
|
|
||||||
}
|
|
||||||
|
|
||||||
subvar() {
|
|
||||||
# $1 = db var name
|
|
||||||
# $2 = config var name
|
|
||||||
db_get $NAME/$1
|
|
||||||
subvar_raw "$RET" "$2"
|
|
||||||
}
|
|
||||||
|
|
||||||
subvar_yn() {
|
|
||||||
# $1 = db var name
|
|
||||||
# $2 = config var name
|
|
||||||
db_get $NAME/$1
|
|
||||||
if [ "$RET" = "true" ]; then subvar_raw "yes" "$2"; else subvar_raw "no" "$2"; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
configure)
|
|
||||||
. /usr/share/debconf/confmodule
|
|
||||||
|
|
||||||
# Generate config file, if it doesn't exist.
|
|
||||||
if [ ! -e $CONFIGFILE ]; then
|
|
||||||
tail -n +4 $TEMPLATECONFIG >$CONFIGFILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f $SEDSCRIPT
|
|
||||||
|
|
||||||
subvar_yn auto-start START_DUMP1090
|
|
||||||
subvar run-as-user DUMP1090_USER
|
|
||||||
subvar log-file LOGFILE
|
|
||||||
subvar rtlsdr-device DEVICE
|
|
||||||
subvar rtlsdr-gain GAIN
|
|
||||||
subvar rtlsdr-ppm PPM
|
|
||||||
subvar_yn rtlsdr-oversample OVERSAMPLE
|
|
||||||
subvar_yn decode-fixcrc FIX_CRC
|
|
||||||
subvar_yn decode-phase-enhance PHASE_ENHANCE
|
|
||||||
subvar_yn decode-aggressive AGGRESSIVE
|
|
||||||
subvar decode-lat LAT
|
|
||||||
subvar decode-lon LON
|
|
||||||
subvar decode-max-range MAX_RANGE
|
|
||||||
subvar net-http-port HTTP_PORT
|
|
||||||
subvar net-ri-port RAW_INPUT_PORT
|
|
||||||
subvar net-ro-port RAW_OUTPUT_PORT
|
|
||||||
subvar net-bi-port BEAST_INPUT_PORT
|
|
||||||
subvar net-bo-port BEAST_OUTPUT_PORT
|
|
||||||
subvar net-sbs-port SBS_OUTPUT_PORT
|
|
||||||
subvar net-fatsv-port FATSV_OUTPUT_PORT
|
|
||||||
subvar net-heartbeat NET_HEARTBEAT
|
|
||||||
subvar net-out-size NET_OUTPUT_SIZE
|
|
||||||
subvar net-out-interval NET_OUTPUT_INTERVAL
|
|
||||||
subvar net-buffer NET_BUFFER
|
|
||||||
subvar net-bind-address NET_BIND_ADDRESS
|
|
||||||
subvar stats-interval STATS_INTERVAL
|
|
||||||
subvar json-dir JSON_DIR
|
|
||||||
subvar json-interval JSON_INTERVAL
|
|
||||||
subvar json-location-accuracy JSON_LOCATION_ACCURACY
|
|
||||||
subvar_yn log-decoded-messages LOG_DECODED_MESSAGES
|
|
||||||
subvar extra-args EXTRA_ARGS
|
|
||||||
|
|
||||||
cp -a -f $CONFIGFILE $CONFIGFILE.tmp
|
|
||||||
sed -f $SEDSCRIPT < $CONFIGFILE > $CONFIGFILE.tmp
|
|
||||||
mv -f $CONFIGFILE.tmp $CONFIGFILE
|
|
||||||
rm $SEDSCRIPT
|
|
||||||
|
|
||||||
db_get $NAME/run-as-user
|
|
||||||
RUNAS="$RET"
|
|
||||||
if ! getent passwd "$RUNAS" >/dev/null
|
|
||||||
then
|
|
||||||
adduser --system --home /usr/share/$NAME --no-create-home --quiet "$RUNAS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create log if missing; change ownership if needed so the cronjob works
|
|
||||||
db_get $NAME/log-file
|
|
||||||
touch $RET
|
|
||||||
chown $RUNAS $RET
|
|
||||||
|
|
||||||
# create cronjob
|
|
||||||
if ! test -e $CRONFILE; then
|
|
||||||
echo "Creating cronjob in $CRONFILE to periodically update the aircraft database.." >&2
|
|
||||||
MIN=$(($RANDOM % 60))
|
|
||||||
tail -n +4 $TEMPLATECRON | sed -e "s/@USER@/$RUNAS/g" -e "s/@MIN@/$MIN/g" >$CRONFILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# update the DB
|
|
||||||
echo "Updating aircraft database now.."
|
|
||||||
mkdir -m 0755 -p /var/cache/$NAME
|
|
||||||
chown $RUNAS /var/cache/$NAME
|
|
||||||
su $RUNAS -s /bin/bash -c /usr/share/$NAME/update-aircraft-database.sh || \
|
|
||||||
echo "Aircraft database update failed. It will be retried periodically from cron." >&2
|
|
||||||
|
|
||||||
# config file changed between 1.14 and 1.15
|
|
||||||
if [ -e /etc/lighttpd/conf-enabled/89-dump1090.conf ]; then
|
|
||||||
if dpkg --compare-versions "$2" le "1.14"; then
|
|
||||||
echo "Restarting lighttpd.." >&2
|
|
||||||
invoke-rc.d lighttpd restart || echo "Warning: lighttpd failed to restart." >&2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
abort-upgrade|abort-remove|abort-deconfigure)
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "postinst called with unknown argument \`$1'" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# dh_installdeb will replace this with shell code automatically
|
|
||||||
# generated by other debhelper scripts.
|
|
||||||
|
|
||||||
#DEBHELPER#
|
|
||||||
|
|
||||||
if [ "$1" = "configure" ]; then db_stop; fi
|
|
||||||
exit 0
|
|
338
debian/dump1090-mutability.templates
vendored
338
debian/dump1090-mutability.templates
vendored
|
@ -1,338 +0,0 @@
|
||||||
Template: dump1090-mutability/auto-start
|
|
||||||
Description: Start dump1090 automatically?
|
|
||||||
dump1090 can be started automatically via an init-script.
|
|
||||||
Otherwise, the init-script does nothing; you must run dump1090 by hand.
|
|
||||||
.
|
|
||||||
You can modify the options used when automatically starting
|
|
||||||
dump1090 by running "dpkg-reconfigure dump1090-mutability" as root,
|
|
||||||
or by editing /etc/default/dump1090-mutability.
|
|
||||||
Type: boolean
|
|
||||||
Default: true
|
|
||||||
|
|
||||||
Template: dump1090-mutability/run-as-user
|
|
||||||
Description: User to run dump1090 as:
|
|
||||||
When started automatically, dump1090 runs as an unprivileged system user.
|
|
||||||
This user will be created if it does not yet exist.
|
|
||||||
Type: string
|
|
||||||
Default: dump1090
|
|
||||||
|
|
||||||
Template: dump1090-mutability/log-file
|
|
||||||
Description: Path to log to:
|
|
||||||
When started automatically, dump1090 will log its output somewhere. This
|
|
||||||
log will contain any startup errors, and periodic statistics reports.
|
|
||||||
Type: string
|
|
||||||
Default: /var/log/dump1090-mutability.log
|
|
||||||
|
|
||||||
Template: dump1090-mutability/rtlsdr-device
|
|
||||||
Description: RTL-SDR dongle to use:
|
|
||||||
If you have only one dongle connected, you can leave this blank.
|
|
||||||
.
|
|
||||||
Otherwise, you can provide the serial number (more reliable) or device
|
|
||||||
index (first device = 0, but the ordering is unpredictable) to choose
|
|
||||||
a particular dongle to use.
|
|
||||||
.
|
|
||||||
To run dump1090 in "net only" mode, specify the literal word "none".
|
|
||||||
Type: string
|
|
||||||
Default:
|
|
||||||
|
|
||||||
Template: dump1090-mutability/rtlsdr-gain
|
|
||||||
Description: RTL-SDR gain, in dB:
|
|
||||||
The tuner gain used by dump1090 can be provided as a value in dB, or
|
|
||||||
"max" to use the maximum gain available, or "agc" to use the tuner's AGC to
|
|
||||||
control the gain. If unsure, choose "max".
|
|
||||||
Type: string
|
|
||||||
Default: max
|
|
||||||
|
|
||||||
Template: dump1090-mutability/rtlsdr-ppm
|
|
||||||
Description: RTL-SDR frequency correction, in PPM:
|
|
||||||
The oscillator in each RTL-SDL dongle is not perfectly accurate. You can
|
|
||||||
choose a correction factor, in parts-per-million, to correct for this. The
|
|
||||||
correction factor varies from dongle to dongle, and also varies with operating
|
|
||||||
temperature. You can find a suitable value with "rtl_test -p" or "kalibrate".
|
|
||||||
If you don't know the value for your dongle, choose 0.
|
|
||||||
Type: string
|
|
||||||
Default: 0
|
|
||||||
|
|
||||||
Template: dump1090-mutability/rtlsdr-oversample
|
|
||||||
Description: Enable oversampling at 2.4MHz?
|
|
||||||
Originally, dump1090 would decode incoming signals by sampling at 2MHz. Newer
|
|
||||||
versions also support sampling at 2.4MHz. This may increase the number of
|
|
||||||
decodable messages, but takes slightly more CPU and is not as well tested.
|
|
||||||
Type: boolean
|
|
||||||
Default: true
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-fixcrc
|
|
||||||
Description: Fix detected CRC errors?
|
|
||||||
dump1090 can fix unambiguous single-bit CRC errors detected in received
|
|
||||||
messages. This allows weaker messages to be decoded. It can slightly increase
|
|
||||||
the rate of undetected errors, but this is not usually significant.
|
|
||||||
Type: boolean
|
|
||||||
Default: true
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-phase-enhance
|
|
||||||
Description: Apply phase enhancement?
|
|
||||||
dump1090 can attempt to correct for messages that are received
|
|
||||||
out-of-phase from the sampling rate, at the expense of taking more CPU.
|
|
||||||
Type: boolean
|
|
||||||
Default: true
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-aggressive
|
|
||||||
Description: Aggressively fix more errors?
|
|
||||||
dump1090 can apply more aggressive corrections to received messages,
|
|
||||||
primarily correcting two-bit CRC errors.
|
|
||||||
.
|
|
||||||
Use with caution! This can significantly increase the rate of undetected
|
|
||||||
message errors (i.e. increase the rate of garbled decoded messages)
|
|
||||||
Type: boolean
|
|
||||||
Default: false
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-lat
|
|
||||||
Description: Latitude of receiver, in decimal degrees:
|
|
||||||
If the location of the receiver is provided, dump1090 can do
|
|
||||||
local position decoding in cases where insufficient position messages are
|
|
||||||
received for unambiguous global position decoding.
|
|
||||||
Type: string
|
|
||||||
Default:
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-lon
|
|
||||||
Description: Longitude of receiver, in decimal degrees:
|
|
||||||
If the location of the receiver is provided, dump1090 can do
|
|
||||||
local position decoding in cases where insufficient position messages are
|
|
||||||
received for unambiguous global position decoding.
|
|
||||||
Type: string
|
|
||||||
Default:
|
|
||||||
|
|
||||||
Template: dump1090-mutability/decode-max-range
|
|
||||||
Description: Absolute maximum range of receiver, in nautical miles:
|
|
||||||
If the maximum range of the receiver is provided, dump1090 can filter
|
|
||||||
out impossible position reports that are due to aircraft that transmit
|
|
||||||
bad data.
|
|
||||||
.
|
|
||||||
Additionally, if the maximum range is larger than 180NM, when local
|
|
||||||
position decoding is used (when insufficient position messages
|
|
||||||
have been received for global position decoding), it is limited to
|
|
||||||
only those positions that would unambiguously decode to a single
|
|
||||||
position within the given receiver range.
|
|
||||||
.
|
|
||||||
This range should be the absolute maximum range - any position data
|
|
||||||
from further away will be entirely discarded!
|
|
||||||
Type: string
|
|
||||||
Default: 300
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-http-port
|
|
||||||
Description: Port for internal webserver (0 disables):
|
|
||||||
dump1090 can provide an internal webserver that serves a basic "virtual
|
|
||||||
radar" map.
|
|
||||||
.
|
|
||||||
It is generally a better idea to use an external webserver, but if you
|
|
||||||
really want to use the internal one, you can select a port to listen
|
|
||||||
on here.
|
|
||||||
Type: string
|
|
||||||
Default: 0
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-ri-port
|
|
||||||
Description: Port for AVR-format input connections (0 disables):
|
|
||||||
dump1090 can accept connections to receive data from other sources in
|
|
||||||
several formats. This setting controls the port dump1090 will listen
|
|
||||||
on for AVR ("raw") format input connections.
|
|
||||||
Type: string
|
|
||||||
Default: 30001
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-ro-port
|
|
||||||
Description: Port for AVR-format output connections (0 disables):
|
|
||||||
dump1090 can forward ADS-B messages to other software in several formats.
|
|
||||||
This setting controls the port dump1090 will listen on for AVR ("raw")
|
|
||||||
format output connections.
|
|
||||||
Type: string
|
|
||||||
Default: 30002
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-bi-port
|
|
||||||
Description: Port for Beast-format input connections (0 disables):
|
|
||||||
dump1090 can accept connections to receive data from other sources in
|
|
||||||
several formats. This setting controls the port dump1090 will listen
|
|
||||||
on for Beast ("binary") format input connections.
|
|
||||||
Type: string
|
|
||||||
Default: 30004
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-bo-port
|
|
||||||
Description: Port for Beast-format output connections (0 disables):
|
|
||||||
dump1090 can forward ADS-B messages to other software in several formats.
|
|
||||||
This setting controls the port dump1090 will listen on for Beast ("binary")
|
|
||||||
format output connections.
|
|
||||||
Type: string
|
|
||||||
Default: 30005
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-sbs-port
|
|
||||||
Description: Port for SBS-format output connections (0 disables):
|
|
||||||
dump1090 can forward ADS-B messages to other software in several formats.
|
|
||||||
This setting controls the port dump1090 will listen on for SBS BaseStation
|
|
||||||
format output connections.
|
|
||||||
Type: string
|
|
||||||
Default: 30003
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-fatsv-port
|
|
||||||
Description: Port for FATSV-format output connections (0 disables):
|
|
||||||
dump1090 can forward ADS-B messages to other software in several formats.
|
|
||||||
This setting controls the port dump1090 will listen on for FlightAware TSV
|
|
||||||
format output connections.
|
|
||||||
Type: string
|
|
||||||
Default: 10001
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-heartbeat
|
|
||||||
Description: Seconds between heartbeat messages (0 disables):
|
|
||||||
If there is no other data sent on a network connection, dump1090 can
|
|
||||||
periodically send an empty heartbeat message to ensure that the
|
|
||||||
connection stays established. This setting controls the interval
|
|
||||||
betweeen heartbeat messages.
|
|
||||||
Type: string
|
|
||||||
Default: 60
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-out-size
|
|
||||||
Description: Minimum output message size:
|
|
||||||
To avoid sending many small network messages, output connections will
|
|
||||||
accumulate data waiting to be sent until either a minimum size is reached
|
|
||||||
or a maximum delay is reached. This setting controls the minimum size,
|
|
||||||
in bytes.
|
|
||||||
Type: string
|
|
||||||
Default: 500
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-out-interval
|
|
||||||
Description: Maximum output buffering time:
|
|
||||||
To avoid sending many small network messages, output connections will
|
|
||||||
buffer data waiting to be sent until either a minimum size is reached
|
|
||||||
or a maximum delay is reached. This setting controls the maximum delay,
|
|
||||||
in seconds.
|
|
||||||
Type: string
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-buffer
|
|
||||||
Description: SO_SNDBUF size:
|
|
||||||
Here you can specify the TCP send buffer size to use on network connections.
|
|
||||||
Type: select
|
|
||||||
Choices: 65536, 131072, 262144
|
|
||||||
Default: 262144
|
|
||||||
|
|
||||||
Template: dump1090-mutability/net-bind-address
|
|
||||||
Description: Interface address to bind to (blank for all interfaces):
|
|
||||||
If you want to limit incoming connections to a particular interface,
|
|
||||||
specify the interface address here. A blank value will bind to the wildcard
|
|
||||||
address, allowing connections on all interfaces.
|
|
||||||
.
|
|
||||||
The default value of 127.0.0.1 will allow connections only on localhost,
|
|
||||||
i.e. only connections that originate on the same machine.
|
|
||||||
Type: string
|
|
||||||
Default: 127.0.0.1
|
|
||||||
|
|
||||||
Template: dump1090-mutability/stats-interval
|
|
||||||
Description: Interval between logging stats, in seconds:
|
|
||||||
dump1090 will periodically log message reception stats to its logfile.
|
|
||||||
This setting controls how often that is done.
|
|
||||||
Type: string
|
|
||||||
Default: 3600
|
|
||||||
|
|
||||||
Template: dump1090-mutability/json-dir
|
|
||||||
Description: Directory to write JSON aircraft state to:
|
|
||||||
As this can be written frequently, you should select a location
|
|
||||||
that is not on a sdcard. The default path under /run is on tmpfs
|
|
||||||
and will not write to the sdcard.
|
|
||||||
.
|
|
||||||
A blank path disables writing JSON state.
|
|
||||||
Type: string
|
|
||||||
Default: /run/dump1090-mutability
|
|
||||||
|
|
||||||
Template: dump1090-mutability/json-interval
|
|
||||||
Description: Interval between writing JSON aircraft state, in seconds:
|
|
||||||
dump1090 periodically write a list of aircraft, in JSON format, for use
|
|
||||||
by the virtual radar view when using an external webserver. This setting
|
|
||||||
controls the directory to write to.
|
|
||||||
.
|
|
||||||
Here you can control how often the JSON state is updated, which determines
|
|
||||||
how frequently the virtual radar view updates.
|
|
||||||
Type: string
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Template: dump1090-mutability/json-location-accuracy
|
|
||||||
Description: Receiver location accuracy to show in the web interface:
|
|
||||||
dump1090 can provide the configured receiver location to the web map,
|
|
||||||
so that the map can show distances from the receiver.
|
|
||||||
.
|
|
||||||
For privacy reasons, if you are making the map publicly available you
|
|
||||||
may not want to show the exact location of the receiver. There are three
|
|
||||||
options available to control what is shown:
|
|
||||||
.
|
|
||||||
approximate: dump1090 will provide the receiver location rounded to the
|
|
||||||
nearest 0.01 degree of latitude and longitude. This gives a location
|
|
||||||
that is accurate to within about 0.5 - 1km.
|
|
||||||
.
|
|
||||||
exact: dump1090 will provide the exact receiver location.
|
|
||||||
.
|
|
||||||
none: dump1090 will not provide the receiver location at all; distance
|
|
||||||
display will be disabled.
|
|
||||||
Type: select
|
|
||||||
Choices: approximate, exact, none
|
|
||||||
Default: approximate
|
|
||||||
|
|
||||||
Template: dump1090-mutability/log-decoded-messages
|
|
||||||
Description: Log all decoded messages?
|
|
||||||
dump1090 can log all decoded messages as text to the logfile.
|
|
||||||
This can result in a very large logfile! Usually you don't need this.
|
|
||||||
Type: boolean
|
|
||||||
Default: false
|
|
||||||
|
|
||||||
Template: dump1090-mutability/extra-args
|
|
||||||
Description: Extra arguments to pass to dump1090:
|
|
||||||
Here you can add any extra arguments you want to pass to dump1090.
|
|
||||||
Type: string
|
|
||||||
Default:
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_unsigned_int
|
|
||||||
Description: Value must be an unsigned integer.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_unsigned_int_or_empty
|
|
||||||
Description: Value must be an unsigned integer, or blank.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_positive_int
|
|
||||||
Description: Value must be a positive integer.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_signed_int
|
|
||||||
Description: Value must be an integer.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_signed_int_or_empty
|
|
||||||
Description: Value must be an integer, or blank.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_not_empty
|
|
||||||
Description: Value cannot be empty.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_port_number
|
|
||||||
Description: Value must be a valid port number (1024-65535), or zero to disable.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_ipaddrish_or_empty
|
|
||||||
Description: Value must be an IP address or empty.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_number
|
|
||||||
Description: Value must be a decimal number
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_number_or_empty
|
|
||||||
Description: Value must be a decimal number or empty.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_unsigned_number
|
|
||||||
Description: Value must be a non-negative number.
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_valid_gain
|
|
||||||
Description: Value must be a numeric gain value, or "max", or "agc".
|
|
||||||
Type: error
|
|
||||||
|
|
||||||
Template: dump1090-mutability/invalid-is_non_root_user
|
|
||||||
Description: Value must be a username (without spaces) that isn't root.
|
|
||||||
Type: error
|
|
|
@ -2,15 +2,10 @@
|
||||||
# and also to the dynamically-generated json parts that contain aircraft
|
# and also to the dynamically-generated json parts that contain aircraft
|
||||||
# data and are periodically written by the dump1090 daemon.
|
# data and are periodically written by the dump1090 daemon.
|
||||||
|
|
||||||
url.redirect += (
|
|
||||||
"^/dump1090/$" => "/dump1090/gmap.html",
|
|
||||||
"^/dump1090$" => "/dump1090/gmap.html"
|
|
||||||
)
|
|
||||||
|
|
||||||
alias.url += (
|
alias.url += (
|
||||||
"/dump1090/data/" => "/run/dump1090-mutability/",
|
"/dump1090-fa/data/" => "/run/dump1090-fa/",
|
||||||
"/dump1090/db/" => "/var/cache/dump1090-mutability/db/",
|
"/dump1090-fa/db/" => "/var/cache/dump1090-fa/db/",
|
||||||
"/dump1090/" => "/usr/share/dump1090-mutability/html/"
|
"/dump1090-fa/" => "/usr/share/dump1090-fa/html/"
|
||||||
)
|
)
|
||||||
|
|
||||||
# The stat cache must be disabled, as aircraft.json changes
|
# The stat cache must be disabled, as aircraft.json changes
|
19
debian/nginx/dump1090-mutability
vendored
19
debian/nginx/dump1090-mutability
vendored
|
@ -1,19 +0,0 @@
|
||||||
# Allows access to the static files that provide the dump1090 map view,
|
|
||||||
# and also to the dynamically-generated json parts that contain aircraft
|
|
||||||
# data and are periodically written by the dump1090 daemon.
|
|
||||||
#
|
|
||||||
server{
|
|
||||||
rewrite ^/dump1090/$ /dump1090/gmap.html permanent;
|
|
||||||
rewrite ^/dump1090$ /dump1090/gmap.html permanent;
|
|
||||||
|
|
||||||
location /dump1090/ {
|
|
||||||
alias /usr/share/dump1090-mutability/html/;
|
|
||||||
}
|
|
||||||
location /dump1090/data/ {
|
|
||||||
alias /run/dump1090-mutability/;
|
|
||||||
}
|
|
||||||
location /dump1090/db/ {
|
|
||||||
alias /var/cache/dump1090-mutability/db/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
10
debian/rules
vendored
10
debian/rules
vendored
|
@ -18,13 +18,13 @@ export DUMP1090_VERSION=$(shell dpkg-parsechangelog | sed -n 's/^Version: /v/p')
|
||||||
SRCNAME=$(shell dpkg-parsechangelog | sed -n 's/^Source: //p')
|
SRCNAME=$(shell dpkg-parsechangelog | sed -n 's/^Source: //p')
|
||||||
|
|
||||||
override_dh_auto_build:
|
override_dh_auto_build:
|
||||||
dh_auto_build -- 'EXTRACFLAGS=-DHTMLPATH=\"/usr/share/dump1090-mutability/html\" -DMODES_DUMP1090_VARIANT=\"$(SRCNAME)\"'
|
dh_auto_build -- 'EXTRACFLAGS=-DHTMLPATH=\"/usr/share/$(SRCNAME)/html\" -DMODES_DUMP1090_VARIANT=\"$(SRCNAME)\"'
|
||||||
|
|
||||||
override_dh_install:
|
override_dh_install:
|
||||||
dh_install
|
dh_install
|
||||||
install -d debian/dump1090-mutability/usr/bin
|
install -d debian/dump1090-fa/usr/bin
|
||||||
cp -a dump1090 debian/dump1090-mutability/usr/bin/dump1090-mutability
|
cp -a dump1090 debian/dump1090-fa/usr/bin/dump1090-fa
|
||||||
cp -a view1090 debian/dump1090-mutability/usr/bin/view1090-mutability
|
cp -a view1090 debian/dump1090-fa/usr/bin/view1090-fa
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@
|
dh $@ --with=systemd
|
||||||
|
|
|
@ -117,10 +117,10 @@ SiteCircles = true; // true to show circles (only shown if the center marker is
|
||||||
SiteCirclesDistances = new Array(100,150,200);
|
SiteCirclesDistances = new Array(100,150,200);
|
||||||
|
|
||||||
// Show the clocks at the top of the righthand pane? You can disable the clocks if you want here
|
// Show the clocks at the top of the righthand pane? You can disable the clocks if you want here
|
||||||
ShowClocks = true;
|
ShowClocks = false;
|
||||||
|
|
||||||
// Controls page title, righthand pane when nothing is selected
|
// Controls page title, righthand pane when nothing is selected
|
||||||
PageName = "DUMP1090";
|
PageName = "Piaware";
|
||||||
|
|
||||||
// Show country flags by ICAO addresses?
|
// Show country flags by ICAO addresses?
|
||||||
ShowFlags = true;
|
ShowFlags = true;
|
||||||
|
|
|
@ -1,318 +0,0 @@
|
||||||
/**
|
|
||||||
* CoolClock 2.1.4
|
|
||||||
* Copyright 2010, Simon Baird
|
|
||||||
* Released under the BSD License.
|
|
||||||
*
|
|
||||||
* Display an analog clock using canvas.
|
|
||||||
* http://randomibis.com/coolclock/
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Constructor for CoolClock objects
|
|
||||||
window.CoolClock = function(options) {
|
|
||||||
return this.init(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config contains some defaults, and clock skins
|
|
||||||
CoolClock.config = {
|
|
||||||
tickDelay: 1000,
|
|
||||||
longTickDelay: 15000,
|
|
||||||
defaultRadius: 85,
|
|
||||||
renderRadius: 100,
|
|
||||||
defaultSkin: "chunkySwiss",
|
|
||||||
// Should be in skin probably...
|
|
||||||
// (TODO: allow skinning of digital display)
|
|
||||||
showSecs: true,
|
|
||||||
showAmPm: true,
|
|
||||||
|
|
||||||
skins: {
|
|
||||||
// There are more skins in moreskins.js
|
|
||||||
// Try making your own skin by copy/pasting one of these and tweaking it
|
|
||||||
swissRail: {
|
|
||||||
outerBorder: { lineWidth: 2, radius:95, color: "black", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 88, endAt: 92, color: "black", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 4, startAt: 79, endAt: 92, color: "black", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
chunkySwiss: {
|
|
||||||
outerBorder: { lineWidth: 4, radius:97, color: "black", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
chunkySwissOnBlack: {
|
|
||||||
outerBorder: { lineWidth: 4, radius:97, color: "white", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "white", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "white", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "white", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "white", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
// Test for IE so we can nurse excanvas in a couple of places
|
|
||||||
isIE: !!document.all,
|
|
||||||
|
|
||||||
// Will store (a reference to) each clock here, indexed by the id of the canvas element
|
|
||||||
clockTracker: {},
|
|
||||||
|
|
||||||
// For giving a unique id to coolclock canvases with no id
|
|
||||||
noIdCount: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define the CoolClock object's methods
|
|
||||||
CoolClock.prototype = {
|
|
||||||
|
|
||||||
// Initialise using the parameters parsed from the colon delimited class
|
|
||||||
init: function(options) {
|
|
||||||
// Parse and store the options
|
|
||||||
this.canvasId = options.canvasId;
|
|
||||||
this.skinId = options.skinId || CoolClock.config.defaultSkin;
|
|
||||||
this.displayRadius = options.displayRadius || CoolClock.config.defaultRadius;
|
|
||||||
this.showSecondHand = typeof options.showSecondHand == "boolean" ? options.showSecondHand : true;
|
|
||||||
this.gmtOffset = (options.gmtOffset != null && options.gmtOffset != '') ? parseFloat(options.gmtOffset) : null;
|
|
||||||
this.showDigital = typeof options.showDigital == "boolean" ? options.showDigital : false;
|
|
||||||
this.logClock = typeof options.logClock == "boolean" ? options.logClock : false;
|
|
||||||
this.logClockRev = typeof options.logClock == "boolean" ? options.logClockRev : false;
|
|
||||||
|
|
||||||
this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay" ];
|
|
||||||
|
|
||||||
// Get the canvas element
|
|
||||||
this.canvas = document.getElementById(this.canvasId);
|
|
||||||
|
|
||||||
// Make the canvas the requested size. It's always square.
|
|
||||||
this.canvas.setAttribute("width",this.displayRadius*2);
|
|
||||||
this.canvas.setAttribute("height",this.displayRadius*2);
|
|
||||||
this.canvas.style.width = this.displayRadius*2 + "px";
|
|
||||||
this.canvas.style.height = this.displayRadius*2 + "px";
|
|
||||||
|
|
||||||
// Explain me please...?
|
|
||||||
this.renderRadius = CoolClock.config.renderRadius;
|
|
||||||
this.scale = this.displayRadius / this.renderRadius;
|
|
||||||
|
|
||||||
// Initialise canvas context
|
|
||||||
this.ctx = this.canvas.getContext("2d");
|
|
||||||
this.ctx.scale(this.scale,this.scale);
|
|
||||||
|
|
||||||
// Keep track of this object
|
|
||||||
CoolClock.config.clockTracker[this.canvasId] = this;
|
|
||||||
|
|
||||||
// Start the clock going
|
|
||||||
this.tick();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Draw a circle at point x,y with params as defined in skin
|
|
||||||
fullCircleAt: function(x,y,skin) {
|
|
||||||
this.ctx.save();
|
|
||||||
this.ctx.globalAlpha = skin.alpha;
|
|
||||||
this.ctx.lineWidth = skin.lineWidth;
|
|
||||||
|
|
||||||
if (!CoolClock.config.isIE) {
|
|
||||||
this.ctx.beginPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CoolClock.config.isIE) {
|
|
||||||
// excanvas doesn't scale line width so we will do it here
|
|
||||||
this.ctx.lineWidth = this.ctx.lineWidth * this.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ctx.arc(x, y, skin.radius, 0, 2*Math.PI, false);
|
|
||||||
|
|
||||||
if (CoolClock.config.isIE) {
|
|
||||||
// excanvas doesn't close the circle so let's fill in the tiny gap
|
|
||||||
this.ctx.arc(x, y, skin.radius, -0.1, 0.1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skin.fillColor) {
|
|
||||||
this.ctx.fillStyle = skin.fillColor
|
|
||||||
this.ctx.fill();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// XXX why not stroke and fill
|
|
||||||
this.ctx.strokeStyle = skin.color;
|
|
||||||
this.ctx.stroke();
|
|
||||||
}
|
|
||||||
this.ctx.restore();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Draw some text centered vertically and horizontally
|
|
||||||
drawTextAt: function(theText,x,y) {
|
|
||||||
this.ctx.save();
|
|
||||||
this.ctx.font = '15px sans-serif';
|
|
||||||
var tSize = this.ctx.measureText(theText);
|
|
||||||
if (!tSize.height) tSize.height = 15; // no height in firefox.. :(
|
|
||||||
this.ctx.fillText(theText,x - tSize.width/2,y - tSize.height/2);
|
|
||||||
this.ctx.restore();
|
|
||||||
},
|
|
||||||
|
|
||||||
lpad2: function(num) {
|
|
||||||
return (num < 10 ? '0' : '') + num;
|
|
||||||
},
|
|
||||||
|
|
||||||
tickAngle: function(second) {
|
|
||||||
// Log algorithm by David Bradshaw
|
|
||||||
var tweak = 3; // If it's lower the one second mark looks wrong (?)
|
|
||||||
if (this.logClock) {
|
|
||||||
return second == 0 ? 0 : (Math.log(second*tweak) / Math.log(60*tweak));
|
|
||||||
}
|
|
||||||
else if (this.logClockRev) {
|
|
||||||
// Flip the seconds then flip the angle (trickiness)
|
|
||||||
second = (60 - second) % 60;
|
|
||||||
return 1.0 - (second == 0 ? 0 : (Math.log(second*tweak) / Math.log(60*tweak)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return second/60.0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
timeText: function(hour,min,sec) {
|
|
||||||
var c = CoolClock.config;
|
|
||||||
return '' +
|
|
||||||
(c.showAmPm ? ((hour%12)==0 ? 12 : (hour%12)) : hour) + ':' +
|
|
||||||
this.lpad2(min) +
|
|
||||||
(c.showSecs ? ':' + this.lpad2(sec) : '') +
|
|
||||||
(c.showAmPm ? (hour < 12 ? ' am' : ' pm') : '')
|
|
||||||
;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Draw a radial line by rotating then drawing a straight line
|
|
||||||
// Ha ha, I think I've accidentally used Taus, (see http://tauday.com/)
|
|
||||||
radialLineAtAngle: function(angleFraction,skin) {
|
|
||||||
this.ctx.save();
|
|
||||||
this.ctx.translate(this.renderRadius,this.renderRadius);
|
|
||||||
this.ctx.rotate(Math.PI * (2.0 * angleFraction - 0.5));
|
|
||||||
this.ctx.globalAlpha = skin.alpha;
|
|
||||||
this.ctx.strokeStyle = skin.color;
|
|
||||||
this.ctx.lineWidth = skin.lineWidth;
|
|
||||||
|
|
||||||
if (CoolClock.config.isIE)
|
|
||||||
// excanvas doesn't scale line width so we will do it here
|
|
||||||
this.ctx.lineWidth = this.ctx.lineWidth * this.scale;
|
|
||||||
|
|
||||||
if (skin.radius) {
|
|
||||||
this.fullCircleAt(skin.startAt,0,skin)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.moveTo(skin.startAt,0)
|
|
||||||
this.ctx.lineTo(skin.endAt,0);
|
|
||||||
this.ctx.stroke();
|
|
||||||
}
|
|
||||||
this.ctx.restore();
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function(hour,min,sec) {
|
|
||||||
// Get the skin
|
|
||||||
var skin = CoolClock.config.skins[this.skinId];
|
|
||||||
if (!skin) skin = CoolClock.config.skins[CoolClock.config.defaultSkin];
|
|
||||||
|
|
||||||
// Clear
|
|
||||||
this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2);
|
|
||||||
|
|
||||||
// Draw the outer edge of the clock
|
|
||||||
if (skin.outerBorder)
|
|
||||||
this.fullCircleAt(this.renderRadius,this.renderRadius,skin.outerBorder);
|
|
||||||
|
|
||||||
// Draw the tick marks. Every 5th one is a big one
|
|
||||||
for (var i=0;i<60;i++) {
|
|
||||||
(i%5) && skin.smallIndicator && this.radialLineAtAngle(this.tickAngle(i),skin.smallIndicator);
|
|
||||||
!(i%5) && skin.largeIndicator && this.radialLineAtAngle(this.tickAngle(i),skin.largeIndicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the time
|
|
||||||
if (this.showDigital) {
|
|
||||||
this.drawTextAt(
|
|
||||||
this.timeText(hour,min,sec),
|
|
||||||
this.renderRadius,
|
|
||||||
this.renderRadius+this.renderRadius/2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the hands
|
|
||||||
if (skin.hourHand)
|
|
||||||
this.radialLineAtAngle(this.tickAngle(((hour%12)*5 + min/12.0)),skin.hourHand);
|
|
||||||
|
|
||||||
if (skin.minuteHand)
|
|
||||||
this.radialLineAtAngle(this.tickAngle((min + sec/60.0)),skin.minuteHand);
|
|
||||||
|
|
||||||
if (this.showSecondHand && skin.secondHand)
|
|
||||||
this.radialLineAtAngle(this.tickAngle(sec),skin.secondHand);
|
|
||||||
|
|
||||||
// Second hand decoration doesn't render right in IE so lets turn it off
|
|
||||||
if (!CoolClock.config.isIE && this.showSecondHand && skin.secondDecoration)
|
|
||||||
this.radialLineAtAngle(this.tickAngle(sec),skin.secondDecoration);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Check the time and display the clock
|
|
||||||
refreshDisplay: function() {
|
|
||||||
var now = new Date();
|
|
||||||
if (this.gmtOffset != null) {
|
|
||||||
// Use GMT + gmtOffset
|
|
||||||
var offsetNow = new Date(now.valueOf() + (this.gmtOffset * 1000 * 60 * 60));
|
|
||||||
this.render(offsetNow.getUTCHours(),offsetNow.getUTCMinutes(),offsetNow.getUTCSeconds());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Use local time
|
|
||||||
this.render(now.getHours(),now.getMinutes(),now.getSeconds());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Set timeout to trigger a tick in the future
|
|
||||||
nextTick: function() {
|
|
||||||
setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Check the canvas element hasn't been removed
|
|
||||||
stillHere: function() {
|
|
||||||
return document.getElementById(this.canvasId) != null;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Main tick handler. Refresh the clock then setup the next tick
|
|
||||||
tick: function() {
|
|
||||||
if (this.stillHere()) {
|
|
||||||
this.refreshDisplay()
|
|
||||||
this.nextTick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find all canvas elements that have the CoolClock class and turns them into clocks
|
|
||||||
CoolClock.findAndCreateClocks = function() {
|
|
||||||
// (Let's not use a jQuery selector here so it's easier to use frameworks other than jQuery)
|
|
||||||
var canvases = document.getElementsByTagName("canvas");
|
|
||||||
for (var i=0;i<canvases.length;i++) {
|
|
||||||
// Pull out the fields from the class. Example "CoolClock:chunkySwissOnBlack:1000"
|
|
||||||
var fields = canvases[i].className.split(" ")[0].split(":");
|
|
||||||
if (fields[0] == "CoolClock") {
|
|
||||||
if (!canvases[i].id) {
|
|
||||||
// If there's no id on this canvas element then give it one
|
|
||||||
canvases[i].id = '_coolclock_auto_id_' + CoolClock.config.noIdCount++;
|
|
||||||
}
|
|
||||||
// Create a clock object for this element
|
|
||||||
new CoolClock({
|
|
||||||
canvasId: canvases[i].id,
|
|
||||||
skinId: fields[1],
|
|
||||||
displayRadius: fields[2],
|
|
||||||
showSecondHand: fields[3]!='noSeconds',
|
|
||||||
gmtOffset: fields[4],
|
|
||||||
showDigital: fields[5]=='showDigital',
|
|
||||||
logClock: fields[6]=='logClock',
|
|
||||||
logClockRev: fields[6]=='logClockRev'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// If you don't have jQuery then you need a body onload like this: <body onload="CoolClock.findAndCreateClocks()">
|
|
||||||
// If you do have jQuery and it's loaded already then we can do it right now
|
|
||||||
if (window.jQuery) jQuery(document).ready(CoolClock.findAndCreateClocks);
|
|
|
@ -1,785 +0,0 @@
|
||||||
// Copyright 2006 Google Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
// Known Issues:
|
|
||||||
//
|
|
||||||
// * Patterns are not implemented.
|
|
||||||
// * Radial gradient are not implemented. The VML version of these look very
|
|
||||||
// different from the canvas one.
|
|
||||||
// * Clipping paths are not implemented.
|
|
||||||
// * Coordsize. The width and height attribute have higher priority than the
|
|
||||||
// width and height style values which isn't correct.
|
|
||||||
// * Painting mode isn't implemented.
|
|
||||||
// * Canvas width/height should is using content-box by default. IE in
|
|
||||||
// Quirks mode will draw the canvas using border-box. Either change your
|
|
||||||
// doctype to HTML5
|
|
||||||
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
|
|
||||||
// or use Box Sizing Behavior from WebFX
|
|
||||||
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
|
|
||||||
// * Optimize. There is always room for speed improvements.
|
|
||||||
|
|
||||||
// only add this code if we do not already have a canvas implementation
|
|
||||||
if (!window.CanvasRenderingContext2D) {
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
// alias some functions to make (compiled) code shorter
|
|
||||||
var m = Math;
|
|
||||||
var mr = m.round;
|
|
||||||
var ms = m.sin;
|
|
||||||
var mc = m.cos;
|
|
||||||
|
|
||||||
// this is used for sub pixel precision
|
|
||||||
var Z = 10;
|
|
||||||
var Z2 = Z / 2;
|
|
||||||
|
|
||||||
var G_vmlCanvasManager_ = {
|
|
||||||
init: function (opt_doc) {
|
|
||||||
var doc = opt_doc || document;
|
|
||||||
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
|
|
||||||
var self = this;
|
|
||||||
doc.attachEvent("onreadystatechange", function () {
|
|
||||||
self.init_(doc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
init_: function (doc) {
|
|
||||||
if (doc.readyState == "complete") {
|
|
||||||
// create xmlns
|
|
||||||
if (!doc.namespaces["g_vml_"]) {
|
|
||||||
doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup default css
|
|
||||||
var ss = doc.createStyleSheet();
|
|
||||||
ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
|
|
||||||
// default size is 300x150 in Gecko and Opera
|
|
||||||
"text-align:left;width:300px;height:150px}" +
|
|
||||||
"g_vml_\\:*{behavior:url(#default#VML)}";
|
|
||||||
|
|
||||||
// find all canvas elements
|
|
||||||
var els = doc.getElementsByTagName("canvas");
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
if (!els[i].getContext) {
|
|
||||||
this.initElement(els[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fixElement_: function (el) {
|
|
||||||
// in IE before version 5.5 we would need to add HTML: to the tag name
|
|
||||||
// but we do not care about IE before version 6
|
|
||||||
var outerHTML = el.outerHTML;
|
|
||||||
|
|
||||||
var newEl = el.ownerDocument.createElement(outerHTML);
|
|
||||||
// if the tag is still open IE has created the children as siblings and
|
|
||||||
// it has also created a tag with the name "/FOO"
|
|
||||||
if (outerHTML.slice(-2) != "/>") {
|
|
||||||
var tagName = "/" + el.tagName;
|
|
||||||
var ns;
|
|
||||||
// remove content
|
|
||||||
while ((ns = el.nextSibling) && ns.tagName != tagName) {
|
|
||||||
ns.removeNode();
|
|
||||||
}
|
|
||||||
// remove the incorrect closing tag
|
|
||||||
if (ns) {
|
|
||||||
ns.removeNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
el.parentNode.replaceChild(newEl, el);
|
|
||||||
return newEl;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public initializes a canvas element so that it can be used as canvas
|
|
||||||
* element from now on. This is called automatically before the page is
|
|
||||||
* loaded but if you are creating elements using createElement you need to
|
|
||||||
* make sure this is called on the element.
|
|
||||||
* @param {HTMLElement} el The canvas element to initialize.
|
|
||||||
* @return {HTMLElement} the element that was created.
|
|
||||||
*/
|
|
||||||
initElement: function (el) {
|
|
||||||
el = this.fixElement_(el);
|
|
||||||
el.getContext = function () {
|
|
||||||
if (this.context_) {
|
|
||||||
return this.context_;
|
|
||||||
}
|
|
||||||
return this.context_ = new CanvasRenderingContext2D_(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
// do not use inline function because that will leak memory
|
|
||||||
el.attachEvent('onpropertychange', onPropertyChange);
|
|
||||||
el.attachEvent('onresize', onResize);
|
|
||||||
|
|
||||||
var attrs = el.attributes;
|
|
||||||
if (attrs.width && attrs.width.specified) {
|
|
||||||
// TODO: use runtimeStyle and coordsize
|
|
||||||
// el.getContext().setWidth_(attrs.width.nodeValue);
|
|
||||||
el.style.width = attrs.width.nodeValue + "px";
|
|
||||||
} else {
|
|
||||||
el.width = el.clientWidth;
|
|
||||||
}
|
|
||||||
if (attrs.height && attrs.height.specified) {
|
|
||||||
// TODO: use runtimeStyle and coordsize
|
|
||||||
// el.getContext().setHeight_(attrs.height.nodeValue);
|
|
||||||
el.style.height = attrs.height.nodeValue + "px";
|
|
||||||
} else {
|
|
||||||
el.height = el.clientHeight;
|
|
||||||
}
|
|
||||||
//el.getContext().setCoordsize_()
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function onPropertyChange(e) {
|
|
||||||
var el = e.srcElement;
|
|
||||||
|
|
||||||
switch (e.propertyName) {
|
|
||||||
case 'width':
|
|
||||||
el.style.width = el.attributes.width.nodeValue + "px";
|
|
||||||
el.getContext().clearRect();
|
|
||||||
break;
|
|
||||||
case 'height':
|
|
||||||
el.style.height = el.attributes.height.nodeValue + "px";
|
|
||||||
el.getContext().clearRect();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onResize(e) {
|
|
||||||
var el = e.srcElement;
|
|
||||||
if (el.firstChild) {
|
|
||||||
el.firstChild.style.width = el.clientWidth + 'px';
|
|
||||||
el.firstChild.style.height = el.clientHeight + 'px';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
G_vmlCanvasManager_.init();
|
|
||||||
|
|
||||||
// precompute "00" to "FF"
|
|
||||||
var dec2hex = [];
|
|
||||||
for (var i = 0; i < 16; i++) {
|
|
||||||
for (var j = 0; j < 16; j++) {
|
|
||||||
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMatrixIdentity() {
|
|
||||||
return [
|
|
||||||
[1, 0, 0],
|
|
||||||
[0, 1, 0],
|
|
||||||
[0, 0, 1]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function matrixMultiply(m1, m2) {
|
|
||||||
var result = createMatrixIdentity();
|
|
||||||
|
|
||||||
for (var x = 0; x < 3; x++) {
|
|
||||||
for (var y = 0; y < 3; y++) {
|
|
||||||
var sum = 0;
|
|
||||||
|
|
||||||
for (var z = 0; z < 3; z++) {
|
|
||||||
sum += m1[x][z] * m2[z][y];
|
|
||||||
}
|
|
||||||
|
|
||||||
result[x][y] = sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyState(o1, o2) {
|
|
||||||
o2.fillStyle = o1.fillStyle;
|
|
||||||
o2.lineCap = o1.lineCap;
|
|
||||||
o2.lineJoin = o1.lineJoin;
|
|
||||||
o2.lineWidth = o1.lineWidth;
|
|
||||||
o2.miterLimit = o1.miterLimit;
|
|
||||||
o2.shadowBlur = o1.shadowBlur;
|
|
||||||
o2.shadowColor = o1.shadowColor;
|
|
||||||
o2.shadowOffsetX = o1.shadowOffsetX;
|
|
||||||
o2.shadowOffsetY = o1.shadowOffsetY;
|
|
||||||
o2.strokeStyle = o1.strokeStyle;
|
|
||||||
o2.arcScaleX_ = o1.arcScaleX_;
|
|
||||||
o2.arcScaleY_ = o1.arcScaleY_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processStyle(styleString) {
|
|
||||||
var str, alpha = 1;
|
|
||||||
|
|
||||||
styleString = String(styleString);
|
|
||||||
if (styleString.substring(0, 3) == "rgb") {
|
|
||||||
var start = styleString.indexOf("(", 3);
|
|
||||||
var end = styleString.indexOf(")", start + 1);
|
|
||||||
var guts = styleString.substring(start + 1, end).split(",");
|
|
||||||
|
|
||||||
str = "#";
|
|
||||||
for (var i = 0; i < 3; i++) {
|
|
||||||
str += dec2hex[Number(guts[i])];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
|
|
||||||
alpha = guts[3];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = styleString;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [str, alpha];
|
|
||||||
}
|
|
||||||
|
|
||||||
function processLineCap(lineCap) {
|
|
||||||
switch (lineCap) {
|
|
||||||
case "butt":
|
|
||||||
return "flat";
|
|
||||||
case "round":
|
|
||||||
return "round";
|
|
||||||
case "square":
|
|
||||||
default:
|
|
||||||
return "square";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements CanvasRenderingContext2D interface as described by
|
|
||||||
* the WHATWG.
|
|
||||||
* @param {HTMLElement} surfaceElement The element that the 2D context should
|
|
||||||
* be associated with
|
|
||||||
*/
|
|
||||||
function CanvasRenderingContext2D_(surfaceElement) {
|
|
||||||
this.m_ = createMatrixIdentity();
|
|
||||||
|
|
||||||
this.mStack_ = [];
|
|
||||||
this.aStack_ = [];
|
|
||||||
this.currentPath_ = [];
|
|
||||||
|
|
||||||
// Canvas context properties
|
|
||||||
this.strokeStyle = "#000";
|
|
||||||
this.fillStyle = "#000";
|
|
||||||
|
|
||||||
this.lineWidth = 1;
|
|
||||||
this.lineJoin = "miter";
|
|
||||||
this.lineCap = "butt";
|
|
||||||
this.miterLimit = Z * 1;
|
|
||||||
this.globalAlpha = 1;
|
|
||||||
this.canvas = surfaceElement;
|
|
||||||
|
|
||||||
var el = surfaceElement.ownerDocument.createElement('div');
|
|
||||||
el.style.width = surfaceElement.clientWidth + 'px';
|
|
||||||
el.style.height = surfaceElement.clientHeight + 'px';
|
|
||||||
el.style.overflow = 'hidden';
|
|
||||||
el.style.position = 'absolute';
|
|
||||||
surfaceElement.appendChild(el);
|
|
||||||
|
|
||||||
this.element_ = el;
|
|
||||||
this.arcScaleX_ = 1;
|
|
||||||
this.arcScaleY_ = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
var contextPrototype = CanvasRenderingContext2D_.prototype;
|
|
||||||
contextPrototype.clearRect = function() {
|
|
||||||
this.element_.innerHTML = "";
|
|
||||||
this.currentPath_ = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.beginPath = function() {
|
|
||||||
// TODO: Branch current matrix so that save/restore has no effect
|
|
||||||
// as per safari docs.
|
|
||||||
|
|
||||||
this.currentPath_ = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.moveTo = function(aX, aY) {
|
|
||||||
this.currentPath_.push({type: "moveTo", x: aX, y: aY});
|
|
||||||
this.currentX_ = aX;
|
|
||||||
this.currentY_ = aY;
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.lineTo = function(aX, aY) {
|
|
||||||
this.currentPath_.push({type: "lineTo", x: aX, y: aY});
|
|
||||||
this.currentX_ = aX;
|
|
||||||
this.currentY_ = aY;
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
|
|
||||||
aCP2x, aCP2y,
|
|
||||||
aX, aY) {
|
|
||||||
this.currentPath_.push({type: "bezierCurveTo",
|
|
||||||
cp1x: aCP1x,
|
|
||||||
cp1y: aCP1y,
|
|
||||||
cp2x: aCP2x,
|
|
||||||
cp2y: aCP2y,
|
|
||||||
x: aX,
|
|
||||||
y: aY});
|
|
||||||
this.currentX_ = aX;
|
|
||||||
this.currentY_ = aY;
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
|
|
||||||
// the following is lifted almost directly from
|
|
||||||
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
|
|
||||||
var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
|
|
||||||
var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
|
|
||||||
var cp2x = cp1x + (aX - this.currentX_) / 3.0;
|
|
||||||
var cp2y = cp1y + (aY - this.currentY_) / 3.0;
|
|
||||||
this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.arc = function(aX, aY, aRadius,
|
|
||||||
aStartAngle, aEndAngle, aClockwise) {
|
|
||||||
aRadius *= Z;
|
|
||||||
var arcType = aClockwise ? "at" : "wa";
|
|
||||||
|
|
||||||
var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
|
|
||||||
var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;
|
|
||||||
|
|
||||||
var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
|
|
||||||
var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;
|
|
||||||
|
|
||||||
// IE won't render arches drawn counter clockwise if xStart == xEnd.
|
|
||||||
if (xStart == xEnd && !aClockwise) {
|
|
||||||
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
|
|
||||||
// that can be represented in binary
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentPath_.push({type: arcType,
|
|
||||||
x: aX,
|
|
||||||
y: aY,
|
|
||||||
radius: aRadius,
|
|
||||||
xStart: xStart,
|
|
||||||
yStart: yStart,
|
|
||||||
xEnd: xEnd,
|
|
||||||
yEnd: yEnd});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
|
|
||||||
this.moveTo(aX, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY + aHeight);
|
|
||||||
this.lineTo(aX, aY + aHeight);
|
|
||||||
this.closePath();
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
|
|
||||||
// Will destroy any existing path (same as FF behaviour)
|
|
||||||
this.beginPath();
|
|
||||||
this.moveTo(aX, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY + aHeight);
|
|
||||||
this.lineTo(aX, aY + aHeight);
|
|
||||||
this.closePath();
|
|
||||||
this.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
|
|
||||||
// Will destroy any existing path (same as FF behaviour)
|
|
||||||
this.beginPath();
|
|
||||||
this.moveTo(aX, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY);
|
|
||||||
this.lineTo(aX + aWidth, aY + aHeight);
|
|
||||||
this.lineTo(aX, aY + aHeight);
|
|
||||||
this.closePath();
|
|
||||||
this.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
|
|
||||||
var gradient = new CanvasGradient_("gradient");
|
|
||||||
return gradient;
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.createRadialGradient = function(aX0, aY0,
|
|
||||||
aR0, aX1,
|
|
||||||
aY1, aR1) {
|
|
||||||
var gradient = new CanvasGradient_("gradientradial");
|
|
||||||
gradient.radius1_ = aR0;
|
|
||||||
gradient.radius2_ = aR1;
|
|
||||||
gradient.focus_.x = aX0;
|
|
||||||
gradient.focus_.y = aY0;
|
|
||||||
return gradient;
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.drawImage = function (image, var_args) {
|
|
||||||
var dx, dy, dw, dh, sx, sy, sw, sh;
|
|
||||||
|
|
||||||
// to find the original width we overide the width and height
|
|
||||||
var oldRuntimeWidth = image.runtimeStyle.width;
|
|
||||||
var oldRuntimeHeight = image.runtimeStyle.height;
|
|
||||||
image.runtimeStyle.width = 'auto';
|
|
||||||
image.runtimeStyle.height = 'auto';
|
|
||||||
|
|
||||||
// get the original size
|
|
||||||
var w = image.width;
|
|
||||||
var h = image.height;
|
|
||||||
|
|
||||||
// and remove overides
|
|
||||||
image.runtimeStyle.width = oldRuntimeWidth;
|
|
||||||
image.runtimeStyle.height = oldRuntimeHeight;
|
|
||||||
|
|
||||||
if (arguments.length == 3) {
|
|
||||||
dx = arguments[1];
|
|
||||||
dy = arguments[2];
|
|
||||||
sx = sy = 0;
|
|
||||||
sw = dw = w;
|
|
||||||
sh = dh = h;
|
|
||||||
} else if (arguments.length == 5) {
|
|
||||||
dx = arguments[1];
|
|
||||||
dy = arguments[2];
|
|
||||||
dw = arguments[3];
|
|
||||||
dh = arguments[4];
|
|
||||||
sx = sy = 0;
|
|
||||||
sw = w;
|
|
||||||
sh = h;
|
|
||||||
} else if (arguments.length == 9) {
|
|
||||||
sx = arguments[1];
|
|
||||||
sy = arguments[2];
|
|
||||||
sw = arguments[3];
|
|
||||||
sh = arguments[4];
|
|
||||||
dx = arguments[5];
|
|
||||||
dy = arguments[6];
|
|
||||||
dw = arguments[7];
|
|
||||||
dh = arguments[8];
|
|
||||||
} else {
|
|
||||||
throw "Invalid number of arguments";
|
|
||||||
}
|
|
||||||
|
|
||||||
var d = this.getCoords_(dx, dy);
|
|
||||||
|
|
||||||
var w2 = sw / 2;
|
|
||||||
var h2 = sh / 2;
|
|
||||||
|
|
||||||
var vmlStr = [];
|
|
||||||
|
|
||||||
var W = 10;
|
|
||||||
var H = 10;
|
|
||||||
|
|
||||||
// For some reason that I've now forgotten, using divs didn't work
|
|
||||||
vmlStr.push(' <g_vml_:group',
|
|
||||||
' coordsize="', Z * W, ',', Z * H, '"',
|
|
||||||
' coordorigin="0,0"' ,
|
|
||||||
' style="width:', W, ';height:', H, ';position:absolute;');
|
|
||||||
|
|
||||||
// If filters are necessary (rotation exists), create them
|
|
||||||
// filters are bog-slow, so only create them if abbsolutely necessary
|
|
||||||
// The following check doesn't account for skews (which don't exist
|
|
||||||
// in the canvas spec (yet) anyway.
|
|
||||||
|
|
||||||
if (this.m_[0][0] != 1 || this.m_[0][1]) {
|
|
||||||
var filter = [];
|
|
||||||
|
|
||||||
// Note the 12/21 reversal
|
|
||||||
filter.push("M11='", this.m_[0][0], "',",
|
|
||||||
"M12='", this.m_[1][0], "',",
|
|
||||||
"M21='", this.m_[0][1], "',",
|
|
||||||
"M22='", this.m_[1][1], "',",
|
|
||||||
"Dx='", mr(d.x / Z), "',",
|
|
||||||
"Dy='", mr(d.y / Z), "'");
|
|
||||||
|
|
||||||
// Bounding box calculation (need to minimize displayed area so that
|
|
||||||
// filters don't waste time on unused pixels.
|
|
||||||
var max = d;
|
|
||||||
var c2 = this.getCoords_(dx + dw, dy);
|
|
||||||
var c3 = this.getCoords_(dx, dy + dh);
|
|
||||||
var c4 = this.getCoords_(dx + dw, dy + dh);
|
|
||||||
|
|
||||||
max.x = Math.max(max.x, c2.x, c3.x, c4.x);
|
|
||||||
max.y = Math.max(max.y, c2.y, c3.y, c4.y);
|
|
||||||
|
|
||||||
vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
|
|
||||||
"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
|
|
||||||
filter.join(""), ", sizingmethod='clip');")
|
|
||||||
} else {
|
|
||||||
vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;")
|
|
||||||
}
|
|
||||||
|
|
||||||
vmlStr.push(' ">' ,
|
|
||||||
'<g_vml_:image src="', image.src, '"',
|
|
||||||
' style="width:', Z * dw, ';',
|
|
||||||
' height:', Z * dh, ';"',
|
|
||||||
' cropleft="', sx / w, '"',
|
|
||||||
' croptop="', sy / h, '"',
|
|
||||||
' cropright="', (w - sx - sw) / w, '"',
|
|
||||||
' cropbottom="', (h - sy - sh) / h, '"',
|
|
||||||
' />',
|
|
||||||
'</g_vml_:group>');
|
|
||||||
|
|
||||||
this.element_.insertAdjacentHTML("BeforeEnd",
|
|
||||||
vmlStr.join(""));
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.stroke = function(aFill) {
|
|
||||||
var lineStr = [];
|
|
||||||
var lineOpen = false;
|
|
||||||
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
|
|
||||||
var color = a[0];
|
|
||||||
var opacity = a[1] * this.globalAlpha;
|
|
||||||
|
|
||||||
var W = 10;
|
|
||||||
var H = 10;
|
|
||||||
|
|
||||||
lineStr.push('<g_vml_:shape',
|
|
||||||
' fillcolor="', color, '"',
|
|
||||||
' filled="', Boolean(aFill), '"',
|
|
||||||
' style="position:absolute;width:', W, ';height:', H, ';"',
|
|
||||||
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
|
|
||||||
' stroked="', !aFill, '"',
|
|
||||||
' strokeweight="', this.lineWidth, '"',
|
|
||||||
' strokecolor="', color, '"',
|
|
||||||
' path="');
|
|
||||||
|
|
||||||
var newSeq = false;
|
|
||||||
var min = {x: null, y: null};
|
|
||||||
var max = {x: null, y: null};
|
|
||||||
|
|
||||||
for (var i = 0; i < this.currentPath_.length; i++) {
|
|
||||||
var p = this.currentPath_[i];
|
|
||||||
|
|
||||||
if (p.type == "moveTo") {
|
|
||||||
lineStr.push(" m ");
|
|
||||||
var c = this.getCoords_(p.x, p.y);
|
|
||||||
lineStr.push(mr(c.x), ",", mr(c.y));
|
|
||||||
} else if (p.type == "lineTo") {
|
|
||||||
lineStr.push(" l ");
|
|
||||||
var c = this.getCoords_(p.x, p.y);
|
|
||||||
lineStr.push(mr(c.x), ",", mr(c.y));
|
|
||||||
} else if (p.type == "close") {
|
|
||||||
lineStr.push(" x ");
|
|
||||||
} else if (p.type == "bezierCurveTo") {
|
|
||||||
lineStr.push(" c ");
|
|
||||||
var c = this.getCoords_(p.x, p.y);
|
|
||||||
var c1 = this.getCoords_(p.cp1x, p.cp1y);
|
|
||||||
var c2 = this.getCoords_(p.cp2x, p.cp2y);
|
|
||||||
lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
|
|
||||||
mr(c2.x), ",", mr(c2.y), ",",
|
|
||||||
mr(c.x), ",", mr(c.y));
|
|
||||||
} else if (p.type == "at" || p.type == "wa") {
|
|
||||||
lineStr.push(" ", p.type, " ");
|
|
||||||
var c = this.getCoords_(p.x, p.y);
|
|
||||||
var cStart = this.getCoords_(p.xStart, p.yStart);
|
|
||||||
var cEnd = this.getCoords_(p.xEnd, p.yEnd);
|
|
||||||
|
|
||||||
lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
|
|
||||||
mr(c.y - this.arcScaleY_ * p.radius), " ",
|
|
||||||
mr(c.x + this.arcScaleX_ * p.radius), ",",
|
|
||||||
mr(c.y + this.arcScaleY_ * p.radius), " ",
|
|
||||||
mr(cStart.x), ",", mr(cStart.y), " ",
|
|
||||||
mr(cEnd.x), ",", mr(cEnd.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Following is broken for curves due to
|
|
||||||
// move to proper paths.
|
|
||||||
|
|
||||||
// Figure out dimensions so we can do gradient fills
|
|
||||||
// properly
|
|
||||||
if(c) {
|
|
||||||
if (min.x == null || c.x < min.x) {
|
|
||||||
min.x = c.x;
|
|
||||||
}
|
|
||||||
if (max.x == null || c.x > max.x) {
|
|
||||||
max.x = c.x;
|
|
||||||
}
|
|
||||||
if (min.y == null || c.y < min.y) {
|
|
||||||
min.y = c.y;
|
|
||||||
}
|
|
||||||
if (max.y == null || c.y > max.y) {
|
|
||||||
max.y = c.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lineStr.push(' ">');
|
|
||||||
|
|
||||||
if (typeof this.fillStyle == "object") {
|
|
||||||
var focus = {x: "50%", y: "50%"};
|
|
||||||
var width = (max.x - min.x);
|
|
||||||
var height = (max.y - min.y);
|
|
||||||
var dimension = (width > height) ? width : height;
|
|
||||||
|
|
||||||
focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
|
|
||||||
focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";
|
|
||||||
|
|
||||||
var colors = [];
|
|
||||||
|
|
||||||
// inside radius (%)
|
|
||||||
if (this.fillStyle.type_ == "gradientradial") {
|
|
||||||
var inside = (this.fillStyle.radius1_ / dimension * 100);
|
|
||||||
|
|
||||||
// percentage that outside radius exceeds inside radius
|
|
||||||
var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
|
|
||||||
} else {
|
|
||||||
var inside = 0;
|
|
||||||
var expansion = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
var insidecolor = {offset: null, color: null};
|
|
||||||
var outsidecolor = {offset: null, color: null};
|
|
||||||
|
|
||||||
// We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
|
|
||||||
// won't interpret it correctly
|
|
||||||
this.fillStyle.colors_.sort(function (cs1, cs2) {
|
|
||||||
return cs1.offset - cs2.offset;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var i = 0; i < this.fillStyle.colors_.length; i++) {
|
|
||||||
var fs = this.fillStyle.colors_[i];
|
|
||||||
|
|
||||||
colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
|
|
||||||
|
|
||||||
if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
|
|
||||||
insidecolor.offset = fs.offset;
|
|
||||||
insidecolor.color = fs.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
|
|
||||||
outsidecolor.offset = fs.offset;
|
|
||||||
outsidecolor.color = fs.color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
colors.pop();
|
|
||||||
|
|
||||||
lineStr.push('<g_vml_:fill',
|
|
||||||
' color="', outsidecolor.color, '"',
|
|
||||||
' color2="', insidecolor.color, '"',
|
|
||||||
' type="', this.fillStyle.type_, '"',
|
|
||||||
' focusposition="', focus.x, ', ', focus.y, '"',
|
|
||||||
' colors="', colors.join(""), '"',
|
|
||||||
' opacity="', opacity, '" />');
|
|
||||||
} else if (aFill) {
|
|
||||||
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
|
|
||||||
} else {
|
|
||||||
lineStr.push(
|
|
||||||
'<g_vml_:stroke',
|
|
||||||
' opacity="', opacity,'"',
|
|
||||||
' joinstyle="', this.lineJoin, '"',
|
|
||||||
' miterlimit="', this.miterLimit, '"',
|
|
||||||
' endcap="', processLineCap(this.lineCap) ,'"',
|
|
||||||
' weight="', this.lineWidth, 'px"',
|
|
||||||
' color="', color,'" />'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
lineStr.push("</g_vml_:shape>");
|
|
||||||
|
|
||||||
this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));
|
|
||||||
|
|
||||||
this.currentPath_ = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.fill = function() {
|
|
||||||
this.stroke(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
contextPrototype.closePath = function() {
|
|
||||||
this.currentPath_.push({type: "close"});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
contextPrototype.getCoords_ = function(aX, aY) {
|
|
||||||
return {
|
|
||||||
x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
|
|
||||||
y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.save = function() {
|
|
||||||
var o = {};
|
|
||||||
copyState(this, o);
|
|
||||||
this.aStack_.push(o);
|
|
||||||
this.mStack_.push(this.m_);
|
|
||||||
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.restore = function() {
|
|
||||||
copyState(this.aStack_.pop(), this);
|
|
||||||
this.m_ = this.mStack_.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.translate = function(aX, aY) {
|
|
||||||
var m1 = [
|
|
||||||
[1, 0, 0],
|
|
||||||
[0, 1, 0],
|
|
||||||
[aX, aY, 1]
|
|
||||||
];
|
|
||||||
|
|
||||||
this.m_ = matrixMultiply(m1, this.m_);
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.rotate = function(aRot) {
|
|
||||||
var c = mc(aRot);
|
|
||||||
var s = ms(aRot);
|
|
||||||
|
|
||||||
var m1 = [
|
|
||||||
[c, s, 0],
|
|
||||||
[-s, c, 0],
|
|
||||||
[0, 0, 1]
|
|
||||||
];
|
|
||||||
|
|
||||||
this.m_ = matrixMultiply(m1, this.m_);
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.scale = function(aX, aY) {
|
|
||||||
this.arcScaleX_ *= aX;
|
|
||||||
this.arcScaleY_ *= aY;
|
|
||||||
var m1 = [
|
|
||||||
[aX, 0, 0],
|
|
||||||
[0, aY, 0],
|
|
||||||
[0, 0, 1]
|
|
||||||
];
|
|
||||||
|
|
||||||
this.m_ = matrixMultiply(m1, this.m_);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******** STUBS ********/
|
|
||||||
contextPrototype.clip = function() {
|
|
||||||
// TODO: Implement
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.arcTo = function() {
|
|
||||||
// TODO: Implement
|
|
||||||
};
|
|
||||||
|
|
||||||
contextPrototype.createPattern = function() {
|
|
||||||
return new CanvasPattern_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Gradient / Pattern Stubs
|
|
||||||
function CanvasGradient_(aType) {
|
|
||||||
this.type_ = aType;
|
|
||||||
this.radius1_ = 0;
|
|
||||||
this.radius2_ = 0;
|
|
||||||
this.colors_ = [];
|
|
||||||
this.focus_ = {x: 0, y: 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
|
|
||||||
aColor = processStyle(aColor);
|
|
||||||
this.colors_.push({offset: 1-aOffset, color: aColor});
|
|
||||||
};
|
|
||||||
|
|
||||||
function CanvasPattern_() {}
|
|
||||||
|
|
||||||
// set up externs
|
|
||||||
G_vmlCanvasManager = G_vmlCanvasManager_;
|
|
||||||
CanvasRenderingContext2D = CanvasRenderingContext2D_;
|
|
||||||
CanvasGradient = CanvasGradient_;
|
|
||||||
CanvasPattern = CanvasPattern_;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
} // if
|
|
|
@ -1,212 +0,0 @@
|
||||||
CoolClock.config.skins = {
|
|
||||||
|
|
||||||
swissRail: {
|
|
||||||
outerBorder: { lineWidth: 2, radius: 95, color: "black", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 88, endAt: 92, color: "black", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 4, startAt: 79, endAt: 92, color: "black", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
chunkySwiss: {
|
|
||||||
outerBorder: { lineWidth: 4, radius: 97, color: "black", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
chunkySwissOnBlack: {
|
|
||||||
outerBorder: { lineWidth: 4, radius: 97, color: "white", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "white", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "white", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "white", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "white", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
fancy: {
|
|
||||||
outerBorder: { lineWidth: 5, radius: 95, color: "green", alpha: 0.7 },
|
|
||||||
smallIndicator: { lineWidth: 1, startAt: 80, endAt: 93, color: "black", alpha: 0.4 },
|
|
||||||
largeIndicator: { lineWidth: 1, startAt: 30, endAt: 93, color: "black", alpha: 0.5 },
|
|
||||||
hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "blue", alpha: 0.7 },
|
|
||||||
minuteHand: { lineWidth: 7, startAt: -15, endAt: 92, color: "red", alpha: 0.7 },
|
|
||||||
secondHand: { lineWidth: 10, startAt: 80, endAt: 85, color: "blue", alpha: 0.3 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 30, radius: 50, fillColor: "blue", color: "red", alpha: 0.15 }
|
|
||||||
},
|
|
||||||
|
|
||||||
machine: {
|
|
||||||
outerBorder: { lineWidth: 60, radius: 55, color: "#dd6655", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 4, startAt: 80, endAt: 95, color: "white", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 14, startAt: 77, endAt: 92, color: "#dd6655", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 18, startAt: -15, endAt: 40, color: "white", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 14, startAt: 24, endAt: 100, color: "#771100", alpha: 0.5 },
|
|
||||||
secondHand: { lineWidth: 3, startAt: 22, endAt: 83, color: "green", alpha: 0 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 52, radius: 26, fillColor: "#ffcccc", color: "red", alpha: 0.5 }
|
|
||||||
},
|
|
||||||
|
|
||||||
simonbaird_com: {
|
|
||||||
hourHand: { lineWidth: 80, startAt: -15, endAt: 35, color: 'magenta', alpha: 0.5 },
|
|
||||||
minuteHand: { lineWidth: 80, startAt: -15, endAt: 65, color: 'cyan', alpha: 0.5 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 40, radius: 40, color: "#fff", fillColor: 'yellow', alpha: 0.5 }
|
|
||||||
},
|
|
||||||
|
|
||||||
// by bonstio, http://bonstio.net
|
|
||||||
classic/*was gIG*/: {
|
|
||||||
outerBorder: { lineWidth: 185, radius: 1, color: "#E5ECF9", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 89, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 4, startAt: 83, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 5, startAt: 0, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 4, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: .85 },
|
|
||||||
secondDecoration: { lineWidth: 3, startAt: 0, radius: 2, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
modern/*was gIG2*/: {
|
|
||||||
outerBorder: { lineWidth: 185, radius: 1, color: "#E5ECF9", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 5, startAt: 88, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 5, startAt: 88, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 8, startAt: 0, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 8, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 5, startAt: 80, endAt: 85, color: "red", alpha: .85 },
|
|
||||||
secondDecoration: { lineWidth: 3, startAt: 0, radius: 4, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
simple/*was gIG3*/: {
|
|
||||||
outerBorder: { lineWidth: 185, radius: 1, color: "#E5ECF9", alpha: 1 },
|
|
||||||
smallIndicator: { lineWidth: 10, startAt: 90, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 10, startAt: 90, endAt: 94, color: "#3366CC", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 8, startAt: 0, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 8, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 5, startAt: 80, endAt: 85, color: "red", alpha: .85 },
|
|
||||||
secondDecoration: { lineWidth: 3, startAt: 0, radius: 4, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
// by securephp
|
|
||||||
securephp: {
|
|
||||||
outerBorder: { lineWidth: 100, radius: 0.45, color: "#669900", alpha: 0.3 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 80, endAt: 90 , color: "green", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8.5, startAt: 20, endAt: 40 , color: "green", alpha: 0.4 },
|
|
||||||
hourHand: { lineWidth: 3, startAt: 0, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 2, startAt: 0, endAt: 75, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -10, endAt: 80, color: "blue", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "blue", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Tes2: {
|
|
||||||
outerBorder: { lineWidth: 4, radius: 95, color: "black", alpha: 0.5 },
|
|
||||||
smallIndicator: { lineWidth: 1, startAt: 10, endAt: 50 , color: "#66CCFF", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 8.5, startAt: 60, endAt: 70, color: "#6699FF", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 5, startAt: -15, endAt: 60, color: "black", alpha: 0.7 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: -25, endAt: 75, color: "black", alpha: 0.7 },
|
|
||||||
secondHand: { lineWidth: 1.5, startAt: -20, endAt: 88, color: "red", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 20, radius: 4, fillColor: "blue", color: "red", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
Lev: {
|
|
||||||
outerBorder: { lineWidth: 10, radius: 95, color: "#CCFF33", alpha: 0.65 },
|
|
||||||
smallIndicator: { lineWidth: 5, startAt: 84, endAt: 90, color: "#996600", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 40, startAt: 25, endAt: 95, color: "#336600", alpha: 0.55 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 0.9 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 0.85 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 85, color: "black", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 5, radius: 10, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Sand: {
|
|
||||||
outerBorder: { lineWidth: 1, radius: 70, color: "black", alpha: 0.5 },
|
|
||||||
smallIndicator: { lineWidth: 3, startAt: 50, endAt: 70, color: "#0066FF", alpha: 0.5 },
|
|
||||||
largeIndicator: { lineWidth: 200, startAt: 80, endAt: 95, color: "#996600", alpha: 0.75 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 0.9 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 0.85 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 85, color: "black", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 5, radius: 10, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Sun: {
|
|
||||||
outerBorder: { lineWidth: 100, radius: 140, color: "#99FFFF", alpha: 0.2 },
|
|
||||||
smallIndicator: { lineWidth: 300, startAt: 50, endAt: 70, color: "black", alpha: 0.1 },
|
|
||||||
largeIndicator: { lineWidth: 5, startAt: 80, endAt: 95, color: "black", alpha: 0.65 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 0.9 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 0.85 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 90, color: "black", alpha: 1 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 5, radius: 10, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Tor: {
|
|
||||||
outerBorder: { lineWidth: 10, radius: 88, color: "#996600", alpha: 0.9 },
|
|
||||||
smallIndicator: { lineWidth: 6, startAt: -10, endAt: 73, color: "green", alpha: 0.3 },
|
|
||||||
largeIndicator: { lineWidth: 6, startAt: 73, endAt: 100, color: "black", alpha: 0.65 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -73, endAt: 73, color: "black", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 2, startAt: 5, radius: 10, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Cold: {
|
|
||||||
outerBorder: { lineWidth: 15, radius: 90, color: "black", alpha: 0.3 },
|
|
||||||
smallIndicator: { lineWidth: 15, startAt: -10, endAt: 95, color: "blue", alpha: 0.1 },
|
|
||||||
largeIndicator: { lineWidth: 3, startAt: 80, endAt: 95, color: "blue", alpha: 0.65 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 85, color: "black", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 5, startAt: 30, radius: 10, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Babosa: {
|
|
||||||
outerBorder: { lineWidth: 100, radius: 25, color: "blue", alpha: 0.25 },
|
|
||||||
smallIndicator: { lineWidth: 3, startAt: 90, endAt: 95, color: "#3366CC", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 4, startAt: 75, endAt: 95, color: "#3366CC", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 60, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 85, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 12, startAt: 75, endAt: 90, color: "red", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 3, startAt: 0, radius: 4, fillColor: "black", color: "black", alpha: 1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Tumb: {
|
|
||||||
outerBorder: { lineWidth: 105, radius: 5, color: "green", alpha: 0.4 },
|
|
||||||
smallIndicator: { lineWidth: 1, startAt: 93, endAt: 98, color: "green", alpha: 1 },
|
|
||||||
largeIndicator: { lineWidth: 50, startAt: 0, endAt: 89, color: "red", alpha: 0.14 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 80, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 85, color: "black", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 5, startAt: 50, radius: 90, fillColor: "black", color: "black", alpha: 0.05 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Stone: {
|
|
||||||
outerBorder: { lineWidth: 15, radius: 80, color: "#339933", alpha: 0.5 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 70, endAt: 90, color: "#FF3300", alpha: 0.7 },
|
|
||||||
largeIndicator: { lineWidth: 15, startAt: 0, endAt: 29, color: "#FF6600", alpha: 0.3 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 75, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: 0, endAt: 85, color: "black", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 5, startAt: 50, radius: 90, fillColor: "black", color: "black", alpha: 0.05 }
|
|
||||||
},
|
|
||||||
|
|
||||||
Disc: {
|
|
||||||
outerBorder: { lineWidth: 105, radius: 1, color: "#666600", alpha: 0.2 },
|
|
||||||
smallIndicator: { lineWidth: 1, startAt: 58, endAt: 95, color: "#669900", alpha: 0.8 },
|
|
||||||
largeIndicator: { lineWidth: 6, startAt: 25, endAt: 35, color: "#666600", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 4, startAt: 0, endAt: 65, color: "black", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 3, startAt: 0, endAt: 75, color: "black", alpha: 1 },
|
|
||||||
secondHand: { lineWidth: 1, startAt: -75, endAt: 75, color: "#99CC00", alpha: 0.8 },
|
|
||||||
secondDecoration: { lineWidth: 5, startAt: 50, radius: 90, fillColor: "#00FF00", color: "green", alpha: 0.05 }
|
|
||||||
},
|
|
||||||
|
|
||||||
// By Yoo Nhe
|
|
||||||
watermelon: {
|
|
||||||
outerBorder: { lineWidth: 100, radius: 1.7, color: "#d93d04", alpha: 5 },
|
|
||||||
smallIndicator: { lineWidth: 2, startAt: 50, endAt: 70, color: "#d93d04", alpha: 5 },
|
|
||||||
largeIndicator: { lineWidth: 2, startAt: 45, endAt: 94, color: "#a9bf04", alpha: 1 },
|
|
||||||
hourHand: { lineWidth: 5, startAt: -20, endAt: 80, color: "#8c0d17", alpha: 1 },
|
|
||||||
minuteHand: { lineWidth: 2, startAt: -20, endAt: 80, color: "#7c8c03", alpha: .9 },
|
|
||||||
secondHand: { lineWidth: 2, startAt: 70, endAt: 94, color: "#d93d04", alpha: .85 },
|
|
||||||
secondDecoration: { lineWidth: 1, startAt: 70, radius: 3, fillColor: "red", color: "black", alpha: .7 }
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -13,10 +13,7 @@
|
||||||
<script type="text/javascript" src="formatter.js"></script>
|
<script type="text/javascript" src="formatter.js"></script>
|
||||||
<script type="text/javascript" src="flags.js"></script>
|
<script type="text/javascript" src="flags.js"></script>
|
||||||
<script type="text/javascript" src="script.js"></script>
|
<script type="text/javascript" src="script.js"></script>
|
||||||
<script type="text/javascript" src="coolclock/excanvas.js"></script>
|
<title>FlightAware - Piaware</title>
|
||||||
<script type="text/javascript" src="coolclock/coolclock.js"></script>
|
|
||||||
<script type="text/javascript" src="coolclock/moreskins.js"></script>
|
|
||||||
<title>DUMP1090</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body onload="initialize()">
|
<body onload="initialize()">
|
||||||
<div id="loader" class="hidden">
|
<div id="loader" class="hidden">
|
||||||
|
@ -42,19 +39,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="sidebar_container">
|
<div id="sidebar_container">
|
||||||
<div id="sidebar_canvas">
|
<div id="sidebar_canvas">
|
||||||
<div id="timestamps" style="align: center">
|
|
||||||
<table width="100%">
|
|
||||||
<tr>
|
|
||||||
<td align="center"> <canvas id="utcclock"></canvas> </td>
|
|
||||||
<td align="center"> <canvas id="receiverclock"></canvas> </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td align="center">UTC</td>
|
|
||||||
<td align="center">Last Update</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div id="sudo_buttons">
|
<div id="sudo_buttons">
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -69,7 +53,7 @@
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr class="infoblock_heading">
|
<tr class="infoblock_heading">
|
||||||
<td>
|
<td>
|
||||||
<b id="infoblock_name">DUMP1090</b>
|
<b id="infoblock_name">Piaware</b>
|
||||||
</td>
|
</td>
|
||||||
<td align="right">
|
<td align="right">
|
||||||
<a href="https://github.com/mutability/dump1090" id="dump1090_version" target="_blank"></span>
|
<a href="https://github.com/mutability/dump1090" id="dump1090_version" target="_blank"></span>
|
||||||
|
@ -123,8 +107,6 @@
|
||||||
<span id="selected_icaotype"></span>
|
<span id="selected_icaotype"></span>
|
||||||
<span id="selected_emergency"></span>
|
<span id="selected_emergency"></span>
|
||||||
<span id="selected_links">
|
<span id="selected_links">
|
||||||
<a id="selected_fr24_link" href="" target="_blank">[FR24]</a>
|
|
||||||
<a id="selected_flightstats_link" href="" target="_blank">[FlightStats]</a>
|
|
||||||
<a id="selected_flightaware_link" href="" target="_blank">[FlightAware]</a>
|
<a id="selected_flightaware_link" href="" target="_blank">[FlightAware]</a>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
|
@ -8,11 +8,11 @@ set -e
|
||||||
|
|
||||||
# defaults that can be overridden:
|
# defaults that can be overridden:
|
||||||
VRS_URL=${VRS_URL:-http://www.virtualradarserver.co.uk/Files/BasicAircraftLookup.sqb.gz}
|
VRS_URL=${VRS_URL:-http://www.virtualradarserver.co.uk/Files/BasicAircraftLookup.sqb.gz}
|
||||||
CACHEDIR=${CACHEDIR:-/var/cache/dump1090-mutability}
|
CACHEDIR=${CACHEDIR:-/var/cache/dump1090-fa}
|
||||||
JSONDIR=${JSONDIR:-$CACHEDIR/db}
|
JSONDIR=${JSONDIR:-$CACHEDIR/db}
|
||||||
SQBDIR=${SQBDIR:-$CACHEDIR/sqb}
|
SQBDIR=${SQBDIR:-$CACHEDIR/sqb}
|
||||||
LOGFILE=${LOGFILE:-/var/log/dump1090-mutability.log}
|
LOGFILE=${LOGFILE:-/dev/null}
|
||||||
UPDATESCRIPT=${UPDATESCRIPT:-/usr/share/dump1090-mutability/vrs-basicaircraft-to-json.py}
|
UPDATESCRIPT=${UPDATESCRIPT:-/usr/share/dump1090-fa/vrs-basicaircraft-to-json.py}
|
||||||
|
|
||||||
if [ -f /etc/default/dump1090-mutability ]
|
if [ -f /etc/default/dump1090-mutability ]
|
||||||
then
|
then
|
||||||
|
|
Loading…
Reference in a new issue