Skip to content

Commit

Permalink
Added version check in GUI (#268)
Browse files Browse the repository at this point in the history
* Added version check in GUI

* Rename JS function

---------

Co-authored-by: Josef Haupt <[email protected]>
  • Loading branch information
Josef-Haupt and Josef Haupt authored Feb 26, 2024
1 parent b84ef12 commit 0e1f552
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 27 deletions.
63 changes: 36 additions & 27 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
sys.stderr = sys.stdout = open("logs.txt", "w")

import multiprocessing
from multiprocessing import freeze_support
from pathlib import Path

import gradio as gr
Expand All @@ -20,7 +19,6 @@
import species
import utils
from train import trainModel
import webbrowser

_WINDOW: webview.Window
OUTPUT_TYPE_MAP = {
Expand Down Expand Up @@ -364,7 +362,7 @@ def runAnalysis(

# Combine results?
if not cfg.OUTPUT_FILE is None:
print("Combining results into {}...".format(cfg.OUTPUT_FILE), end='', flush=True)
print(f"Combining results into {cfg.OUTPUT_FILE}...", end="", flush=True)
analyze.combineResults(cfg.OUTPUT_PATH, cfg.OUTPUT_FILE)
print("done!", flush=True)

Expand Down Expand Up @@ -434,8 +432,8 @@ def select_subdirectories():
labels = []

for folder in subdirs:
labels_in_folder = folder.split(',')
labels_in_folder = folder.split(",")

for label in labels_in_folder:
if not label in labels:
labels.append(label)
Expand All @@ -455,6 +453,7 @@ def select_file(filetypes=()):
The selected file or None of the dialog was canceled.
"""
files = _WINDOW.create_file_dialog(webview.OPEN_DIALOG, file_types=filetypes)

return files[0] if files else None


Expand All @@ -472,7 +471,7 @@ def format_seconds(secs: float):
hours, secs = divmod(secs, 3600)
minutes, secs = divmod(secs, 60)

return "{:2.0f}:{:02.0f}:{:06.3f}".format(hours, minutes, secs)
return f"{hours:2.0f}:{minutes:02.0f}:{secs:06.3f}"


def select_directory(collect_files=True):
Expand Down Expand Up @@ -585,15 +584,17 @@ def start_training(
cfg.TRAIN_CACHE_MODE = cache_mode
cfg.TRAIN_CACHE_FILE = os.path.join(cache_file, cache_file_name) if cache_mode == "save" else cache_file
cfg.TFLITE_THREADS = 1
cfg.CPU_THREADS = max(1, multiprocessing.cpu_count() - 1) # let's use everything we have (well, almost)
cfg.CPU_THREADS = max(1, multiprocessing.cpu_count() - 1) # let's use everything we have (well, almost)

cfg.AUTOTUNE = autotune
cfg.AUTOTUNE_TRIALS = autotune_trials
cfg.AUTOTUNE_EXECUTIONS_PER_TRIAL = int(autotune_executions_per_trials)

def dataLoadProgression(num_files, num_total_files, label):
if progress is not None:
progress((num_files, num_total_files), total=num_total_files, unit="files", desc=f"Loading data for '{label}'")
progress(
(num_files, num_total_files), total=num_total_files, unit="files", desc=f"Loading data for '{label}'"
)

def epochProgression(epoch, logs=None):
if progress is not None:
Expand All @@ -606,7 +607,9 @@ def trialProgression(trial):
if progress is not None:
progress((trial, autotune_trials), total=autotune_trials, unit="trials", desc=f"Autotune in progress")

history = trainModel(on_epoch_end=epochProgression, on_trial_result=trialProgression, on_data_load_end=dataLoadProgression)
history = trainModel(
on_epoch_end=epochProgression, on_trial_result=trialProgression, on_data_load_end=dataLoadProgression
)

if len(history.epoch) < epochs:
gr.Info("Stopped early - validation metric not improving.")
Expand Down Expand Up @@ -845,37 +848,36 @@ def on_custom_classifier_selection_click():


if __name__ == "__main__":
freeze_support()
multiprocessing.freeze_support()

def build_header():

# Custom HTML header with gr.Markdown
# There has to be another way, but this works for now; paths are weird in gradio
with gr.Row():
gr.Markdown(
"""
f"""
<div style='display: flex; align-items: center;'>
<img src='data:image/png;base64,{}' style='width: 50px; height: 50px; margin-right: 10px;'>
<img src='data:image/png;base64,{utils.img2base64("gui/img/birdnet_logo.png")}' style='width: 50px; height: 50px; margin-right: 10px;'>
<h2>BirdNET Analyzer</h2>
</div>
""".format(
utils.img2base64("gui/img/birdnet_logo.png") # There has to be another way, but this works for now; paths are weird in gradio
)
"""
)

def build_footer():
with gr.Row():
gr.Markdown(
"""
f"""
<div style='display: flex; justify-content: space-around; align-items: center; padding: 10px; text-align: center'>
<div>GUI version: {}<br>Model version: {}</div>
<div>
<div style="display: flex;flex-direction: row;">GUI version: <span id="current-version">{cfg.GUI_VERSION}</span><span style="display: none" id="update-available"><a>+</a></span></div>
<div>Model version: {cfg.MODEL_VERSION}</div>
</div>
<div>K. Lisa Yang Center for Conservation Bioacoustics<br>Chemnitz University of Technology</div>
<div>For docs and support visit:<br><a href='https://birdnet.cornell.edu/analyzer' target='_blank'>birdnet.cornell.edu/analyzer</a></div>
</div>
""".format(
cfg.GUI_VERSION, cfg.MODEL_VERSION
)
)

"""
)

def build_single_analysis_tab():
with gr.Tab("Single file"):
Expand Down Expand Up @@ -1007,16 +1009,22 @@ def on_output_type_change(value, check):
return gr.Checkbox(visible=value == "Raven selection table"), gr.Textbox(visible=check)

output_type_radio.change(
on_output_type_change, inputs=[output_type_radio, combine_tables_checkbox], outputs=[combine_tables_checkbox, output_filename], show_progress=False
on_output_type_change,
inputs=[output_type_radio, combine_tables_checkbox],
outputs=[combine_tables_checkbox, output_filename],
show_progress=False,
)

def on_combine_tables_change(value):
return gr.Textbox(visible=value)

combine_tables_checkbox.change(
on_combine_tables_change, inputs=combine_tables_checkbox, outputs=output_filename, show_progress=False
on_combine_tables_change,
inputs=combine_tables_checkbox,
outputs=output_filename,
show_progress=False,
)

with gr.Row():
batch_size_number = gr.Number(
precision=1, label="Batch size", value=1, info="Number of samples to process at the same time."
Expand Down Expand Up @@ -1155,7 +1163,7 @@ def on_autotune_change(value):

autotune_cb.change(
on_autotune_change, inputs=autotune_cb, outputs=[custom_params, autotune_params], show_progress=False
)
)

with gr.Row():

Expand Down Expand Up @@ -1404,7 +1412,8 @@ def select_directory_and_update_tb():
)

with gr.Blocks(
css=r".d-block .wrap {display: block !important;} .mh-200 {max-height: 300px; overflow-y: auto !important;} footer {display: none !important;} #single_file_audio, #single_file_audio * {max-height: 81.6px; min-height: 0;}",
css="gui/gui.css",
js="gui/gui.js",
theme=gr.themes.Default(),
analytics_enabled=False,
) as demo:
Expand Down
25 changes: 25 additions & 0 deletions gui/gui.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.d-block .wrap {
display: block !important;
}

.mh-200 {
max-height: 300px;
overflow-y: auto !important;
}

footer {
display: none !important;
}

#single_file_audio,
#single_file_audio * {
max-height: 81.6px;
min-height: 0;
}

#update-notification {
background: green;
border-radius: 50%;
width: 1rem;
height: 1rem;
}
38 changes: 38 additions & 0 deletions gui/gui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function checkForNewerVersion() {
function sendGetRequest(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error(`Request failed with status ${xhr.status}`));
}
};
xhr.onerror = () => {
reject(new Error("Request failed"));
};
xhr.send();
});
}

const apiUrl = "https://api.github.com/repos/kahst/BirdNET-Analyzer/releases/latest";

sendGetRequest(apiUrl)
.then(response => {
const current_version = "v" + document.getElementById("current-version").textContent;
const response_object = JSON.parse(response);
const latest_version = response_object.tag_name;

if (current_version !== latest_version) {
const updateNotification = document.getElementById("update-available");

updateNotification.style.display = "block";
updateNotification.getElementsByTagName("a")[0].href = response_object.html_url;
}
})
.catch(error => {
console.error(error);
});
}

0 comments on commit 0e1f552

Please sign in to comment.