Merge branch 'mcguirepr89:main' into main
This commit is contained in:
+18
-4
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
error_reporting(E_ERROR);
|
||||
|
||||
if (file_exists('./scripts/thisrun.txt')) {
|
||||
$config = parse_ini_file('./scripts/thisrun.txt');
|
||||
@@ -157,6 +156,16 @@ if(isset($_GET['submit'])) {
|
||||
$contents2 = preg_replace("/AUDIOFMT=.*/", "AUDIOFMT=$audiofmt", $contents2);
|
||||
}
|
||||
}
|
||||
if(isset($_GET["silence_update_indicator"])) {
|
||||
$silence_update_indicator = 1;
|
||||
if(strcmp($silence_update_indicator,$config['SILENCE_UPDATE_INDICATOR']) !== 0) {
|
||||
$contents = preg_replace("/SILENCE_UPDATE_INDICATOR=.*/", "SILENCE_UPDATE_INDICATOR=$silence_update_indicator", $contents);
|
||||
$contents2 = preg_replace("/SILENCE_UPDATE_INDICATOR=.*/", "SILENCE_UPDATE_INDICATOR=$silence_update_indicator", $contents2);
|
||||
}
|
||||
} else {
|
||||
$contents = preg_replace("/SILENCE_UPDATE_INDICATOR=.*/", "SILENCE_UPDATE_INDICATOR=0", $contents);
|
||||
$contents2 = preg_replace("/SILENCE_UPDATE_INDICATOR=.*/", "SILENCE_UPDATE_INDICATOR=0", $contents2);
|
||||
}
|
||||
|
||||
$fh = fopen('/etc/birdnet/birdnet.conf', "w");
|
||||
$fh2 = fopen("./scripts/thisrun.txt", "w");
|
||||
@@ -164,7 +173,10 @@ if(isset($_GET['submit'])) {
|
||||
fwrite($fh2, $contents2);
|
||||
}
|
||||
|
||||
$count_labels = count(file("./scripts/labels.txt"));
|
||||
$user = trim(shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"));
|
||||
$home = trim(shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"));
|
||||
|
||||
$count_labels = count(file($home."/BirdNET-Pi/model/labels.txt"));
|
||||
$count = $count_labels;
|
||||
?>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@@ -233,13 +245,15 @@ foreach($formats as $format){
|
||||
<h3>BirdNET-Pi Password</h3>
|
||||
<p>This password will protect your "Tools" page and "Live Audio" stream.</p>
|
||||
<label for="caddy_pwd">Password: </label>
|
||||
<input style="width:40ch" name="caddy_pwd" type="text" value="<?php print($newconfig['CADDY_PWD']);?>" /><br>
|
||||
<input style="width:40ch" name="caddy_pwd" id="caddy_pwd" type="password" value="<?php print($newconfig['CADDY_PWD']);?>" /><span id="showpassword" onmouseover="document.getElementById('caddy_pwd').type='text';" onmouseout="document.getElementById('caddy_pwd').type='password';">show</span><br>
|
||||
<h3>Custom URL</h3>
|
||||
<p><a href="mailto:mcguirepr89@gmail.com?subject=Request%20BirdNET-Pi%20Subdomain&body=<?php include('birdnetpi_request.php'); ?>" target="_blank">Email Me</a> if you would like a BirdNETPi.com subdomain. This would be, <i>https://YourLocation.birdnetpi.com</i></p>
|
||||
<p>When you update the URL below, the web server will reload, so be sure to wait at least 30 seconds and then go to your new URL.</p>
|
||||
<label for="birdnetpi_url">BirdNET-Pi URL: </label>
|
||||
<input style="width:40ch;" name="birdnetpi_url" type="url" value="<?php print($newconfig['BIRDNETPI_URL']);?>" /><br>
|
||||
<p>The BirdNET-Pi URL is how the main page will be reached. If you want your installation to respond to an IP address, place that here, but be sure to indicate "<i>http://</i>".<br>Example for IP: <i>http://192.168.0.109</i><br>Example if you own your own domain: <i>https://virginia.birdnetpi.com</i></p>
|
||||
<label for="silence_update_indicator">Silence Update Indicator: </label>
|
||||
<input type="checkbox" name="silence_update_indicator" <?php if($newconfig['SILENCE_UPDATE_INDICATOR'] == 1) { echo "checked"; };?> ><br>
|
||||
<h3>BirdNET-Lite Settings</h3>
|
||||
<label for="overlap">Overlap: </label>
|
||||
<input name="overlap" type="number" min="0.0" max="2.9" step="0.1" value="<?php print($newconfig['OVERLAP']);?>" required/><br>
|
||||
|
||||
@@ -128,11 +128,11 @@ run_analysis() {
|
||||
BIRDWEATHER_ID_PARAM=""
|
||||
BIRDWEATHER_ID_LOG=""
|
||||
fi
|
||||
echo $PYTHON_VIRTUAL_ENV "$DIR\analyze.py" \
|
||||
echo $PYTHON_VIRTUAL_ENV "$DIR/analyze.py" \
|
||||
--i "${1}/${i}" \
|
||||
--o "${1}/${i}.csv" \
|
||||
--lat "${LATITUDE}" \
|
||||
--lon "${LONGITUDE}" \
|
||||
--lat $(echo "${LATITUDE}" | awk '{print int($1+0.5)}').XX \
|
||||
--lon $(echo "${LONGITUDE}" | awk '{print int($1+0.5)}').XX \
|
||||
--week "${WEEK}" \
|
||||
--overlap "${OVERLAP}" \
|
||||
--sensitivity "${SENSITIVITY}" \
|
||||
@@ -168,7 +168,7 @@ until grep 5050 <(netstat -tulpn 2>&1) &> /dev/null 2>&1;do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ $(find ${RECS_DIR}/StreamData -maxdepth 1 -name '*wav' | wc -l) -gt 0 ];then
|
||||
if [ $(find ${RECS_DIR}/StreamData -maxdepth 1 -name '*wav' 2>/dev/null| wc -l) -gt 0 ];then
|
||||
find $RECS_DIR -maxdepth 1 -name '*wav' -type f -size 0 -delete
|
||||
run_birdnet "${RECS_DIR}/StreamData"
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source /etc/birdnet/birdnet.conf
|
||||
set -x
|
||||
|
||||
cd "${PROCESSED}" || exit 1
|
||||
empties=($(find ${PROCESSED} -size 57c))
|
||||
@@ -11,3 +12,7 @@ done
|
||||
if [[ "$(find ${PROCESSED} | wc -l)" -ge 100 ]];then
|
||||
ls -1t . | tail -n +100 | xargs -r rm -vv
|
||||
fi
|
||||
|
||||
#accumulated_files=$(find $RECS_DIR -path $PROCESSED -prune -o -path $EXTRACTED -prune -o -type f -print | wc -l)
|
||||
#[ $accumulated_files -ge 10 ] && stop_core_services.sh
|
||||
#echo "$(date "+%b %e %I:%M:%S") Stopped Core Services -- It looks like analysis stopped. Check raw recordings in $RECS_DIR and check the birdnet_analysis.service and birdnet_server.service \"journalctl -eu birdnet_analysis -u birdnet_server\"" | sudo tee -a /var/log/syslog
|
||||
|
||||
@@ -34,6 +34,7 @@ sudo -u ${USER} ln -fs $my_dir/overview.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/stats.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/todays_detections.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/history.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/weekly_report.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/homepage/images/favicon.ico ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $(dirname $my_dir)/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
||||
|
||||
+25
-3
@@ -46,6 +46,11 @@ if(isset($_GET["latitude"])){
|
||||
} else {
|
||||
$apprise_notify_new_species_each_day = 0;
|
||||
}
|
||||
if(isset($_GET['apprise_weekly_report'])) {
|
||||
$apprise_weekly_report = 1;
|
||||
} else {
|
||||
$apprise_weekly_report = 0;
|
||||
}
|
||||
|
||||
if(isset($timezone)) {
|
||||
shell_exec("sudo timedatectl set-timezone ".$timezone);
|
||||
@@ -101,6 +106,7 @@ if(isset($_GET["latitude"])){
|
||||
$contents = preg_replace("/APPRISE_NOTIFY_EACH_DETECTION=.*/", "APPRISE_NOTIFY_EACH_DETECTION=$apprise_notify_each_detection", $contents);
|
||||
$contents = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES=.*/", "APPRISE_NOTIFY_NEW_SPECIES=$apprise_notify_new_species", $contents);
|
||||
$contents = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=.*/", "APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=$apprise_notify_new_species_each_day", $contents);
|
||||
$contents = preg_replace("/APPRISE_WEEKLY_REPORT=.*/", "APPRISE_WEEKLY_REPORT=$apprise_weekly_report", $contents);
|
||||
$contents = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents);
|
||||
$contents = preg_replace("/DATABASE_LANG=.*/", "DATABASE_LANG=$language", $contents);
|
||||
$contents = preg_replace("/FLICKR_FILTER_EMAIL=.*/", "FLICKR_FILTER_EMAIL=$flickr_filter_email", $contents);
|
||||
@@ -114,6 +120,7 @@ if(isset($_GET["latitude"])){
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFY_EACH_DETECTION=.*/", "APPRISE_NOTIFY_EACH_DETECTION=$apprise_notify_each_detection", $contents2);
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES=.*/", "APPRISE_NOTIFY_NEW_SPECIES=$apprise_notify_new_species", $contents2);
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=.*/", "APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY=$apprise_notify_new_species_each_day", $contents2);
|
||||
$contents2 = preg_replace("/APPRISE_WEEKLY_REPORT=.*/", "APPRISE_WEEKLY_REPORT=$apprise_weekly_report", $contents2);
|
||||
$contents2 = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents2);
|
||||
$contents2 = preg_replace("/DATABASE_LANG=.*/", "DATABASE_LANG=$language", $contents2);
|
||||
$contents2 = preg_replace("/FLICKR_FILTER_EMAIL=.*/", "FLICKR_FILTER_EMAIL=$flickr_filter_email", $contents2);
|
||||
@@ -180,6 +187,15 @@ if(isset($_GET['sendtest']) && $_GET['sendtest'] == "true") {
|
||||
$filename = "http://birdnetpi.local/"."?filename=".$filename;
|
||||
}
|
||||
|
||||
$attach="";
|
||||
$exampleimage = "https://live.staticflickr.com/7430/27545810581_8bfa8289a3_c.jpg";
|
||||
if (strpos($body, '$flickrimage') !== false) {
|
||||
$attach = "--attach ".$exampleimage;
|
||||
}
|
||||
if (strpos($body, '{') === false) {
|
||||
$exampleimage = "";
|
||||
}
|
||||
|
||||
$title = str_replace("\$sciname", $sciname, $title);
|
||||
$title = str_replace("\$comname", $comname, $title);
|
||||
$title = str_replace("\$confidence", $confidence, $title);
|
||||
@@ -192,6 +208,7 @@ if(isset($_GET['sendtest']) && $_GET['sendtest'] == "true") {
|
||||
$title = str_replace("\$cutoff", $cutoff, $title);
|
||||
$title = str_replace("\$sens", $sens, $title);
|
||||
$title = str_replace("\$overlap", $overlap, $title);
|
||||
$title = str_replace("\$flickrimage", $exampleimage, $title);
|
||||
|
||||
$body = str_replace("\$sciname", $sciname, $body);
|
||||
$body = str_replace("\$comname", $comname, $body);
|
||||
@@ -205,8 +222,9 @@ if(isset($_GET['sendtest']) && $_GET['sendtest'] == "true") {
|
||||
$body = str_replace("\$cutoff", $cutoff, $body);
|
||||
$body = str_replace("\$sens", $sens, $body);
|
||||
$body = str_replace("\$overlap", $overlap, $body);
|
||||
$body = str_replace("\$flickrimage", $exampleimage, $body);
|
||||
|
||||
echo "<pre class=\"bash\">".shell_exec($home."/BirdNET-Pi/birdnet/bin/apprise -vv -t '".$title."' -b '".$body."' ".$cf." ")."</pre>";
|
||||
echo "<pre class=\"bash\">".shell_exec($home."/BirdNET-Pi/birdnet/bin/apprise -vv -t '".$title."' -b '".$body."' ".$attach." ".$cf." ")."</pre>";
|
||||
|
||||
die();
|
||||
}
|
||||
@@ -320,6 +338,8 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}
|
||||
<dd>Sigmoid Sensitivity set in "Advanced Settings"</dd>
|
||||
<dt>$overlap</dt>
|
||||
<dd>Overlap set in "Advanced Settings"</dd>
|
||||
<dt>$flickrimage</dt>
|
||||
<dd>A preview image of the detected species from Flickr. Set your API key below.</dd>
|
||||
</dl>
|
||||
<p>Use the variables defined above to customize your notification title and body.</p>
|
||||
<label for="apprise_notification_title">Notification Title: </label>
|
||||
@@ -329,9 +349,11 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}
|
||||
<input type="checkbox" name="apprise_notify_new_species" <?php if($config['APPRISE_NOTIFY_NEW_SPECIES'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
|
||||
<label for="apprise_notify_new_species">Notify each new infrequent species detection (<5 visits per week)</label><br>
|
||||
<input type="checkbox" name="apprise_notify_new_species_each_day" <?php if($config['APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
|
||||
<label for="apprise_notify_new_species_each_day">Notify each new species detection of the day</label><br>
|
||||
<label for="apprise_notify_new_species_each_day">Notify each species first detection of the day</label><br>
|
||||
<input type="checkbox" name="apprise_notify_each_detection" <?php if($config['APPRISE_NOTIFY_EACH_DETECTION'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
|
||||
<label for="apprise_notify_each_detection">Notify each new detection</label><br><br>
|
||||
<label for="apprise_weekly_report">Notify each new detection</label><br>
|
||||
<input type="checkbox" name="apprise_weekly_report" <?php if($config['APPRISE_WEEKLY_REPORT'] == 1 && filesize($home."/BirdNET-Pi/apprise.txt") != 0) { echo "checked"; };?> >
|
||||
<label for="apprise_weekly_report">Send weekly report</label><br><br>
|
||||
|
||||
<button type="button" class="testbtn" onclick="sendTestNotification(this)">Send Test Notification</button><br>
|
||||
<span id="testsuccessmsg"></span>
|
||||
|
||||
+112
-3
@@ -1,7 +1,13 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors',1);
|
||||
ini_set('display_startup_errors',1);
|
||||
|
||||
if (file_exists('./scripts/thisrun.txt')) {
|
||||
$config = parse_ini_file('./scripts/thisrun.txt');
|
||||
} elseif (file_exists('./scripts/firstrun.ini')) {
|
||||
$config = parse_ini_file('./scripts/firstrun.ini');
|
||||
}
|
||||
|
||||
if(isset($_GET['date'])){
|
||||
$theDate = $_GET['date'];
|
||||
@@ -18,15 +24,118 @@ $statement1 = $db->prepare("SELECT COUNT(*) FROM detections
|
||||
$result1 = $statement1->execute();
|
||||
$totalcount = $result1->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
if(isset($_GET['blocation']) ) {
|
||||
|
||||
header("Content-type: text/csv");
|
||||
header("Content-Disposition: attachment; filename=result_file.csv");
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: 0");
|
||||
|
||||
|
||||
$user = trim(shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"));
|
||||
$home = trim(shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"));
|
||||
|
||||
|
||||
//$sunrise = date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $config["LATITUDE"], $config["LONGITUDE"]);
|
||||
//$sunset = date_sunset(time(), SUNFUNCS_RET_TIMESTAMP, $config["LATITUDE"], $config["LONGITUDE"]);
|
||||
|
||||
$list = array ();
|
||||
|
||||
//$hrsinday = intval(($sunset-$sunrise)/60/60);
|
||||
$hrsinday = 24;
|
||||
for($i=0;$i<$hrsinday;$i++) {
|
||||
$starttime = strtotime("12 AM") + (3600*$i);
|
||||
|
||||
$statement1 = $db->prepare("SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date == \"$theDate\" AND Time > '".date("H:i", $starttime)."' AND Time < '".date("H:i",$starttime + 3600)."' AND Confidence > 0.75 GROUP By Com_Name ORDER BY COUNT(*) DESC");
|
||||
if($statement1 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result1 = $statement1->execute();
|
||||
|
||||
$detections = [];
|
||||
while($detection=$result1->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$detections[$detection["Com_Name"]] = $detection["COUNT(*)"];
|
||||
}
|
||||
foreach($detections as $com_name=>$scount)
|
||||
{
|
||||
array_push($list, array($com_name,'','','1','',$_GET['blocation'],$config["LATITUDE"],$config["LONGITUDE"],date("m/d/Y", strtotime($theDate)), date("H:i", $starttime), $_GET['state'], $_GET['country'], $_GET['protocol'], $_GET['num_observers'], '60', 'Y', $_GET['dist_traveled'],'',$_GET['notes'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
$output = fopen("php://output", "w");
|
||||
foreach ($list as $row) {
|
||||
fputcsv($output, $row);
|
||||
}
|
||||
fclose($output);
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<head>
|
||||
|
||||
<style>
|
||||
#attribution-dialog p {
|
||||
display:inline;
|
||||
}
|
||||
#attribution-dialog {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="history centered">
|
||||
|
||||
<dialog id="attribution-dialog">
|
||||
<p style="display:none" id="filename"></p>
|
||||
<h1 id="modalHeading">Enter Checklist Information</h1>
|
||||
<p id="modalText">Location Name:</p> <input placeholder="My house" id="blocation"><br><br>
|
||||
<p id="modalText">State (2 letter code):</p> <input maxlength="3" id="state"><br><br>
|
||||
<p id="modalText">Country (2 letter code):</p> <input maxlength="2" id="country"><br><br>
|
||||
<p id="modalText">Protocol:</p> <select id="protocol">
|
||||
<option value="casual">casual</option>
|
||||
<option value="stationary">stationary</option>
|
||||
<option value="traveling">traveling</option>
|
||||
<option value="area">area</option>
|
||||
</select>
|
||||
<br><br>
|
||||
<p id="modalText">Number of observers:</p> <input type="number" id="num_observers"><br><br>
|
||||
<p id="modalText">Distance traveled (miles):</p> <input type="number" id="dist_traveled"><br><br>
|
||||
<p id="modalText">Notes:</p> <input id="notes"><br><br>
|
||||
<button onclick="submitID()">Submit</button>
|
||||
</dialog>
|
||||
<script>
|
||||
var dialog = document.querySelector('dialog');
|
||||
dialogPolyfill.registerDialog(dialog);
|
||||
|
||||
function showDialog() {
|
||||
document.getElementById('attribution-dialog').showModal();
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
document.getElementById('attribution-dialog').close();
|
||||
}
|
||||
|
||||
function submitID() {
|
||||
blocation = document.getElementById("blocation").value;
|
||||
state = document.getElementById("state").value;
|
||||
country = document.getElementById("country").value;
|
||||
protocol = document.getElementById("protocol").value;
|
||||
num_observers = document.getElementById("num_observers").value;
|
||||
dist_traveled = document.getElementById("dist_traveled").value;
|
||||
notes = document.getElementById("notes").value;
|
||||
|
||||
window.open("history.php?blocation="+blocation+"&state="+state+"&country="+country+"&protocol="+protocol+"&num_observers="+num_observers+"&dist_traveled="+dist_traveled+"¬es="+notes+"&date="+"<?php echo $theDate; ?>");
|
||||
|
||||
document.getElementById('attribution-dialog').innerHTML = "<h3>Success!</h3><p>Your checklist will start downloading momentarily.<br><br>Refer to <a target='_blank' href='https://ebird.org/content/eBirdCommon/docs/ebird_import_data_process.pdf'>this guide</a> for information on how to import it in eBird. The checklist file format is: 'eBird Record Format (Extended)'.<br><br><span style='font-size:small'>Note: Only detections with a confidence > 0.75 were included, and entries have been limited to 1 detection per hour per species, to comply with eBird's data quality guidelines.<br>It's always good practice to manually verify your checklist before submitting, especially for nocturnal hours.</span></p><br><br><button onclick=\"closeDialog()\">Close</button>";
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form action="" method="GET">
|
||||
<input type="date" name="date" value="<?php echo $theDate;?>">
|
||||
<button type="submit" name="view" value="Daily Charts">Submit Date</button>
|
||||
@@ -37,7 +146,7 @@ $totalcount = $result1->fetchArray(SQLITE3_ASSOC);
|
||||
<td><?php echo $totalcount['COUNT(*)'];?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br><br>
|
||||
<?php // <br><button type="button" onclick="showDialog()">Export as CSV for eBird</button><br><br> ?>
|
||||
<?php
|
||||
if (file_exists('./Charts/'.$chart)) {
|
||||
echo "<img src=\"/Charts/$chart?nocache=time()\" >";
|
||||
|
||||
@@ -75,6 +75,7 @@ APPRISE_NOTIFICATION_TITLE="New BirdNET-Pi Detection"
|
||||
APPRISE_NOTIFICATION_BODY="A \$sciname \$comname was just detected with a confidence of \$confidence"
|
||||
APPRISE_NOTIFY_EACH_DETECTION=0
|
||||
APPRISE_NOTIFY_NEW_SPECIES=0
|
||||
APPRISE_WEEKLY_REPORT=1
|
||||
|
||||
#---------------------- Flickr Images API Configuration -----------------------#
|
||||
## If FLICKR_API_KEY is set, the web interface will try and display bird images
|
||||
@@ -170,6 +171,12 @@ AUDIOFMT=mp3
|
||||
## DATABASE_LANG is the language used for the bird species database
|
||||
DATABASE_LANG=en
|
||||
|
||||
## SILENCE_UPDATE_INDICATOR is for quieting the display of how many commits
|
||||
## your installation is behind by, relative to the Github repo. This number
|
||||
## appears next to "Tools" when you're 50 or more commits behind.
|
||||
|
||||
SILENCE_UPDATE_INDICATOR=0
|
||||
|
||||
## These are just for debugging
|
||||
LAST_RUN=
|
||||
THIS_RUN=
|
||||
|
||||
@@ -111,6 +111,7 @@ create_necessary_dirs() {
|
||||
sudo -u ${USER} ln -fs $my_dir/scripts/stats.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/scripts/todays_detections.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/scripts/history.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/scripts/weekly_report.php ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/homepage/images/favicon.ico ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs ${HOME}/phpsysinfo ${EXTRACTED}
|
||||
sudo -u ${USER} ln -fs $my_dir/templates/phpsysinfo.ini ${HOME}/phpsysinfo/
|
||||
@@ -274,7 +275,7 @@ Restart=on-failure
|
||||
RestartSec=5
|
||||
Type=simple
|
||||
User=${USER}
|
||||
ExecStart=$HOME/BirdNET-Pi/birdnet/bin/streamlit run $HOME/BirdNET-Pi/scripts/plotly_streamlit.py --server.address localhost --server.baseUrlPath "/stats"
|
||||
ExecStart=$HOME/BirdNET-Pi/birdnet/bin/streamlit run $HOME/BirdNET-Pi/scripts/plotly_streamlit.py --browser.gatherUsageStats false --server.address localhost --server.baseUrlPath "/stats"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -379,6 +380,8 @@ config_icecast() {
|
||||
for i in "${passwords[@]}";do
|
||||
sed -i "s/<${i}password>.*<\/${i}password>/<${i}password>${ICE_PWD}<\/${i}password>/g" /etc/icecast2/icecast.xml
|
||||
done
|
||||
sed -i 's|<!-- <bind-address>.*|<bind-address>127.0.0.1</bind-address>|;s|<!-- <shoutcast-mount>.*|<shoutcast-mount>/stream</shoutcast-mount>|'
|
||||
|
||||
systemctl enable icecast2.service
|
||||
}
|
||||
|
||||
@@ -406,6 +409,10 @@ install_cleanup_cron() {
|
||||
sed "s/\$USER/$USER/g" $my_dir/templates/cleanup.cron >> /etc/crontab
|
||||
}
|
||||
|
||||
install_weekly_cron() {
|
||||
sed "s/\$USER/$USER/g" $my_dir/templates/weekly_report.cron >> /etc/crontab
|
||||
}
|
||||
|
||||
chown_things() {
|
||||
chown -R $USER:$USER $HOME/Bird*
|
||||
}
|
||||
@@ -431,6 +438,7 @@ install_services() {
|
||||
install_phpsysinfo
|
||||
install_livestream_service
|
||||
install_cleanup_cron
|
||||
install_weekly_cron
|
||||
|
||||
create_necessary_dirs
|
||||
generate_BirdDB
|
||||
|
||||
+13
-6
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(E_ERROR);
|
||||
ini_set('display_errors',1);
|
||||
ini_set('session.gc_maxlifetime', 7200);
|
||||
session_set_cookie_params(7200);
|
||||
session_start();
|
||||
@@ -50,12 +50,15 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
$comname = preg_replace('/\'/', '', $comname);
|
||||
$filename = "/By_Date/".$mostrecent['Date']."/".$comname."/".$mostrecent['File_Name'];
|
||||
$args = "&license=2%2C3%2C4%2C5%2C6%2C9&orientation=square,portrait";
|
||||
$comnameprefix = "%20bird";
|
||||
|
||||
// check to make sure the image actually exists, sometimes it takes a minute to be created\
|
||||
if(file_exists($home."/BirdSongs/Extracted".$filename.".png")){
|
||||
if($_GET['previous_detection_identifier'] == $filename) { die(); }
|
||||
if($_GET['only_name'] == "true") { echo $comname.",".$filename;die(); }
|
||||
|
||||
$iterations++;
|
||||
|
||||
if (!empty($config["FLICKR_API_KEY"])) {
|
||||
|
||||
if(!empty($config["FLICKR_FILTER_EMAIL"])) {
|
||||
@@ -64,6 +67,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
$_SESSION['FLICKR_FILTER_EMAIL'] = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.people.findByEmail&api_key=".$config["FLICKR_API_KEY"]."&find_email=".$config["FLICKR_FILTER_EMAIL"]."&format=json&nojsoncallback=1"), true)["user"]["nsid"];
|
||||
}
|
||||
$args = "&user_id=".$_SESSION['FLICKR_FILTER_EMAIL'];
|
||||
$comnameprefix = "";
|
||||
} else {
|
||||
if(isset($_SESSION["FLICKR_FILTER_EMAIL"])) {
|
||||
unset($_SESSION["FLICKR_FILTER_EMAIL"]);
|
||||
@@ -89,7 +93,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
}
|
||||
}
|
||||
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=\"".str_replace(" ", "%20", $engname)."\"&sort=relevance".$args."&per_page=5&media=photos&format=json&nojsoncallback=1"), true)["photos"]["photo"][0];
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=".str_replace(" ", "%20", $engname).$comnameprefix."&sort=relevance".$args."&per_page=5&media=photos&format=json&nojsoncallback=1"), true)["photos"]["photo"][0];
|
||||
$modaltext = "https://flickr.com/photos/".$flickrjson["owner"]."/".$flickrjson["id"];
|
||||
$authorlink = "https://flickr.com/people/".$flickrjson["owner"];
|
||||
$imageurl = 'https://farm' .$flickrjson["farm"]. '.static.flickr.com/' .$flickrjson["server"]. '/' .$flickrjson["id"]. '_' .$flickrjson["secret"]. '.jpg';
|
||||
@@ -120,7 +124,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
<table class="<?php echo ($_GET['previous_detection_identifier'] == 'undefined') ? '' : 'fade-in'; ?>">
|
||||
<h3>Most Recent Detection: <span style="font-weight: normal;"><?php echo $mostrecent['Date']." ".$mostrecent['Time'];?></span></h3>
|
||||
<tr>
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $mostrecent['File_Name']; ?>"><img class="copyimage" width="25" height="25" src="images/copy.png"></a>
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $mostrecent['File_Name']; ?>"><img class="copyimage" title="Open in new tab" width="25" height="25" src="images/copy.png"></a>
|
||||
<div class="centered_image_container" style="margin-bottom: 0px !important;">
|
||||
<?php if(!empty($config["FLICKR_API_KEY"]) && strlen($image[2]) > 0) { ?>
|
||||
<img onclick='setModalText(<?php echo $iterations; ?>,"<?php echo urlencode($image[2]); ?>", "<?php echo $image[3]; ?>", "<?php echo $image[4]; ?>", "<?php echo $image[1]; ?>")' src="<?php echo $image[1]; ?>" class="img1">
|
||||
@@ -136,6 +140,9 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
</table> <?php break;
|
||||
}
|
||||
}
|
||||
if($iterations == 0) {
|
||||
echo "<h3>No Detections For Today.</h3>";
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -284,7 +291,7 @@ function loadDetectionIfNewExists(previous_detection_identifier=undefined) {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.onload = function() {
|
||||
// if there's a new detection that needs to be updated to the page
|
||||
if(this.responseText.length > 0 && !this.responseText.includes("Database is busy")) {
|
||||
if(this.responseText.length > 0 && !this.responseText.includes("Database is busy") && !this.responseText.includes("No Detections") || previous_detection_identifier == undefined) {
|
||||
document.getElementById("most_recent_detection").innerHTML = this.responseText;
|
||||
|
||||
// only going to load left chart & 5 most recents if there's a new detection
|
||||
@@ -309,7 +316,7 @@ function loadLeftChart() {
|
||||
function refreshTopTen() {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.onload = function() {
|
||||
if(this.responseText.length > 0 && !this.responseText.includes("Database is busy")) {
|
||||
if(this.responseText.length > 0 && !this.responseText.includes("Database is busy") && !this.responseText.includes("No Detections") || previous_detection_identifier == undefined) {
|
||||
document.getElementById("chart").src = "/Charts/"+this.responseText+"?nocache="+Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
+202
-143
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
error_reporting(E_ERROR);
|
||||
ini_set('display_errors',1);
|
||||
|
||||
$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
||||
if($db == False){
|
||||
@@ -17,6 +18,41 @@ $user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd");
|
||||
$home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd");
|
||||
$home = trim($home);
|
||||
|
||||
|
||||
if(isset($_GET['deletefile'])) {
|
||||
if(isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
$submittedpwd = $_SERVER['PHP_AUTH_PW'];
|
||||
$submitteduser = $_SERVER['PHP_AUTH_USER'];
|
||||
if($submittedpwd == $config['CADDY_PWD'] && $submitteduser == 'birdnet'){
|
||||
$statement1 = $db->prepare('DELETE FROM detections WHERE File_Name = "'.explode("/",$_GET['deletefile'])[2].'" LIMIT 1');
|
||||
if($statement1 == False){
|
||||
echo "Error";
|
||||
header("refresh: 0;");
|
||||
} else {
|
||||
$file_pointer = $home."/BirdSongs/Extracted/By_Date/".$_GET['deletefile'];
|
||||
if (!exec("sudo rm $file_pointer && sudo rm $file_pointer.png")) {
|
||||
echo "OK";
|
||||
} else {
|
||||
echo "Error";
|
||||
}
|
||||
|
||||
}
|
||||
$result1 = $statement1->execute();
|
||||
die();
|
||||
} else {
|
||||
header('WWW-Authenticate: Basic realm="My Realm"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'You must be authenticated to change the protection of files.';
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
header('WWW-Authenticate: Basic realm="My Realm"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'You must be authenticated to change the protection of files.';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_GET['excludefile'])) {
|
||||
if(isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
$submittedpwd = $_SERVER['PHP_AUTH_PW'];
|
||||
@@ -27,21 +63,21 @@ if(isset($_GET['excludefile'])) {
|
||||
}
|
||||
if(isset($_GET['exclude_add'])) {
|
||||
$myfile = fopen($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", "a") or die("Unable to open file!");
|
||||
$txt = $_GET['excludefile'];
|
||||
fwrite($myfile, $txt."\n");
|
||||
fwrite($myfile, $txt.".png\n");
|
||||
fclose($myfile);
|
||||
echo "OK";
|
||||
die();
|
||||
$txt = $_GET['excludefile'];
|
||||
fwrite($myfile, $txt."\n");
|
||||
fwrite($myfile, $txt.".png\n");
|
||||
fclose($myfile);
|
||||
echo "OK";
|
||||
die();
|
||||
} else {
|
||||
$lines = file($home."/BirdNET-Pi/scripts/disk_check_exclude.txt");
|
||||
$search = $_GET['excludefile'];
|
||||
|
||||
$result = '';
|
||||
foreach($lines as $line) {
|
||||
if(stripos($line, $search) === false && stripos($line, $search.".png") === false) {
|
||||
$result .= $line;
|
||||
}
|
||||
if(stripos($line, $search) === false && stripos($line, $search.".png") === false) {
|
||||
$result .= $line;
|
||||
}
|
||||
}
|
||||
file_put_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", $result);
|
||||
echo "OK";
|
||||
@@ -90,7 +126,7 @@ if(isset($_GET['bydate'])){
|
||||
#By Species
|
||||
} elseif(isset($_GET['byspecies'])) {
|
||||
if(isset($_GET['sort']) && $_GET['sort'] == "occurrences") {
|
||||
$statement = $db->prepare('SELECT DISTINCT(Com_Name) FROM detections GROUP BY Com_Name ORDER BY COUNT(*) DESC');
|
||||
$statement = $db->prepare('SELECT DISTINCT(Com_Name) FROM detections GROUP BY Com_Name ORDER BY COUNT(*) DESC');
|
||||
} else {
|
||||
$statement = $db->prepare('SELECT DISTINCT(Com_Name) FROM detections ORDER BY Com_Name ASC');
|
||||
}
|
||||
@@ -132,18 +168,37 @@ if(isset($_GET['bydate'])){
|
||||
</head>
|
||||
|
||||
<script>
|
||||
function deleteDetection(filename,copylink=false) {
|
||||
if (confirm("Are you sure you want to delete this detection from the database?") == true) {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.onload = function() {
|
||||
if(this.responseText == "OK"){
|
||||
if(copylink == true) {
|
||||
window.top.close();
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
} else {
|
||||
alert("Database busy.")
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", "play.php?deletefile="+filename, true);
|
||||
xhttp.send();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleLock(filename, type, elem) {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.onload = function() {
|
||||
if(this.responseText == "OK"){
|
||||
if(type == "add") {
|
||||
elem.setAttribute("src","images/lock.svg");
|
||||
elem.setAttribute("title", "This file is delete protected.");
|
||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("add","del"));
|
||||
elem.setAttribute("src","images/lock.svg");
|
||||
elem.setAttribute("title", "This file is excluded from being purged.");
|
||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("add","del"));
|
||||
} else {
|
||||
elem.setAttribute("src","images/unlock.svg");
|
||||
elem.setAttribute("title", "This file is not delete protected.");
|
||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("del","add"));
|
||||
elem.setAttribute("src","images/unlock.svg");
|
||||
elem.setAttribute("title", "This file is not excluded from being purged.");
|
||||
elem.setAttribute("onclick", elem.getAttribute("onclick").replace("del","add"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,28 +242,28 @@ if(!isset($_GET['species']) && !isset($_GET['filename'])){
|
||||
while($results=$result->fetchArray(SQLITE3_ASSOC)){
|
||||
$date = $results['Date'];
|
||||
if(realpath($home."/BirdSongs/Extracted/By_Date/".$date) !== false){
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"date\" value=\"$date\">$date</button></td></tr>";}}
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"date\" value=\"$date\">".($date == date('Y-m-d') ? "Today" : $date)."</button></td></tr>";}}
|
||||
|
||||
#By Species
|
||||
#By Species
|
||||
} elseif($view == "byspecies") {
|
||||
while($results=$result->fetchArray(SQLITE3_ASSOC)){
|
||||
$name = $results['Com_Name'];
|
||||
|
||||
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"species\" value=\"$name\">$name</button></td></tr>";}
|
||||
|
||||
#Specific Date
|
||||
#Specific Date
|
||||
} elseif($view == "date") {
|
||||
while($results=$result->fetchArray(SQLITE3_ASSOC)){
|
||||
$name = $results['Com_Name'];
|
||||
if(realpath($home."/BirdSongs/Extracted/By_Date/".$date."/".str_replace(" ", "_",$name)) !== false){
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"species\" value=\"$name\">$name</button></td></tr>";
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"species\" value=\"$name\">$name</button></td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
#Choose
|
||||
#Choose
|
||||
} else {
|
||||
echo "<td>
|
||||
<button action=\"submit\" name=\"byspecies\" value=\"byspecies\">By Species</button></td></tr>
|
||||
@@ -216,8 +271,8 @@ if(!isset($_GET['species']) && !isset($_GET['filename'])){
|
||||
}
|
||||
|
||||
echo "</form>
|
||||
</tr>
|
||||
</table>";
|
||||
</tr>
|
||||
</table>";
|
||||
}
|
||||
|
||||
#Specific Species
|
||||
@@ -227,142 +282,146 @@ if(isset($_GET['species'])){ ?>
|
||||
<form action="" method="GET">
|
||||
<input type="hidden" name="view" value="Recordings">
|
||||
<input type="hidden" name="species" value="<?php echo $_GET['species']; ?>">
|
||||
<button <?php if(!isset($_GET['sort']) || $_GET['sort'] == "date"){ echo "style='background:#9fe29b !important;'"; }?> class="sortbutton" type="submit" name="sort" value="date">
|
||||
<input type="hidden" name="sort" value="<?php echo $_GET['sort']; ?>">
|
||||
<button <?php if(!isset($_GET['sort']) || $_GET['sort'] == "" || $_GET['sort'] == "date"){ echo "style='background:#9fe29b !important;'"; }?> class="sortbutton" type="submit" name="sort" value="date">
|
||||
<img width=35px src="images/sort_date.svg" title="Sort by date" alt="Sort by date">
|
||||
</button>
|
||||
<button <?php if(isset($_GET['sort']) && $_GET['sort'] == "confidence"){ echo "style='background:#9fe29b !important;'"; }?> class="sortbutton" type="submit" name="sort" value="confidence">
|
||||
<img src="images/sort_occ.svg" title="Sort by confidence" alt="Sort by confidence">
|
||||
</button>
|
||||
</button><br>
|
||||
<input style="margin-top:10px" <?php if(isset($_GET['only_excluded'])){ echo "checked"; }?> type="checkbox" name="only_excluded" onChange="submit()">
|
||||
<label for="onlyverified">Only Show Purge Excluded</label>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
// add disk_check_exclude.txt lines into an array for grepping
|
||||
$fp = @fopen($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", 'r');
|
||||
if ($fp) {
|
||||
$disk_check_exclude_arr = explode("\n", fread($fp, filesize($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")));
|
||||
}
|
||||
|
||||
$name = $_GET['species'];
|
||||
if(isset($_SESSION['date'])) {
|
||||
$date = $_SESSION['date'];
|
||||
if(isset($_GET['sort']) && $_GET['sort'] == "confidence") {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" AND Date == \"$date\" ORDER BY Confidence DESC");
|
||||
} else {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" AND Date == \"$date\" ORDER BY Time DESC");
|
||||
}
|
||||
if ($fp) {
|
||||
$disk_check_exclude_arr = explode("\n", fread($fp, filesize($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")));
|
||||
}
|
||||
|
||||
$name = $_GET['species'];
|
||||
if(isset($_SESSION['date'])) {
|
||||
$date = $_SESSION['date'];
|
||||
if(isset($_GET['sort']) && $_GET['sort'] == "confidence") {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" AND Date == \"$date\" ORDER BY Confidence DESC");
|
||||
} else {
|
||||
if(isset($_GET['sort']) && $_GET['sort'] == "confidence") {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" ORDER BY Confidence DESC");
|
||||
} else {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" ORDER BY Date DESC, Time DESC");
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" AND Date == \"$date\" ORDER BY Time DESC");
|
||||
}
|
||||
} else {
|
||||
if(isset($_GET['sort']) && $_GET['sort'] == "confidence") {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" ORDER BY Confidence DESC");
|
||||
} else {
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where Com_Name == \"$name\" ORDER BY Date DESC, Time DESC");
|
||||
}
|
||||
}
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
echo "<table>
|
||||
<tr>
|
||||
<th>$name</th>
|
||||
</tr>";
|
||||
$iter=0;
|
||||
while($results=$result2->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$comname = preg_replace('/ /', '_', $results['Com_Name']);
|
||||
$comname = preg_replace('/\'/', '', $comname);
|
||||
$date = $results['Date'];
|
||||
$filename = "/By_Date/".$date."/".$comname."/".$results['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $results['Sci_Name']);
|
||||
$sci_name = $results['Sci_Name'];
|
||||
$time = $results['Time'];
|
||||
$confidence = round((float)round($results['Confidence'],2) * 100 ) . '%';
|
||||
$filename_formatted = $date."/".$comname."/".$results['File_Name'];
|
||||
|
||||
// file was deleted by disk check, no need to show the detection in recordings
|
||||
if(!file_exists($home."/BirdSongs/Extracted/".$filename)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
echo "<table>
|
||||
<tr>
|
||||
<th>$name</th>
|
||||
</tr>";
|
||||
$iter=0;
|
||||
while($results=$result2->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$comname = preg_replace('/ /', '_', $results['Com_Name']);
|
||||
$comname = preg_replace('/\'/', '', $comname);
|
||||
$date = $results['Date'];
|
||||
$filename = "/By_Date/".$date."/".$comname."/".$results['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $results['Sci_Name']);
|
||||
$sci_name = $results['Sci_Name'];
|
||||
$time = $results['Time'];
|
||||
$confidence = round((float)round($results['Confidence'],2) * 100 ) . '%';
|
||||
$filename_formatted = $date."/".$comname."/".$results['File_Name'];
|
||||
if(!in_array($filename_formatted, $disk_check_exclude_arr) && isset($_GET['only_excluded'])) {
|
||||
continue;
|
||||
}
|
||||
$iter++;
|
||||
|
||||
// file was deleted by disk check, no need to show the detection in recordings
|
||||
if(!file_exists($home."/BirdSongs/Extracted/".$filename)) {
|
||||
continue;
|
||||
if($config["FULL_DISK"] == "purge") {
|
||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||
$imageicon = "images/unlock.svg";
|
||||
$title = "This file is not excluded from being purged.";
|
||||
$type = "add";
|
||||
} else {
|
||||
$imageicon = "images/lock.svg";
|
||||
$title = "This file is excluded from being purged.";
|
||||
$type = "del";
|
||||
}
|
||||
$iter++;
|
||||
|
||||
if($config["FULL_DISK"] == "purge") {
|
||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||
$imageicon = "images/unlock.svg";
|
||||
$title = "This file is not delete protected.";
|
||||
$type = "add";
|
||||
} else {
|
||||
$imageicon = "images/lock.svg";
|
||||
$title = "This file is delete protected.";
|
||||
$type = "del";
|
||||
echo "<tr>
|
||||
<td class=\"relative\"><img style='cursor:pointer;right:45px' src='images/delete.svg' onclick='deleteDetection(\"".$filename_formatted."\")' class=\"copyimage\" width=25 title='Delete Detection'> <img style='cursor:pointer' onclick='toggleLock(\"".$filename_formatted."\",\"".$type."\", this)' class=\"copyimage\" width=25 title=\"".$title."\" src=\"".$imageicon."\">$date $time<br>$confidence<br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
} else {
|
||||
echo "<tr>
|
||||
<td class=\"relative\">$date $time<br>$confidence<img style='cursor:pointer' src='images/delete.svg' onclick='deleteDetection(\"".$filename_formatted."\")' class=\"copyimage\" width=25 title='Delete Detection'><br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
}if($iter == 0){ echo "<tr><td><b>No recordings were found.</b><br><br><span style='font-size:medium'>They may have been deleted to make space for new recordings. You can prevent this from happening in the future by clicking the <img src='images/unlock.svg' style='width:20px'> icon in the top right of a recording.<br>You can also modify this behavior globally under \"Full Disk Behavior\" <a href='views.php?view=Advanced'>here.</a></span></td></tr>";}echo "</table>";}
|
||||
|
||||
if(isset($_GET['filename'])){
|
||||
$name = $_GET['filename'];
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where File_name == \"$name\" ORDER BY Date DESC, Time DESC");
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
echo "<table>
|
||||
<tr>
|
||||
<th>$name</th>
|
||||
</tr>";
|
||||
while($results=$result2->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$comname = preg_replace('/ /', '_', $results['Com_Name']);
|
||||
$comname = preg_replace('/\'/', '', $comname);
|
||||
$date = $results['Date'];
|
||||
$filename = "/By_Date/".$date."/".$comname."/".$results['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $results['Sci_Name']);
|
||||
$sci_name = $results['Sci_Name'];
|
||||
$time = $results['Time'];
|
||||
$confidence = round((float)round($results['Confidence'],2) * 100 ) . '%';
|
||||
$filename_formatted = $date."/".$comname."/".$results['File_Name'];
|
||||
|
||||
// add disk_check_exclude.txt lines into an array for grepping
|
||||
$fp = @fopen($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", 'r');
|
||||
if ($fp) {
|
||||
$disk_check_exclude_arr = explode("\n", fread($fp, filesize($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")));
|
||||
}
|
||||
|
||||
echo "<tr>
|
||||
<td class='relative'>$date $time<br>$confidence<br><img style='cursor:pointer' onclick='toggleLock(\"".$filename_formatted."\",\"".$type."\", this)' class=\"copyimage\" width=25 title=\"".$title."\" src=\"".$imageicon."\">
|
||||
<a href=\"$filename\"><img src=\"$filename.png\"></a>
|
||||
</td>
|
||||
</tr>";
|
||||
} else {
|
||||
echo "<tr>
|
||||
<td class='relative'>$date $time<br>$confidence<br>
|
||||
<a href=\"$filename\"><img src=\"$filename.png\"></a>
|
||||
</td>
|
||||
</tr>";
|
||||
}
|
||||
if($config["FULL_DISK"] == "purge") {
|
||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||
$imageicon = "images/unlock.svg";
|
||||
$title = "This file is not excluded from being purged.";
|
||||
$type = "add";
|
||||
} else {
|
||||
$imageicon = "images/lock.svg";
|
||||
$title = "This file is excluded from being purged.";
|
||||
$type = "del";
|
||||
}
|
||||
|
||||
}if($iter == 0){ echo "<tr><td><b>No recordings were found.</b><br><br><span style='font-size:medium'>They may have been deleted to make space for new recordings. You can prevent this from happening in the future by clicking the <img src='images/unlock.svg' style='width:20px'> icon in the top right of a recording.<br>You can also modify this behavior globally under \"Full Disk Behavior\" <a href='views.php?view=Advanced'>here.</a></span></td></tr>";}echo "</table>";}
|
||||
|
||||
if(isset($_GET['filename'])){
|
||||
$name = $_GET['filename'];
|
||||
$statement2 = $db->prepare("SELECT * FROM detections where File_name == \"$name\" ORDER BY Date DESC, Time DESC");
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
echo "<table>
|
||||
<tr>
|
||||
<th>$name</th>
|
||||
</tr>";
|
||||
while($results=$result2->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$comname = preg_replace('/ /', '_', $results['Com_Name']);
|
||||
$comname = preg_replace('/\'/', '', $comname);
|
||||
$date = $results['Date'];
|
||||
$filename = "/By_Date/".$date."/".$comname."/".$results['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $results['Sci_Name']);
|
||||
$sci_name = $results['Sci_Name'];
|
||||
$time = $results['Time'];
|
||||
$confidence = round((float)round($results['Confidence'],2) * 100 ) . '%';
|
||||
$filename_formatted = $date."/".$comname."/".$results['File_Name'];
|
||||
|
||||
// add disk_check_exclude.txt lines into an array for grepping
|
||||
$fp = @fopen($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", 'r');
|
||||
if ($fp) {
|
||||
$disk_check_exclude_arr = explode("\n", fread($fp, filesize($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")));
|
||||
}
|
||||
|
||||
if($config["FULL_DISK"] == "purge") {
|
||||
if(!in_array($filename_formatted, $disk_check_exclude_arr)) {
|
||||
$imageicon = "images/unlock.svg";
|
||||
$title = "This file is not delete protected.";
|
||||
$type = "add";
|
||||
echo "<tr>
|
||||
<td class=\"relative\"><img style='cursor:pointer;right:45px' src='images/delete.svg' onclick='deleteDetection(\"".$filename_formatted."\", true)' class=\"copyimage\" width=25 title='Delete Detection'> <img style='cursor:pointer' onclick='toggleLock(\"".$filename_formatted."\",\"".$type."\", this)' class=\"copyimage\" width=25 title=\"".$title."\" src=\"".$imageicon."\">$date $time<br>$confidence<br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
} else {
|
||||
$imageicon = "images/lock.svg";
|
||||
$title = "This file is delete protected.";
|
||||
$type = "del";
|
||||
echo "<tr>
|
||||
<td class=\"relative\">$date $time<br>$confidence<img style='cursor:pointer' src='images/delete.svg' onclick='deleteDetection(\"".$filename_formatted."\", true)' class=\"copyimage\" width=25 title='Delete Detection'><br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
echo "<tr>
|
||||
<td class=\"relative\"><img style='cursor:pointer' onclick='toggleLock(\"".$filename_formatted."\",\"".$type."\", this)' class=\"copyimage\" width=25 title=\"".$title."\" src=\"".$imageicon."\">$date $time<br>$confidence<br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
} else {
|
||||
echo "<tr>
|
||||
<td class=\"relative\">$date $time<br>$confidence<br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" preload=\"none\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
}echo "</table>";}?>
|
||||
}echo "</table>";}?>
|
||||
</div>
|
||||
</html>
|
||||
|
||||
@@ -8,7 +8,9 @@ my_dir=$HOME/BirdNET-Pi/scripts
|
||||
sudo systemctl stop birdnet_server.service
|
||||
sudo systemctl stop birdnet_recording.service
|
||||
|
||||
services=(icecast2.service
|
||||
services=(chart_viewer.service
|
||||
spectrogram_viewer.service
|
||||
icecast2.service
|
||||
extraction.service
|
||||
birdnet_recording.service
|
||||
birdnet_log.service)
|
||||
|
||||
@@ -1,73 +1,93 @@
|
||||
<?php
|
||||
function service_status($name) {
|
||||
$user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd");
|
||||
$home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd");
|
||||
$home = trim($home);
|
||||
|
||||
if($name == "birdnet_server.service") {
|
||||
$filesinproc=trim(shell_exec("ls ".$home."/BirdSongs/Processed | wc -l"));
|
||||
if($filesinproc > 200) {
|
||||
echo "<span style='color:#fc6603'>(stalled - backlog of ".$filesinproc." files in ~/BirdSongs/Processed/)</span>";
|
||||
return;
|
||||
}
|
||||
}
|
||||
$op = shell_exec("sudo systemctl status ".$name." | grep Active | grep ' active\| activating\|running\|waiting\|start'");
|
||||
if(strlen($op) > 0) {
|
||||
echo "<span style='color:green'>(active)</span>";
|
||||
} else {
|
||||
echo "<span style='color:#fc6603'>(inactive)</span>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<br>
|
||||
<br>
|
||||
<div class="servicecontrols">
|
||||
<form action="" method="GET">
|
||||
<h3>Live Audio Stream</h3>
|
||||
<h3>Live Audio Stream <?php echo service_status("livestream.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop livestream.service && sudo /etc/init.d/icecast2 stop">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart livestream.service && sudo /etc/init.d/icecast2 restart">Restart </button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now livestream.service && sudo systemctl disable icecast2 && sudo /etc/init.d/icecast2 stop">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable icecast2 && sudo /etc/init.d/icecast2 start && sudo systemctl enable --now livestream.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Web Terminal</h3>
|
||||
<h3>Web Terminal <?php echo service_status("web_terminal.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop web_terminal.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart web_terminal.service">Restart </button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now web_terminal.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now web_terminal.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>BirdNET Log</h3>
|
||||
<h3>BirdNET Log <?php echo service_status("birdnet_log.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop birdnet_log.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart birdnet_log.service">Restart </button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now birdnet_log.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now birdnet_log.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Extraction Service</h3>
|
||||
<h3>Extraction Service <?php echo service_status("extraction.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop extraction.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart extraction.service">Restart </button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now extraction.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now extraction.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>BirdNET Analysis Server</h3>
|
||||
<h3>BirdNET Analysis Server <?php echo service_status("birdnet_server.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop birdnet_server.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart birdnet_server.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now birdnet_server.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now birdnet_server.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>BirdNET Analysis Client</h3>
|
||||
<h3>BirdNET Analysis Client <?php echo service_status("birdnet_analysis.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop birdnet_analysis.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart birdnet_analysis.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now birdnet_analysis.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now birdnet_analysis.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Streamlit Statistics</h3>
|
||||
<h3>Streamlit Statistics <?php echo service_status("birdnet_stats.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop birdnet_stats.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart birdnet_stats.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now birdnet_stats.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now birdnet_stats.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Recording Service</h3>
|
||||
<h3>Recording Service <?php echo service_status("birdnet_recording.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop birdnet_recording.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart birdnet_recording.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now birdnet_recording.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now birdnet_recording.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Chart Viewer</h3>
|
||||
<h3>Chart Viewer <?php echo service_status("chart_viewer.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop chart_viewer.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart chart_viewer.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now chart_viewer.service">Disable</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl enable --now chart_viewer.service">Enable</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<h3>Spectrogram Viewer</h3>
|
||||
<h3>Spectrogram Viewer <?php echo service_status("spectrogram_viewer.service");?></h3>
|
||||
<button type="submit" name="submit" value="sudo systemctl stop spectrogram_viewer.service">Stop</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl restart spectrogram_viewer.service">Restart</button>
|
||||
<button type="submit" name="submit" value="sudo systemctl disable --now spectrogram_viewer.service">Disable</button>
|
||||
@@ -75,8 +95,8 @@
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<button type="submit" name="submit" value="stop_core_services.sh">Stop Core Services</button>
|
||||
</form>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<button type="submit" name="submit" value="restart_services.sh">Restart Core Services</button>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
error_reporting(E_ERROR);
|
||||
ini_set('display_errors',1);
|
||||
if(isset($_GET['ajax_csv'])) {
|
||||
|
||||
if (file_exists('./scripts/thisrun.txt')) {
|
||||
@@ -66,7 +68,7 @@ window.onload = function(){
|
||||
};
|
||||
|
||||
// if user agent includes iPhone or Mac use legacy mode
|
||||
if(window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("Mac") || legacy == true) {
|
||||
if(((window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("Mac")) && !window.navigator.userAgent.includes("Chrome")) || legacy == true) {
|
||||
document.getElementById("spectrogramimage").style.display="";
|
||||
document.body.querySelector('canvas').remove();
|
||||
document.getElementById('player').remove();
|
||||
|
||||
+2
-2
@@ -155,7 +155,7 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){
|
||||
$filename = "/By_Date/".$date."/".$comname."/".$results['File_Name'];
|
||||
echo str_pad("<h3>$species</h3>
|
||||
<table><tr>
|
||||
<td class=\"relative\"><a target=\"_blank\" href=\"index.php?filename=".$results['File_Name']."\"><img class=\"copyimage\" width=25 src=\"images/copy.png\"></a> <a href=\"https://wikipedia.org/wiki/$dbsciname\" target=\"top\"/><i>$sciname</i></a><br>
|
||||
<td class=\"relative\"><a target=\"_blank\" href=\"index.php?filename=".$results['File_Name']."\"><img title=\"Open in new tab\" class=\"copyimage\" width=25 src=\"images/copy.png\"></a> <a href=\"https://wikipedia.org/wiki/$dbsciname\" target=\"top\"/><i>$sciname</i></a><br>
|
||||
<b>Occurrences: </b>$count<br>
|
||||
<b>Max Confidence: </b>$maxconf<br>
|
||||
<b>Best Recording: </b>$date $time<br>
|
||||
@@ -223,7 +223,7 @@ array_push($excludelines, $results['Date']."/".$comname."/".$results['File_Name'
|
||||
<tr>
|
||||
<form action="" method="GET">
|
||||
<input type="hidden" name="sort" value="<?php if(isset($_GET['sort'])){echo $_GET['sort'];}?>">
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $results['File_Name']; ?>"><img class="copyimage" width=25 src="images/copy.png"></a><input type="hidden" name="view" value="Species Stats">
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $results['File_Name']; ?>"><img title="Open in new tab" class="copyimage" width=25 src="images/copy.png"></a><input type="hidden" name="view" value="Species Stats">
|
||||
<button type="submit" name="species" value="<?php echo $results['Com_Name'];?>"><?php echo $results['Com_Name'];?></button><br><b>Occurrences:</b> <?php echo $results['COUNT(*)'];?><br>
|
||||
<b>Max Confidence:</b> <?php echo $percent = round((float)round($results['MAX(Confidence)'],2) * 100 ) . '%';?><br>
|
||||
<b>Best Recording:</b> <?php echo $results['Date']." ".$results['Time'];?><br><video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster="<?php echo $filename.".png";?>" preload="none" title="<?php echo $filename;?>"><source src="<?php echo $filename;?>" type="audio/mp3"></video></td>
|
||||
|
||||
@@ -5,19 +5,28 @@ $user = trim($user);
|
||||
$home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd");
|
||||
$home = trim($home);
|
||||
$fetch = shell_exec("sudo -u".$user." git -C ".$home."/BirdNET-Pi fetch 2>&1");
|
||||
if(strlen($fetch) > 0) {
|
||||
$_SESSION['behind'] = trim(shell_exec("sudo -u".$user." git -C ".$home."/BirdNET-Pi status | sed -n '2 p' | cut -d ' ' -f 7"));
|
||||
}
|
||||
$_SESSION['behind'] = trim(shell_exec("sudo -u".$user." git -C ".$home."/BirdNET-Pi status | sed -n '2 p' | cut -d ' ' -f 7"));
|
||||
?><html>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<br>
|
||||
<br>
|
||||
<script>
|
||||
var seconds = 0;
|
||||
function update() {
|
||||
if(confirm('Are you sure you want to update?')) {
|
||||
setInterval(function(){ seconds += 1; document.getElementById('updatebtn').innerHTML = "Updating: <pre id='timer' class='bash'>"+new Date(seconds * 1000).toISOString().substring(14, 19)+"</span>"; }, 1000);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="systemcontrols">
|
||||
<form action="" method="GET">
|
||||
<button type="submit" name="submit" value="sudo reboot" onclick="return confirm('Are you sure you want to reboot?')">Reboot</button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<button type="submit" name="submit" value="update_birdnet.sh" onclick="return confirm('Are you sure you want to update?')">Update <?php if(isset($_SESSION['behind']) && $_SESSION['behind'] != "0" && $_SESSION['behind'] != "with"){?><div class="updatenumber"><?php echo $_SESSION['behind']; ?></div><?php } ?></button>
|
||||
<button type="submit" name="submit" id="updatebtn" value="update_birdnet.sh" onclick="update();">Update <?php if(isset($_SESSION['behind']) && $_SESSION['behind'] != "0" && $_SESSION['behind'] != "with"){?><div class="updatenumber"><?php echo $_SESSION['behind']; ?></div><?php } ?></button>
|
||||
</form>
|
||||
<form action="" method="GET">
|
||||
<button type="submit" name="submit" value="sudo shutdown now" onclick="return confirm('Are you sure you want to shutdown?')">Shutdown</button>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
ini_set('session.gc_maxlifetime', 7200);
|
||||
session_set_cookie_params(7200);
|
||||
session_start();
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(E_ERROR);
|
||||
ini_set('display_errors',1);
|
||||
|
||||
$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
||||
if($db == False){
|
||||
@@ -119,6 +119,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
$filename = "/By_Date/".date('Y-m-d')."/".$comname."/".$todaytable['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $todaytable['Sci_Name']);
|
||||
$args = "&license=2%2C3%2C4%2C5%2C6%2C9&orientation=square,portrait";
|
||||
$comnameprefix = "%20bird";
|
||||
|
||||
if (!empty($config["FLICKR_API_KEY"]) && (isset($_GET['display_limit']) || isset($_GET['hard_limit']))) {
|
||||
|
||||
@@ -128,6 +129,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
$_SESSION['FLICKR_FILTER_EMAIL'] = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.people.findByEmail&api_key=".$config["FLICKR_API_KEY"]."&find_email=".$config["FLICKR_FILTER_EMAIL"]."&format=json&nojsoncallback=1"), true)["user"]["nsid"];
|
||||
}
|
||||
$args = "&user_id=".$_SESSION['FLICKR_FILTER_EMAIL'];
|
||||
$comnameprefix = "";
|
||||
} else {
|
||||
if(isset($_SESSION["FLICKR_FILTER_EMAIL"])) {
|
||||
unset($_SESSION["FLICKR_FILTER_EMAIL"]);
|
||||
@@ -151,7 +153,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=\"".str_replace(" ", "%20", $engname)."\"&sort=relevance".$args."&per_page=5&media=photos&format=json&nojsoncallback=1"), true)["photos"]["photo"][0];
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=".str_replace(" ", "%20", $engname).$comnameprefix."&sort=relevance".$args."&per_page=5&media=photos&format=json&nojsoncallback=1"), true)["photos"]["photo"][0];
|
||||
$modaltext = "https://flickr.com/photos/".$flickrjson["owner"]."/".$flickrjson["id"];
|
||||
$authorlink = "https://flickr.com/people/".$flickrjson["owner"];
|
||||
$imageurl = 'https://farm' .$flickrjson["farm"]. '.static.flickr.com/' .$flickrjson["server"]. '/' .$flickrjson["id"]. '_' .$flickrjson["secret"]. '.jpg';
|
||||
@@ -162,7 +164,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
?>
|
||||
<?php if(isset($_GET['display_limit']) && is_numeric($_GET['display_limit'])){ ?>
|
||||
<tr class="relative" id="<?php echo $iterations; ?>">
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $todaytable['File_Name']; ?>"><img class="copyimage" width=25 src="images/copy.png"></a>
|
||||
<td class="relative"><a target="_blank" href="index.php?filename=<?php echo $todaytable['File_Name']; ?>"><img class="copyimage" title="Open in new tab" width=25 src="images/copy.png"></a>
|
||||
|
||||
<div class="centered_image_container">
|
||||
<?php if(!empty($config["FLICKR_API_KEY"]) && strlen($image[2]) > 0) { ?>
|
||||
@@ -199,6 +201,10 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
</table>
|
||||
|
||||
<?php
|
||||
if($iterations == 0) {
|
||||
echo "<h3>No Detections For Today.</h3>";
|
||||
}
|
||||
|
||||
// don't show the button if there's no more detections to be displayed, we're at the end of the list
|
||||
if($iterations >= 40 && isset($_GET['display_limit']) && is_numeric($_GET['display_limit'])) { ?>
|
||||
<center>
|
||||
|
||||
@@ -6,6 +6,10 @@ USER=$(awk -F: '/1000/ {print $1}' /etc/passwd)
|
||||
HOME=$(awk -F: '/1000/ {print $6}' /etc/passwd)
|
||||
my_dir=$HOME/BirdNET-Pi/scripts
|
||||
|
||||
# Sets proper permissions and ownership
|
||||
sudo -E chown -R $USER:$USER $HOME/*
|
||||
sudo chmod -R g+wr $HOME/*
|
||||
|
||||
if ! grep PRIVACY_THRESHOLD /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||
sudo -u$USER echo "PRIVACY_THRESHOLD=0" >> /etc/birdnet/birdnet.conf
|
||||
git -C $HOME/BirdNET-Pi rm $my_dir/privacy_server.py
|
||||
@@ -94,6 +98,27 @@ if [[ "$pytest_installation_status" = "not installed" ]];then
|
||||
$HOME/BirdNET-Pi/birdnet/bin/pip3 install pytest==7.1.2 pytest-mock==3.7.0
|
||||
fi
|
||||
|
||||
[ -L ~/BirdSongs/Extracted/weekly_report.php ] || ln -sf ~/BirdNET-Pi/scripts/weekly_report.php ~/BirdSongs/Extracted
|
||||
|
||||
if ! grep weekly_report /etc/crontab &>/dev/null;then
|
||||
sed "s/\$USER/$USER/g" $HOME/BirdNET-Pi/templates/weekly_report.cron | sudo tee -a /etc/crontab
|
||||
fi
|
||||
if ! grep APPRISE_WEEKLY_REPORT /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||
sudo -u$USER echo "APPRISE_WEEKLY_REPORT=1" >> /etc/birdnet/birdnet.conf
|
||||
fi
|
||||
|
||||
if ! grep SILENCE_UPDATE_INDICATOR /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||
sudo -u$USER echo "SILENCE_UPDATE_INDICATOR=0" >> /etc/birdnet/birdnet.conf
|
||||
fi
|
||||
|
||||
if ! grep '\-\-browser.gatherUsageStats false' $HOME/BirdNET-Pi/templates/birdnet_stats.service &>/dev/null ;then
|
||||
sudo -E sed -i "s|ExecStart=.*|ExecStart=$HOME/BirdNET-Pi/birdnet/bin/streamlit run $HOME/BirdNET-Pi/scripts/plotly_streamlit.py --browser.gatherUsageStats false --server.address localhost --server.baseUrlPath \"/stats\"|" $HOME/BirdNET-Pi/templates/birdnet_stats.service
|
||||
sudo systemctl daemon-reload && restart_services.sh
|
||||
fi
|
||||
|
||||
# Make IceCast2 a little more secure
|
||||
sudo sed -i 's|<!-- <bind-address>.*|<bind-address>127.0.0.1</bind-address>|;s|<!-- <shoutcast-mount>.*|<shoutcast-mount>/stream</shoutcast-mount>|' /etc/icecast2/icecast.xml
|
||||
sudo systemctl restart icecast2
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
restart_services.sh
|
||||
|
||||
@@ -3,21 +3,29 @@ import os
|
||||
import socket
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
||||
userDir = os.path.expanduser('~')
|
||||
APPRISE_CONFIG = userDir + '/BirdNET-Pi/apprise.txt'
|
||||
DB_PATH = userDir + '/BirdNET-Pi/scripts/birds.db'
|
||||
|
||||
|
||||
def notify(body, title):
|
||||
def notify(body, title, attached=""):
|
||||
apobj = apprise.Apprise()
|
||||
config = apprise.AppriseConfig()
|
||||
config.add(APPRISE_CONFIG)
|
||||
apobj.add(config)
|
||||
apobj.notify(
|
||||
body=body,
|
||||
title=title,
|
||||
)
|
||||
if attached != "":
|
||||
apobj.notify(
|
||||
body=body,
|
||||
title=title,
|
||||
attach=attached,
|
||||
)
|
||||
else:
|
||||
apobj.notify(
|
||||
body=body,
|
||||
title=title,
|
||||
)
|
||||
|
||||
|
||||
def sendAppriseNotifications(species, confidence, path, date, time, week, latitude, longitude, cutoff, sens, overlap, settings_dict, db_path=DB_PATH):
|
||||
@@ -37,6 +45,25 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
websiteurl = "http://"+socket.gethostname()+".local"
|
||||
|
||||
listenurl = websiteurl+"?filename="+path
|
||||
image_url = ""
|
||||
flickr_images = {}
|
||||
|
||||
if len(settings_dict.get('FLICKR_API_KEY')) > 0 and "$flickrimage" in body:
|
||||
if not comName in flickr_images:
|
||||
try:
|
||||
# TODO: Make this work with non-english comnames. Implement the "// convert sci name to English name" logic from overview.php here
|
||||
url = 'https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key='+str(settings_dict.get('FLICKR_API_KEY'))+'&text='+str(comName)+' bird&sort=relevance&per_page=5&media=photos&format=json&license=2%2C3%2C4%2C5%2C6%2C9&nojsoncallback=1'
|
||||
resp = requests.get(url=url)
|
||||
data = resp.json()["photos"]["photo"][0]
|
||||
|
||||
image_url = 'https://farm'+str(data["farm"])+'.static.flickr.com/'+str(data["server"])+'/'+str(data["id"])+'_'+str(data["secret"])+'_n.jpg'
|
||||
flickr_images[comName] = image_url
|
||||
except Exception as e:
|
||||
print("FLICKR API ERROR: "+str(e))
|
||||
image_url = ""
|
||||
else:
|
||||
image_url = flickr_images[comName]
|
||||
|
||||
|
||||
if settings_dict.get('APPRISE_NOTIFY_EACH_DETECTION') == "1":
|
||||
notify_body = body.replace("$sciname", sciName)\
|
||||
@@ -50,6 +77,7 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)
|
||||
notify_title = title.replace("$sciname", sciName)\
|
||||
.replace("$comname", comName)\
|
||||
@@ -62,8 +90,9 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)
|
||||
notify(notify_body, notify_title)
|
||||
notify(notify_body, notify_title, image_url)
|
||||
|
||||
APPRISE_NOTIFICATION_NEW_SPECIES_DAILY_COUNT_LIMIT = 1 # Notifies the first N per day.
|
||||
if settings_dict.get('APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY') == "1":
|
||||
@@ -90,6 +119,7 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)\
|
||||
+ " (first time today)"
|
||||
notify_title = title.replace("$sciname", sciName)\
|
||||
@@ -103,9 +133,10 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)\
|
||||
+ " (first time today)"
|
||||
notify(notify_body, notify_title)
|
||||
notify(notify_body, notify_title, image_url)
|
||||
con.close()
|
||||
except sqlite3.Error as e:
|
||||
print(e)
|
||||
@@ -135,6 +166,7 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)\
|
||||
+ " (only seen " + str(int(numberDetections)) + " times in last 7d)"
|
||||
notify_title = title.replace("$sciname", sciName)\
|
||||
@@ -148,9 +180,10 @@ def sendAppriseNotifications(species, confidence, path, date, time, week, latitu
|
||||
.replace("$longitude", longitude)\
|
||||
.replace("$cutoff", cutoff)\
|
||||
.replace("$sens", sens)\
|
||||
.replace("$flickrimage", image_url if "{" in body else "")\
|
||||
.replace("$overlap", overlap)\
|
||||
+ " (only seen " + str(int(numberDetections)) + " times in last 7d)"
|
||||
notify(notify_body, notify_title)
|
||||
notify(notify_body, notify_title, image_url)
|
||||
con.close()
|
||||
except sqlite3.Error:
|
||||
print("Database busy")
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$startdate = strtotime('last sunday') - (7*86400);
|
||||
$enddate = strtotime('last sunday') - (1*86400);
|
||||
|
||||
$debug = false;
|
||||
|
||||
if(isset($_GET['ascii'])) {
|
||||
|
||||
$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
||||
if($db == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
|
||||
$statement1 = $db->prepare('SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'" GROUP By Com_Name ORDER BY COUNT(*) DESC');
|
||||
if($statement1 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result1 = $statement1->execute();
|
||||
|
||||
$statement4 = $db->prepare('SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'"');
|
||||
if($statement4 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result4 = $statement4->execute();
|
||||
$totalcount = $result4->fetchArray(SQLITE3_ASSOC)['COUNT(*)'];
|
||||
|
||||
$statement5 = $db->prepare('SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate- (7*86400)).'" AND "'.date("Y-m-d",$enddate- (7*86400)).'"');
|
||||
if($statement5 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result5 = $statement5->execute();
|
||||
$priortotalcount = $result5->fetchArray(SQLITE3_ASSOC)['COUNT(*)'];
|
||||
|
||||
$statement6 = $db->prepare('SELECT COUNT(DISTINCT(Com_Name)) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'"');
|
||||
if($statement6 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result6 = $statement6->execute();
|
||||
$totalspeciestally = $result6->fetchArray(SQLITE3_ASSOC)['COUNT(DISTINCT(Com_Name))'];
|
||||
|
||||
$statement7 = $db->prepare('SELECT COUNT(DISTINCT(Com_Name)) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate- (7*86400)).'" AND "'.date("Y-m-d",$enddate- (7*86400)).'"');
|
||||
if($statement7 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result7= $statement7->execute();
|
||||
$priortotalspeciestally = $result7->fetchArray(SQLITE3_ASSOC)['COUNT(DISTINCT(Com_Name))'];
|
||||
|
||||
$percentagedifftotal = round((1 - $priortotalcount / $totalcount) * 100);
|
||||
|
||||
if($percentagedifftotal > 0) {
|
||||
$percentagedifftotal = "<span style='color:green;font-size:small'>+".$percentagedifftotal."%</span>";
|
||||
} else {
|
||||
$percentagedifftotal = "<span style='color:red;font-size:small'>-".abs($percentagedifftotal)."%</span>";
|
||||
}
|
||||
|
||||
$percentagedifftotaldistinctspecies = round((1 - $priortotalspeciestally / $totalspeciestally) * 100);
|
||||
if($percentagedifftotaldistinctspecies > 0) {
|
||||
$percentagedifftotaldistinctspecies = "<span style='color:green;font-size:small'>+".$percentagedifftotaldistinctspecies."%</span>";
|
||||
} else {
|
||||
$percentagedifftotaldistinctspecies = "<span style='color:red;font-size:small'>-".abs($percentagedifftotaldistinctspecies)."%</span>";
|
||||
}
|
||||
|
||||
$detections = [];
|
||||
$i = 0;
|
||||
while($detection=$result1->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$detections[$detection["Com_Name"]] = $detection["COUNT(*)"];
|
||||
}
|
||||
|
||||
echo "# BirdNET-Pi: Week ".date('W', $enddate)." Report\n";
|
||||
|
||||
echo "Total Detections: <b>".$totalcount."</b> (".$percentagedifftotal.")<br>";
|
||||
echo "Unique Species Detected: <b>".$totalspeciestally."</b> (".$percentagedifftotaldistinctspecies.")<br><br>";
|
||||
|
||||
echo "= <b>Top 10 Species</b> =<br>";
|
||||
|
||||
$i = 0;
|
||||
foreach($detections as $com_name=>$scount)
|
||||
{
|
||||
$i++;
|
||||
|
||||
if($i <= 10) {
|
||||
$statement2 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Com_Name == "'.$com_name.'" AND Date BETWEEN "'.date("Y-m-d",$startdate - (7*86400)).'" AND "'.date("Y-m-d",$enddate - (7*86400)).'"');
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
$totalcount = $result2->fetchArray(SQLITE3_ASSOC);
|
||||
$priorweekcount = $totalcount['COUNT(*)'];
|
||||
|
||||
$percentagediff = round((1 - $priorweekcount / $scount) * 100);
|
||||
|
||||
if($percentagediff > 0) {
|
||||
$percentagediff = "<span style='color:green;font-size:small'>+".$percentagediff."%</span>";
|
||||
} else {
|
||||
$percentagediff = "<span style='color:red;font-size:small'>-".abs($percentagediff)."%</span>";
|
||||
}
|
||||
|
||||
echo $com_name." - ".$scount." (".$percentagediff.")<br>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "<br>= <b>Species Detected for the First Time</b> =<br>";
|
||||
|
||||
$newspeciescount=0;
|
||||
foreach($detections as $com_name=>$scount)
|
||||
{
|
||||
$statement3 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Com_Name == "'.$com_name.'" AND Date NOT BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'"');
|
||||
if($statement3 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result3 = $statement3->execute();
|
||||
$totalcount = $result3->fetchArray(SQLITE3_ASSOC);
|
||||
$nonthisweekcount = $totalcount['COUNT(*)'];
|
||||
|
||||
if($nonthisweekcount == 0) {
|
||||
$newspeciescount++;
|
||||
echo $com_name." - ".$scount."<br>";
|
||||
}
|
||||
}
|
||||
if($newspeciescount == 0) {
|
||||
echo "No new species were seen this week.";
|
||||
}
|
||||
|
||||
echo "<hr><small>* data from ".date('Y-m-d', $startdate)." — ".date('Y-m-d',$enddate).".</small><br>";
|
||||
echo '<small>* percentages are calculated relative to week '.(date('W', $enddate) - 1).'.</small>';
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="brbanner"> <?php
|
||||
echo "<h1>Week ".date('W', $enddate)." Report</h1>".date('F jS, Y',$startdate)." — ".date('F jS, Y',$enddate)."<br>";
|
||||
?></div><?php
|
||||
|
||||
$db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
|
||||
if($db == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
|
||||
if($debug == false){
|
||||
$statement1 = $db->prepare('SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'" GROUP By Com_Name ORDER BY COUNT(*) DESC');
|
||||
} else {
|
||||
$statement1 = $db->prepare('SELECT DISTINCT(Com_Name), COUNT(*) FROM detections WHERE Date BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'" GROUP By Com_Name ORDER BY COUNT(*) ASC');
|
||||
}
|
||||
if($statement1 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result1 = $statement1->execute();
|
||||
|
||||
$detections = [];
|
||||
$i = 0;
|
||||
while($detection=$result1->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
if($debug == true){
|
||||
if($i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
$detections[$detection["Com_Name"]] = $detection["COUNT(*)"];
|
||||
|
||||
}
|
||||
?>
|
||||
<br>
|
||||
<?php // TODO: fix the box shadows, maybe make them a bit smaller on the tr ?>
|
||||
<table align="center" style="box-shadow:unset"><tr><td style="background-color:#77c487">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo "Top 10 Species: <br>"; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
$i = 0;
|
||||
foreach($detections as $com_name=>$scount)
|
||||
{
|
||||
$i++;
|
||||
if($i <= 10) {
|
||||
$statement2 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Com_Name == "'.$com_name.'" AND Date BETWEEN "'.date("Y-m-d",$startdate - (7*86400)).'" AND "'.date("Y-m-d",$enddate - (7*86400)).'"');
|
||||
if($statement2 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result2 = $statement2->execute();
|
||||
$totalcount = $result2->fetchArray(SQLITE3_ASSOC);
|
||||
$priorweekcount = $totalcount['COUNT(*)'];
|
||||
|
||||
$percentagediff = round((1 - $priorweekcount / $scount) * 100);
|
||||
|
||||
if($percentagediff > 0) {
|
||||
$percentagediff = "<span style='color:green;font-size:small'>+".$percentagediff."%</span>";
|
||||
} else {
|
||||
$percentagediff = "<span style='color:red;font-size:small'>-".abs($percentagediff)."%</span>";
|
||||
}
|
||||
|
||||
echo "<tr><td>".$com_name."<br><small style=\"font-size:small\">".$scount." (".$percentagediff.")</small><br></td></tr>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</td><td style="background-color:#77c487">
|
||||
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo "Species Detected for the First Time: <br>"; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
$newspeciescount=0;
|
||||
foreach($detections as $com_name=>$scount)
|
||||
{
|
||||
$statement3 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Com_Name == "'.$com_name.'" AND Date NOT BETWEEN "'.date("Y-m-d",$startdate).'" AND "'.date("Y-m-d",$enddate).'"');
|
||||
if($statement3 == False){
|
||||
echo "Database is busy";
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result3 = $statement3->execute();
|
||||
$totalcount = $result3->fetchArray(SQLITE3_ASSOC);
|
||||
$nonthisweekcount = $totalcount['COUNT(*)'];
|
||||
|
||||
if($nonthisweekcount == 0) {
|
||||
$newspeciescount++;
|
||||
echo "<tr><td>".$com_name."<br><small style=\"font-size:small\">".$scount."</small><br></td></tr>";
|
||||
}
|
||||
}
|
||||
if($newspeciescount == 0) {
|
||||
echo "<tr><td>No new species were seen this week.</td></tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
<br>
|
||||
<div style="text-align:center">
|
||||
<hr><small style="font-size:small">* percentages are calculated relative to week <?php echo date('W', $enddate) - 1; ?></small>
|
||||
</div>
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
source /etc/birdnet/birdnet.conf
|
||||
if [ ${APPRISE_WEEKLY_REPORT} == 1 ];then
|
||||
NOTIFICATION=$(curl 'localhost/views.php?view=Weekly%20Report&ascii=true')
|
||||
NOTIFICATION=${NOTIFICATION#*#}
|
||||
firstLine=`echo "${NOTIFICATION}" | head -1`
|
||||
NOTIFICATION=`echo "${NOTIFICATION}" | tail -n +2`
|
||||
$HOME/BirdNET-Pi/birdnet/bin/apprise -vv -t "${firstLine}" -b "${NOTIFICATION}" --input-format=html --config=$HOME/BirdNET-Pi/apprise.txt
|
||||
fi
|
||||
Reference in New Issue
Block a user