Flickr Implementation
This commit is contained in:
@@ -62,6 +62,10 @@ 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=false
|
||||
|
||||
#---------------------- Flickr Images API Configuration -----------------------#
|
||||
|
||||
FLICKR_API_KEY=
|
||||
|
||||
################################################################################
|
||||
#-------------------------------- Defaults ----------------------------------#
|
||||
################################################################################
|
||||
|
||||
+33
-1
@@ -585,4 +585,36 @@ tr {
|
||||
input {
|
||||
box-shadow: 0px 0px 17px 1px rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
dialog {
|
||||
border:none;
|
||||
}
|
||||
dialog::backdrop {
|
||||
background: repeating-linear-gradient(
|
||||
30deg,
|
||||
rgba(24, 194, 236, 0.2),
|
||||
rgba(24, 194, 236, 0.2) 1px,
|
||||
rgba(24, 194, 236, 0.3) 1px,
|
||||
rgba(24, 194, 236, 0.3) 20px
|
||||
);
|
||||
backdrop-filter: blur(1px)
|
||||
}
|
||||
.centered_image_container {
|
||||
font-size:19px !important;
|
||||
display:inline-block;
|
||||
position:relative;
|
||||
margin-bottom:3px;
|
||||
}
|
||||
.centered_image_container img.img1 {
|
||||
cursor:pointer;
|
||||
height:95%;
|
||||
position:absolute;
|
||||
right:110%;
|
||||
top:0px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.centered_image_container * {
|
||||
font-size:19px !important;
|
||||
}
|
||||
.centered_image_container form {
|
||||
margin-bottom:0px;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ $birdweather_id = $_GET["birdweather_id"];
|
||||
$apprise_input = $_GET['apprise_input'];
|
||||
$apprise_notification_title = $_GET['apprise_notification_title'];
|
||||
$apprise_notification_body = $_GET['apprise_notification_body'];
|
||||
$flickr_api_key = $_GET['flickr_api_key'];
|
||||
if(isset($_GET['apprise_notify_each_detection'])) {
|
||||
$apprise_notify_each_detection = 1;
|
||||
} else {
|
||||
@@ -45,6 +46,7 @@ $contents = preg_replace("/BIRDWEATHER_ID=.*/", "BIRDWEATHER_ID=$birdweather_id"
|
||||
$contents = preg_replace("/APPRISE_NOTIFICATION_TITLE=.*/", "APPRISE_NOTIFICATION_TITLE=\"$apprise_notification_title\"", $contents);
|
||||
$contents = preg_replace("/APPRISE_NOTIFICATION_BODY=.*/", "APPRISE_NOTIFICATION_BODY=\"$apprise_notification_body\"", $contents);
|
||||
$contents = preg_replace("/APPRISE_NOTIFY_EACH_DETECTION=.*/", "APPRISE_NOTIFY_EACH_DETECTION=$apprise_notify_each_detection", $contents);
|
||||
$contents = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents);
|
||||
|
||||
|
||||
$contents2 = file_get_contents("./scripts/thisrun.txt");
|
||||
@@ -54,6 +56,8 @@ $contents2 = preg_replace("/BIRDWEATHER_ID=.*/", "BIRDWEATHER_ID=$birdweather_id
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFICATION_TITLE=.*/", "APPRISE_NOTIFICATION_TITLE=\"$apprise_notification_title\"", $contents2);
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFICATION_BODY=.*/", "APPRISE_NOTIFICATION_BODY=\"$apprise_notification_body\"", $contents2);
|
||||
$contents2 = preg_replace("/APPRISE_NOTIFY_EACH_DETECTION=.*/", "APPRISE_NOTIFY_EACH_DETECTION=$apprise_notify_each_detection", $contents2);
|
||||
$contents2 = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents2);
|
||||
|
||||
|
||||
$fh = fopen("/etc/birdnet/birdnet.conf", "w");
|
||||
$fh2 = fopen("./scripts/thisrun.txt", "w");
|
||||
@@ -144,6 +148,10 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}
|
||||
<label for="apprise_notify_each_species">Notify each new species</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>
|
||||
<h3>Bird Photos from Flickr</h3>
|
||||
<label for="flickr_api_key">Flickr API Key: </label>
|
||||
<input name="flickr_api_key" type="text" value="<?php print($config['FLICKR_API_KEY']);?>" required/><br>
|
||||
<p>Set your Flickr API key to enable the display of bird images next to detections. <a href="https://www.flickr.com/services/api/misc.api_keys.html">Get your free key here.</a></p>
|
||||
<h3>Localization</h3>
|
||||
<label for="language">Database Language: </label>
|
||||
<select name="language">
|
||||
|
||||
@@ -75,6 +75,10 @@ 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=false
|
||||
|
||||
#---------------------- Flickr Images API Configuration -----------------------#
|
||||
|
||||
FLICKR_API_KEY=
|
||||
|
||||
################################################################################
|
||||
#-------------------------------- Defaults ----------------------------------#
|
||||
################################################################################
|
||||
|
||||
+52
-6
@@ -8,6 +8,12 @@ if($db == False) {
|
||||
header("refresh: 0;");
|
||||
}
|
||||
|
||||
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['ajax_detections']) && $_GET['ajax_detections'] == "true" && isset($_GET['previous_detection_identifier'])) {
|
||||
|
||||
$statement4 = $db->prepare('SELECT Com_Name, Sci_Name, Date, Time, Confidence, File_Name FROM detections ORDER BY Date DESC, Time DESC LIMIT 5');
|
||||
@@ -16,6 +22,8 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
header("refresh: 0;");
|
||||
}
|
||||
$result4 = $statement4->execute();
|
||||
$images = [];
|
||||
$iterations = 0;
|
||||
// hopefully one of the 5 most recent detections has an image that is valid, we'll use that one as the most recent detection until the newer ones get their images created
|
||||
while($mostrecent = $result4->fetchArray(SQLITE3_ASSOC)) {
|
||||
$comname = preg_replace('/ /', '_', $mostrecent['Com_Name']);
|
||||
@@ -37,6 +45,22 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
// we've found our valid detection! ignore everything else from the database loop
|
||||
if(strpos($headers[0],'200')) {
|
||||
if($_GET['previous_detection_identifier'] == $filename) { die(); }
|
||||
|
||||
if (!empty($config["FLICKR_API_KEY"])) {
|
||||
// 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($images, 0));
|
||||
if($key !== false) {
|
||||
$image = $images[$key];
|
||||
} else {
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=".$comname."&license=7%2C9%2C10&sort=relevance&per_page=5&orientation=landscape,square&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 = 'http://farm' .$flickrjson["farm"]. '.static.flickr.com/' .$flickrjson["server"]. '/' .$flickrjson["id"]. '_' .$flickrjson["secret"]. '.jpg';
|
||||
array_push($images, array($comname,$imageurl,$flickrjson["title"], $modaltext, $authorlink));
|
||||
$image = $images[count($images)-1];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<style>
|
||||
.fade-in {
|
||||
@@ -60,11 +84,15 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse
|
||||
<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>
|
||||
<div class="centered_image_container" style="margin-bottom: 0px !important;">
|
||||
<?php if(!empty($config["FLICKR_API_KEY"])) { ?>
|
||||
<img onclick='setModalText(<?php echo $iterations; ?>,"<?php echo $image[2] ?>", "<?php echo $image[3]; ?>", "<?php echo $image[4]; ?>")' src="<?php echo $image[1]; ?>" class="img1">
|
||||
<?php } ?>
|
||||
<form action="" method="GET">
|
||||
<input type="hidden" name="view" value="Species Stats">
|
||||
<button type="submit" name="species" value="<?php echo $mostrecent['Com_Name'];?>"><?php echo $mostrecent['Com_Name'];?></button></br>
|
||||
<a href="https://wikipedia.org/wiki/<?php echo $sciname;?>" target="_blank"/><i><?php echo $mostrecent['Sci_Name'];?></i></a>
|
||||
<br>Confidence: <?php echo round($mostrecent['Confidence'],2);?><br>
|
||||
<br>Confidence: <?php echo round($mostrecent['Confidence'],2);?><br></div><br>
|
||||
<video style="margin-top:10px" 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;?>"></video></td>
|
||||
</form>
|
||||
</tr>
|
||||
@@ -153,17 +181,35 @@ body::-webkit-scrollbar {
|
||||
</style>
|
||||
</head>
|
||||
<div class="overview">
|
||||
<dialog id="attribution-dialog">
|
||||
<h1 id="modalHeading"></h1>
|
||||
<p id="modalText"></p>
|
||||
<button onclick="hideDialog()">Close</button>
|
||||
</dialog>
|
||||
<script>
|
||||
var dialog = document.querySelector('dialog');
|
||||
dialogPolyfill.registerDialog(dialog);
|
||||
|
||||
function showDialog() {
|
||||
document.getElementById('attribution-dialog').showModal();
|
||||
}
|
||||
|
||||
function hideDialog() {
|
||||
document.getElementById('attribution-dialog').close();
|
||||
}
|
||||
|
||||
function setModalText(iter, title, text, authorlink) {
|
||||
document.getElementById('modalHeading').innerHTML = "Photo: \""+title+"\" Attribution";
|
||||
document.getElementById('modalText').innerHTML = "Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a>";
|
||||
showDialog();
|
||||
}
|
||||
</script>
|
||||
<div class="overview-stats">
|
||||
<div class="left-column">
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div class="chart">
|
||||
<?php
|
||||
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');
|
||||
}
|
||||
$refresh = $config['RECORDING_LENGTH'];
|
||||
$time = time();
|
||||
if (file_exists('./Charts/'.$chart)) {
|
||||
|
||||
+33
-11
@@ -117,14 +117,37 @@ $filename = "/By_Date/".$results['Date']."/".$comname."/".$results['File_Name'];
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<dialog id="attribution-dialog">
|
||||
<h1 id="modalHeading"></h1>
|
||||
<p id="modalText"></p>
|
||||
<button onclick="hideDialog()">Close</button>
|
||||
</dialog>
|
||||
<script>
|
||||
var dialog = document.querySelector('dialog');
|
||||
dialogPolyfill.registerDialog(dialog);
|
||||
|
||||
function showDialog() {
|
||||
document.getElementById('attribution-dialog').showModal();
|
||||
}
|
||||
|
||||
function hideDialog() {
|
||||
document.getElementById('attribution-dialog').close();
|
||||
}
|
||||
|
||||
function setModalText(iter, title, text, authorlink) {
|
||||
document.getElementById('modalHeading').innerHTML = "Photo "+iter+": \""+title+"\" Attribution";
|
||||
document.getElementById('modalText').innerHTML = "Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a>";
|
||||
showDialog();
|
||||
}
|
||||
</script>
|
||||
<div class="column center">
|
||||
<?php if(!isset($_GET['species'])){
|
||||
?><p class="centered">Choose a species to load images from Wikimedia Commons.</p>
|
||||
?><p class="centered">Choose a species to load images from Flickr.</p>
|
||||
<?php
|
||||
};?>
|
||||
<?php if(isset($_GET['species'])){
|
||||
$species = $_GET['species'];
|
||||
|
||||
$iter=0;
|
||||
while($results=$result3->fetchArray(SQLITE3_ASSOC)){
|
||||
$count = $results['COUNT(*)'];
|
||||
$maxconf = round($results['MAX(Confidence)'],2);
|
||||
@@ -147,20 +170,19 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster=\"$filename.png\" title=\"$filename\"><source src=\"$filename\"></video></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Loading Images from <a href=\"https://commons.wikimedia.org/w/index.php?search=$linkname&title=Special:MediaSearch&go=Go&type=image\" target=\"_blank\">Wikimedia Commons</a></p>", '6096');
|
||||
<p>Loading Images from Flickr</p>", '6096');
|
||||
|
||||
echo "<script>document.getElementsByTagName(\"h3\")[0].scrollIntoView();</script>";
|
||||
|
||||
ob_flush();
|
||||
flush();
|
||||
$imagelink = "https://commons.wikimedia.org/w/index.php?search=$linkname&title=Special:MediaSearch&go=Go&type=image";
|
||||
$homepage = file_get_contents($imagelink);
|
||||
preg_match_all("{<img\\s*(.*?)src=('.*?'|\".*?\"|[^\\s]+)(.*?)\\s*/?>}ims", $homepage, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $val) {
|
||||
$pos = strpos($val[2],"/");
|
||||
$link = substr($val[2],1,-1);
|
||||
if($pos !== 1 && strpos($link, "upload") == true && strpos($link, "CentralAutoLogin") == false)
|
||||
echo "<img src=\"$link\">";
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=2158f6c5d66e89778bd0d340953f1bcf&text=\"".str_replace('_', '+', $comname)."\"&license=2%2C3%2C4%2C5%2C6%2C9&sort=relevance&per_page=15&format=json&nojsoncallback=1"), true)["photos"]["photo"];
|
||||
foreach ($flickrjson as $val) {
|
||||
$iter++;
|
||||
$modaltext = "https://flickr.com/photos/".$val["owner"]."/".$val["id"];
|
||||
$authorlink = "https://flickr.com/people/".$val["owner"];
|
||||
$imageurl = 'http://farm' .$val["farm"]. '.static.flickr.com/' .$val["server"]. '/' .$val["id"]. '_' .$val["secret"]. '.jpg';
|
||||
echo "<img style='vertical-align:top' src=\"$imageurl\"><span style='cursor:pointer;color:blue;text-decoration:underline;' onclick='setModalText(".$iter.",\"".$val["title"]."\",\"".$modaltext."\", \"".$authorlink."\")'>".$iter."</span>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,15 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
|
||||
?> <table>
|
||||
<?php
|
||||
$images = [];
|
||||
$iterations = 0;
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
while($todaytable=$result0->fetchArray(SQLITE3_ASSOC))
|
||||
{
|
||||
$iterations++;
|
||||
@@ -86,13 +94,35 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
$comname = preg_replace('/\'/', '_', $comname);
|
||||
$filename = "/By_Date/".date('Y-m-d')."/".$comname."/".$todaytable['File_Name'];
|
||||
$sciname = preg_replace('/ /', '_', $todaytable['Sci_Name']);
|
||||
|
||||
if (!empty($config["FLICKR_API_KEY"])) {
|
||||
// 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($images, 0));
|
||||
if($key !== false) {
|
||||
$image = $images[$key];
|
||||
} else {
|
||||
$flickrjson = json_decode(file_get_contents("https://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=".$config["FLICKR_API_KEY"]."&text=".$comname."&license=7%2C9%2C10&sort=relevance&per_page=5&orientation=landscape,square&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 = 'http://farm' .$flickrjson["farm"]. '.static.flickr.com/' .$flickrjson["server"]. '/' .$flickrjson["id"]. '_' .$flickrjson["secret"]. '.jpg';
|
||||
array_push($images, array($comname,$imageurl,$flickrjson["title"], $modaltext, $authorlink));
|
||||
$image = $images[count($images)-1];
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?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><?php echo $todaytable['Time'];?><br>
|
||||
<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>
|
||||
|
||||
<div class="centered_image_container">
|
||||
<?php if(!empty($config["FLICKR_API_KEY"])) { ?>
|
||||
<img onclick='setModalText(<?php echo $iterations; ?>,"<?php echo $image[2] ?>", "<?php echo $image[3]; ?>", "<?php echo $image[4]; ?>")' src="<?php echo $image[1]; ?>" class="img1">
|
||||
<?php } ?>
|
||||
|
||||
<?php echo $todaytable['Time'];?><br>
|
||||
<b><a class="a2" href="https://allaboutbirds.org/guide/<?php echo $comname;?>" target="top"><?php echo $todaytable['Com_Name'];?></a></b><br>
|
||||
<a class="a2" href="https://wikipedia.org/wiki/<?php echo $sciname;?>" target="top"><i><?php echo $todaytable['Sci_Name'];?></i></a><br>
|
||||
<b>Confidence:</b> <?php echo round($todaytable['Confidence'],2);?><br>
|
||||
<b>Confidence:</b> <?php echo round($todaytable['Confidence'],2);?><br></div><br>
|
||||
<video onplay='setLiveStreamVolume(0)' onended='setLiveStreamVolume(1)' onpause='setLiveStreamVolume(1)' controls poster="<?php echo $filename.".png";?>" preload="none" title="<?php echo $filename;?>"><source preload="none" src="<?php echo $filename;?>"></video>
|
||||
</td>
|
||||
<?php } else { //legacy mode ?>
|
||||
@@ -132,6 +162,29 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) {
|
||||
</style>
|
||||
</head>
|
||||
<div class="viewdb">
|
||||
<dialog id="attribution-dialog">
|
||||
<h1 id="modalHeading"></h1>
|
||||
<p id="modalText"></p>
|
||||
<button onclick="hideDialog()">Close</button>
|
||||
</dialog>
|
||||
<script>
|
||||
var dialog = document.querySelector('dialog');
|
||||
dialogPolyfill.registerDialog(dialog);
|
||||
|
||||
function showDialog() {
|
||||
document.getElementById('attribution-dialog').showModal();
|
||||
}
|
||||
|
||||
function hideDialog() {
|
||||
document.getElementById('attribution-dialog').close();
|
||||
}
|
||||
|
||||
function setModalText(iter, title, text, authorlink) {
|
||||
document.getElementById('modalHeading').innerHTML = "Photo "+iter+": \""+title+"\" Attribution";
|
||||
document.getElementById('modalText').innerHTML = "Image link: <a target='_blank' href="+text+">"+text+"</a><br>Author link: <a target='_blank' href="+authorlink+">"+authorlink+"</a>";
|
||||
showDialog();
|
||||
}
|
||||
</script>
|
||||
<h3>Number of Detections</h3>
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
@@ -50,3 +50,6 @@ if grep bash $HOME/BirdNET-Pi/templates/web_terminal.service;then
|
||||
sudo systemctl restart web_terminal.service
|
||||
fi
|
||||
[ -L ~/BirdSongs/Extracted/static ] || ln -sf ~/BirdNET-Pi/homepage/static ~/BirdSongs/Extracted
|
||||
if ! grep FLICKR_API_KEY /etc/birdnet/birdnet.conf &>/dev/null;then
|
||||
sudo -u$USER echo "FLICKR_API_KEY=" >> /etc/birdnet/birdnet.conf
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user