diff --git a/.gitignore b/.gitignore index bcc7033..4a63335 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,6 @@ to_do.txt csv_info.txt pyinstaller_cmd.txt themes/.current_theme -*.bat +launch.bat *.sh .vscode/ diff --git a/artemis.py b/artemis.py index 5b48943..012d820 100644 --- a/artemis.py +++ b/artemis.py @@ -23,6 +23,7 @@ from PyQt5.QtCore import (QFileInfo, from audio_player import AudioPlayer from space_weather_data import SpaceWeatherData +from forecastdata import ForecastData from download_window import DownloadWindow from switchable_label import SwitchableLabelsIterable from constants import (Constants, @@ -31,8 +32,9 @@ from constants import (Constants, Database, ChecksumWhat, Messages, - Signal,) -from themes import Theme + Signal, + Months) +from themesmanager import ThemeManager from utilities import (checksum_ok, uncheck_and_emit, pop_up, @@ -80,6 +82,7 @@ class Artemis(QMainWindow, Ui_MainWindow): self.current_signal_name = '' self.signal_names = [] self.total_signals = 0 + self.switchable_r_labels = SwitchableLabelsIterable( self.r0_now_lbl, self.r1_now_lbl, @@ -138,23 +141,23 @@ class Artemis(QMainWindow, Ui_MainWindow): self.a_quiet_lbl ) - self.forecast_labels = ( - self.forecast_lbl_0, - self.forecast_lbl_1, - self.forecast_lbl_2, - self.forecast_lbl_3, - self.forecast_lbl_4, - self.forecast_lbl_5, - self.forecast_lbl_6, - self.forecast_lbl_7, - self.forecast_lbl_8 + self.space_weather_labels = ( + self.space_weather_lbl_0, + self.space_weather_lbl_1, + self.space_weather_lbl_2, + self.space_weather_lbl_3, + self.space_weather_lbl_4, + self.space_weather_lbl_5, + self.space_weather_lbl_6, + self.space_weather_lbl_7, + self.space_weather_lbl_8 ) - for lab in self.forecast_labels: + for lab in self.space_weather_labels: lab.set_default_stylesheet() - self.forecast_label_container.labels = self.forecast_labels - self.theme = Theme(self) + self.space_weather_label_container.labels = self.space_weather_labels + self.theme_manager = ThemeManager(self) # Manage frequency filters. self.frequency_filters_btns = ( @@ -501,18 +504,52 @@ class Artemis(QMainWindow, Ui_MainWindow): # Space weather self.info_now_btn.clicked.connect( - lambda : webbrowser.open(Constants.FORECAST_INFO) + lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO) ) self.update_now_bar.clicked.connect(self.start_update_space_weather) self.update_now_bar.set_idle() self.space_weather_data = SpaceWeatherData() self.space_weather_data.update_complete.connect(self.update_space_weather) + # Forecast + self.forecast_info_btn.clicked.connect( + lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO) + ) + self.update_forecast_bar.clicked.connect(self.start_update_forecast) + self.update_forecast_bar.set_idle() + self.forecast_data = ForecastData() + self.today_forecast_labels = [] + self.today_p1_forecast_labels = [] + self.today_p2_forecast_labels = [] + self.all_forecast_labels = [] + flags = ['', 'p1_', 'p2_'] + for flag in flags: + title_lbl = getattr(self, "today_" + flag + "lbl") + title_lbl.setText("-") + for index in range(20): + label = getattr( + self, + "forecast_today_" + flag + str(index) + "_lbl" + ) + label.setText(Constants.UNKNOWN) + self.all_forecast_labels.append(label) + if flag == flags[0]: + self.today_forecast_labels.append(label) + if flag == flags[1]: + self.today_p1_forecast_labels.append(label) + if flag == flags[2]: + self.today_p2_forecast_labels.append(label) + + # Final operations. - self.theme.initialize() + self.theme_manager.start() self.load_db() self.display_signals() + @pyqtSlot() + def start_update_forecast(self): + pass + @pyqtSlot() def start_update_space_weather(self): if not self.space_weather_data.is_updating: @@ -659,7 +696,7 @@ class Artemis(QMainWindow, Ui_MainWindow): val = int([x[4] for x in self.space_weather_data.sgas if "SSN" in x][0]) self.sn_lbl.setText(f"{val:d}") - for label, pixmap in zip(self.forecast_labels, self.space_weather_data.images): + for label, pixmap in zip(self.space_weather_labels, self.space_weather_data.images): label.pixmap = pixmap label.make_transparent() label.apply_pixmap() diff --git a/artemis.ui b/artemis.ui index 86163b4..5524ce9 100644 --- a/artemis.ui +++ b/artemis.ui @@ -178,7 +178,7 @@ QTabWidget::Rounded - 0 + 3 true @@ -4681,7 +4681,10 @@ www.qrg.globaltuners.com - + + + 1 + Now @@ -4751,6 +4754,9 @@ www.qrg.globaltuners.com Radio Blackout + + 25 + @@ -4935,6 +4941,9 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto Solar Radiation Storm + + 25 + @@ -6076,6 +6085,9 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto Peak Flux Class + + 25 + @@ -6371,7 +6383,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6380,7 +6392,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6415,7 +6427,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6444,7 +6456,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6473,7 +6485,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6502,7 +6514,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6531,7 +6543,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6560,7 +6572,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6589,7 +6601,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6618,7 +6630,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - + 0 @@ -6844,8 +6856,1063 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,sto - Tab 2 + Forecast + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 21 - 00 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 18 - 21 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 15 - 18 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 12 - 15 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 03 - 06 + + + 25 + + + + + + + + 11 + 75 + true + + + + Kp Index Forecast + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 09 - 12 + + + 25 + + + + + + + 00 - 03 + + + 25 + + + + + + + 06 - 09 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Major + + + 50 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 10 + + + + High Lat. + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Major + + + 50 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Minor + + + 50 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Active + + + 50 + + + + + + + Active + + + 50 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Minor + + + 50 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 10 + + + + Mid Lat. + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 11 + 75 + true + + + + Geomagnetic Act. + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + R1 - R2 + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 11 + 75 + true + + + + Radio Blackout Act. + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Info + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + today+1 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + today+2 + + + Qt::AlignCenter + + + + + + + + 11 + 75 + true + + + + Solar Radiation Storm + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + S1 or Greater + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 1 + + + 0 + + + false + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + today + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 11 + 75 + true + + + + Event Probabilities + + + + + + + Class M flare + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + Class X flare + + + 25 + + + + + + + Proton flare + + + 25 + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + > R3 + + + 25 + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + @@ -7230,6 +8297,16 @@ QSlider::handle:horizontal { QLabel
fixed_aspect_ratio_label.h
+ + SingleColorSwitchableLabel + QLabel +
switchable_label.h
+
+ + MultiColorSwitchableLabel + QLabel +
switchable_label.h
+
diff --git a/clickable_progress_bar.py b/clickable_progress_bar.py index 815a8e3..2ab387d 100644 --- a/clickable_progress_bar.py +++ b/clickable_progress_bar.py @@ -11,18 +11,20 @@ class ClickableProgressBar(QProgressBar): self.__text = '' super().__init__(parent) - def __set_text(self, text): - self.__text = text + # def __set_text(self, text): + # self.__text = text def text(self): return self.__text def set_idle(self): - self.__set_text(Constants.CLICK_TO_UPDATE_STR) + # self.__set_text(Constants.CLICK_TO_UPDATE_STR) + self.__text = Constants.CLICK_TO_UPDATE_STR self.setMaximum(self.minimum() + 1) def set_updating(self): - self.__set_text(Constants.UPDATING_STR) + # self.__set_text(Constants.UPDATING_STR) + self.__text = Constants.UPDATING_STR self.setMaximum(self.minimum()) def mousePressEvent(self, event): diff --git a/constants.py b/constants.py index c465342..0870dd3 100644 --- a/constants.py +++ b/constants.py @@ -2,7 +2,7 @@ from collections import namedtuple from enum import Enum, auto -class Ftype(object): +class Ftype: FREQ = "freq" BAND = "band" @@ -17,7 +17,7 @@ class ChecksumWhat(Enum): DB = auto() -class Messages(object): +class Messages: DB_UP_TO_DATE = "Already up to date" DB_UP_TO_DATE_MSG = "No newer version to download." DB_NEW_VER = "New version available" @@ -32,7 +32,7 @@ class Messages(object): BAD_DOWNLOAD_MSG = "Something went wrong with the downaload.\nCheck your internet connection and try again." -class Signal(object): +class Signal: NAME = "name" INF_FREQ = "inf_freq" SUP_FREQ = "sup_freq" @@ -48,7 +48,7 @@ class Signal(object): WIKI_CLICKED = "url_clicked" -class Database(object): +class Database: LINK_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip" LINK_REF = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log" NAME = "db.csv" @@ -73,128 +73,155 @@ class Database(object): Signal.CATEGORY_CODE,) -class Constants(object): - CLICK_TO_UPDATE_STR = "Click to update" - SIGIDWIKI = "https://www.sigidwiki.com/wiki/Signal_Identification_Guide" - ADD_SIGNAL_LINK = "https://www.sigidwiki.com/index.php/Special:FormEdit/Signal/?preload=Signal_Identification_Wiki:Signal_form_preload_text" - FORUM_LINK = "https://aresvalley.com/community/" - ARESVALLEY_LINK = "https://aresvalley.com/" - RTL_SDL_LINK = "https://www.rtl-sdr.com/" - UPDATING_STR = "Updating..." - ACF_DOCS = "https://aresvalley.com/documentation/" - FORECAST_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt" - FORECAST_PROT_EL = "https://services.swpc.noaa.gov/text/goes-particle-flux-primary.txt" - FORECAST_AK_INDEX = "https://services.swpc.noaa.gov/text/wwv.txt" - FORECAST_SGAS = "https://services.swpc.noaa.gov/text/sgas.txt" - FORECAST_GEO_STORM = "https://services.swpc.noaa.gov/text/3-day-forecast.txt" - FORECAST_INFO = "https://www.swpc.noaa.gov/sites/default/files/images/NOAAscales.pdf" - FORECAST_IMGS = ["http://www.mmmonvhf.de/eme/eme.png", - "http://www.mmmonvhf.de/ms/ms.png", - "http://www.mmmonvhf.de/es/es.png", - "http://www.mmmonvhf.de/solar/solar.png", - "http://amunters.home.xs4all.nl/eskip50status.gif", - "http://amunters.home.xs4all.nl/eskip70status.gif", - "http://amunters.home.xs4all.nl/eskipstatus.gif", - "https://amunters.home.xs4all.nl/eskipstatusNA.gif", - "https://amunters.home.xs4all.nl/aurorastatus.gif"] - 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" - LABEL_ON_COLOR = "on" - LABEL_OFF_COLOR = "off" - TEXT_COLOR = "text" - 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) - MAX_DIGITS = 3 - RANGE_SEPARATOR = ' ÷ ' - GFD_SITE = "http://qrg.globaltuners.com/" - 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",) +class ForecastColors: + WARNING_COLOR = "#F95423" + KP9_COLOR = "#FFCCCB" + KP8_COLOR = "#FFCC9A" + KP7_COLOR = "#FFFECD" + KP6_COLOR = "#CDFFCC" + KP5_COLOR = "#BEE3FE" + + +class Months: + MONTS = [ + "0", + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ] + + +class Constants: + CLICK_TO_UPDATE_STR = "Click to update" + SIGIDWIKI = "https://www.sigidwiki.com/wiki/Signal_Identification_Guide" + ADD_SIGNAL_LINK = "https://www.sigidwiki.com/index.php/Special:FormEdit/Signal/?preload=Signal_Identification_Wiki:Signal_form_preload_text" + FORUM_LINK = "https://aresvalley.com/community/" + ARESVALLEY_LINK = "https://aresvalley.com/" + RTL_SDL_LINK = "https://www.rtl-sdr.com/" + UPDATING_STR = "Updating..." + ACF_DOCS = "https://aresvalley.com/documentation/" + SPACE_WEATHER_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt" + SPACE_WEATHER_PROT_EL = "https://services.swpc.noaa.gov/text/goes-particle-flux-primary.txt" + SPACE_WEATHER_AK_INDEX = "https://services.swpc.noaa.gov/text/wwv.txt" + SPACE_WEATHER_SGAS = "https://services.swpc.noaa.gov/text/sgas.txt" + SPACE_WEATHER_GEO_STORM = "https://services.swpc.noaa.gov/text/3-day-forecast.txt" + SPACE_WEATHER_INFO = "https://www.swpc.noaa.gov/sites/default/files/images/NOAAscales.pdf" + SPACE_WEATHER_IMGS = ["http://www.mmmonvhf.de/eme/eme.png", + "http://www.mmmonvhf.de/ms/ms.png", + "http://www.mmmonvhf.de/es/es.png", + "http://www.mmmonvhf.de/solar/solar.png", + "http://amunters.home.xs4all.nl/eskip50status.gif", + "http://amunters.home.xs4all.nl/eskip70status.gif", + "http://amunters.home.xs4all.nl/eskipstatus.gif", + "https://amunters.home.xs4all.nl/eskipstatusNA.gif", + "https://amunters.home.xs4all.nl/aurorastatus.gif"] + 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" + LABEL_ON_COLOR = "on" + LABEL_OFF_COLOR = "off" + TEXT_COLOR = "text" + 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) + MAX_DIGITS = 3 + RANGE_SEPARATOR = ' ÷ ' + GFD_SITE = "http://qrg.globaltuners.com/" + 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",) diff --git a/fixed_aspect_ratio_label.py b/fixed_aspect_ratio_label.py index 3b61f9b..8f13adc 100644 --- a/fixed_aspect_ratio_label.py +++ b/fixed_aspect_ratio_label.py @@ -8,14 +8,16 @@ class FixedAspectRatioLabel(QLabel): self.pixmap = None def set_default_stylesheet(self): - self.setStyleSheet(""" - color: #ffffff; - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #304352 ,stop: 1 #d7d2cc); - """) + self.setStyleSheet("border: 3px;") + # self.setStyleSheet(""" + # color: #ffffff; + # background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #304352 ,stop: 1 #d7d2cc); + # """) def make_transparent(self): self.setText('') - self.setStyleSheet("background-color: transparent;") + self.setStyleSheet("border: 0px;") + # self.setStyleSheet("background-color: transparent;") def apply_pixmap(self): if self.pixmap: diff --git a/forecastdata.py b/forecastdata.py new file mode 100644 index 0000000..5c1a0ed --- /dev/null +++ b/forecastdata.py @@ -0,0 +1,3 @@ +class ForecastData: + def __init__(self): + pass diff --git a/space_weather_data.py b/space_weather_data.py index 4f3b764..7928ec0 100644 --- a/space_weather_data.py +++ b/space_weather_data.py @@ -1,6 +1,6 @@ from PyQt5.QtGui import QPixmap from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject -from threads import UpadteSpaceWeatherThread, ThreadStatus +from threads import UpdateSpaceWeatherThread, ThreadStatus class SpaceWeatherData(QObject): @@ -24,7 +24,7 @@ class SpaceWeatherData(QObject): QPixmap(), QPixmap() ] - self.__update_thread = UpadteSpaceWeatherThread(self) + self.__update_thread = UpdateSpaceWeatherThread(self) self.__update_thread.finished.connect(self.__parse_and_emit_signal) @property diff --git a/switchable_label.py b/switchable_label.py index 6e6e074..f853295 100644 --- a/switchable_label.py +++ b/switchable_label.py @@ -1,20 +1,32 @@ from PyQt5.QtWidgets import QLabel +from constants import ForecastColors -class SwitchableLabel(QLabel): +class _BaseSwitchableLabel(QLabel): + def __init__(self, parent=None): + super().__init__(parent) + self.is_on = False + + def switch_on(self): + self.is_on = True + + def switch_off(self): + self.is_on = False + + +class SwitchableLabel(_BaseSwitchableLabel): def __init__(self, parent=None): super().__init__(parent) self.switch_on_colors = () self.switch_off_colors = () self.text_color = '' - self.is_on = False def switch_on(self): - self.is_on = True + super().switch_on() self.__apply_colors(*self.switch_on_colors) def switch_off(self): - self.is_on = False + super().switch_off() self.__apply_colors(*self.switch_off_colors) def __apply_colors(self, start, end): @@ -26,7 +38,47 @@ class SwitchableLabel(QLabel): ) -class SwitchableLabelsIterable(object): +class SingleColorSwitchableLabel(_BaseSwitchableLabel): + def __init__(self, parent=None): + super().__init__(parent) + self.active_color = ForecastColors.WARNING_COLOR + + def switch_on(self): + super().switch_on() + self.setStyleSheet(f"background-color: {self.active_color};") + + def switch_off(self): + super().switch_off() + self.setStyleSheet("background-color: transparent;") + + +class MultiColorSwitchableLabel(_BaseSwitchableLabel): + + LEVEL_COLORS = { + 9: ForecastColors.KP9_COLOR, + 8: ForecastColors.KP8_COLOR, + 7: ForecastColors.KP7_COLOR, + 6: ForecastColors.KP6_COLOR, + 5: ForecastColors.KP5_COLOR + } + + def __init__(self, parent=None): + super().__init__(parent) + self.level = 0 + + def switch_on(self): + if 5 <= self.level <= 9: + super().switch_on() + self.setStyleSheet(f""" + background-color: {self.LEVEL_COLORS[self.level]}; + """) + + def switch_off(self): + super().switch_off() + self.setStyleSheet("background-color: transparent;") + + +class SwitchableLabelsIterable: def __init__(self, *labels): self.labels = labels diff --git a/themes.py b/themesmanager.py similarity index 95% rename from themes.py rename to themesmanager.py index 38798dc..70a979d 100644 --- a/themes.py +++ b/themesmanager.py @@ -10,7 +10,7 @@ from switchable_label import SwitchableLabelsIterable from utilities import pop_up -class ThemeConstants(object): +class ThemeConstants: FOLDER = "themes" EXTENSION = ".qss" ICONS_FOLDER = "icons" @@ -26,7 +26,7 @@ class ThemeConstants(object): THEME_NOT_FOUND = "Theme not found" MISSING_THEME = "Missing theme in '" + FOLDER + "' folder." -class Theme(object): +class ThemeManager: def __init__(self, parent): self.__parent = parent self.__parent.active_color = ThemeConstants.DEFAULT_ACTIVE_COLOR @@ -41,7 +41,7 @@ class Theme(object): ThemeConstants.ICONS_FOLDER ) - self.__forecast_labels = SwitchableLabelsIterable( + self.__space_weather_labels = SwitchableLabelsIterable( *list( chain( self.__parent.switchable_r_labels, @@ -55,11 +55,11 @@ class Theme(object): ) ) - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_on_colors", ThemeConstants.DEFAULT_ON_COLORS ) - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_off_colors", ThemeConstants.DEFAULT_OFF_COLORS ) @@ -106,7 +106,7 @@ class Theme(object): self.__parent.active_color, self.__parent.inactive_color ) - self.__forecast_labels.refresh() + self.__space_weather_labels.refresh() def __pretty_name(self, bad_name): return ' '.join( @@ -257,20 +257,20 @@ class Theme(object): inactive_color_ok = True if quality.lower() == Constants.TEXT_COLOR: text_color_ok = True - self.__forecast_labels.set( + self.__space_weather_labels.set( "text_color", color ) if color_len == 2: if quality.lower() == Constants.LABEL_ON_COLOR: switch_on_color_ok = True - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_on_colors", color ) if quality.lower() == Constants.LABEL_OFF_COLOR: switch_off_color_ok = True - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_off_colors", color ) @@ -280,17 +280,17 @@ class Theme(object): self.__parent.inactive_color = ThemeConstants.DEFAULT_INACTIVE_COLOR if not (switch_on_color_ok and switch_off_color_ok): - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_on_colors", ThemeConstants.DEFAULT_ON_COLORS ) - self.__forecast_labels.set( + self.__space_weather_labels.set( "switch_off_colors", ThemeConstants.DEFAULT_OFF_COLORS ) if not text_color_ok: - self.__forecast_labels.set( + self.__space_weather_labels.set( "text_color", ThemeConstants.DEFAULT_TEXT_COLOR ) @@ -305,7 +305,7 @@ class Theme(object): except Exception: pass - def initialize(self): + def start(self): current_theme_file = os.path.join( ThemeConstants.FOLDER, ThemeConstants.CURRENT diff --git a/threads.py b/threads.py index f85e830..13d49a0 100644 --- a/threads.py +++ b/threads.py @@ -66,7 +66,7 @@ class DownloadThread(_BaseDownloadThread): self.status = ThreadStatus.OK -class UpadteSpaceWeatherThread(_BaseDownloadThread): +class UpdateSpaceWeatherThread(_BaseDownloadThread): __properties = ("xray", "prot_el", "ak_index", "sgas", "geo_storm") @@ -79,12 +79,12 @@ class UpadteSpaceWeatherThread(_BaseDownloadThread): return await resp.read() async def __download_property(self, session, property_name): - link = getattr(Constants, "FORECAST_" + property_name.upper()) + link = getattr(Constants, "SPACE_WEATHER_" + property_name.upper()) data = await self.__download_resource(session, link) setattr(self.__space_weather_data, property_name, str(data, 'utf-8')) async def __download_image(self, session, n): - im = await self.__download_resource(session, Constants.FORECAST_IMGS[n]) + im = await self.__download_resource(session, Constants.SPACE_WEATHER_IMGS[n]) self.__space_weather_data.images[n].loadFromData(im) async def __download_resources(self, *links): @@ -96,7 +96,7 @@ class UpadteSpaceWeatherThread(_BaseDownloadThread): asyncio.create_task(self.__download_property(session, p)) ) - tot_images = range(len(Constants.FORECAST_IMGS)) + tot_images = range(len(Constants.SPACE_WEATHER_IMGS)) t1 = [] for im_number in tot_images: t1.append(