From 2fd75ccafcbc5b82807125cf9362629d075dac15 Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Thu, 30 May 2024 11:30:09 +0200 Subject: [PATCH] Feat : change specie detected (#62) * Add changedetection function * Create birdnet_changeidentification.sh * Add files via upload * Use a modal box for display of the species * Allow filtering on safari ios * Reset the dropdown if cancelled * Fix : click outside modal box to cancel it in safari ios * Switch modal style to style.css * Switch modal style to style.css * Improves modal rendition on small screens * Use ./scripts/labels.txt instead of hardcoded home * Added physical cancel button * ensure user pi executes the scripts https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Specify exec if not explicit https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Try another way to define the variables https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Align shebang with other scripts https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Allow different HOME https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Update birdnet_changeidentification.sh * Align way to call sudo -u $user with other birdnet-pi code https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Align with proposal https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Successfully converted message https://github.com/Nachtzuster/BirdNET-Pi/pull/62 * Align "safe" variables logic to helpers.py * Make birdnet_changeidentification.sh executable * Force confidence to 1.001 * Set confidence to 0 https://github.com/Nachtzuster/BirdNET-Pi/pull/62 --- homepage/images/bird.svg | 22 ++++ homepage/style.css | 32 ++++++ scripts/birdnet_changeidentification.sh | 120 ++++++++++++++++++++ scripts/play.php | 144 +++++++++++++++++++++++- 4 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 homepage/images/bird.svg create mode 100755 scripts/birdnet_changeidentification.sh diff --git a/homepage/images/bird.svg b/homepage/images/bird.svg new file mode 100644 index 0000000..c8ead99 --- /dev/null +++ b/homepage/images/bird.svg @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/homepage/style.css b/homepage/style.css index 2a7c97f..3274e22 100644 --- a/homepage/style.css +++ b/homepage/style.css @@ -139,6 +139,38 @@ button:hover { padding: 10px; } +.modal { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0,0,0,0.4); +} + +.modal-content { + background-color: #fefefe; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + text-align: center; /* Center the content */ +} + +@media (max-width: 768px) { + .modal-content { + width: 95%; + margin: 10% auto; + } + #labelDropdown { + max-width: 100%; + overflow-x: auto; + } +} + .topnav { background-color: rgb(159, 226, 155); display: flex; diff --git a/scripts/birdnet_changeidentification.sh b/scripts/birdnet_changeidentification.sh new file mode 100755 index 0000000..3a2a27d --- /dev/null +++ b/scripts/birdnet_changeidentification.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +# This scripts allows to change the identification of a Birdnet-pi detection + +################# +# SET VARIABLES # +################# + +# Define HOME in case environment is not correctly set +HOME="${HOME:-/home/pi}" + +# shellcheck disable=sc1091 +source /etc/birdnet/birdnet.conf &>/dev/null + +# Get arguments +OLDNAME="$1" #OLDNAME="Mésange_charbonnière-78-2024-05-02-birdnet-RTSP_1-18:14:08.mp3" +NEWNAME="$2" #NEWNAME="Lapinus atricapilla_Lapinu à tête noire" + +# Set log level +OUTPUT_TYPE="${3:-debug}" # Set 3rd argument to debug to have all outputs + +# Ask for user input if no arguments +if [ -z "$OLDNAME" ]; then read -r -p 'OLDNAME (finishing by mp3): ' OLDNAME; fi +if [ -z "$NEWNAME" ]; then read -r -p 'NEWNAME (sciname_commoname): ' NEWNAME; fi + +# Fixed values +LABELS_FILE="$HOME/BirdNET-Pi/model/labels.txt" +DB_FILE="$HOME/BirdNET-Pi/scripts/birds.db" +DETECTIONS_TABLE="detections" + +################### +# VALIDITY CHECKS # +################### + +# Check if files exist +if [ ! -f "$LABELS_FILE" ]; then echo "$LABELS_FILE doesn't exist, exiting" && exit 1; fi +if [ ! -f "$DB_FILE" ]; then echo "$DB_FILE doesn't exist, exiting" && exit 1; fi + +# Check if inputs are valid +if [[ "$1" != *".mp3" ]]; then + echo "The first argument should be a filename starting with the common name of the bird and finishing by mp3!" + echo "Instead, it is : $1" + exit 1 +elif [[ "$2" != *"_"* ]]; then + echo "The second argument should be in the format : \"scientific name_common name\"" + echo "Instead, it is : $2" + exit 1 +fi + +# Check if $NEWNAME is found in the file $LABELS_FILE +if ! grep -q "$NEWNAME" "$LABELS_FILE"; then + echo "Error: $NEWNAME not found in $LABELS_FILE" + exit 1 +fi + +# Check if the common name as the same as the first +OLDNAME_space="${OLDNAME//_/ }" +if [[ "${OLDNAME_space%%-*}" == "${NEWNAME#*_}" ]]; then + echo "Error: $OLDNAME has the same common name as $NEWNAME" + exit 1 +fi + +################## +# EXECUTE SCRIPT # +################## + +# Intro +[[ "$OUTPUT_TYPE" == "debug" ]] && echo "Starting to modify $OLDNAME to $NEWNAME" + +# Get the line where the column "File_Name" matches exactly $OLDNAME +IFS='|' read -r OLDNAME_sciname OLDNAME_comname OLDNAME_date < <(sqlite3 "$DB_FILE" "SELECT Sci_Name, Com_Name, Date FROM $DETECTIONS_TABLE WHERE File_Name = '$OLDNAME' LIMIT 1;") + +if [[ -z "$OLDNAME_sciname" ]]; then + echo "Error: No line matching $OLDNAME in $DB_FILE" + exit 1 +fi + +# Extract the part before the _ from $NEWNAME +NEWNAME_comname="${NEWNAME#*_}" +NEWNAME_sciname="${NEWNAME%%_*}" + +# Replace spaces with underscores, and ' with "" (same logic as helpers.py) +NEWNAME_comname_safe="$(echo "$NEWNAME_comname" | tr -d "'" | tr ' ' '_')" +OLDNAME_comname_safe="$(echo "$OLDNAME_comname" | tr -d "'" | tr ' ' '_')" + +# Replace OLDNAME_comname_safe with NEWNAME_comname_safe in OLDNAME +NEWNAME_filename="${OLDNAME//$OLDNAME_comname_safe/$NEWNAME_comname_safe}" + +[[ "$OUTPUT_TYPE" == "debug" ]] && echo "This script will change the identification $OLDNAME from $OLDNAME_comname to ${NEWNAME#*_}" + +######################## +# EXECUTE : MOVE FILES # +######################## + +# Check if the file exists +FILE_PATH="$HOME/BirdSongs/Extracted/By_Date/$OLDNAME_date/$OLDNAME_comname_safe/$OLDNAME" +if [[ -f $FILE_PATH ]]; then + # Ensure the new directory exists + NEW_DIR="$HOME/BirdSongs/Extracted/By_Date/$OLDNAME_date/$NEWNAME_comname_safe" + mkdir -p "$NEW_DIR" + + # Move and rename the file + mv "$FILE_PATH" "$NEW_DIR/$NEWNAME_filename" + mv "$FILE_PATH".png "$NEW_DIR/$NEWNAME_filename".png + + [[ "$OUTPUT_TYPE" == "debug" ]] && echo "Files moved!" +else + echo "Error: File $FILE_PATH does not exist" +fi + +################################### +# EXECUTE : UPDATE DATABASE FILES # +################################### + +# Update the database +sqlite3 "$DB_FILE" "UPDATE $DETECTIONS_TABLE SET Sci_Name = '$NEWNAME_sciname', Com_Name = '$NEWNAME_comname', Confidence = '0', File_Name = '$NEWNAME_filename' WHERE File_Name = '$OLDNAME';" + +[[ "$OUTPUT_TYPE" == "debug" ]] && echo "Database entry removed" + +[[ "$OUTPUT_TYPE" == "debug" ]] && echo "All done!" diff --git a/scripts/play.php b/scripts/play.php index d5cfdf0..dc9286f 100644 --- a/scripts/play.php +++ b/scripts/play.php @@ -9,6 +9,7 @@ ini_set('display_errors',1); require_once 'scripts/common.php'; $home = get_home(); $config = get_config(); +$user = get_user(); $db = new SQLite3('./scripts/birds.db', SQLITE3_OPEN_READONLY); $db->busyTimeout(1000); @@ -67,6 +68,28 @@ if(isset($_GET['excludefile'])) { } } +if(isset($_GET['getlabels'])) { + $labels = file('./scripts/labels.txt', FILE_IGNORE_NEW_LINES); + echo json_encode($labels); + die(); +} + +if(isset($_GET['changefile']) && isset($_GET['newname'])) { + ensure_authenticated('You must be authenticated to delete files.'); + if (preg_match('~^.*(\.\.\/).+$~', $_GET['changefile'])) { + echo "Error"; + die(); + } + $oldname = basename(urldecode($_GET['changefile'])); + $newname = urldecode($_GET['newname']); + if (!exec("sudo -u ".$user." ".$home."/BirdNET-Pi/scripts/birdnet_changeidentification.sh \"$oldname\" \"$newname\" log_errors 2>&1", $output)) { + echo "OK"; + } else { + echo "Error : " . implode(", ", $output) . "
"; + } + die(); +} + $shifted_path = $home."/BirdSongs/Extracted/By_Date/shifted/"; if(isset($_GET['shiftfile'])) { @@ -163,6 +186,7 @@ if (get_included_files()[0] === __FILE__) { ?> echo " - + + $date $time
$confidence
@@ -553,7 +692,8 @@ echo " echo "
- + + $date $time
$confidence