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.
|
||||
* 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
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 ##
|
||||
## 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
15
debian/control
vendored
|
@ -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.
|
||||
|
|
2
debian/cron-template
vendored
2
debian/cron-template
vendored
|
@ -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
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,14 +20,20 @@ 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)
|
||||
;;
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
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
|
||||
# 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
|
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')
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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="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>
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue