Start trimming dump1090-mutability down for use in piaware.

This commit is contained in:
Oliver Jowett 2016-01-13 00:00:08 +00:00
parent 9479a5c9be
commit b433a521bf
26 changed files with 162 additions and 2458 deletions

10
debian/changelog vendored
View file

@ -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.
* 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.
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

2
debian/compat vendored
View file

@ -1 +1 @@
8
9

127
debian/config-template vendored
View file

@ -1,128 +1,21 @@
## TEMPLATE FILE - This is used to create /etc/default/dump1090-mutability ##
## The first three lines will be discarded ##
# dump1090-fa configuration
# 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
# This is a POSIX shell fragment.
# You can edit this file directly, or use
# "dpkg-reconfigure dump1090-mutability"
# User to run as.
DUMP1090_USER=dump1090
# Set to "yes" to start dump1090 on boot.
START_DUMP1090=
# User to run dump1090 as.
DUMP1090_USER=
# Logfile to log to
LOGFILE=
#
# Receiver options
#
# Where to log to. (See also /etc/logrotate.d/dump1090-fa.conf)
LOGFILE=/var/log/dump1090-fa.log
# RTLSDR device index or serial number to use
# If set to "none", dump1090 will be started in --net-only mode
DEVICE=
DEVICE=0
# RTLSDR gain in dB.
# 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.
GAIN=
GAIN=agc
# RTLSDR frequency correction in PPM
PPM=
# 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=
PPM=0

15
debian/control vendored
View file

@ -1,21 +1,18 @@
Source: dump1090-mutability
Source: dump1090-fa
Section: embedded
Priority: extra
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
Homepage: https://github.com/mutability/dump1090
Vcs-Git: https://github.com/mutability/dump1090.git
Package: dump1090-mutability
Package: dump1090-fa
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
Recommends: python(>=2.5), cron | cron-daemon, curl
Suggests: lighttpd
Provides: fatsv-data-source
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, python(>=2.5), cron | cron-daemon, curl, lighttpd
Description: ADS-B Ground Station System for RTL-SDR
Networked Aviation Mode S / ADS-B decoder/translator with RTL-SDR software
defined radio USB device support.
.
This is a packaging of the "mutability" fork of dump1090 that includes
sampling at 2.4MHz and other improvements.
This is FlightAware's packaging of dump1090-mutability, customized for use
in the piaware sdcard images.

View file

@ -9,4 +9,4 @@
# all installs hitting the server at the same time.
# 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
View 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
View 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
View 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

View file

@ -20,10 +20,16 @@ set -e
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)
rm -f /etc/default/dump1090-mutability
rm -f /etc/cron.d/dump1090-mutability
rm -rf /var/cache/dump1090-mutability
rm -f /etc/default/dump1090-fa
rm -f /etc/cron.d/dump1090-fa
rm -rf /var/cache/dump1090-fa
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)

24
debian/dump1090-fa.service vendored Normal file
View 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

View file

@ -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

View file

@ -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

View file

@ -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
:

View file

@ -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

View file

@ -1,5 +0,0 @@
/var/log/dump1090-mutability.log {
weekly
rotate 4
copytruncate
}

View file

@ -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

View file

@ -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

View file

@ -2,15 +2,10 @@
# and also to the dynamically-generated json parts that contain aircraft
# data and are periodically written by the dump1090 daemon.
url.redirect += (
"^/dump1090/$" => "/dump1090/gmap.html",
"^/dump1090$" => "/dump1090/gmap.html"
)
alias.url += (
"/dump1090/data/" => "/run/dump1090-mutability/",
"/dump1090/db/" => "/var/cache/dump1090-mutability/db/",
"/dump1090/" => "/usr/share/dump1090-mutability/html/"
"/dump1090-fa/data/" => "/run/dump1090-fa/",
"/dump1090-fa/db/" => "/var/cache/dump1090-fa/db/",
"/dump1090-fa/" => "/usr/share/dump1090-fa/html/"
)
# The stat cache must be disabled, as aircraft.json changes

View file

@ -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
View file

@ -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')
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:
dh_install
install -d debian/dump1090-mutability/usr/bin
cp -a dump1090 debian/dump1090-mutability/usr/bin/dump1090-mutability
cp -a view1090 debian/dump1090-mutability/usr/bin/view1090-mutability
install -d debian/dump1090-fa/usr/bin
cp -a dump1090 debian/dump1090-fa/usr/bin/dump1090-fa
cp -a view1090 debian/dump1090-fa/usr/bin/view1090-fa
%:
dh $@
dh $@ --with=systemd

View file

@ -117,10 +117,10 @@ SiteCircles = true; // true to show circles (only shown if the center marker is
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
ShowClocks = true;
ShowClocks = false;
// Controls page title, righthand pane when nothing is selected
PageName = "DUMP1090";
PageName = "Piaware";
// Show country flags by ICAO addresses?
ShowFlags = true;

View file

@ -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);

View file

@ -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

View file

@ -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 }
}
};

View file

@ -13,10 +13,7 @@
<script type="text/javascript" src="formatter.js"></script>
<script type="text/javascript" src="flags.js"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="coolclock/excanvas.js"></script>
<script type="text/javascript" src="coolclock/coolclock.js"></script>
<script type="text/javascript" src="coolclock/moreskins.js"></script>
<title>DUMP1090</title>
<title>FlightAware - Piaware</title>
</head>
<body onload="initialize()">
<div id="loader" class="hidden">
@ -42,19 +39,6 @@
</div>
<div id="sidebar_container">
<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">
<table width="100%">
<tr>
@ -69,7 +53,7 @@
<table width="100%">
<tr class="infoblock_heading">
<td>
<b id="infoblock_name">DUMP1090</b>
<b id="infoblock_name">Piaware</b>
</td>
<td align="right">
<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_emergency"></span>
<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>
</span>
</td>

View file

@ -8,11 +8,11 @@ set -e
# defaults that can be overridden:
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}
SQBDIR=${SQBDIR:-$CACHEDIR/sqb}
LOGFILE=${LOGFILE:-/var/log/dump1090-mutability.log}
UPDATESCRIPT=${UPDATESCRIPT:-/usr/share/dump1090-mutability/vrs-basicaircraft-to-json.py}
LOGFILE=${LOGFILE:-/dev/null}
UPDATESCRIPT=${UPDATESCRIPT:-/usr/share/dump1090-fa/vrs-basicaircraft-to-json.py}
if [ -f /etc/default/dump1090-mutability ]
then