diff --git a/.gitignore b/.gitignore
index 660e8c3..364da4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,9 @@ Data
.ipynb_checkpoints
*.ipynb
wav_converter.py
-*.txt
+to_do.txt
+csv_info.txt
+pyinstaller_cmd.txt
icons_imgs
TestData
themes/.current_theme
diff --git a/audio_player.py b/audio_player.py
index 2d4c2f5..01ec3df 100644
--- a/audio_player.py
+++ b/audio_player.py
@@ -4,7 +4,7 @@ from pydub import AudioSegment
from pygame import mixer
from PyQt5.QtCore import QTimer, QTimer, pyqtSlot, QObject
-from utilities import Constants
+import constants
import qtawesome as qta
@@ -82,7 +82,7 @@ class AudioPlayer(QObject): # Maybe useless inheriting from QObject
def set_audio_player(self, fname = ""):
self.__first_call = True
self.__reset_audio_widget()
- full_name = os.path.join(Constants.DATA_FOLDER, Constants.AUDIO_FOLDER, fname + '.ogg')
+ full_name = os.path.join(constants.DATA_FOLDER, constants.AUDIO_FOLDER, fname + '.ogg')
if os.path.exists(full_name):
self.__play.setEnabled(True)
self.__audio_file = full_name
diff --git a/constants.py b/constants.py
new file mode 100644
index 0000000..2c46a5b
--- /dev/null
+++ b/constants.py
@@ -0,0 +1,168 @@
+from collections import namedtuple
+from enum import Enum, auto
+
+class Ftype(object):
+ FREQ = "freq"
+ BAND = "band"
+
+class ChecksumWhat(Enum):
+ FOLDER = auto()
+ DB = auto()
+
+class Theme(object):
+ FOLDER = "themes"
+ EXTENSION = ".qss"
+ ICONS_FOLDER = "icons"
+ DEFAULT = "1-system"
+ CURRENT = ".current_theme"
+ COLORS = "colors.txt"
+ COLOR_SEPARATOR = "="
+ DEFAULT_ACTIVE_COLOR = "#39eaff"
+ DEFAULT_INACTIVE_COLOR = "#9f9f9f"
+
+class Messages(object):
+ NO_DB_AVAIL = "No database available.\nGo to Updates->Update database."
+ NO_DB = "No database"
+ THEME_NOT_FOUND = "Theme not found"
+ MISSING_THEME = "Missing theme in " + Theme.FOLDER + " folder."
+ NO_CONNECTION = "No internet connection"
+ NO_CONNECTION_MSG = "Unable to establish an internet connection."
+ BAD_DOWNLOAD = "Something went wrong"
+ BAD_DOWNLOAD_MSG = "Something went wrong with the downaload.\nCheck your internet connection and try again."
+ BAD_FILE = "Bad file detected"
+ BAD_FILE_MSG = "The downloaded file seems to be corrupted.\nThe old database has not been deleted and\nthe downloaded file has been discarded."
+
+class Signal(object):
+ NAME = "name"
+ INF_FREQ = "inf_freq"
+ SUP_FREQ = "sup_freq"
+ MODE = "mode"
+ INF_BAND = "inf_band"
+ SUP_BAND = "sup_band"
+ LOCATION = "location"
+ URL = "url"
+ DESCRIPTION = "description"
+ MODULATION = "modulation"
+ CATEGORY_CODE = "category_code"
+ ACF = "acf"
+ WIKI_CLICKED = "url_clicked"
+
+class Database(object):
+ LINK_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip"
+ LINK_REF = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log"
+ NAME = "db.csv"
+ NAMES = (Signal.NAME,
+ Signal.INF_FREQ,
+ Signal.SUP_FREQ,
+ Signal.MODE,
+ Signal.INF_BAND,
+ Signal.SUP_BAND,
+ Signal.LOCATION,
+ Signal.URL,
+ Signal.DESCRIPTION,
+ Signal.MODULATION,
+ Signal.CATEGORY_CODE,
+ Signal.ACF,)
+ DELIMITER = "*"
+ STRINGS = (Signal.INF_FREQ,
+ Signal.SUP_FREQ,
+ Signal.MODE,
+ Signal.INF_BAND,
+ Signal.SUP_BAND,
+ Signal.CATEGORY_CODE,)
+
+SEARCH_LABEL_IMG = "search_icon.png"
+VOLUME_LABEL_IMG = "volume.png"
+DATA_FOLDER = "Data"
+SPECTRA_FOLDER = "Spectra"
+SPECTRA_EXT = ".png"
+AUDIO_FOLDER = "Audio"
+ACTIVE = "active"
+INACTIVE = "inactive"
+NOT_AVAILABLE = "spectrumnotavailable.png"
+NOT_SELECTED = "nosignalselected.png"
+__Band = namedtuple("Band", ["lower", "upper"])
+__ELF = __Band(0, 30) # Formally it is (3, 30) Hz.
+__SLF = __Band(30, 300)
+__ULF = __Band(300, 3000)
+__VLF = __Band(3000, 30000)
+__LF = __Band(30 * 10**3, 300 * 10**3)
+__MF = __Band(300 * 10 ** 3, 3000 * 10**3)
+__HF = __Band(3 * 10**6, 30 * 10**6)
+__VHF = __Band(30 * 10**6, 300 * 10**6)
+__UHF = __Band(300 * 10**6, 3000 * 10**6)
+__SHF = __Band(3 * 10**9, 30 * 10**9)
+__EHF = __Band(30 * 10**9, 300 * 10**9)
+BANDS = (__ELF, __SLF, __ULF, __VLF, __LF, __MF, __HF, __VHF, __UHF, __SHF, __EHF)
+CONVERSION_FACTORS = {"Hz" : 1,
+ "kHz": 1000,
+ "MHz": 1000000,
+ "GHz": 1000000000}
+MODES = {"FM": ("NFM", "WFM"),
+ "AM": (),
+ "CW": (),
+ "SK": ("FSK", "PSK", "MSK"),
+ "SB": ("LSB", "USB", "DSB"),
+ "Chirp Spread Spectrum": (),
+ "FHSS-TDM": (),
+ "RAW": (),
+ "SC-FDMA": (),}
+APPLY = "Apply"
+REMOVE = "Remove"
+UNKNOWN = "N/A"
+MODULATIONS = ("8VSB",
+ "AFSK",
+ "AM",
+ "BFSK",
+ "C4FM",
+ "CDMA",
+ "COFDM",
+ "CW",
+ "FFSK",
+ "FM",
+ "FMCW",
+ "FMOP",
+ "FSK",
+ "GFSK",
+ "GMSK",
+ "IFK",
+ "MFSK",
+ "MSK",
+ "OFDM",
+ "OOK",
+ "PAM",
+ "PPM",
+ "PSK",
+ "QAM",
+ "TDMA",)
+LOCATIONS = (UNKNOWN,
+ "Australia",
+ "Canada",
+ "Central Europe",
+ "China",
+ "Cyprus",
+ "Eastern Europe",
+ "Europe",
+ "Europe, japan and Asia",
+ "Exmouth, Australia",
+ "Finland",
+ "France",
+ "Germany",
+ "Home Base Mobile , AL",
+ "Hungary",
+ "Iran",
+ "Israel",
+ "Japan",
+ "LaMour, North Dakota",
+ "Lualualei, Hawaii",
+ "North America",
+ "North Korea",
+ "Poland",
+ "Romania",
+ "Ruda, Sweden",
+ "UK",
+ "United Kingdom",
+ "United States",
+ "Varberg, Sweden",
+ "World Wide",
+ "Worldwide",)
\ No newline at end of file
diff --git a/download_db_window.ui b/download_db_window.ui
index 6f3c1f8..0da9b37 100644
--- a/download_db_window.ui
+++ b/download_db_window.ui
@@ -7,7 +7,7 @@
0
0
400
- 151
+ 137
@@ -29,7 +29,7 @@
Downloading database
-Please wait
+Please wait...
Qt::AlignCenter
diff --git a/download_window.py b/download_window.py
index 2291e34..cfce206 100644
--- a/download_window.py
+++ b/download_window.py
@@ -1,7 +1,9 @@
from PyQt5 import uic
from PyQt5.QtCore import Qt, pyqtSlot
-from PyQt5.QtWidgets import QWidget, QMessageBox
+from PyQt5.QtWidgets import QWidget
from threads import DownloadThread, ThreadStatus
+from utilities import throwable_message
+from constants import Messages
Ui_Download_window, _ = uic.loadUiType("download_db_window.ui")
@@ -17,24 +19,19 @@ class DownloadWindow(QWidget, Ui_Download_window):
# 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.setText("""Something went wrong with the downaload.
- Check your internet connection and try again.""")
- self.bad_db_download_msg.finished.connect(self.close)
+ self.no_internet_msg = throwable_message(self, title = Messages.NO_CONNECTION,
+ text = Messages.NO_CONNECTION_MSG,
+ connection = self.close)
- self.bad_file_msg = QMessageBox(self)
- self.bad_file_msg.setWindowTitle("Bad file detected")
- self.bad_file_msg.setText("""The downloaded file seems to be corrupted.
- The old database has not been deleted and
- the downloaded file has been discarded.""")
- self.bad_file_msg.finished.connect(self.close)
+ self.bad_db_download_msg = throwable_message(self, title = Messages.BAD_DOWNLOAD,
+ text = Messages.BAD_DOWNLOAD_MSG,
+ connection = self.close)
+
+ # Never used (should exploit the checksum check for the single file)
+ self.bad_file_msg = throwable_message(self, title = Messages.BAD_FILE,
+ text = Messages.BAD_FILE_MSG,
+ connection = self.close)
self.download_thread = DownloadThread()
self.download_thread.finished.connect(self.wait_close)
@@ -42,8 +39,6 @@ class DownloadWindow(QWidget, Ui_Download_window):
self.cancel_btn.clicked.connect(self.terminate_process)
def show_no_connection_warning(self):
- self.bad_db_download_msg.setText(f"""Unable to correctly download the database.
- Reason: {self.download_thread.reason}""")
self.no_internet_msg.show()
self.everything_ok = False
@@ -51,6 +46,10 @@ class DownloadWindow(QWidget, Ui_Download_window):
self.bad_db_download_msg.show()
self.everything_ok = False
+ def show_bad_file_warning(self):
+ self.bad_file_msg.show()
+ self.everything_ok = False
+
@pyqtSlot()
def terminate_process(self):
if self.download_thread.isRunning():
@@ -65,7 +64,7 @@ class DownloadWindow(QWidget, Ui_Download_window):
elif self.download_thread.status == ThreadStatus.NO_CONNECTION_ERR:
self.show_no_connection_warning()
elif self.download_thread.status == ThreadStatus.BAD_DOWNLOAD_ERR:
- self.show_bad_download_warning
+ self.show_bad_download_warning()
else:
self.close()
diff --git a/main.py b/main.py
index 7a14016..378690e 100644
--- a/main.py
+++ b/main.py
@@ -9,7 +9,6 @@ from pandas import read_csv
from PyQt5.QtWidgets import (QMainWindow,
QApplication,
QAction,
- QMessageBox,
qApp,
QDesktopWidget,
QListWidgetItem,
@@ -27,17 +26,23 @@ from audio_player import AudioPlayer
from double_text_button import DoubleTextButton
from download_window import DownloadWindow
+import constants
-from utilities import (Constants,
- reset_apply_remove_btn,
+from utilities import (reset_apply_remove_btn,
throwable_message,
- is_valid_html_color,)
+ is_valid_html_color,
+ connect_to,
+ filters_ok,
+ is_undef_freq,
+ is_undef_band,
+ change_unit,
+ format_numbers)
qt_creator_file = "main_window.ui"
Ui_MainWindow, _ = uic.loadUiType(qt_creator_file)
-class MyApp(QMainWindow, Ui_MainWindow):
+class MyApp(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
@@ -49,8 +54,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.current_signal_name = ''
self.signal_names = []
self.total_signals = 0
- self.active_color = Constants.ACTIVE_COLOR
- self.inactive_color = Constants.INACTIVE_COLOR
+ self.active_color = constants.Theme.DEFAULT_ACTIVE_COLOR
+ self.inactive_color = constants.Theme.DEFAULT_INACTIVE_COLOR
# Manage frequency filters.
self.frequency_filters_btns = (
@@ -67,7 +72,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.ehf_filter_btn,
)
- self.connect_to(
+ connect_to(
objects_to_connect = [self.lower_freq_spinbox.valueChanged,
self.upper_freq_spinbox.valueChanged,
self.lower_freq_filter_unit.currentTextChanged,
@@ -80,7 +85,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.upper_freq_spinbox]
)
- self.connect_to(
+ connect_to(
objects_to_connect = [self.lower_freq_spinbox.valueChanged,
self.upper_freq_spinbox.valueChanged,
self.lower_freq_filter_unit.currentTextChanged,
@@ -117,7 +122,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.upper_freq_confidence)
)
- self.apply_remove_freq_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_freq_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_freq_filter_btn.set_slave_filters(
[
*self.frequency_filters_btns,
@@ -139,11 +144,11 @@ class MyApp(QMainWindow, Ui_MainWindow):
],
)
self.apply_remove_freq_filter_btn.clicked.connect(self.display_signals)
- self.reset_frequency_filters_btn.clicked.connect(partial(self.reset_fb_filters, 'freq'))
+ self.reset_frequency_filters_btn.clicked.connect(partial(self.reset_fb_filters, constants.Ftype.FREQ))
# Manage bandwidth filters.
- self.connect_to(
+ connect_to(
objects_to_connect = [self.lower_band_spinbox.valueChanged,
self.upper_band_spinbox.valueChanged,
self.lower_band_filter_unit.currentTextChanged,
@@ -156,7 +161,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.upper_band_spinbox]
)
- self.connect_to(
+ connect_to(
objects_to_connect = [self.lower_band_spinbox.valueChanged,
self.upper_band_spinbox.valueChanged,
self.lower_band_filter_unit.currentTextChanged,
@@ -193,7 +198,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.upper_band_confidence)
)
- self.apply_remove_band_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_band_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_band_filter_btn.set_slave_filters(
[
self.include_undef_bands,
@@ -214,7 +219,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
],
)
self.apply_remove_band_filter_btn.clicked.connect(self.display_signals)
- self.reset_band_filters_btn.clicked.connect(partial(self.reset_fb_filters, 'band'))
+ self.reset_band_filters_btn.clicked.connect(partial(self.reset_fb_filters, constants.Ftype.BAND))
# Manage category filters
@@ -237,7 +242,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.number_stations_btn,
self.time_signal_btn,]
- self.apply_remove_cat_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_cat_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_cat_filter_btn.set_slave_filters([*self.cat_filter_btns,
self.cat_at_least_one,
self.cat_all])
@@ -283,16 +288,16 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.set_mode_tree_widget()
self.mode_tree_widget.itemSelectionChanged.connect(self.manage_mode_selections)
self.reset_mode_filters_btn.clicked.connect(self.reset_mode_filters)
- self.apply_remove_mode_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_mode_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_mode_filter_btn.set_slave_filters([self.mode_tree_widget,
self.include_unknown_modes_btn])
self.apply_remove_mode_filter_btn.clicked.connect(self.display_signals)
# Set modulation filter screen.
- self.modulation_list.addItems(Constants.MODULATIONS)
+ self.modulation_list.addItems(constants.MODULATIONS)
self.search_bar_modulation.textEdited.connect(self.show_matching_modulations)
- self.apply_remove_modulation_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_modulation_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_modulation_filter_btn.set_slave_filters([self.search_bar_modulation,
self.modulation_list])
self.apply_remove_modulation_filter_btn.clicked.connect(self.display_signals)
@@ -301,9 +306,9 @@ class MyApp(QMainWindow, Ui_MainWindow):
# Set location filter screen.
- self.locations_list.addItems(Constants.LOCATIONS)
+ self.locations_list.addItems(constants.LOCATIONS)
self.search_bar_location.textEdited.connect(self.show_matching_locations)
- self.apply_remove_location_filter_btn.set_texts(Constants.APPLY, Constants.REMOVE)
+ self.apply_remove_location_filter_btn.set_texts(constants.APPLY, constants.REMOVE)
self.apply_remove_location_filter_btn.set_slave_filters([self.search_bar_location,
self.locations_list])
self.apply_remove_location_filter_btn.clicked.connect(self.display_signals)
@@ -311,11 +316,9 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.locations_list.itemClicked.connect(self.remove_if_unselected_location)
# Find available themes.
- self.default_images_folder = os.path.join(Constants.THEMES_FOLDER,
- Constants.DEFAULT_THEME,
- Constants.ICONS_FOLDER)
- # self.find_themes()
- # self.set_theme()
+ self.default_images_folder = os.path.join(constants.Theme.FOLDER,
+ constants.Theme.DEFAULT,
+ constants.Theme.ICONS_FOLDER)
# ##########################################################################################
@@ -357,10 +360,10 @@ class MyApp(QMainWindow, Ui_MainWindow):
def find_themes(self):
themes = []
- for theme_folder in os.listdir(Constants.THEMES_FOLDER):
- relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
+ for theme_folder in os.listdir(constants.Theme.FOLDER):
+ relative_folder = os.path.join(constants.Theme.FOLDER, theme_folder)
if os.path.isdir(os.path.abspath(relative_folder)):
- relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
+ relative_folder = os.path.join(constants.Theme.FOLDER, theme_folder)
themes.append(relative_folder)
for theme in themes:
theme_name = '&' + ' '.join(
@@ -382,26 +385,26 @@ class MyApp(QMainWindow, Ui_MainWindow):
try:
with open(os.path.join(
theme_path,
- os.path.basename(theme_path).split('-')[1] + Constants.THEME_EXTENSION)
+ os.path.basename(theme_path).split('-')[1] + constants.Theme.EXTENSION)
) as stylesheet:
style = stylesheet.read()
self.setStyleSheet(style)
self.download_window.setStyleSheet(style)
except FileNotFoundError:
- throwable_message(self, title = "Theme not found",
- text = f"Missing theme in {Constants.THEMES_FOLDER} folder.").show()
+ throwable_message(self, title = constants.Messages.THEME_NOT_FOUND,
+ text = constants.Messages.MISSING_THEME).show()
else:
- icons_path = os.path.join(theme_path, Constants.ICONS_FOLDER)
- default_icons_path = os.path.join(Constants.THEMES_FOLDER, Constants.DEFAULT_THEME, Constants.ICONS_FOLDER)
+ icons_path = os.path.join(theme_path, constants.Theme.ICONS_FOLDER)
+ default_icons_path = os.path.join(constants.Theme.FOLDER, constants.Theme.DEFAULT, constants.Theme.ICONS_FOLDER)
- if os.path.exists(os.path.join(icons_path, Constants.NOT_SELECTED)) and \
- os.path.exists(os.path.join(icons_path, Constants.NOT_AVAILABLE)):
+ if os.path.exists(os.path.join(icons_path, constants.NOT_SELECTED)) and \
+ os.path.exists(os.path.join(icons_path, constants.NOT_AVAILABLE)):
self.default_images_folder = icons_path
else:
self.default_images_folder = default_icons_path
- path_to_search_label = os.path.join(icons_path, Constants.SEARCH_LABEL_IMG)
- default_search_label = os.path.join(default_icons_path, Constants.SEARCH_LABEL_IMG)
+ path_to_search_label = os.path.join(icons_path, constants.SEARCH_LABEL_IMG)
+ default_search_label = os.path.join(default_icons_path, constants.SEARCH_LABEL_IMG)
if os.path.exists(path_to_search_label):
self.search_label.setPixmap(QPixmap(path_to_search_label))
@@ -416,8 +419,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.modulation_search_label.setScaledContents(True)
self.location_search_label.setScaledContents(True)
- path_to_volume_label = os.path.join(icons_path, Constants.VOLUME_LABEL_IMG)
- default_volume_label = os.path.join(default_icons_path, Constants.VOLUME_LABEL_IMG)
+ path_to_volume_label = os.path.join(icons_path, constants.VOLUME_LABEL_IMG)
+ default_volume_label = os.path.join(default_icons_path, constants.VOLUME_LABEL_IMG)
if os.path.exists(path_to_volume_label):
self.volume_label.setPixmap(QPixmap(path_to_volume_label))
@@ -426,7 +429,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.volume_label.setScaledContents(True)
- path_to_colors = os.path.join(theme_path, Constants.THEME_COLORS)
+ path_to_colors = os.path.join(theme_path, constants.Theme.COLORS)
active_color_ok = False
inactive_color_ok = False
valid_format = False
@@ -435,36 +438,36 @@ class MyApp(QMainWindow, Ui_MainWindow):
valid_file = True
with open(path_to_colors, "r") as colors_file:
for line in colors_file:
- if '=' in line:
+ if constants.Theme.COLOR_SEPARATOR in line:
valid_format = True
- quality, color = line.split("=")
+ quality, color = line.split(constants.Theme.COLOR_SEPARATOR)
color = color.rstrip()
- if quality == "active" and is_valid_html_color(color):
+ if quality.lower() == constants.ACTIVE and is_valid_html_color(color):
self.active_color = color
active_color_ok = True
- if quality == "inactive" and is_valid_html_color(color):
+ if quality.lower() == constants.INACTIVE and is_valid_html_color(color):
self.inactive_color = color
inactive_color_ok = True
if not all([valid_file, valid_format, active_color_ok, inactive_color_ok]):
- self.active_color = Constants.ACTIVE_COLOR
- self.inactive_color = Constants.INACTIVE_COLOR
+ self.active_color = constants.Theme.DEFAULT_ACTIVE_COLOR
+ self.inactive_color = constants.Theme.DEFAULT_INACTIVE_COLOR
self.audio_widget.refresh_btns_colors(self.active_color, self.inactive_color)
try:
- with open(os.path.join(Constants.THEMES_FOLDER,
- Constants.CURRENT_THEME), "w") as current_theme:
+ with open(os.path.join(constants.Theme.FOLDER,
+ constants.Theme.CURRENT), "w") as current_theme:
current_theme.write(theme_path)
except:
pass
def set_theme(self):
- current_theme_file = os.path.join(Constants.THEMES_FOLDER, Constants.CURRENT_THEME)
+ current_theme_file = os.path.join(constants.Theme.FOLDER, constants.Theme.CURRENT)
if os.path.exists(current_theme_file):
with open(current_theme_file) as current_theme:
theme = current_theme.read()
- if theme != Constants.DEFAULT_THEME:
+ if theme != constants.Theme.DEFAULT:
self.change_theme(theme)
@pyqtSlot(QListWidgetItem)
@@ -494,7 +497,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
item.setHidden(True)
def set_mode_tree_widget(self):
- for parent, children in Constants.MODES.items():
+ for parent, children in constants.MODES.items():
iparent = QTreeWidgetItem([parent])
self.mode_tree_widget.addTopLevelItem(iparent)
for child in children:
@@ -504,11 +507,11 @@ class MyApp(QMainWindow, Ui_MainWindow):
def manage_mode_selections(self):
selected_items = self.mode_tree_widget.selectedItems()
- parents = Constants.MODES.keys()
+ parents = constants.MODES.keys()
for parent in parents:
for item in selected_items:
if parent == item.text(0):
- for i in range(len(Constants.MODES[parent])):
+ for i in range(len(constants.MODES[parent])):
item.child(i).setSelected(True)
def set_initial_size(self):
@@ -571,32 +574,25 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.display_signals()
def load_db(self):
- names = Constants.DB_NAMES
+ names = constants.Database.NAMES
try:
- self.db = read_csv(os.path.join(Constants.DATA_FOLDER, Constants.DB_NAME),
- sep = '*',
+ self.db = read_csv(os.path.join(constants.DATA_FOLDER, constants.Database.NAME),
+ sep = constants.Database.DELIMITER,
header = None,
index_col = 0,
- dtype = {name : str for name in Constants.DB_STRINGS},
+ dtype = {name : str for name in constants.Database.STRINGS},
names = names,)
except FileNotFoundError:
self.search_bar.setDisabled(True)
- box = QMessageBox(self)
- box.setWindowTitle(Constants.Messages.NO_DB)
- box.setText(Constants.Messages.NO_DB_AVAIL)
- box.show()
+ throwable_message(self, title = constants.Messages.NO_DB,
+ text = constants.Messages.NO_DB_AVAIL).show()
else:
self.signal_names = self.db.index
self.total_signals = len(self.signal_names)
- self.db.fillna(Constants.UNKNOWN, inplace = True)
- self.db[Constants.DB_WIKI_CLICKED] = False
+ self.db.fillna(constants.UNKNOWN, inplace = True)
+ self.db[constants.Signal.WIKI_CLICKED] = False
self.update_status_tip(self.total_signals)
- @staticmethod
- def connect_to(objects_to_connect, fun_to_connect, fun_args):
- for signal in objects_to_connect:
- signal.connect(partial(fun_to_connect, *fun_args))
-
@pyqtSlot()
def set_min_value_upper_limit(self, lower_combo_box,
lower_spin_box,
@@ -605,14 +601,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
if lower_spin_box.isEnabled():
unit_conversion = {'Hz' : ['kHz', 'MHz', 'GHz'],
'kHz': ['MHz', 'GHz'],
- 'MHz': ['GHz']
- }
+ 'MHz': ['GHz']}
lower_units = lower_combo_box.currentText()
upper_units = upper_combo_box.currentText()
lower_value = lower_spin_box.value()
upper_value = upper_spin_box.value()
- inf_limit = (lower_value * Constants.CONVERSION_FACTORS[lower_units]) \
- // Constants.CONVERSION_FACTORS[upper_units]
+ inf_limit = (lower_value * constants.CONVERSION_FACTORS[lower_units]) \
+ // constants.CONVERSION_FACTORS[upper_units]
counter = 0
while inf_limit > upper_spin_box.maximum():
counter += 1
@@ -685,8 +680,6 @@ class MyApp(QMainWindow, Ui_MainWindow):
@pyqtSlot()
def display_signals(self):
- # for i in range(self.result_list.count()):
- # self.result_list.item(i).setHidden(True)
text = self.search_bar.text()
available_signals = 0
for index, signal in enumerate(self.signal_names):
@@ -712,7 +705,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
@pyqtSlot()
def reset_fb_filters(self, ftype):
- if ftype != 'freq' and ftype != 'band':
+ if ftype != constants.Ftype.FREQ and ftype != constants.Ftype.BAND:
raise ValueError("Wrong ftype in function 'reset_fb_filters'")
apply_remove_btn = getattr(self, 'apply_remove_' + ftype + '_filter_btn')
include_undef_btn = getattr(self, 'include_undef_' + ftype + 's')
@@ -724,8 +717,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
upper_spinbox = getattr(self, 'upper_' + ftype + '_spinbox')
lower_confidence = getattr(self, 'lower_' + ftype + '_confidence')
upper_confidence = getattr(self, 'lower_' + ftype + '_confidence')
- default_val = 1 if ftype == 'freq' else 5000
- if ftype == 'freq':
+ default_val = 1 if ftype == constants.Ftype.FREQ else 5000
+ if ftype == constants.Ftype.FREQ:
for f in self.frequency_filters_btns:
if f.isChecked():
f.setChecked(False)
@@ -776,19 +769,19 @@ 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.is_undef_freq(self.db.loc[signal_name])
+ undef_freq = is_undef_freq(self.db.loc[signal_name])
if undef_freq:
if self.include_undef_freqs.isChecked():
return True
else:
return False
- signal_freqs = (int(self.db.at[signal_name, "inf_freq"]),
- int(self.db.at[signal_name, "sup_freq"]))
+ signal_freqs = (int(self.db.at[signal_name, constants.Signal.INF_FREQ]),
+ int(self.db.at[signal_name, constants.Signal.SUP_FREQ]))
band_filter_ok = False
any_checked = False
- for btn, band_limits in zip(self.frequency_filters_btns, Constants.BANDS):
+ for btn, band_limits in zip(self.frequency_filters_btns, constants.BANDS):
if btn.isChecked():
any_checked = True
if signal_freqs[0] < band_limits.upper and signal_freqs[1] >= band_limits.lower:
@@ -796,14 +789,14 @@ class MyApp(QMainWindow, Ui_MainWindow):
lower_limit_ok = True
upper_limit_ok = True
if self.activate_low_freq_filter_btn.isChecked():
- if not signal_freqs[1] >= self.filters_ok(self.lower_freq_spinbox,
- self.lower_freq_filter_unit,
- self.lower_freq_confidence, -1):
+ if not signal_freqs[1] >= filters_ok(self.lower_freq_spinbox,
+ self.lower_freq_filter_unit,
+ self.lower_freq_confidence, -1):
lower_limit_ok = False
if self.activate_up_freq_filter_btn.isChecked():
- if not signal_freqs[0] < self.filters_ok(self.upper_freq_spinbox,
- self.upper_freq_filter_unit,
- self.upper_freq_confidence):
+ if not signal_freqs[0] < filters_ok(self.upper_freq_spinbox,
+ self.upper_freq_filter_unit,
+ self.upper_freq_confidence):
upper_limit_ok = False
if any_checked:
return band_filter_ok and lower_limit_ok and upper_limit_ok
@@ -813,34 +806,34 @@ 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.is_undef_band(self.db.loc[signal_name])
+ undef_band = is_undef_band(self.db.loc[signal_name])
if undef_band:
if self.include_undef_bands.isChecked():
return True
else:
return False
- signal_bands = (int(self.db.at[signal_name, "inf_band"]),
- int(self.db.at[signal_name, "sup_band"]))
+ signal_bands = (int(self.db.at[signal_name, constants.Signal.INF_BAND]),
+ int(self.db.at[signal_name, constants.Signal.SUP_BAND]))
lower_limit_ok = True
upper_limit_ok = True
if self.activate_low_band_filter_btn.isChecked():
- if not signal_bands[1] >= self.filters_ok(self.lower_band_spinbox,
- self.lower_band_filter_unit,
- self.lower_band_confidence, -1):
+ if not signal_bands[1] >= filters_ok(self.lower_band_spinbox,
+ self.lower_band_filter_unit,
+ self.lower_band_confidence, -1):
lower_limit_ok = False
if self.activate_up_band_filter_btn.isChecked():
- if not signal_bands[0] < self.filters_ok(self.upper_band_spinbox,
- self.upper_band_filter_unit,
- self.upper_band_confidence):
+ if not signal_bands[0] < filters_ok(self.upper_band_spinbox,
+ self.upper_band_filter_unit,
+ self.upper_band_confidence):
upper_limit_ok = False
return lower_limit_ok and upper_limit_ok
def category_filters_ok(self, signal_name):
if not self.apply_remove_cat_filter_btn.isChecked():
return True
- cat_code = self.db.at[signal_name, 'category_code']
+ cat_code = self.db.at[signal_name, constants.Signal.CATEGORY_CODE]
cat_checked = 0
positive_cases = 0
for index, cat in enumerate(self.cat_filter_btns):
@@ -856,15 +849,15 @@ class MyApp(QMainWindow, Ui_MainWindow):
def mode_filters_ok(self, signal_name):
if not self.apply_remove_mode_filter_btn.isChecked():
return True
- signal_mode = self.db.at[signal_name, "mode"]
- if signal_mode == Constants.UNKNOWN:
+ signal_mode = self.db.at[signal_name, constants.Signal.MODE]
+ if signal_mode == constants.UNKNOWN:
if self.include_unknown_modes_btn.isChecked():
return True
else:
return False
selected_items = [item for item in self.mode_tree_widget.selectedItems()]
selected_items_text = [i.text(0) for i in selected_items]
- parents = [item for item in selected_items_text if item in Constants.MODES.keys()]
+ parents = [item for item in selected_items_text if item in constants.MODES.keys()]
children = [item for item in selected_items_text if item not in parents]
ok = []
for item in selected_items:
@@ -877,7 +870,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
def modulation_filters_ok(self, signal_name):
if not self.apply_remove_modulation_filter_btn.isChecked():
return True
- signal_modulation = self.db.at[signal_name, "modulation"]
+ signal_modulation = self.db.at[signal_name, constants.Signal.MODULATION]
for item in self.modulation_list.selectedItems():
if item.text() == signal_modulation:
return True
@@ -886,17 +879,12 @@ class MyApp(QMainWindow, Ui_MainWindow):
def location_filters_ok(self, signal_name):
if not self.apply_remove_location_filter_btn.isChecked():
return True
- signal_location = self.db.at[signal_name, "location"]
+ signal_location = self.db.at[signal_name, constants.Signal.LOCATION]
for item in self.locations_list.selectedItems():
if item.text() == signal_location:
return True
return False
- @staticmethod
- def filters_ok(spinbox, filter_unit, confidence, sign = 1):
- band_filter = spinbox.value() * Constants.CONVERSION_FACTORS[filter_unit.currentText()]
- return band_filter + sign * (confidence.value() * band_filter) // 100
-
@pyqtSlot(QListWidgetItem, QListWidgetItem)
def display_specs(self, item, previous_item):
self.display_spectrogram()
@@ -906,33 +894,31 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.name_lab.setAlignment(Qt.AlignHCenter)
current_signal = self.db.loc[self.current_signal_name]
self.url_button.setEnabled(True)
- if not current_signal.at["url_clicked"]:
+ if not current_signal.at[constants.Signal.WIKI_CLICKED]:
self.url_button.setStyleSheet(f"color: {self.url_button.colors.active};")
else:
self.url_button.setStyleSheet(f"color: {self.url_button.colors.clicked};")
- category_code = current_signal.at["category_code"]
- undef_freq = self.is_undef_freq(current_signal)
- undef_band = self.is_undef_band(current_signal)
+ category_code = current_signal.at[constants.Signal.CATEGORY_CODE]
+ undef_freq = is_undef_freq(current_signal)
+ undef_band = is_undef_band(current_signal)
if not undef_freq:
- self.freq_lab.setText(self.format_numbers(
- current_signal.at["inf_freq"],
- current_signal.at["sup_freq"])
+ self.freq_lab.setText(format_numbers(current_signal.at[constants.Signal.INF_FREQ],
+ current_signal.at[constants.Signal.SUP_FREQ])
)
else:
self.freq_lab.setText("Undefined")
if not undef_band:
- self.band_lab.setText(self.format_numbers(
- current_signal.at["inf_band"],
- current_signal.at["sup_band"])
+ self.band_lab.setText(format_numbers(current_signal.at[constants.Signal.INF_BAND],
+ current_signal.at[constants.Signal.SUP_BAND])
)
else:
self.band_lab.setText("Undefined")
- self.mode_lab.setText(current_signal.at["mode"])
- self.modul_lab.setText(current_signal.at["modulation"])
- self.loc_lab.setText(current_signal.at["location"])
- self.acf_lab.setText(current_signal.at["acf"])
- self.description_text.setText(current_signal.at["description"])
+ self.mode_lab.setText(current_signal.at[constants.Signal.MODE])
+ self.modul_lab.setText(current_signal.at[constants.Signal.MODULATION])
+ self.loc_lab.setText(current_signal.at[constants.Signal.LOCATION])
+ self.acf_lab.setText(current_signal.at[constants.Signal.ACF])
+ self.description_text.setText(current_signal.at[constants.Signal.DESCRIPTION])
for cat, cat_lab in zip(category_code, self.category_labels):
if cat == '0':
cat_lab.setStyleSheet(f"color: {self.inactive_color};")
@@ -947,64 +933,22 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.name_lab.setText("No Signal")
self.name_lab.setAlignment(Qt.AlignHCenter)
for lab in self.property_labels:
- lab.setText(Constants.UNKNOWN)
+ lab.setText(constants.UNKNOWN)
for lab in self.category_labels:
lab.setStyleSheet(f"color: {self.inactive_color};")
self.set_band_range()
self.audio_widget.set_audio_player()
-
- @staticmethod
- def is_undef_freq(current_signal):
- lower_freq = current_signal.at["inf_freq"]
- upper_freq = current_signal.at["sup_freq"]
- return lower_freq == Constants.UNKNOWN or upper_freq == Constants.UNKNOWN
-
- @staticmethod
- def is_undef_band(current_signal):
- lower_band = current_signal.at["inf_band"]
- upper_band = current_signal.at["sup_band"]
- return lower_band == Constants.UNKNOWN or upper_band == Constants.UNKNOWN
-
- @classmethod
- def format_numbers(cls, lower, upper):
- units = {1: 'Hz', 1000: 'kHz', 10**6: 'MHz', 10**9: 'GHz'}
- lower_factor = cls.change_unit(lower)
- upper_factor = cls.change_unit(upper)
- pre_lower = lower
- pre_upper = upper
- lower = int(lower) / lower_factor
- upper = int(upper) / upper_factor
- if lower.is_integer():
- lower = int(lower)
- if upper.is_integer():
- upper = int(upper)
- if pre_lower != pre_upper:
- return f"{lower:,} {units[lower_factor]} - {upper:,} {units[upper_factor]}"
- else:
- return f"{lower:,} {units[lower_factor]}"
-
- @staticmethod
- def change_unit(num):
- digits = len(num)
- if digits < 4:
- return 1
- elif digits < 7:
- return 1000
- elif digits < 10:
- return 10**6
- else:
- return 10**9
def display_spectrogram(self):
- default_pic = os.path.join(self.default_images_folder, Constants.NOT_SELECTED)
+ default_pic = os.path.join(self.default_images_folder, constants.NOT_SELECTED)
item = self.result_list.currentItem()
if item:
spectrogram_name = item.text()
- path_spectr = os.path.join(Constants.DATA_FOLDER,
- Constants.SPECTRA_FOLDER,
- spectrogram_name + Constants.SPECTRA_EXT)
+ path_spectr = os.path.join(constants.DATA_FOLDER,
+ constants.SPECTRA_FOLDER,
+ spectrogram_name + constants.SPECTRA_EXT)
if not QFileInfo(path_spectr).exists():
- path_spectr = os.path.join(self.default_images_folder, Constants.NOT_AVAILABLE)
+ path_spectr = os.path.join(self.default_images_folder, constants.NOT_AVAILABLE)
else:
path_spectr = default_pic
self.spectrogram.setPixmap(QPixmap(path_spectr))
@@ -1015,10 +959,10 @@ 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.is_undef_freq(current_signal):
- lower_freq = int(current_signal.at["inf_freq"])
- upper_freq = int(current_signal.at["sup_freq"])
- zipped = list(zip(Constants.BANDS, self.band_labels))
+ if current_signal is not None and not is_undef_freq(current_signal):
+ lower_freq = int(current_signal.at[constants.Signal.INF_FREQ])
+ upper_freq = int(current_signal.at[constants.Signal.SUP_FREQ])
+ zipped = list(zip(constants.BANDS, self.band_labels))
for i, w in enumerate(zipped):
band, band_label = w
if lower_freq >= band.lower and lower_freq < band.upper:
@@ -1048,8 +992,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
def go_to_web_page_signal(self):
if self.current_signal_name:
self.url_button.setStyleSheet(f"color: {self.url_button.colors.clicked}")
- webbrowser.open(self.db.at[self.current_signal_name, "url"])
- self.db.at[self.current_signal_name, "url_clicked"] = True
+ webbrowser.open(self.db.at[self.current_signal_name, constants.Signal.URL])
+ self.db.at[self.current_signal_name, constants.Signal.WIKI_CLICKED] = True
def closeEvent(self, event):
if self.download_window.isVisible():
diff --git a/main_window.ui b/main_window.ui
index 6b9a454..c1cc79b 100644
--- a/main_window.ui
+++ b/main_window.ui
@@ -174,7 +174,7 @@
QTabWidget::Rounded
- 0
+ 1
true
@@ -1771,7 +1771,7 @@ p, li { white-space: pre-wrap; }
- 5
+ 6
true
@@ -3873,6 +3873,282 @@ Inactive
ACF
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Include undefined ACFs
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 50
+ 20
+
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ AC interval
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 80
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+ 12
+
+
+
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 1
+
+
+ 100000000
+
+
+ 50
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ ms
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 49
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Confidence %
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 50
+ 16777215
+
+
+
+
+ 12
+
+
+
+
+
+
+ false
+
+
+ Qt::AlignCenter
+
+
+ QAbstractSpinBox::UpDownArrows
+
+
+
+
+
+ 100
+
+
+ 0
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 50
+ 20
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 12
+ 75
+ false
+ true
+ false
+
+
+
+
+
+
+ Selected range:
+
+Inactive
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Apply
+
+
+ true
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Reset
+
+
+ false
+
+
+
+
diff --git a/themes/1-system/system.th b/themes/1-system/system.qss
similarity index 100%
rename from themes/1-system/system.th
rename to themes/1-system/system.qss
diff --git a/themes/2-dark/dark.th b/themes/2-dark/dark.qss
similarity index 100%
rename from themes/2-dark/dark.th
rename to themes/2-dark/dark.qss
diff --git a/themes/3-material_design/colors.txt b/themes/3-material_design/colors.txt
new file mode 100644
index 0000000..cd95572
--- /dev/null
+++ b/themes/3-material_design/colors.txt
@@ -0,0 +1,2 @@
+active=#ddffdf
+inactive=#949494
\ No newline at end of file
diff --git a/themes/3-material_design/material_design.th b/themes/3-material_design/material_design.qss
similarity index 100%
rename from themes/3-material_design/material_design.th
rename to themes/3-material_design/material_design.qss
diff --git a/threads.py b/threads.py
index 43ff35b..9c8efc0 100644
--- a/threads.py
+++ b/threads.py
@@ -6,13 +6,15 @@ from shutil import rmtree
import urllib3
from zipfile import ZipFile
from PyQt5.QtCore import QThread
-from utilities import checksum_ok, Constants
+import constants
+from utilities import checksum_ok
+import constants
class ThreadStatus(Enum):
- OK = auto()
+ OK = auto()
NO_CONNECTION_ERR = auto()
- UNKNOWN_ERR = auto()
- BAD_DOWNLOAD_ERR = auto()
+ UNKNOWN_ERR = auto()
+ BAD_DOWNLOAD_ERR = auto()
class DownloadThread(QThread):
def __init__(self):
@@ -30,8 +32,8 @@ class DownloadThread(QThread):
def run(self):
try:
- db = urllib3.PoolManager().request('GET', Constants.DB_LOCATION)
- # db = urllib.request.urlopen(Constants.DB_LOCATION)
+ db = urllib3.PoolManager().request('GET', constants.Database.LINK_LOC)
+ # db = urllib.request.urlopen(constants.Database.LINK_LOC)
# raise urllib.error.URLError('Test')
except urllib3.exceptions.MaxRetryError: # No internet connection.
self.__status = ThreadStatus.NO_CONNECTION_ERR
@@ -40,11 +42,11 @@ class DownloadThread(QThread):
self.reason = db.reason
self.__status = ThreadStatus.BAD_DOWNLOAD_ERR
return
- if not checksum_ok(db.data, "folder"):
+ if not checksum_ok(db.data, constants.ChecksumWhat.FOLDER):
self.__status = ThreadStatus.BAD_DOWNLOAD_ERR
return
- if os.path.exists(Constants.DATA_FOLDER):
- rmtree(Constants.DATA_FOLDER)
+ if os.path.exists(constants.DATA_FOLDER):
+ rmtree(constants.DATA_FOLDER)
try:
# data_folder = db.read()
with ZipFile(BytesIO(db.data)) as zipped:
diff --git a/utilities.py b/utilities.py
index 3f58e4d..547e86d 100644
--- a/utilities.py
+++ b/utilities.py
@@ -1,159 +1,12 @@
-from collections import namedtuple
+from functools import partial
import hashlib
import re
from pandas import read_csv
from PyQt5.QtWidgets import QMessageBox
-# class _ReadOnlyProperty(object):
-# def __init__(self, value):
-# self.__value = value
-
-# def __get__(self, obj, objtype):
-# return self.__value
+import constants
-# def __set__(self, obj, value):
-# return NotImplementedError("Cannot change a constant.")
-
-# def __make_read_only(cls):
-# for k, v in cls.__dict__.items():
-# if not callable(getattr(cls, k)) and '__' not in k:
-# setattr(cls, k, _ReadOnlyProperty(v))
-# # def raise_err(self, attr, value):
-# # raise NotImplementedError("Cannot add an attribute.")
-# # setattr(cls, '__setattr__', raise_err)
-# return cls
-
-# @__make_read_only
-class Constants(object):
- class Messages(object):
- NO_DB_AVAIL = "No database available.\nGo to Updates->Update database."
- NO_DB = "No database"
- DB_LOCATION = "https://aresvalley.com/Storage/Artemis/Database/data.zip"
- REF_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log"
- DB_NAME = "db.csv"
- DB_NAMES = ("name",
- "inf_freq",
- "sup_freq",
- "mode",
- "inf_band",
- "sup_band",
- "location",
- "url",
- "description",
- "modulation",
- "category_code",
- "acf",)
- DB_WIKI_CLICKED = "url_clicked"
- DB_STRINGS = ('inf_freq',
- 'sup_freq',
- 'mode',
- 'inf_band',
- 'sup_band',
- 'category_code',)
- DATA_FOLDER = "Data"
- SPECTRA_FOLDER = "Spectra"
- SPECTRA_EXT = ".png"
- AUDIO_FOLDER = "Audio"
- THEMES_FOLDER = "themes"
- THEME_EXTENSION = ".th"
- ICONS_FOLDER = "icons"
- DEFAULT_THEME = "1-system"
- CURRENT_THEME = ".current_theme"
- THEME_COLORS = "colors.txt"
- NOT_AVAILABLE = "spectrumnotavailable.png"
- NOT_SELECTED = "nosignalselected.png"
- SEARCH_LABEL_IMG = "search_icon.png"
- VOLUME_LABEL_IMG = "volume.png"
- __Band = namedtuple("Band", ["lower", "upper"])
- __ELF = __Band(0, 30) # Formally it is (3, 30) Hz.
- __SLF = __Band(30, 300)
- __ULF = __Band(300, 3000)
- __VLF = __Band(3000, 30000)
- __LF = __Band(30 * 10**3, 300 * 10**3)
- __MF = __Band(300 * 10 ** 3, 3000 * 10**3)
- __HF = __Band(3 * 10**6, 30 * 10**6)
- __VHF = __Band(30 * 10**6, 300 * 10**6)
- __UHF = __Band(300 * 10**6, 3000 * 10**6)
- __SHF = __Band(3 * 10**9, 30 * 10**9)
- __EHF = __Band(30 * 10**9, 300 * 10**9)
- BANDS = (__ELF, __SLF, __ULF, __VLF, __LF, __MF, __HF, __VHF, __UHF, __SHF, __EHF)
- ACTIVE_COLOR = "#39eaff"
- INACTIVE_COLOR = "#9f9f9f"
- CONVERSION_FACTORS = {"Hz" : 1,
- "kHz": 1000,
- "MHz": 1000000,
- "GHz": 1000000000}
- MODES = {"FM": ("NFM", "WFM"),
- "AM": (),
- "CW": (),
- "SK": ("FSK", "PSK", "MSK"),
- "SB": ("LSB", "USB", "DSB"),
- "Chirp Spread Spectrum": (),
- "FHSS-TDM": (),
- "RAW": (),
- "SC-FDMA": (),}
- APPLY = "Apply"
- REMOVE = "Remove"
- UNKNOWN = "N/A"
- MODULATIONS = ("8VSB",
- "AFSK",
- "AM",
- "BFSK",
- "C4FM",
- "CDMA",
- "COFDM",
- "CW",
- "FFSK",
- "FM",
- "FMCW",
- "FMOP",
- "FSK",
- "GFSK",
- "GMSK",
- "IFK",
- "MFSK",
- "MSK",
- "OFDM",
- "OOK",
- "PAM",
- "PPM",
- "PSK",
- "QAM",
- "TDMA",)
- LOCATIONS = (UNKNOWN,
- "Australia",
- "Canada",
- "Central Europe",
- "China",
- "Cyprus",
- "Eastern Europe",
- "Europe",
- "Europe, japan and Asia",
- "Exmouth, Australia",
- "Finland",
- "France",
- "Germany",
- "Home Base Mobile , AL",
- "Hungary",
- "Iran",
- "Israel",
- "Japan",
- "LaMour, North Dakota",
- "Lualualei, Hawaii",
- "North America",
- "North Korea",
- "Poland",
- "Romania",
- "Ruda, Sweden",
- "UK",
- "United Kingdom",
- "United States",
- "Varberg, Sweden",
- "World Wide",
- "Worldwide",)
-
-# Constants = __Constants()
def reset_apply_remove_btn(button):
if button.isChecked():
@@ -165,23 +18,70 @@ def throwable_message(cls, title, text, connection = None):
msg.setWindowTitle(title)
msg.setText(text)
if connection:
- msg.setText(text).finished.connect(connection)
+ msg.finished.connect(connection)
return msg
def checksum_ok(data, what):
code = hashlib.sha256()
code.update(data)
- if what == "folder":
+ if what == constants.ChecksumWhat.FOLDER:
n = 0
- elif what == "db":
+ elif what == constants.ChecksumWhat.DB:
n = 1
else:
raise ValueError("Wrong entry name.")
try:
- reference = read_csv(Constants.REF_LOC, delimiter = '*').iat[-1, n]
+ reference = read_csv(constants.Database.LINK_REF,
+ delimiter = constants.Database.DELIMITER).iat[-1, n]
except HTTPError:
return False
return code.hexdigest() == reference
def is_valid_html_color(color):
return bool(re.match("#([a-zA-Z0-9]){6}", color))
+
+def connect_to(objects_to_connect, fun_to_connect, fun_args):
+ for signal in objects_to_connect:
+ signal.connect(partial(fun_to_connect, *fun_args))
+
+def filters_ok(spinbox, filter_unit, confidence, sign = 1):
+ band_filter = spinbox.value() * constants.CONVERSION_FACTORS[filter_unit.currentText()]
+ return band_filter + sign * (confidence.value() * band_filter) // 100
+
+def is_undef_freq(current_signal):
+ lower_freq = current_signal.at[constants.Signal.INF_FREQ]
+ upper_freq = current_signal.at[constants.Signal.SUP_FREQ]
+ return lower_freq == constants.UNKNOWN or upper_freq == constants.UNKNOWN
+
+def is_undef_band(current_signal):
+ lower_band = current_signal.at[constants.Signal.INF_BAND]
+ upper_band = current_signal.at[constants.Signal.SUP_BAND]
+ return lower_band == constants.UNKNOWN or upper_band == constants.UNKNOWN
+
+def change_unit(num):
+ digits = len(num)
+ if digits < 4:
+ return 1
+ elif digits < 7:
+ return 1000
+ elif digits < 10:
+ return 10**6
+ else:
+ return 10**9
+
+def format_numbers(lower, upper):
+ units = {1: 'Hz', 1000: 'kHz', 10**6: 'MHz', 10**9: 'GHz'}
+ lower_factor = change_unit(lower)
+ upper_factor = change_unit(upper)
+ pre_lower = lower
+ pre_upper = upper
+ lower = int(lower) / lower_factor
+ upper = int(upper) / upper_factor
+ if lower.is_integer():
+ lower = int(lower)
+ if upper.is_integer():
+ upper = int(upper)
+ if pre_lower != pre_upper:
+ return f"{lower:,} {units[lower_factor]} - {upper:,} {units[upper_factor]}"
+ else:
+ return f"{lower:,} {units[lower_factor]}"
\ No newline at end of file