diff --git a/audio_player.py b/audio_player.py
index 13005f2..0ecbd01 100644
--- a/audio_player.py
+++ b/audio_player.py
@@ -15,8 +15,10 @@ class AudioPlayer(QObject):
__time_step = 500 # Milliseconds.
- def __init__(self, play, pause, stop, volume, audio_progress):
+ def __init__(self, play, pause, stop, volume, audio_progress, data_folder, audio_folder):
super().__init__()
+ self.__data_folder = data_folder
+ self.__audio_folder = audio_folder
self.__paused = False
self.__first_call = True
self.__play = play
@@ -77,7 +79,7 @@ class AudioPlayer(QObject):
def set_audio_player(self, fname = ""):
self.__first_call = True
self.__reset_audio_widget()
- full_name = os.path.join('Data', 'Audio_ogg', fname + '.ogg')
+ full_name = os.path.join(self.__data_folder, self.__audio_folder, fname + '.ogg')
if os.path.exists(full_name):
self.__play.setEnabled(True)
self.__audio_file = full_name
diff --git a/download_db_window.ui b/download_db_window.ui
new file mode 100644
index 0000000..2f17663
--- /dev/null
+++ b/download_db_window.ui
@@ -0,0 +1,112 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 400
+ 151
+
+
+
+ Download database
+
+
+ QWidget {
+ background-color: #464646
+}
+
+QLabel {
+ color: #ffffff;
+}
+
+QProgressBar {
+ border: 2px #7a7a7a;
+ border-radius: 5px;
+ background-color: #7a7a7a;
+}
+
+QProgressBar::chunk {
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
+ border-radius: 5px;
+}
+
+
+QMessageBox {
+ color: #ffffff;
+}
+
+QPushButton {
+ color: #ffffff;
+}
+
+
+
+ QLayout::SetDefaultConstraint
+
+ -
+
+
+
+ 12
+
+
+
+ Downloading database
+Please wait
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
+ -1
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ QPushButton {
+ background-color: rgb(52,52,52);
+ color: #FFFFFF;
+ border: 1px solid gray;
+ border-radius: 8px;
+}
+
+
+
+ Cancel
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+
diff --git a/download_thread.py b/download_thread.py
new file mode 100644
index 0000000..2a7d0c1
--- /dev/null
+++ b/download_thread.py
@@ -0,0 +1,43 @@
+from io import BytesIO
+from os import mkdir
+import os.path
+from shutil import rmtree
+import urllib
+from zipfile import ZipFile
+from PyQt5.QtCore import QThread, pyqtSignal
+
+class DownloadThread(QThread):
+ no_connection_error = pyqtSignal()
+ bad_db_download_error = pyqtSignal()
+
+ def __init__(self, db_location, path):
+ super().__init__()
+ self.__db_location = db_location
+ self.__path = path
+ self.regular_execution = True
+ self.reason = 0
+
+ def __del__(self):
+ self.terminate()
+ self.wait()
+
+ def run(self):
+ if os.path.exists(self.__path):
+ rmtree(self.__path)
+ try:
+ db = urllib.request.urlopen(self.__db_location)
+ # raise urllib.error.URLError('Test')
+ except urllib.error.URLError: # No internet connection.
+ self.regular_execution = False
+ self.no_connection_error.emit()
+ return
+ if db.status != 200:
+ self.regular_execution = False
+ self.reason = db.reason
+ self.bad_db_download_error.emit()
+ return
+ try:
+ with ZipFile(BytesIO(db.read())) as zipped:
+ zipped.extractall()
+ except:
+ pass
diff --git a/download_window.py b/download_window.py
new file mode 100644
index 0000000..d609bcf
--- /dev/null
+++ b/download_window.py
@@ -0,0 +1,63 @@
+from PyQt5 import uic
+from PyQt5.QtCore import Qt, pyqtSlot
+from PyQt5.QtWidgets import QWidget, QMessageBox
+from download_thread import DownloadThread
+Ui_Download_window, _ = uic.loadUiType("download_db_window.ui")
+
+class DownloadWindow(QWidget, Ui_Download_window):
+ def __init__(self, db_location, data_folder):
+ super().__init__()
+ self.setupUi(self)
+ self.setWindowFlags(
+ #Qt.Window |
+ Qt.CustomizeWindowHint |
+ Qt.WindowTitleHint |
+ Qt.WindowCloseButtonHint #|
+ # Qt.WindowStaysOnTopHint
+ )
+ self.everything_ok = True
+ self.no_internet_msg = QMessageBox(self)
+ self.no_internet_msg.setWindowTitle("No internet connection")
+ self.no_internet_msg.setText("Unable to establish an internet connection")
+ # self.no_internet_msg.buttonClicked.connect(self.close)
+ self.no_internet_msg.finished.connect(self.close)
+
+ self.bad_db_download_msg = QMessageBox(self)
+ self.bad_db_download_msg.setWindowTitle("Something wrong")
+ self.bad_db_download_msg.finished.connect(self.close)
+
+ self.download_thread = DownloadThread(db_location, data_folder)
+ self.download_thread.finished.connect(self.wait_close)
+ self.download_thread.no_connection_error.connect(self.show_no_connection_warning)
+ self.download_thread.bad_db_download_error.connect(self.show_bad_download_warning)
+
+ self.cancel_btn.clicked.connect(self.terminate_process)
+
+ @pyqtSlot()
+ def show_no_connection_warning(self):
+ self.bad_db_download_msg.setText(f"Unable to correctly download the database.\nReason: {self.download_thread.reason}")
+ self.no_internet_msg.show()
+ self.everything_ok = False
+
+ @pyqtSlot()
+ def show_bad_download_warning(self):
+ self.bad_db_download_msg.show()
+ self.everything_ok = False
+
+ @pyqtSlot()
+ def terminate_process(self):
+ if self.download_thread.isRunning():
+ self.download_thread.terminate()
+ self.download_thread.wait()
+ self.close()
+
+ @pyqtSlot()
+ def wait_close(self):
+ if self.download_thread.regular_execution:
+ self.close()
+
+ def reject(self):
+ if self.download_thread.isRunning():
+ self.download_thread.terminate()
+ self.download_thread.wait()
+ super().reject()
diff --git a/main.py b/main.py
index 1e93fcb..80a5ea0 100644
--- a/main.py
+++ b/main.py
@@ -13,17 +13,26 @@ from PyQt5.QtWidgets import (QMainWindow,
QListWidgetItem,)
from PyQt5.QtGui import QPixmap
from PyQt5 import uic
-from PyQt5.QtCore import QFileInfo, QSize, Qt, pyqtSlot
+from PyQt5.QtCore import (QFileInfo,
+ QSize,
+ Qt,
+ pyqtSlot,)
from audio_player import AudioPlayer
from double_text_button import DoubleTextButton
+from download_window import DownloadWindow
qt_creator_file = "main_window.ui"
-
Ui_MainWindow, _ = uic.loadUiType(qt_creator_file)
class MyApp(QMainWindow, Ui_MainWindow):
+ db_location = 'https://aresvalley.com/Storage/Artemis/Database/data.zip'
+ data_folder = 'Data'
+ spectra_folder = 'Spectra'
+ audio_folder = 'Audio'
+ icons_folder = 'icons_imgs'
+
Band = namedtuple("Band", ["lower", "upper"])
ELF = Band(0, 30) # Formally it is (3, 30) Hz.
SLF = Band(30, 300)
@@ -45,8 +54,10 @@ class MyApp(QMainWindow, Ui_MainWindow):
super().__init__()
self.setupUi(self)
self.set_initial_size()
+ self.download_window = DownloadWindow(self.db_location, self.data_folder)
self.show()
self.actionExit.triggered.connect(qApp.quit)
+ self.action_update_database.triggered.connect(self.download_db)
self.db_version = None
self.db = None
self.current_signal_name = ''
@@ -286,7 +297,9 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.pause,
self.stop,
self.volume,
- self.audio_progress)
+ self.audio_progress,
+ self.data_folder,
+ self.audio_folder)
BandLabel = namedtuple("BandLabel", ["left", "center", "right"])
self.band_labels = [
@@ -324,6 +337,14 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.upper_freq_filter_unit.setFixedWidth(120)
self.lower_freq_confidence.setFixedWidth(120)
self.upper_freq_confidence.setFixedWidth(120)
+
+ self.lower_band_spinbox.setFixedWidth(200)
+ self.upper_band_spinbox.setFixedWidth(200)
+ self.lower_band_filter_unit.setFixedWidth(120)
+ self.upper_band_filter_unit.setFixedWidth(120)
+ self.lower_band_confidence.setFixedWidth(120)
+ self.upper_band_confidence.setFixedWidth(120)
+
self.audio_progress.setFixedHeight(20)
self.volume.setStyleSheet("""
QSlider::groove:horizontal {
@@ -341,6 +362,19 @@ class MyApp(QMainWindow, Ui_MainWindow):
}
""")
+ @pyqtSlot()
+ def download_db(self):
+ self.download_window.download_thread.finished.connect(self.show_downloaded_signals)
+ self.download_window.download_thread.start()
+ self.download_window.show()
+
+ @pyqtSlot()
+ def show_downloaded_signals(self):
+ if self.download_window.everything_ok:
+ self.search_bar.setEnabled(True)
+ self.load_db()
+ self.display_signals()
+
def load_db(self):
names = ["name",
"inf_freq",
@@ -355,7 +389,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
"category_code",
"acf",]
try:
- self.db = read_csv(os.path.join('Data', 'db.csv'),
+ self.db = read_csv(os.path.join(self.data_folder, 'db.csv'),
sep = '*',
header = None,
index_col = 0,
@@ -371,27 +405,14 @@ class MyApp(QMainWindow, Ui_MainWindow):
box = QMessageBox(self)
box.setWindowTitle("No database")
box.setText("No database available.\n"
- "Go to Updates->Download database.")
+ "Go to Updates->Update database.")
box.show()
else:
self.signal_names = self.db.index
self.total_signals = len(self.signal_names)
self.db.fillna("N/A", inplace = True)
self.db["url_clicked"] = False
- try:
- with open(os.path.join('Data', 'verdb.ini'), 'r') as dbver:
- self.db_version = int(dbver.read())
- except (FileNotFoundError, ValueError):
- box = QMessageBox(self)
- box.setWindowTitle("No database version")
- box.setText("Unable to detect database version.\n"
- "Possible data curruption.\n"
- "Go to Updates->Force Download.")
- box.show()
- self.statusbar.setStyleSheet(f'color: {self.active_color}')
- self.statusbar.showMessage("Database version: undefined.")
- else:
- self.update_status_tip(self.total_signals)
+ self.update_status_tip(self.total_signals)
@staticmethod
def connect_to(objects_to_connect, fun_to_connect, fun_args):
@@ -556,7 +577,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
def frequency_filters_ok(self, signal_name):
if not self.apply_remove_freq_filter_btn.isChecked():
return True
- undef_freq, _ = self.find_if_undefined(self.db.loc[signal_name])
+ undef_freq = self.is_undef_freq(self.db.loc[signal_name])
if undef_freq:
if self.include_undef_freqs.isChecked():
return True
@@ -593,7 +614,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
def band_filters_ok(self, signal_name):
if not self.apply_remove_band_filter_btn.isChecked():
return True
- _, undef_band = self.find_if_undefined(self.db.loc[signal_name])
+ undef_band = self.is_undef_band(self.db.loc[signal_name])
if undef_band:
if self.include_undef_bands.isChecked():
return True
@@ -652,7 +673,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
else:
self.url_button.setStyleSheet(f"color: {self.url_button.colors.clicked};")
category_code = current_signal.at["category_code"]
- undef_freq, undef_band = self.find_if_undefined(current_signal)
+ undef_freq = self.is_undef_freq(current_signal)
+ undef_band = self.is_undef_band(current_signal)
if not undef_freq:
self.freq_lab.setText(self.format_numbers(
current_signal.at["inf_freq"],
@@ -694,20 +716,16 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.audio_widget.set_audio_player()
@staticmethod
- def find_if_undefined(current_signal):
+ def is_undef_freq(current_signal):
lower_freq = current_signal.at["inf_freq"]
- lower_band = current_signal.at["inf_band"]
upper_freq = current_signal.at["sup_freq"]
+ return lower_freq == 'N/A' or upper_freq == 'N/A'
+
+ @staticmethod
+ def is_undef_band(current_signal):
+ lower_band = current_signal.at["inf_band"]
upper_band = current_signal.at["sup_band"]
- if lower_freq == '0' and upper_freq == "100000000000":
- undefined_freq = True
- else:
- undefined_freq = False
- if lower_band == '0' and upper_band == '100000000':
- undefined_band = True
- else:
- undefined_band = False
- return undefined_freq, undefined_band
+ return lower_band == 'N/A' or upper_band == 'N/A'
@classmethod
def format_numbers(cls, lower, upper):
@@ -740,13 +758,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
return 10**9
def display_spectrogram(self):
- default_pic = os.path.join("icons_imgs", "nosignalselected.png")
+ default_pic = os.path.join(self.icons_folder, "nosignalselected.png")
item = self.result_list.currentItem()
if item:
spectrogram_name = item.text()
- path_spectr = os.path.join("Data", "Spectra", spectrogram_name + ".jpg")
+ path_spectr = os.path.join(self.data_folder, self.spectra_folder, spectrogram_name + ".png")
if not QFileInfo(path_spectr).exists():
- path_spectr = os.path.join("icons_imgs", "spectrumnotavailable.png")
+ path_spectr = os.path.join(self.icons_folder, "spectrumnotavailable.png")
else:
path_spectr = default_pic
self.spectrogram.setPixmap(QPixmap(path_spectr))
@@ -758,7 +776,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
label.setStyleSheet(f"color: {color};")
def set_band_range(self, current_signal = None):
- if current_signal is not None and not self.find_if_undefined(current_signal)[0]:
+ if current_signal is not None and not self.is_undef_freq(current_signal):
lower_freq = int(current_signal.at["inf_freq"])
upper_freq = int(current_signal.at["sup_freq"])
zipped = list(zip(self.bands, self.band_labels))
@@ -791,6 +809,11 @@ class MyApp(QMainWindow, Ui_MainWindow):
webbrowser.open(self.db.at[self.current_signal_name, "url"])
self.db.at[self.current_signal_name, "url_clicked"] = True
+ def closeEvent(self, event):
+ if self.download_window.isVisible():
+ self.download_window.close()
+ super().closeEvent(event)
+
if __name__ == '__main__':
diff --git a/main_window.ui b/main_window.ui
index bd14a26..32fcc1d 100644
--- a/main_window.ui
+++ b/main_window.ui
@@ -323,7 +323,7 @@ QPushButton:!enabled {
QTabWidget::Rounded
- 1
+ 0
true
@@ -4032,11 +4032,15 @@ QMenuBar::item:selected {
QMenu::item:selected {
background-color: #999999;
color: #1d5eff
+}
+
+QMenu {
+ color: #ffffff;
}
@@ -4061,6 +4066,11 @@ QMenu::item:selected {
Exit
+
+
+ Update database
+
+