$site_name


"; } $db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_READONLY); $db->busyTimeout(1000); $statement1 = $db->prepare('SELECT COUNT(*) FROM detections'); ensure_db_ok($statement1); $result1 = $statement1->execute(); $totalcount = $result1->fetchArray(SQLITE3_ASSOC); $statement2 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Date == DATE(\'now\', \'localtime\')'); ensure_db_ok($statement2); $result2 = $statement2->execute(); $todaycount = $result2->fetchArray(SQLITE3_ASSOC); $statement3 = $db->prepare('SELECT COUNT(*) FROM detections WHERE Date == Date(\'now\', \'localtime\') AND TIME >= TIME(\'now\', \'localtime\', \'-1 hour\')'); ensure_db_ok($statement3); $result3 = $statement3->execute(); $hourcount = $result3->fetchArray(SQLITE3_ASSOC); $statement4 = $db->prepare('SELECT Com_Name, Sci_Name, Time, Confidence FROM detections LIMIT 1'); ensure_db_ok($statement4); $result4 = $statement4->execute(); $mostrecent = $result4->fetchArray(SQLITE3_ASSOC); $statement5 = $db->prepare('SELECT COUNT(DISTINCT(Com_Name)) FROM detections WHERE Date == Date(\'now\', \'localtime\')'); ensure_db_ok($statement5); $result5 = $statement5->execute(); $todayspeciestally = $result5->fetchArray(SQLITE3_ASSOC); $statement6 = $db->prepare('SELECT COUNT(DISTINCT(Com_Name)) FROM detections'); ensure_db_ok($statement6); $result6 = $statement6->execute(); $totalspeciestally = $result6->fetchArray(SQLITE3_ASSOC); $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['comname'])) { $birdName = $_GET['comname']; $birdName = str_replace("_", " ", $birdName); // Prepare a SQL statement to retrieve the detection data for the specified bird $stmt = $db->prepare('SELECT Date, COUNT(*) AS Detections FROM detections WHERE Com_Name = :com_name AND Date BETWEEN DATE("now", "-30 days") AND DATE("now") GROUP BY Date'); // Bind the bird name parameter to the SQL statement $stmt->bindValue(':com_name', $birdName); // Execute the SQL statement and get the result set $result = $stmt->execute(); // Fetch the result set as an associative array $data = array(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $data[$row['Date']] = $row['Detections']; } // Create an array of all dates in the last 14 days $last14Days = array(); for ($i = 0; $i < 31; $i++) { $last14Days[] = date('Y-m-d', strtotime("-$i days")); } // Merge the data array with the last14Days array $data = array_merge(array_fill_keys($last14Days, 0), $data); // Sort the data by date in ascending order ksort($data); // Convert the data to an array of objects $data = array_map(function($date, $count) { return array('date' => $date, 'count' => $count); }, array_keys($data), $data); // Close the database connection $db->close(); // Return the data as JSON echo json_encode($data); die(); } // from https://stackoverflow.com/questions/2690504/php-producing-relative-date-time-from-timestamps function relativeTime($ts) { if(!ctype_digit($ts)) $ts = strtotime($ts); $diff = time() - $ts; if($diff == 0) return 'now'; elseif($diff > 0) { $day_diff = floor($diff / 86400); if($day_diff == 0) { if($diff < 60) return 'just now'; if($diff < 120) return '1 minute ago'; if($diff < 3600) return floor($diff / 60) . ' minutes ago'; if($diff < 7200) return '1 hour ago'; if($diff < 86400) return floor($diff / 3600) . ' hours ago'; } if($day_diff == 1) return 'Yesterday'; if($day_diff < 7) return $day_diff . ' days ago'; if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago'; if($day_diff < 60) return 'last month'; return date('F Y', $ts); } else { $diff = abs($diff); $day_diff = floor($diff / 86400); if($day_diff == 0) { if($diff < 120) return 'in a minute'; if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes'; if($diff < 7200) return 'in an hour'; if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours'; } if($day_diff == 1) return 'Tomorrow'; if($day_diff < 4) return date('l', $ts); if($day_diff < 7 + (7 - date('w'))) return 'next week'; if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks'; if(date('n', $ts) == date('n') + 1) return 'next month'; return date('F Y', $ts); } } if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) { if(isset($_GET['searchterm'])) { if(strtolower(explode(" ", $_GET['searchterm'])[0]) == "not") { $not = "NOT "; $operator = "AND"; $_GET['searchterm'] = str_replace("not ", "", $_GET['searchterm']); $_GET['searchterm'] = str_replace("NOT ", "", $_GET['searchterm']); } else { $not = ""; $operator = "OR"; } $searchquery = "AND (Com_name ".$not."LIKE '%".$_GET['searchterm']."%' ".$operator." Sci_name ".$not."LIKE '%".$_GET['searchterm']."%' ".$operator." Confidence ".$not."LIKE '%".$_GET['searchterm']."%' ".$operator." File_Name ".$not."LIKE '%".$_GET['searchterm']."%' ".$operator." Time ".$not."LIKE '%".$_GET['searchterm']."%')"; } else { $searchquery = ""; } if(isset($_GET['display_limit']) && is_numeric($_GET['display_limit'])){ $statement0 = $db->prepare('SELECT Time, Com_Name, Sci_Name, Confidence, File_Name FROM detections WHERE Date == Date(\'now\', \'localtime\') '.$searchquery.' ORDER BY Time DESC LIMIT '.(intval($_GET['display_limit'])-40).',40'); } else { // legacy mode if(isset($_GET['hard_limit']) && is_numeric($_GET['hard_limit'])) { $statement0 = $db->prepare('SELECT Time, Com_Name, Sci_Name, Confidence, File_Name FROM detections WHERE Date == Date(\'now\', \'localtime\') '.$searchquery.' ORDER BY Time DESC LIMIT '.$_GET['hard_limit']); } else { $statement0 = $db->prepare('SELECT Time, Com_Name, Sci_Name, Confidence, File_Name FROM detections WHERE Date == Date(\'now\', \'localtime\') '.$searchquery.' ORDER BY Time DESC'); } } ensure_db_ok($statement0); $result0 = $statement0->execute(); ?> fetchArray(SQLITE3_ASSOC)) { $iterations++; $comname = preg_replace('/ /', '_', $todaytable['Com_Name']); $comname = preg_replace('/\'/', '_', $comname); $filename = "/By_Date/".date('Y-m-d')."/".$comname."/".$todaytable['File_Name']; $filename_formatted = $todaytable['Date']."/".$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']) || $_GET['kiosk'] == true) ) { if(!empty($config["FLICKR_FILTER_EMAIL"])) { if(!isset($_SESSION["FLICKR_FILTER_EMAIL"])) { unset($_SESSION['images']); $_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"]); unset($_SESSION['images']); } } // if we already searched flickr for this species before, use the previous image rather than doing an unneccesary api call $key = array_search($comname, array_column($_SESSION['images'], 0)); if($key !== false) { $image = $_SESSION['images'][$key]; } else { // Get license information if we haven't already if (empty($licenses_urls)) { $licenses_url = "https://api.flickr.com/services/rest/?method=flickr.photos.licenses.getInfo&api_key=".$config["FLICKR_API_KEY"]."&format=json&nojsoncallback=1"; $licenses_response = file_get_contents($licenses_url); $licenses_data = json_decode($licenses_response, true)["licenses"]["license"]; foreach ($licenses_data as $license) { $license_id = $license["id"]; $license_name = $license["name"]; $license_url = $license["url"]; $licenses_urls[$license_id] = $license_url; } } // only open the file once per script execution if(!isset($lines)) { $lines = file($home."/BirdNET-Pi/model/labels_flickr.txt"); } // convert sci name to English name foreach($lines as $line){ if(strpos($line, $todaytable['Sci_Name']) !== false){ $engname = trim(explode("_", $line)[1]); break; } } // Read the blacklisted image ids from the file into an array $blacklisted_file = file($home."/BirdNET-Pi/scripts/blacklisted_images.txt"); if ($blacklisted_file) { $blacklisted_ids = array_map('trim', $blacklisted_file); } else { $blacklisted_ids = []; } // Make the API call $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"]; // Find the first photo that is not blacklisted or is not the specific blacklisted id $photo = null; foreach ($flickrjson as $flickrphoto) { if ($flickrphoto["id"] !== "4892923285" && !in_array($flickrphoto["id"], $blacklisted_ids)) { $photo = $flickrphoto; break; } } $license_url = "https://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=".$config["FLICKR_API_KEY"]."&photo_id=".$photo["id"]."&format=json&nojsoncallback=1"; $license_response = file_get_contents($license_url); $license_info = json_decode($license_response, true)["photo"]["license"]; $license_url = $licenses_urls[$license_info]; $modaltext = "https://flickr.com/photos/".$photo["owner"]."/".$photo["id"]; $authorlink = "https://flickr.com/people/".$photo["owner"]; $imageurl = 'https://farm' .$photo["farm"]. '.static.flickr.com/' .$photo["server"]. '/' .$photo["id"]. '_' .$photo["secret"]. '.jpg'; array_push($_SESSION['images'], array($comname,$imageurl,$photo["title"], $modaltext, $authorlink, $license_url)); $image = $_SESSION['images'][count($_SESSION['images'])-1]; } } ?>
0) { ?>


Confidence:


0) { ?>
Confidence:
No Detections For Today."; } // 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'])) { ?>
Total Today Last Hour Unique Species Total Unique Species Today
BirdNET-Pi DB

Number of Detections

Total Today Last Hour Unique Species Total Unique Species Today

Today's Detections

Loading...