From 354fce1aaf69b1f6f5a6d4a55689ce10e5f812db Mon Sep 17 00:00:00 2001 From: Patrick McGuire <60325264+mcguirepr89@users.noreply.github.com> Date: Wed, 18 May 2022 16:44:26 -0400 Subject: [PATCH 01/46] Update install_services.sh --- scripts/install_services.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install_services.sh b/scripts/install_services.sh index b909977..093047b 100755 --- a/scripts/install_services.sh +++ b/scripts/install_services.sh @@ -11,7 +11,7 @@ export HOME=$HOME install_depends() { apt install -y debian-keyring debian-archive-keyring apt-transport-https - curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc + curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list apt -qqq update && apt -qqy upgrade echo "icecast2 icecast2/icecast-setup boolean false" | debconf-set-selections From ed045683224dcfb523dbaed027d3817f59d1e2c3 Mon Sep 17 00:00:00 2001 From: CaiusX Date: Thu, 19 May 2022 11:05:28 +0200 Subject: [PATCH 02/46] Further enhancements to Species Stats for user testing and feedback --- scripts/plotly_streamlit.py | 59 +++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/scripts/plotly_streamlit.py b/scripts/plotly_streamlit.py index da8d771..2d7eb6a 100755 --- a/scripts/plotly_streamlit.py +++ b/scripts/plotly_streamlit.py @@ -8,6 +8,7 @@ from datetime import timedelta, datetime from pathlib import Path import sqlite3 from sqlite3 import Connection +import plotly.express as px userDir = os.path.expanduser('~') URI_SQLITE_DB = userDir + '/BirdNET-Pi/scripts/birds.db' @@ -122,42 +123,43 @@ filt=df2['Com_Name']==specie df_counts=sum(df5==specie) -fig = make_subplots( + + + +if resample_time != '1D': + fig = make_subplots( rows=3, cols =2, specs= [[{"type":"xy","rowspan":3}, {"type":"polar","rowspan":2}], [{"rowspan":1}, {"rowspan":1} ], [None, {"type":"xy","rowspan":1}]], - subplot_titles=('Top '+ str(top_N) + ' Species in Date Range '+str(Date_Slider[0])+' to '+str(Date_Slider[1])+'', + subplot_titles=('Top '+ str(top_N) + ' Species in Date Range '+str(Date_Slider[0])+' to '+str(Date_Slider[1])+' for '+str(resample_sel)+' sampling interval.'+'', 'Total Detect:'+str('{:,}'.format(df_counts))+ ' Confidence Max:'+str('{:.2f}%'.format(max(df2[df2['Com_Name']==specie]['Confidence'])*100))+ ' '+' Median:'+str('{:.2f}%'.format(np.median(df2[df2['Com_Name']==specie]['Confidence'])*100)) ) - ) -fig.layout.annotations[1].update(x=0.7,y=0.25, font_size=15) + ) + fig.layout.annotations[1].update(x=0.7,y=0.25, font_size=15) -#Plot seen species for selected date range and number of species -fig.add_trace(go.Bar(y=top_N_species.index, x=top_N_species, orientation='h'), row=1,col=1) + #Plot seen species for selected date range and number of species + fig.add_trace(go.Bar(y=top_N_species.index, x=top_N_species, orientation='h'), row=1,col=1) -fig.update_layout( - margin=dict(l=0, r=0, t=50, b=0), - yaxis={'categoryorder':'total ascending'}) + fig.update_layout( + margin=dict(l=0, r=0, t=50, b=0), + yaxis={'categoryorder':'total ascending'}) -# Set 360 degrees, 24 hours for polar plot -theta = np.linspace(0.0, 360, 24, endpoint=False) + # Set 360 degrees, 24 hours for polar plot + theta = np.linspace(0.0, 360, 24, endpoint=False) -specie_filt= df5==specie -df3=df5[specie_filt] + specie_filt= df5==specie + df3=df5[specie_filt] -detections2= pd.crosstab(df3, df3.index.hour) + detections2= pd.crosstab(df3, df3.index.hour) -d=pd.DataFrame(np.zeros((23,1))).squeeze() -detections = hourly.loc[specie] -detections=(d+detections).fillna(0) - - -if resample_time != '1D': + d=pd.DataFrame(np.zeros((23,1))).squeeze() + detections = hourly.loc[specie] + detections=(d+detections).fillna(0) fig.add_trace(go.Barpolar(r = detections, theta=theta), row=1, col=2) fig.update_layout( autosize=False, @@ -191,15 +193,18 @@ if resample_time != '1D': else: fig = make_subplots( rows=1, cols =2, -# specs= [[{"type":"xy","rowspan":1}], -# [{"rowspan":1}], -# ], -# subplot_titles=('Top '+ str(top_N) + ' Species in Date Range '+str(Date_Slider[0])+' to '+str(Date_Slider[1])+'', + specs= [[{"type":"xy","rowspan":1},{"type":"xy","rowspan":1}]], + + + subplot_titles=('Daily Top '+ str(top_N) + ' Species in Date Range '+str(Date_Slider[0])+' to '+str(Date_Slider[1])+'', + 'Daily ' + specie+ ' Detections on 15 minute intervals '), # 'Total Detect:'+str('{:,}'.format(df_counts))+ # ' Confidence Max:'+str('{:.2f}%'.format(max(df2[df2['Com_Name']==specie]['Confidence'])*100))+ # ' '+' Median:'+str('{:.2f}%'.format(np.median(df2[df2['Com_Name']==specie]['Confidence'])*100)) # ) ) + + fig.add_trace(go.Bar(y=top_N_species.index, x=top_N_species, orientation='h'), row=1,col=1) df4=df2['Com_Name'][df2['Com_Name']==specie].resample('15min').count() df4.index=[df4.index.date, df4.index.time] day_hour_freq=df4.unstack().fillna(0) @@ -208,11 +213,13 @@ else: fig_y = [h.strftime('%H:%M') for h in day_hour_freq.columns.tolist()] fig_z = day_hour_freq.values.transpose() fig_heatmap = go.Figure(data=go.Heatmap(x=fig_x,y=fig_y,z=fig_z)) - fig.add_trace(go.Bar(y=top_N_species.index, x=top_N_species, orientation='h'), row=1,col=1) + fig.update_layout( margin=dict(l=0, r=0, t=50, b=0), yaxis={'categoryorder':'total ascending'}) - fig.add_trace(go.Heatmap(x=fig_x,y=fig_y,z=fig_z, autocolorscale = False, colorscale = 'blackbody'), row=1, col=2) + color_pals= px.colors.named_colorscales() + selected_pal = cols2.selectbox('Select Color Pallet for Daily Detections', color_pals) + fig.add_trace(go.Heatmap(x=fig_x,y=fig_y,z=fig_z, autocolorscale = False, colorscale = selected_pal), row=1, col=2) # container=st.container() # config={'displayModelBar': False} st.plotly_chart(fig, use_container_width=True) #, config=config) From e7e823beceecc4982bb162a1546bc760e74ee4b9 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Fri, 20 May 2022 09:42:56 -0400 Subject: [PATCH 03/46] Much better Best Recordings > disk_check_exclude.txt logic --- scripts/stats.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/scripts/stats.php b/scripts/stats.php index fce469b..3987187 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -59,15 +59,6 @@ $home = trim($home); if(!file_exists($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")) { file_put_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", "##start\n##end"); } -function editfile( $sourcefile, $start='##start', $end='##end', $data=array() ){ - $lines=array_filter( file( $sourcefile , FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES ) ); - $output=array_merge( - array_splice( $lines, 0, array_search( strtolower( $start ), array_map('strtolower', $lines ) ) + 1 ), - $data, - array_splice( $lines, array_search( strtolower( $end ), array_map('strtolower', $lines ) ) ) - ); - file_put_contents( $sourcefile, implode( PHP_EOL, $output ) ); -} ?> @@ -210,8 +201,10 @@ array_push($excludelines, $results['Date']."/".$comname."/".$results['File_Name' Best Recording:
From bd7fee901246ee35d869a1f77813457b25a0bb9f Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Fri, 20 May 2022 09:51:26 -0400 Subject: [PATCH 04/46] Update stats.php --- scripts/stats.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/stats.php b/scripts/stats.php index 3987187..329aa7d 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -56,8 +56,9 @@ if(isset($_GET['species'])){ $user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"); $home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"); $home = trim($home); -if(!file_exists($home."/BirdNET-Pi/scripts/disk_check_exclude.txt")) { - file_put_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", "##start\n##end"); +if(!file_exists($home."/BirdNET-Pi/scripts/disk_check_exclude.txt") || strpos(file_get_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt"),"##start") === false) { + file_put_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", ""); + file_put_contents($home."/BirdNET-Pi/scripts/disk_check_exclude.txt", "##start\n##end\n"); } ?> From 12434c195d7935ae3ede409fd57c7989034ab2bd Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Fri, 20 May 2022 12:31:05 -0400 Subject: [PATCH 05/46] amplifying the spectrogram -- @ehpersonal38 what do you think? --- scripts/spectrogram.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index 48eb20f..abfc81a 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -30,7 +30,7 @@ function initialize() { SOURCE.connect(ACTX.destination) const DATA = new Uint8Array(ANALYSER.frequencyBinCount); const LEN = DATA.length; - const h = H / LEN; + const h = (H / LEN + .8); const x = W - 1; CTX.fillStyle = 'hsl(280, 100%, 10%)'; CTX.fillRect(0, 0, W, H); From 182821e037b6fe65833ceb203480029c3672d15a Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Fri, 20 May 2022 13:08:40 -0400 Subject: [PATCH 06/46] Use "Live Audio" stream in top right if running Prevents duplicate audio sources --- scripts/spectrogram.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index abfc81a..7ae4b1e 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -4,7 +4,17 @@ // UPDATE: there is a problem in chrome with starting audio context // before a user gesture. This fixes it. var started = null; +var player = null; window.onload = function(){ + var audioelement = window.parent.document.getElementsByTagName("audio")[0]; + if (typeof(audioelement) != 'undefined') { + + document.getElementById('player').remove(); + + player = audioelement; + } else { + player = document.getElementById('player'); + } if (started) return; started = true; initialize(); @@ -25,7 +35,7 @@ function initialize() { process(); function process() { - const SOURCE = ACTX.createMediaElementSource(document.getElementById('player')); + const SOURCE = ACTX.createMediaElementSource(player); SOURCE.connect(ANALYSER); SOURCE.connect(ACTX.destination) const DATA = new Uint8Array(ANALYSER.frequencyBinCount); @@ -79,6 +89,7 @@ h1 { } +

Loading...

From 29e88400f8c27097cfc6c453fae8ea86d3b808ae Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Fri, 20 May 2022 13:08:58 -0400 Subject: [PATCH 07/46] this seems like a really good balance of gain and zoom --- scripts/spectrogram.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index abfc81a..14e96c0 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -30,7 +30,7 @@ function initialize() { SOURCE.connect(ACTX.destination) const DATA = new Uint8Array(ANALYSER.frequencyBinCount); const LEN = DATA.length; - const h = (H / LEN + .8); + const h = (H / LEN + .9); const x = W - 1; CTX.fillStyle = 'hsl(280, 100%, 10%)'; CTX.fillRect(0, 0, W, H); @@ -44,7 +44,7 @@ function initialize() { CTX.putImageData(imgData, 0, 0); ANALYSER.getByteFrequencyData(DATA); for (let i = 0; i < LEN; i++) { - let rat = DATA[i] / 128; + let rat = DATA[i] / 196 ; let hue = Math.round((rat * 120) + 280 % 360); let sat = '100%'; let lit = 10 + (70 * rat) + '%'; From 63a74499b671371048c87eeb8049621b91bc0d62 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Fri, 20 May 2022 14:25:33 -0400 Subject: [PATCH 08/46] Adding detections to the spectrogram --- scripts/overview.php | 1 + scripts/spectrogram.php | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/scripts/overview.php b/scripts/overview.php index a5a3bdc..7ca08ef 100644 --- a/scripts/overview.php +++ b/scripts/overview.php @@ -45,6 +45,7 @@ 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($_GET['only_name'] == "true") { echo $comname.",".$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 diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index f04d7ff..2df3421 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -1,10 +1,11 @@ -
@@ -91,18 +91,18 @@ if(isset($_GET['view'])){ if($submittedpwd == $caddypwd && $submitteduser == 'birdnet'){ $url = $_SERVER['SERVER_NAME']."/scripts/adminer.php"; echo "
-
- - - - - - - - - -
-
"; +
+ + + + + + + + + +
+
"; } else { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); @@ -196,36 +196,86 @@ if(isset($_GET['view'])){ } } } elseif(isset($_GET['submit'])) { - 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'); - } - $caddypwd = $config['CADDY_PWD']; - if (!isset($_SERVER['PHP_AUTH_USER'])) { - header('WWW-Authenticate: Basic realm="My Realm"'); - header('HTTP/1.0 401 Unauthorized'); - echo 'You cannot access the web terminal'; - exit; - } else { - $submittedpwd = $_SERVER['PHP_AUTH_PW']; - $submitteduser = $_SERVER['PHP_AUTH_USER']; - if($submittedpwd == $caddypwd && $submitteduser == 'birdnet'){ - $command = $_GET['submit']; - if(isset($command)){ + 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'); + } + $caddypwd = $config['CADDY_PWD']; + if (!isset($_SERVER['PHP_AUTH_USER'])) { + header('WWW-Authenticate: Basic realm="My Realm"'); + header('HTTP/1.0 401 Unauthorized'); + echo 'You cannot access the web terminal'; + exit; + } else { + $submittedpwd = $_SERVER['PHP_AUTH_PW']; + $submitteduser = $_SERVER['PHP_AUTH_USER']; + $allowedCommands = array('sudo systemctl stop livestream.service && sudo /etc/init.d/icecast2 stop', + 'sudo systemctl restart livestream.service && sudo /etc/init.d/icecast2 restart', + 'sudo systemctl disable --now livestream.service && sudo systemctl disable icecast2 && sudo /etc/init.d/icecast2 stop', + 'sudo systemctl enable icecast2 && sudo /etc/init.d/icecast2 start && sudo systemctl enable --now livestream.service', + 'sudo systemctl stop web_terminal.service', + 'sudo systemctl restart web_terminal.service', + 'sudo systemctl disable --now web_terminal.service', + 'sudo systemctl enable --now web_terminal.service', + 'sudo systemctl stop birdnet_log.service', + 'sudo systemctl restart birdnet_log.service', + 'sudo systemctl disable --now birdnet_log.service', + 'sudo systemctl enable --now birdnet_log.service', + 'sudo systemctl stop extraction.service', + 'sudo systemctl restart extraction.service', + 'sudo systemctl disable --now extraction.service', + 'sudo systemctl enable --now extraction.service', + 'sudo systemctl stop birdnet_server.service', + 'sudo systemctl restart birdnet_server.service', + 'sudo systemctl disable --now birdnet_server.service', + 'sudo systemctl enable --now birdnet_server.service', + 'sudo systemctl stop birdnet_analysis.service', + 'sudo systemctl restart birdnet_analysis.service', + 'sudo systemctl disable --now birdnet_analysis.service', + 'sudo systemctl enable --now birdnet_analysis.service', + 'sudo systemctl stop birdnet_stats.service', + 'sudo systemctl restart birdnet_stats.service', + 'sudo systemctl disable --now birdnet_stats.service', + 'sudo systemctl enable --now birdnet_stats.service', + 'sudo systemctl stop birdnet_recording.service', + 'sudo systemctl restart birdnet_recording.service', + 'sudo systemctl disable --now birdnet_recording.service', + 'sudo systemctl enable --now birdnet_recording.service', + 'sudo systemctl stop chart_viewer.service', + 'sudo systemctl restart chart_viewer.service', + 'sudo systemctl disable --now chart_viewer.service', + 'sudo systemctl enable --now chart_viewer.service', + 'sudo systemctl stop spectrogram_viewer.service', + 'sudo systemctl restart spectrogram_viewer.service', + 'sudo systemctl disable --now spectrogram_viewer.service', + 'sudo systemctl enable --now spectrogram_viewer.service', + 'sudo systemctl stop pushed_notifications.service', + 'sudo systemctl restart pushed_notifications.service', + 'sudo systemctl disable --now pushed_notifications.service', + 'sudo systemctl enable --now pushed_notifications.service', + 'stop_core_services.sh', + 'restart_services.sh', + 'sudo reboot', + 'update_birdnet.sh', + 'sudo shutdown now', + 'sudo clear_all_data.sh'); + $command = $_GET['submit']; + if($submittedpwd == $caddypwd && $submitteduser == 'birdnet' && in_array($command,$allowedCommands)){ + if(isset($command)){ $initcommand = $command; - if (strpos($command, "systemctl") !== false) { - $tmp = explode(" ",trim($command)); - $command .= "& sleep 3;sudo systemctl status ".end($tmp); - } - $results = shell_exec("$command 2>&1"); - $results = str_replace("FAILURE", "FAILURE", $results); - $results = str_replace("failed", "failed",$results); - $results = str_replace("active (running)", "active (running)",$results); - if(strlen($results) == 0) { + if (strpos($command, "systemctl") !== false) { + $tmp = explode(" ",trim($command)); + $command .= "& sleep 3;sudo systemctl status ".end($tmp); + } + $results = shell_exec("$command 2>&1"); + $results = str_replace("FAILURE", "FAILURE", $results); + $results = str_replace("failed", "failed",$results); + $results = str_replace("active (running)", "active (running)",$results); + if(strlen($results) == 0) { $results = "This command has no output."; - } - echo "
Output of command:`".$initcommand."`
$results
"; + } + echo "
Output of command:`".$initcommand."`
$results
"; } else { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); From dd2091a2b8fbc858618235a27b59815580a09641 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sat, 21 May 2022 15:20:14 -0400 Subject: [PATCH 21/46] Update play.php Silencing harmless notice that appears if the user doesn't have a disk_check_exclude.txt created yet. --- scripts/play.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/play.php b/scripts/play.php index 9789c3d..7fdc90b 100644 --- a/scripts/play.php +++ b/scripts/play.php @@ -1,7 +1,5 @@ Date: Sat, 21 May 2022 15:45:17 -0400 Subject: [PATCH 22/46] removed hi line - put label closer to audio signal --- scripts/spectrogram.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index b2b241d..c710bd7 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -24,7 +24,7 @@ window.onload = function(){ function applyText(text) { CTX.fillStyle = 'white'; CTX.font = '25px Roboto Flex'; - CTX.fillText(text, document.body.querySelector('canvas').scrollWidth - (document.body.querySelector('canvas').scrollWidth * 0.50), document.body.querySelector('canvas').scrollHeight * 0.35); + CTX.fillText(text, document.body.querySelector('canvas').scrollWidth - (document.body.querySelector('canvas').scrollWidth * 0.20), document.body.querySelector('canvas').scrollHeight * 0.35); CTX.fillStyle = 'hsl(280, 100%, 10%)'; } @@ -122,7 +122,3 @@ h1 {

Loading...

- -
-hi - From 2c46f98a5bff6d10492b7c3eaf29d4d910de9bc7 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sat, 21 May 2022 15:52:20 -0400 Subject: [PATCH 23/46] Update daily_plot.py Squashed! --- scripts/daily_plot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/daily_plot.py b/scripts/daily_plot.py index 2d80dc3..a20e8d2 100755 --- a/scripts/daily_plot.py +++ b/scripts/daily_plot.py @@ -32,7 +32,7 @@ df['Hour of Day'] = [r.hour for r in df.Time] df_plt=df #Default to use the whole Dbase # Add every font at the specified location -font_dir = ['$HOME/BirdNET-Pi/homepage/static'] +font_dir = [userDir+'/BirdNET-Pi/homepage/static'] for font in font_manager.findSystemFonts(font_dir): font_manager.fontManager.addfont(font) From 72ca3fe5950e94812181f3c8d6de744724798681 Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Sat, 21 May 2022 16:11:58 -0400 Subject: [PATCH 24/46] new cleanup.cron --- templates/cleanup.cron | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/cleanup.cron b/templates/cleanup.cron index 4fb2fec..03a84f5 100644 --- a/templates/cleanup.cron +++ b/templates/cleanup.cron @@ -1,6 +1,6 @@ #birdnet -*/5 * * * * $USER /usr/local/bin/disk_check.sh &> /dev/null +*/5 * * * * $USER /usr/local/bin/disk_check.sh >/dev/null 2>&1 #birdnet -*/3 * * * * $USER /usr/local/bin/cleanup.sh &> /dev/null +*/3 * * * * $USER /usr/local/bin/cleanup.sh >/dev/null 2>&1 #birdnet -@reboot $USER /usr/local/bin/cleanup.sh &> /dev/null +@reboot $USER /usr/local/bin/cleanup.sh >/dev/null 2>&1 From 477143a9c4268e1e5e6f7baf418e528e1ce80e4b Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Sat, 21 May 2022 18:34:00 -0400 Subject: [PATCH 25/46] I thought I did this? --- scripts/stats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stats.php b/scripts/stats.php index aab6bc3..974cda7 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -180,7 +180,7 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){ $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'; + $imageurl = 'https://farm' .$val["farm"]. '.static.flickr.com/' .$val["server"]. '/' .$val["id"]. '_' .$val["secret"]. '.jpg'; echo "".$iter.""; } } From 86fcdafbe2c7dfe7bd044a2bbd9b9a2d74e1562c Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Sat, 21 May 2022 18:36:10 -0400 Subject: [PATCH 26/46] make the image the link --- scripts/stats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stats.php b/scripts/stats.php index 974cda7..81dc0b0 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -181,7 +181,7 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){ $modaltext = "https://flickr.com/photos/".$val["owner"]."/".$val["id"]; $authorlink = "https://flickr.com/people/".$val["owner"]; $imageurl = 'https://farm' .$val["farm"]. '.static.flickr.com/' .$val["server"]. '/' .$val["id"]. '_' .$val["secret"]. '.jpg'; - echo "".$iter.""; + echo ""; } } } From 9fd68a913cd12886141dee272858b3863b0c50d2 Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Sat, 21 May 2022 19:04:56 -0400 Subject: [PATCH 27/46] removed style not used --- scripts/stats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stats.php b/scripts/stats.php index 81dc0b0..9e6b095 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -181,7 +181,7 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){ $modaltext = "https://flickr.com/photos/".$val["owner"]."/".$val["id"]; $authorlink = "https://flickr.com/people/".$val["owner"]; $imageurl = 'https://farm' .$val["farm"]. '.static.flickr.com/' .$val["server"]. '/' .$val["id"]. '_' .$val["secret"]. '.jpg'; - echo ""; + echo ""; } } } From fa82f4c50ddf6daca6f0f328c854ac49e37f4c1f Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 22 May 2022 08:54:04 -0400 Subject: [PATCH 28/46] iOS Legacy Mode + Responsive Text Scaling @mcguirepr89 Try this out on your iOS device(s) and let me know how/if it works! --- scripts/spectrogram.php | 46 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index c710bd7..8b61cc0 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -7,6 +7,29 @@ var started = null; var player = null; const ctx = null; window.onload = function(){ + // if user agent includes iPhone or Mac, AND is not chrome, use legacy mode + if( (window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("Mac")) && !window.navigator.userAgent.includes("CriOS")) { + document.getElementById("spectrogramimage").style.display=""; + document.body.querySelector('canvas').remove(); + document.getElementById('player').remove(); + document.body.querySelector('h1').remove(); + + + // every $refresh seconds, this loop will run and refresh the spectrogram image + window.setInterval(function(){ + document.getElementById("spectrogramimage").src = "/spectrogram.png?nocache="+Date.now(); + }, *1000); + } else { + document.getElementById("spectrogramimage").remove(); + var audioelement = window.parent.document.getElementsByTagName("audio")[0]; if (typeof(audioelement) != 'undefined') { @@ -16,15 +39,27 @@ window.onload = function(){ } else { player = document.getElementById('player'); } + player.play(); if (started) return; - started = true; - initialize(); + started = true; + initialize(); + } }; +function fitTextOnCanvas(text,fontface,yPosition){ + var fontsize=300; + do{ + fontsize--; + CTX.font=fontsize+"px "+fontface; + }while(CTX.measureText(text).width>document.body.querySelector('canvas').width) + CTX.font = CTX.font=(fontsize*0.35)+"px "+fontface; + CTX.fillText(text,document.body.querySelector('canvas').width - (document.body.querySelector('canvas').width * 0.50),yPosition); +} + function applyText(text) { CTX.fillStyle = 'white'; CTX.font = '25px Roboto Flex'; - CTX.fillText(text, document.body.querySelector('canvas').scrollWidth - (document.body.querySelector('canvas').scrollWidth * 0.20), document.body.querySelector('canvas').scrollHeight * 0.35); + fitTextOnCanvas(text,"Roboto Flex",document.body.querySelector('canvas').scrollHeight * 0.35) CTX.fillStyle = 'hsl(280, 100%, 10%)'; } @@ -46,7 +81,7 @@ function loadDetectionIfNewExists() { window.setInterval(function(){ loadDetectionIfNewExists(); -}, 5000); +}, 2500); function initialize() { document.body.querySelector('h1').remove(); @@ -118,7 +153,8 @@ h1 { } + - +

Loading...

From 913c0141c8e9faf739d1029ddeaab28c1ce644b1 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 22 May 2022 10:20:01 -0400 Subject: [PATCH 29/46] Update spectrogram.php --- scripts/spectrogram.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index 8b61cc0..a109f94 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -7,8 +7,8 @@ var started = null; var player = null; const ctx = null; window.onload = function(){ - // if user agent includes iPhone or Mac, AND is not chrome, use legacy mode - if( (window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("Mac")) && !window.navigator.userAgent.includes("CriOS")) { + // if user agent includes iPhone or Mac use legacy mode + if(window.navigator.userAgent.includes("iPhone") || window.navigator.userAgent.includes("Mac")) { document.getElementById("spectrogramimage").style.display=""; document.body.querySelector('canvas').remove(); document.getElementById('player').remove(); From 27462d31594d3939d3aafde256bdb35fdb068fc2 Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Sun, 22 May 2022 10:37:51 -0400 Subject: [PATCH 30/46] you had this right the first time --- scripts/spectrogram.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index a109f94..f95ee72 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -118,7 +118,7 @@ function initialize() { CTX.putImageData(imgData, 0, 0); ANALYSER.getByteFrequencyData(DATA); for (let i = 0; i < LEN; i++) { - let rat = DATA[i] / 196 ; + let rat = DATA[i] / 128 ; let hue = Math.round((rat * 120) + 280 % 360); let sat = '100%'; let lit = 10 + (70 * rat) + '%'; From 3a3c3e58c332ee160d048ae324fdfde4ab189111 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 22 May 2022 13:22:01 -0400 Subject: [PATCH 31/46] shrunk & unbroke --- homepage/style.css | 2 +- homepage/views.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homepage/style.css b/homepage/style.css index b43b2c3..dcfceb0 100644 --- a/homepage/style.css +++ b/homepage/style.css @@ -181,7 +181,7 @@ button:hover { } .stats table { - width: 75%; + width: 60%; } .overview th { diff --git a/homepage/views.php b/homepage/views.php index 0ebd926..323fc84 100644 --- a/homepage/views.php +++ b/homepage/views.php @@ -70,7 +70,7 @@ if(isset($_GET['view'])){ if($_GET['view'] == "View Log"){echo "";} if($_GET['view'] == "Overview"){include('overview.php');} if($_GET['view'] == "Today's Detections"){include('todays_detections.php');} - if($_GET['view'] == "Species Stats"){echo "

";include('stats.php');} + if($_GET['view'] == "Species Stats"){include('stats.php');} if($_GET['view'] == "Streamlit"){echo "";} if($_GET['view'] == "Daily Charts"){include('history.php');} if($_GET['view'] == "Tools"){ From 0462e1ec2b137b8bad1b818efeebc5a00b8d611a Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Sun, 22 May 2022 17:21:42 -0400 Subject: [PATCH 32/46] Things have been made better - All buttons and bird images now have nice transitions on hover - Bird images have an added drop shadow for the aesthetics. :sunglasses: - When hovering over sort icons, a tooltip describing the button is now displayed - Best Recordings has been cleaned up and made a little clearer --- homepage/style.css | 17 ++++++++++++++++- scripts/play.php | 8 ++++---- scripts/stats.php | 11 ++++++++--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/homepage/style.css b/homepage/style.css index dcfceb0..9e92938 100644 --- a/homepage/style.css +++ b/homepage/style.css @@ -70,11 +70,16 @@ label { font-weight: bold; } +hr { + border-color:black; +} + button { background-color: transparent; border: none; color: black; cursor: pointer; + transition:background-color 0.2s; } button:hover { @@ -546,7 +551,7 @@ button:hover { font-size:x-large; background:#dbffeb; padding:5px; - + box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, 0.10); } button.legacyview { color:gray; @@ -605,6 +610,7 @@ dialog::backdrop { margin-bottom:3px; } .centered_image_container img.img1 { + box-shadow:0px 2px 3px 0px rgb(0 0 0 / 29%); cursor:pointer; height:95%; position:absolute; @@ -613,9 +619,18 @@ dialog::backdrop { border-radius: 5px; width:unset; } +.centered_image_container img.img1:hover{ + opacity:0.8; +} .centered_image_container * { font-size:19px !important; } .centered_image_container form { margin-bottom:0px; +} +.brbanner { + padding:15px; + background-color:rgb(159, 226, 155); + text-align:center; + font-size:large; } \ No newline at end of file diff --git a/scripts/play.php b/scripts/play.php index 7fdc90b..cf7e30f 100644 --- a/scripts/play.php +++ b/scripts/play.php @@ -168,10 +168,10 @@ if(!isset($_GET['species']) && !isset($_GET['filename'])){ @@ -228,10 +228,10 @@ if(isset($_GET['species'])){ ?> diff --git a/scripts/stats.php b/scripts/stats.php index 9e6b095..3ad11f0 100644 --- a/scripts/stats.php +++ b/scripts/stats.php @@ -81,10 +81,10 @@ if(!file_exists($home."/BirdNET-Pi/scripts/disk_check_exclude.txt") || strpos(fi @@ -187,7 +187,12 @@ while($results=$result3->fetchArray(SQLITE3_ASSOC)){ } } ?> -


+ +

+
Best Recordings for Other Species:

+ +

+ Date: Mon, 23 May 2022 13:22:26 -0400 Subject: [PATCH 33/46] hehe --- homepage/views.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homepage/views.php b/homepage/views.php index 323fc84..4dbd247 100644 --- a/homepage/views.php +++ b/homepage/views.php @@ -97,7 +97,7 @@ if(isset($_GET['view'])){ - + From 7cf38359d46a7761cc29bd7a89e92606220733b4 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 23 May 2022 14:09:10 -0400 Subject: [PATCH 34/46] Logo & shadows --- homepage/images/bnp.png | Bin 0 -> 17314 bytes homepage/style.css | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 homepage/images/bnp.png diff --git a/homepage/images/bnp.png b/homepage/images/bnp.png new file mode 100644 index 0000000000000000000000000000000000000000..cd67dce95053703869b9b9963f774a622f5acc61 GIT binary patch literal 17314 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 Bhh+c& literal 0 HcmV?d00001 diff --git a/homepage/style.css b/homepage/style.css index 9e92938..3319185 100644 --- a/homepage/style.css +++ b/homepage/style.css @@ -143,10 +143,15 @@ button:hover { margin-left: auto; margin-right: auto; margin-bottom: 15px; - box-shadow: 0px 0px 17px 1px rgba(0, 0, 0, 0.10); !important; + box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.10); !important; border-radius: 4px; } +.topimage { + width:175px; + display:initial !important; +} + .topnav form { margin: 0; padding: 0; @@ -252,11 +257,14 @@ button:hover { .views .centered button { background-color: rgb(219, 255, 235); padding: 12px; + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + box-shadow:0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%); } .views .centered button:hover { background-color: rgb(159, 226, 155); color: black; + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); } .settings { @@ -562,15 +570,31 @@ button.legacyview { font-size:small; background:#dbffeb; padding:5px; - + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + box-shadow:0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%); } +button.legacyview:hover { + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); +} + button.loadmore { margin-top:10px; font-size:x-large; background:#dbffeb; padding:10px; + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + box-shadow:0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%); } +button.loadmore:hover { + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); +} +#searchterm { + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); +} +#searchterm:hover { + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); +} tr { background-color:#9fe29b; @@ -586,6 +610,11 @@ tr { .centered form#views button { box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, 0.10); margin:2px; + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + box-shadow:0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%); +} +.centered form#views button:hover { + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); } input { box-shadow: 0px 0px 17px 1px rgba(0, 0, 0, 0.10); @@ -610,7 +639,8 @@ dialog::backdrop { margin-bottom:3px; } .centered_image_container img.img1 { - box-shadow:0px 2px 3px 0px rgb(0 0 0 / 29%); + transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + box-shadow:0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%); cursor:pointer; height:95%; position:absolute; @@ -621,6 +651,7 @@ dialog::backdrop { } .centered_image_container img.img1:hover{ opacity:0.8; + box-shadow:0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); } .centered_image_container * { font-size:19px !important; From 87f34b494b8a1a031a1d88ed36a8ebf680812a6e Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 23 May 2022 16:46:20 -0400 Subject: [PATCH 35/46] Using $_SESSION for storing and retrieving Flickr URLs Significantly decreases API calls --- scripts/overview.php | 15 ++++++++++----- scripts/todays_detections.php | 16 +++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/scripts/overview.php b/scripts/overview.php index ca308fd..39be33b 100644 --- a/scripts/overview.php +++ b/scripts/overview.php @@ -1,4 +1,7 @@ execute(); - $images = []; + if(!isset($_SESSION['images'])) { + $_SESSION['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)) { @@ -49,16 +54,16 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" && isse 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)); + $key = array_search($comname, array_column($_SESSION['images'], 0)); if($key !== false) { - $image = $images[$key]; + $image = $_SESSION['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=".str_replace("_", "%20", $comname)."&license=2%2C3%2C4%2C5%2C6%2C9&sort=relevance&per_page=5&orientation=square,portrait&format=json&media=photos&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'; - array_push($images, array($comname,$imageurl,$flickrjson["title"], $modaltext, $authorlink)); - $image = $images[count($images)-1]; + array_push($_SESSION['images'], array($comname,$imageurl,$flickrjson["title"], $modaltext, $authorlink)); + $image = $_SESSION['images'][count($_SESSION['images'])-1]; } } diff --git a/scripts/todays_detections.php b/scripts/todays_detections.php index bacd06f..0eaaf3f 100644 --- a/scripts/todays_detections.php +++ b/scripts/todays_detections.php @@ -1,4 +1,7 @@
From a74daccca7d0081d2c6ea42df87ab83b90913202 Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 23 May 2022 18:29:14 -0400 Subject: [PATCH 36/46] Update README.md I think "microphone" is a more familiar term than "sound card" for most people. Nitpicky but I think it'll help potential users understand better :) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df8e235..f23451c 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Icon made by Freepik from

## Introduction -BirdNET-Pi is built on the [TFLite version of BirdNET](https://github.com/kahst/BirdNET-Lite) by [**@kahst**](https://github.com/kahst) using [pre-built TFLite binaries](https://github.com/PINTO0309/TensorflowLite-bin) by [**@PINTO0309**](https://github.com/PINTO0309) . It is able to recognize bird sounds from a USB sound card in realtime and share its data with the rest of the world. +BirdNET-Pi is built on the [TFLite version of BirdNET](https://github.com/kahst/BirdNET-Lite) by [**@kahst**](https://github.com/kahst) using [pre-built TFLite binaries](https://github.com/PINTO0309/TensorflowLite-bin) by [**@PINTO0309**](https://github.com/PINTO0309) . It is able to recognize bird sounds from a USB microphone or sound card in realtime and share its data with the rest of the world. Check out birds from around the world - [BirdWeather](https://app.birdweather.com)
From bf46a174fc02222fe82ca0d86641c0be9c4c731d Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 23 May 2022 18:37:37 -0400 Subject: [PATCH 37/46] Update todays_detections.php --- scripts/todays_detections.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/todays_detections.php b/scripts/todays_detections.php index 0eaaf3f..35216a7 100644 --- a/scripts/todays_detections.php +++ b/scripts/todays_detections.php @@ -247,7 +247,7 @@ document.getElementById("searchterm").onkeydown = (function(e) { }); function switchViews(element) { - document.getElementById("detections_table").innerHTML = ""; + document.getElementById("detections_table").innerHTML = "

Loading detections...

"; if(element.innerHTML == "Legacy view") { element.innerHTML = "Normal view"; loadDetections(undefined); From cdbadbb45c73cb15ffe1f07266b4c1c4eac724ba Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Mon, 23 May 2022 18:41:16 -0400 Subject: [PATCH 38/46] starting this to get some help --- birdnet.conf-defaults | 3 ++- homepage/views.php | 4 ---- scripts/config.php | 12 +++++++----- scripts/install_config.sh | 1 + scripts/install_services.sh | 17 ----------------- scripts/restart_services.sh | 3 +-- scripts/server.py | 26 ++++++++++++++++++++++++++ scripts/service_controls.php | 7 ------- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/birdnet.conf-defaults b/birdnet.conf-defaults index e75cda1..e53af20 100644 --- a/birdnet.conf-defaults +++ b/birdnet.conf-defaults @@ -60,7 +60,8 @@ RTSP_STREAM= 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 +APPRISE_NOTIFY_EACH_DETECTION=0 +APPRISE_NOTIFY_NEW_SPECIES=0 #---------------------- Flickr Images API Configuration -----------------------# diff --git a/homepage/views.php b/homepage/views.php index 4dbd247..33f4621 100644 --- a/homepage/views.php +++ b/homepage/views.php @@ -250,10 +250,6 @@ if(isset($_GET['view'])){ 'sudo systemctl restart spectrogram_viewer.service', 'sudo systemctl disable --now spectrogram_viewer.service', 'sudo systemctl enable --now spectrogram_viewer.service', - 'sudo systemctl stop pushed_notifications.service', - 'sudo systemctl restart pushed_notifications.service', - 'sudo systemctl disable --now pushed_notifications.service', - 'sudo systemctl enable --now pushed_notifications.service', 'stop_core_services.sh', 'restart_services.sh', 'sudo reboot', diff --git a/scripts/config.php b/scripts/config.php index 78f0055..8b13084 100644 --- a/scripts/config.php +++ b/scripts/config.php @@ -16,10 +16,10 @@ if(isset($_GET['apprise_notify_each_detection'])) { } else { $apprise_notify_each_detection = 0; } -if(isset($_GET['apprise_notify_each_species'])) { - exec('sudo systemctl start pushed_notifications.service'); +if(isset($_GET['apprise_notify_new_species'])) { + $apprise_notify_new_species = 1; } else { - exec('sudo systemctl stop pushed_notifications.service'); + $apprise_notify_new_species = 0; } // logic for setting the date and time based on user inputs from the form below @@ -46,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("/APPRISE_NOTIFY_NEW_SPECIES=.*/", "APPRISE_NOTIFY_NEW_SPECIES=$apprise_notify_new_species", $contents); $contents = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents); @@ -56,6 +57,7 @@ $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("/APPRISE_NOTIFY_NEW_SPECIES=.*/", "APPRISE_NOTIFY_NEW_SPECIES=$apprise_notify_new_species", $contents2); $contents2 = preg_replace("/FLICKR_API_KEY=.*/", "FLICKR_API_KEY=$flickr_api_key", $contents2); @@ -144,8 +146,8 @@ https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}

- > -
+ > +
>

Bird Photos from Flickr

diff --git a/scripts/install_config.sh b/scripts/install_config.sh index e74ac56..daab688 100755 --- a/scripts/install_config.sh +++ b/scripts/install_config.sh @@ -74,6 +74,7 @@ RTSP_STREAM= 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 #---------------------- Flickr Images API Configuration -----------------------# diff --git a/scripts/install_services.sh b/scripts/install_services.sh index 093047b..1d038b9 100755 --- a/scripts/install_services.sh +++ b/scripts/install_services.sh @@ -91,22 +91,6 @@ EOF systemctl enable extraction.service } -install_pushed_notifications() { - cat << EOF > $HOME/BirdNET-Pi/templates/pushed_notifications.service -[Unit] -Description=BirdNET-Pi Pushed.co Notifications -[Service] -Restart=on-success -RestartSec=3 -Type=simple -User=$USER -ExecStart=/usr/local/bin/species_notifier.sh -[Install] -WantedBy=multi-user.target -EOF - ln -sf $HOME/BirdNET-Pi/templates/pushed_notifications.service /usr/lib/systemd/system -} - create_necessary_dirs() { echo "Creating necessary directories" [ -d ${EXTRACTED} ] || sudo -u ${USER} mkdir -p ${EXTRACTED} @@ -436,7 +420,6 @@ install_services() { install_recording_service install_custom_recording_service # But does not enable install_extraction_service - install_pushed_notifications install_spectrogram_service install_chart_viewer_service install_gotty_logs diff --git a/scripts/restart_services.sh b/scripts/restart_services.sh index 98993af..ad4e9f3 100755 --- a/scripts/restart_services.sh +++ b/scripts/restart_services.sh @@ -9,7 +9,6 @@ sudo pkill server.py sudo systemctl stop birdnet_recording.service services=(web_terminal.service spectrogram_viewer.service -pushed_notifications.service livestream.service icecast2.service extraction.service @@ -22,6 +21,6 @@ sudo systemctl restart "${i}" done until grep 5050 <(netstat -tulpn 2>&1);do sudo systemctl restart birdnet_server.service -sleep 30 +sleep 45 done sudo systemctl restart birdnet_analysis.service diff --git a/scripts/server.py b/scripts/server.py index 35833e1..627b1a0 100755 --- a/scripts/server.py +++ b/scripts/server.py @@ -243,6 +243,32 @@ def sendAppriseNotifications(species,confidence): title=title, ) + if str(str(str([i for i in this_run if i.startswith('APPRISE_NOTIFY_NEW_SPECIES')]).split('=')[1]).split('\\')[0]) == "1": + try: + con = sqlite3.connect(userDir + '/BirdNET-Pi/scripts/birds.db') + cur = con.cursor() + cur.execute("SELECT DISTINCT(Com_Name) FROM detections") + known_species = cur.fetchall() + sciName,comName = species.split("_") + + print("\ncomName: ",comName) + print("\nknown_species: ",known_species) + if comName not in known_species: + apobj = apprise.Apprise() + config = apprise.AppriseConfig() + config.add(userDir + '/BirdNET-Pi/apprise.txt') + apobj.add(config) + + apobj.notify( + body=body.replace("$sciname",species.split("_")[0]).replace("$comname",species.split("_")[1]).replace("$confidence",confidence), + title=title, + ) + + con.close() + except: + print("Database busy") + time.sleep(2) + def writeResultsToFile(detections, min_conf, path): print('WRITING RESULTS TO', path, '...', end=' ') diff --git a/scripts/service_controls.php b/scripts/service_controls.php index 8abde5e..e81952b 100644 --- a/scripts/service_controls.php +++ b/scripts/service_controls.php @@ -73,13 +73,6 @@ -
-

Pushed Notifications

- - - - -
From 9987d332f2f45b267701634ca7e98f34e04686da Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Mon, 23 May 2022 18:45:32 -0400 Subject: [PATCH 39/46] Fix searching in legacy mode --- scripts/todays_detections.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/todays_detections.php b/scripts/todays_detections.php index 35216a7..a5866cd 100644 --- a/scripts/todays_detections.php +++ b/scripts/todays_detections.php @@ -70,7 +70,7 @@ if(isset($_GET['ajax_detections']) && $_GET['ajax_detections'] == "true" ) { $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 - $statement0 = $db->prepare('SELECT Time, Com_Name, Sci_Name, Confidence, File_Name FROM detections WHERE Date == Date(\'now\', \'localtime\') '.$searchquery.' ORDER BY Time DESC '.$searchquery); + $statement0 = $db->prepare('SELECT Time, Com_Name, Sci_Name, Confidence, File_Name FROM detections WHERE Date == Date(\'now\', \'localtime\') '.$searchquery.' ORDER BY Time DESC'); } if($statement0 == False){ echo "Database is busy"; @@ -259,7 +259,11 @@ function switchViews(element) { function searchDetections(searchvalue) { document.getElementById("detections_table").innerHTML = "

Loading...

"; searchterm = searchvalue; - loadDetections(40,undefined); + if(document.getElementsByClassName('legacyview')[0].innerHTML == "Normal view") { + loadDetections(undefined,undefined); + } else { + loadDetections(40,undefined); + } } function loadDetections(detections_limit, element=undefined) { const xhttp = new XMLHttpRequest(); From 10e5770c82ed8a7e8251cd6b618a2519ba174ddc Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Tue, 24 May 2022 09:22:04 -0400 Subject: [PATCH 40/46] Prevent style caching on new update I assume this'll be 0.14? --- homepage/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homepage/index.php b/homepage/index.php index 03f8c34..eab5f2a 100644 --- a/homepage/index.php +++ b/homepage/index.php @@ -5,7 +5,7 @@ body::-webkit-scrollbar { display:none } - + "; } else { header('WWW-Authenticate: Basic realm="My Realm"'); @@ -46,12 +46,12 @@ if(isset($_GET['stream'])){ } } } else { - echo " + echo "
-

BirdNET-Pi

+

"; } if(isset($_GET['filename'])) { From 92e990a44f81865502aadc24a03e6c86062c6e71 Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Tue, 24 May 2022 10:21:28 -0400 Subject: [PATCH 44/46] adding new variable to update_snippets --- scripts/update_birdnet_snippets.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/update_birdnet_snippets.sh b/scripts/update_birdnet_snippets.sh index 0082ca2..9f27cc2 100755 --- a/scripts/update_birdnet_snippets.sh +++ b/scripts/update_birdnet_snippets.sh @@ -30,7 +30,10 @@ if ! grep APPRISE_NOTIFICATION_BODY /etc/birdnet/birdnet.conf &>/dev/null;then sudo -u$USER echo "APPRISE_NOTIFICATION_BODY=\"A \$sciname \$comname was just detected with a confidence of \$confidence\"" >> /etc/birdnet/birdnet.conf fi if ! grep APPRISE_NOTIFY_EACH_DETECTION /etc/birdnet/birdnet.conf &>/dev/null;then - sudo -u$USER echo "APPRISE_NOTIFY_EACH_DETECTION=false" >> /etc/birdnet/birdnet.conf + sudo -u$USER echo "APPRISE_NOTIFY_EACH_DETECTION=0 " >> /etc/birdnet/birdnet.conf +fi +if ! grep APPRISE_NOTIFY_NEW_SPECIES /etc/birdnet/birdnet.conf &>/dev/null;then + sudo -u$USER echo "APPRISE_NOTIFY_EACH_DETECTION=0 " >> /etc/birdnet/birdnet.conf fi apprise_installation_status=$(~/BirdNET-Pi/birdnet/bin/python3 -c 'import pkgutil; print("installed" if pkgutil.find_loader("apprise") else "not installed")') if [[ "$apprise_installation_status" = "not installed" ]];then From 7cb6da59104a9ed99a7de130157877ffc0bcfcc4 Mon Sep 17 00:00:00 2001 From: mcguirepr89 Date: Tue, 24 May 2022 10:35:45 -0400 Subject: [PATCH 45/46] removes pushed_notifications.service on update --- scripts/update_birdnet_snippets.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/update_birdnet_snippets.sh b/scripts/update_birdnet_snippets.sh index 9f27cc2..912574d 100755 --- a/scripts/update_birdnet_snippets.sh +++ b/scripts/update_birdnet_snippets.sh @@ -56,3 +56,8 @@ fi if ! grep FLICKR_API_KEY /etc/birdnet/birdnet.conf &>/dev/null;then sudo -u$USER echo "FLICKR_API_KEY=" >> /etc/birdnet/birdnet.conf fi +if systemctl list-unit-files pushed_notifications.service;then + sudo systemctl disable --now pushed_notifications.service + sudo rm -f /usr/lib/systemd/system/pushed_notifications.service + sudo rm $HOME/BirdNET-Pi/templates/pushed_notifications.service +fi From d540b5dbdd3d0994323783950b23a51051e16a0f Mon Sep 17 00:00:00 2001 From: ehpersonal38 <103586016+ehpersonal38@users.noreply.github.com> Date: Tue, 24 May 2022 11:27:54 -0400 Subject: [PATCH 46/46] Final banner! --- homepage/images/bnp.png | Bin 30595 -> 23501 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/homepage/images/bnp.png b/homepage/images/bnp.png index 72dfddadc09bf2224c28314f5112128118fbc25c..db5334b98a38cba522a2a44d6564a9aa9962ac3e 100644 GIT binary patch literal 23501 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 bozsfeczWbs-D>(>CimG>-M`Bo+r9ih0yy)z