<commit_before>#
# piaware - status file creation
#
# Copyright (C) 2016 FlightAware LLC, All Rights Reserved
#

package require json::write
package require tryfinallyshim

set ::statusFileInterval 5000

proc periodically_update_status_file {} {
	if {$::params(statusfile) ne ""} {
		after $::statusFileInterval update_status_file
	}
}

proc update_status_file {} {
	periodically_update_status_file

	if {[catch {write_status_file} result]} {
		logger "failed to write status file: $result"
		logger "traceback: $::errorInfo"
	}
}

proc write_status_file {} {
	set contents [build_status]
	set newfile "${::params(statusfile)}.new"

	try {
		set f [open $newfile "w"]
		puts $f $contents
		try {
			close $f
		} finally {
			unset f
		}

		file rename -force -- $newfile $::params(statusfile)
		unset newfile
	} finally {
		if {[info exists f]} {
			catch {close $f}
		}

		if {[info exists newfile]} {
			catch {file delete -- $newfile}
		}
	}
}

proc status_entry {color message} {
	set data(status) [::json::write string $color]
	set data(message) [::json::write string $message]
	return [::json::write object {*}[array get data]]
}

proc build_status {} {
	set data(time) [clock milliseconds]
	set data(interval) $::statusFileInterval
	set data(expiry) [expr {$data(time) + $::statusFileInterval * 2 + 1000}]

	# site URL, if available
	if {[info exists ::siteURL]} {
		set data(site_url) [::json::write string $::siteURL]
	}

	# site UUID, if unclaimed
	if {[info exists ::feederID] && [info exists ::loggedInUser] && $::loggedInUser eq "guest"} {
		set data(unclaimed_feeder_id) [::json::write string $::feederID]
	}

	# piaware: our own health
	set data(piaware) [status_entry "green" "PiAware $::piawareVersionFull is running"]

	# adept: status of the connection to the adept server
	if {[adept is_logged_in]} {
		set data(adept) [status_entry "green" "Connected to FlightAware and logged in"]
	} elseif {[adept is_connected]} {
		set data(adept) [status_entry "amber" "Connected to FlightAware, but not logged in"]
	} else {
		set data(adept) [status_entry "red" "Not connected to FlightAware"]
	}

	# radio: status of the connection to the receiver process
	if {[info exists ::faup1090] && [$::faup1090 is_connected]} {
		if {([clock seconds] - [$::faup1090 last_message_received]) < 60} {
			set data(radio) [status_entry "green" "Received Mode S data recently"]
		} else {
			set data(radio) [status_entry "amber" "Connected to receiver, but no recent data seen"]
		}
	} else {
		set data(radio) [status_entry "red" "Not connected to receiver"]
	}

	# mlat: status of mlat
	switch $::mlatStatus {
		not_enabled {<commit_msg>Add statusfile support for 978MHz<commit_after>#
# piaware - status file creation
#
# Copyright (C) 2016 FlightAware LLC, All Rights Reserved
#

package require json::write
package require tryfinallyshim

set ::statusFileInterval 5000

proc periodically_update_status_file {} {
	if {$::params(statusfile) ne ""} {
		after $::statusFileInterval update_status_file
	}
}

proc update_status_file {} {
	periodically_update_status_file

	if {[catch {write_status_file} result]} {
		logger "failed to write status file: $result"
		logger "traceback: $::errorInfo"
	}
}

proc write_status_file {} {
	set contents [build_status]
	set newfile "${::params(statusfile)}.new"

	try {
		set f [open $newfile "w"]
		puts $f $contents
		try {
			close $f
		} finally {
			unset f
		}

		file rename -force -- $newfile $::params(statusfile)
		unset newfile
	} finally {
		if {[info exists f]} {
			catch {close $f}
		}

		if {[info exists newfile]} {
			catch {file delete -- $newfile}
		}
	}
}

proc status_entry {color message} {
	set data(status) [::json::write string $color]
	set data(message) [::json::write string $message]
	return [::json::write object {*}[array get data]]
}

proc build_status {} {
	set data(time) [clock milliseconds]
	set data(interval) $::statusFileInterval
	set data(expiry) [expr {$data(time) + $::statusFileInterval * 2 + 1000}]

	# site URL, if available
	if {[info exists ::siteURL]} {
		set data(site_url) [::json::write string $::siteURL]
	}

	# site UUID, if unclaimed
	if {[info exists ::feederID] && [info exists ::loggedInUser] && $::loggedInUser eq "guest"} {
		set data(unclaimed_feeder_id) [::json::write string $::feederID]
	}

	# piaware: our own health
	set data(piaware) [status_entry "green" "PiAware $::piawareVersionFull is running"]

	# adept: status of the connection to the adept server
	if {[adept is_logged_in]} {
		set data(adept) [status_entry "green" "Connected to FlightAware and logged in"]
	} elseif {[adept is_connected]} {
		set data(adept) [status_entry "amber" "Connected to FlightAware, but not logged in"]
	} else {
		set data(adept) [status_entry "red" "Not connected to FlightAware"]
	}

	# radio: status of the connection to the receiver process
	array set reasons {}
	foreach {faupvar name} {::faup1090 "Mode S" ::faup978 "UAT"} {
		if {![info exists $faupvar]} {
			continue
		}

		set faup [set $faupvar]
		if {[$faup is_connected]} {
			if {([clock seconds] - [$::faup1090 last_message_received]) < 60} {
				lappend reasons(green) "Received $name data recently"
			} else {
				lappend reasons(amber) "Connected to $name receiver, but no recent data seen"
			}
		} else {
			lappend reasons(red) "Not connected to $name receiver"
		}
	}

	foreach status {red amber green} {
		if {[info exists reasons($status)]} {
			set data(radio) [status_entry $status [join $reasons($status) "; "]]
			break
		}
	}
	if {![info exists data(radio)]} {
		set data(radio) [status_entry "red" "No receivers configured"]
	}

	# mlat: status of mlat
	switch $::mlatStatus {
		not_enabled {
{'fraction_non_alphanumeric': 0.13451015004413064, 'fraction_numerical': 0.009885260370697264, 'mean_word_length': 4.442843419788665, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '340093', 'n_tokens_mistral': 2130, 'n_tokens_neox': 1945, 'n_words': 597}