Comments added
This commit is contained in:
parent
c31db1b65f
commit
ae24570c19
4 changed files with 62 additions and 4 deletions
7
api.py
7
api.py
|
@ -1,5 +1,6 @@
|
||||||
import requests, json
|
import requests, json
|
||||||
|
|
||||||
|
# API request handler and data access
|
||||||
class WorldState():
|
class WorldState():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.client = requests.Session()
|
self.client = requests.Session()
|
||||||
|
@ -12,6 +13,12 @@ class WorldState():
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# aribtrary mapping, some skipped, some not-standard anyway
|
||||||
|
# better way is probably to do setattr in a loop, but then need to
|
||||||
|
# change code and handle baro.
|
||||||
|
# not willing to change it on the off chance much of this is replaced if
|
||||||
|
# content API becomes useful and names change again
|
||||||
|
|
||||||
self.fissures = self.ws.get('fissures')
|
self.fissures = self.ws.get('fissures')
|
||||||
self.invasions = self.ws.get('invasions')
|
self.invasions = self.ws.get('invasions')
|
||||||
self.sorties = self.ws.get('sortie')
|
self.sorties = self.ws.get('sortie')
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
# custom widgets, code is largely ripped from placeholders from
|
||||||
|
# a generated gui_base.py file and additional bits slapped on
|
||||||
|
# and some minor changes in create_gui, mostly in naming of
|
||||||
|
# widgets including indexing and subobjects as well with self.i
|
||||||
|
|
||||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
# util for clocks
|
||||||
utcoffset = time.time() - time.mktime(time.gmtime())
|
utcoffset = time.time() - time.mktime(time.gmtime())
|
||||||
|
|
||||||
class Fissure(QtWidgets.QWidget):
|
class Fissure(QtWidgets.QWidget):
|
||||||
|
@ -53,6 +59,7 @@ class Fissure(QtWidgets.QWidget):
|
||||||
self.gridLayout_3.addWidget(self.FissureType, 1, 1, 1, 1)
|
self.gridLayout_3.addWidget(self.FissureType, 1, 1, 1, 1)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# attempt an update, will fail during initial pass before worldstate init so try-except
|
||||||
try:
|
try:
|
||||||
self.FissureTier.setText(f"{self.fissure_info['tier']} - T{self.fissure_info['tierNum']}")
|
self.FissureTier.setText(f"{self.fissure_info['tier']} - T{self.fissure_info['tierNum']}")
|
||||||
self.update_timer()
|
self.update_timer()
|
||||||
|
@ -62,6 +69,7 @@ class Fissure(QtWidgets.QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_timer(self):
|
def update_timer(self):
|
||||||
|
# update timer, same as global timers in main
|
||||||
eta = round(time.mktime(time.strptime(self.fissure_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
eta = round(time.mktime(time.strptime(self.fissure_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
||||||
if eta >= 0:
|
if eta >= 0:
|
||||||
self.FissureTimer.setText(f"{str(eta // 3600) + 'h' if eta // 3600 > 0 else ''} {(eta // 60) % 60}m {eta % 60}s")
|
self.FissureTimer.setText(f"{str(eta // 3600) + 'h' if eta // 3600 > 0 else ''} {(eta // 60) % 60}m {eta % 60}s")
|
||||||
|
@ -113,6 +121,7 @@ class Invasion(QtWidgets.QWidget):
|
||||||
self.gridLayout_4.addWidget(self.Reward1, 0, 0, 1, 1)
|
self.gridLayout_4.addWidget(self.Reward1, 0, 0, 1, 1)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# same as Fissures, progress bars are colored according to factions involved, update css
|
||||||
try:
|
try:
|
||||||
faction_colors = {'Grineer': 'red', 'Corpus': 'blue', 'Infested': 'green'}
|
faction_colors = {'Grineer': 'red', 'Corpus': 'blue', 'Infested': 'green'}
|
||||||
self.Reward1.setText(f"{self.invasion_info['attackerReward']['itemString']}")
|
self.Reward1.setText(f"{self.invasion_info['attackerReward']['itemString']}")
|
||||||
|
@ -123,6 +132,7 @@ class Invasion(QtWidgets.QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_progress(self):
|
def update_progress(self):
|
||||||
|
# invasion progerss tracked with progressbar, set here as psuedo-timer
|
||||||
self.InvasionProgress.setProperty('value', self.invasion_info['completion'])
|
self.InvasionProgress.setProperty('value', self.invasion_info['completion'])
|
||||||
|
|
||||||
class Alert(QtWidgets.QWidget):
|
class Alert(QtWidgets.QWidget):
|
||||||
|
@ -162,6 +172,7 @@ class Alert(QtWidgets.QWidget):
|
||||||
self.horizontalLayout_6.addWidget(self.AlertTimer)
|
self.horizontalLayout_6.addWidget(self.AlertTimer)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# same as fissure
|
||||||
try:
|
try:
|
||||||
self.AlertReward.setText(self.alert_info['mission']['reward']['itemString'])
|
self.AlertReward.setText(self.alert_info['mission']['reward']['itemString'])
|
||||||
self.update_timer()
|
self.update_timer()
|
||||||
|
@ -169,6 +180,7 @@ class Alert(QtWidgets.QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_timer(self):
|
def update_timer(self):
|
||||||
|
# same as fissure
|
||||||
eta = round(time.mktime(time.strptime(self.alert_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
eta = round(time.mktime(time.strptime(self.alert_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
||||||
if eta > 0:
|
if eta > 0:
|
||||||
self.AlertTimer.setText(f'{str(eta // 86400) + "d " if eta // 86400 > 0 else ""}{str((eta // 3600) % 24) + "h" if eta // 3600 > 0 else ""} {(eta // 60) % 60}m {eta % 60}s')
|
self.AlertTimer.setText(f'{str(eta // 86400) + "d " if eta // 86400 > 0 else ""}{str((eta // 3600) % 24) + "h" if eta // 3600 > 0 else ""} {(eta // 60) % 60}m {eta % 60}s')
|
||||||
|
@ -198,6 +210,7 @@ class BaroItem(QtWidgets.QWidget):
|
||||||
self.gridLayout_7.addWidget(self.ItemName, 0, 0, 1, 1)
|
self.gridLayout_7.addWidget(self.ItemName, 0, 0, 1, 1)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# same as fissure, except no dynamic timer needing updates
|
||||||
try:
|
try:
|
||||||
self.ItemName.setText(self.item_info['item'])
|
self.ItemName.setText(self.item_info['item'])
|
||||||
except:
|
except:
|
||||||
|
@ -239,6 +252,7 @@ class Event(QtWidgets.QWidget):
|
||||||
self.horizontalLayout_11.addWidget(self.EventTimer)
|
self.horizontalLayout_11.addWidget(self.EventTimer)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# same as fissure
|
||||||
try:
|
try:
|
||||||
self.EventName.setText(self.event_info['description'])
|
self.EventName.setText(self.event_info['description'])
|
||||||
self.update_timer()
|
self.update_timer()
|
||||||
|
@ -246,6 +260,7 @@ class Event(QtWidgets.QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_timer(self):
|
def update_timer(self):
|
||||||
|
# same as fissure
|
||||||
eta = round(time.mktime(time.strptime(self.event_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
eta = round(time.mktime(time.strptime(self.event_info['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
||||||
if eta > 0:
|
if eta > 0:
|
||||||
self.EventTimer.setText(f'{str(eta // 86400) + "d " if eta // 86400 > 0 else ""}{(eta // 3600) % 24}h')
|
self.EventTimer.setText(f'{str(eta // 86400) + "d " if eta // 86400 > 0 else ""}{(eta // 3600) % 24}h')
|
||||||
|
@ -295,6 +310,7 @@ class NewsBlurb(QtWidgets.QWidget):
|
||||||
self.horizontalLayout_12.addWidget(self.NewsBlurbRelTimer)
|
self.horizontalLayout_12.addWidget(self.NewsBlurbRelTimer)
|
||||||
|
|
||||||
def update_gui(self):
|
def update_gui(self):
|
||||||
|
# same as fissure, except populate hyperlink instead of setting labels.
|
||||||
try:
|
try:
|
||||||
self.NewsBlurbHyperLink.setText(f'<a href=\"{self.news_info["link"]}\">{self.news_info["message"]}</a>')
|
self.NewsBlurbHyperLink.setText(f'<a href=\"{self.news_info["link"]}\">{self.news_info["message"]}</a>')
|
||||||
self.update_timer()
|
self.update_timer()
|
||||||
|
@ -302,6 +318,16 @@ class NewsBlurb(QtWidgets.QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_timer(self):
|
def update_timer(self):
|
||||||
|
# timers are wonkier than fissure since there can be both start and end dates
|
||||||
|
# chosen strat:
|
||||||
|
# if event starts in the future:
|
||||||
|
# starts in
|
||||||
|
# elif event has started and end date not reached:
|
||||||
|
# ends in
|
||||||
|
# else if no end date and start date past if it even existed:
|
||||||
|
# just display time difference to date, as in 1d ago
|
||||||
|
#
|
||||||
|
# if time delta is > 1d, only display day, else h and min
|
||||||
prefix = ''
|
prefix = ''
|
||||||
if self.news_info.get('startDate'):
|
if self.news_info.get('startDate'):
|
||||||
eta = round(time.mktime(time.strptime(self.news_info.get('startDate'), '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
eta = round(time.mktime(time.strptime(self.news_info.get('startDate'), '%Y-%m-%dT%H:%M:%S.%fZ')) - time.time() + utcoffset)
|
||||||
|
|
6
gui.py
6
gui.py
|
@ -1,14 +1,18 @@
|
||||||
|
import gui_base
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import gui_base
|
|
||||||
|
|
||||||
|
# GUI constructor from generated gui_base file
|
||||||
|
# doesn't really need to exist but its here now
|
||||||
class GUI(QtWidgets.QMainWindow, gui_base.Ui_MainWindow):
|
class GUI(QtWidgets.QMainWindow, gui_base.Ui_MainWindow):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
|
# test code
|
||||||
def main():
|
def main():
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
gui = ExampleApp()
|
gui = ExampleApp()
|
||||||
|
|
25
main.py
25
main.py
|
@ -1,3 +1,5 @@
|
||||||
|
# central controller, main loop
|
||||||
|
|
||||||
from gui import GUI
|
from gui import GUI
|
||||||
from api import WorldState
|
from api import WorldState
|
||||||
from extra_widgets import *
|
from extra_widgets import *
|
||||||
|
@ -11,25 +13,32 @@ import sys
|
||||||
class App(GUI):
|
class App(GUI):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# fetch world state info from API
|
||||||
self.ws = WorldState()
|
self.ws = WorldState()
|
||||||
|
# if bad fetch, error for retry until quit or fetched
|
||||||
while self.ws.ws == {}:
|
while self.ws.ws == {}:
|
||||||
self.network_error()
|
self.network_error()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# remove placeholder templates for given widgets, replaced with actual data later in redraw
|
||||||
[widget.setParent(None) for widget in [self.Fissure, self.Invasion, self.Alert, self.BaroItem, self.Event, self.NewsBlurb]]
|
[widget.setParent(None) for widget in [self.Fissure, self.Invasion, self.Alert, self.BaroItem, self.Event, self.NewsBlurb]]
|
||||||
|
|
||||||
|
# update interval for clocks
|
||||||
self.timers_timer = QTimer(self)
|
self.timers_timer = QTimer(self)
|
||||||
self.timers_timer.timeout.connect(self.update_timers)
|
self.timers_timer.timeout.connect(self.update_timers)
|
||||||
self.timers_timer.start(1000)
|
self.timers_timer.start(1000)
|
||||||
|
|
||||||
|
# update interval for data refresh
|
||||||
self.ws_update_timer = QTimer(self)
|
self.ws_update_timer = QTimer(self)
|
||||||
self.ws_update_timer.timeout.connect(self.update_world_state)
|
self.ws_update_timer.timeout.connect(self.update_world_state)
|
||||||
self.ws_update_timer.start(1000 * 60 * 5)
|
self.ws_update_timer.start(1000 * 60 * 5)
|
||||||
|
|
||||||
|
# largely just creating custom widgets, and mapping to existing parent widgets
|
||||||
self.redraw_content()
|
self.redraw_content()
|
||||||
|
|
||||||
def redraw_content(self):
|
def redraw_content(self):
|
||||||
self.redraw_content_dynamic()
|
self.redraw_content_dynamic() # content that varies in number, invasions, fissures, etc
|
||||||
self.redraw_content_static()
|
self.redraw_content_static() # static content that won't change/only one, arbi, archons, etc
|
||||||
|
|
||||||
def redraw_content_dynamic(self):
|
def redraw_content_dynamic(self):
|
||||||
self.Fissure_list = [Fissure(self.FissureHolder, fissure_info, fissure_i) for (fissure_i, fissure_info) in enumerate(self.ws.fissures)]
|
self.Fissure_list = [Fissure(self.FissureHolder, fissure_info, fissure_i) for (fissure_i, fissure_info) in enumerate(self.ws.fissures)]
|
||||||
|
@ -41,6 +50,7 @@ class App(GUI):
|
||||||
self.Alert_list = [Alert(self.AlertHolder, alert_info, alert_i) for (alert_i, alert_info) in enumerate(self.ws.alerts)]
|
self.Alert_list = [Alert(self.AlertHolder, alert_info, alert_i) for (alert_i, alert_info) in enumerate(self.ws.alerts)]
|
||||||
[self.AlertList.addWidget(i) for i in self.Alert_list]
|
[self.AlertList.addWidget(i) for i in self.Alert_list]
|
||||||
|
|
||||||
|
# if baro key is [], no baro, switch tab to inactive, else populate grid
|
||||||
if len(self.ws.baro_items) == 0:
|
if len(self.ws.baro_items) == 0:
|
||||||
self.BaroTabs.setCurrentIndex(0)
|
self.BaroTabs.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
|
@ -63,6 +73,7 @@ class App(GUI):
|
||||||
for i in range(1, 4):
|
for i in range(1, 4):
|
||||||
getattr(self, 'ArchonHuntM' + str(i)).setText(self.ws.archon_hunt['missions'][i - 1]['type'])
|
getattr(self, 'ArchonHuntM' + str(i)).setText(self.ws.archon_hunt['missions'][i - 1]['type'])
|
||||||
|
|
||||||
|
# warframestat.us arbi jank fix until content API adds arbis and can use that directly
|
||||||
if not self.ws.arbitration:
|
if not self.ws.arbitration:
|
||||||
self.ArbitrationTabs.setCurrentIndex(0)
|
self.ArbitrationTabs.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
|
@ -70,6 +81,7 @@ class App(GUI):
|
||||||
self.ArbitrationMT.setText(self.ws.arbitration['type'])
|
self.ArbitrationMT.setText(self.ws.arbitration['type'])
|
||||||
self.ArbitrationFaction.setText(self.ws.arbitration['enemy'])
|
self.ArbitrationFaction.setText(self.ws.arbitration['enemy'])
|
||||||
|
|
||||||
|
# nightwave mission mapping if active
|
||||||
daily_i = 1
|
daily_i = 1
|
||||||
weekly_i = 1
|
weekly_i = 1
|
||||||
elite_i = 1
|
elite_i = 1
|
||||||
|
@ -94,25 +106,33 @@ class App(GUI):
|
||||||
self.NightwaveTabs.setCurrentIndex(0)
|
self.NightwaveTabs.setCurrentIndex(0)
|
||||||
|
|
||||||
def update_timers(self):
|
def update_timers(self):
|
||||||
|
# call timer updates and invasion progress changes
|
||||||
[i.update_timer() for i in self.Fissure_list]
|
[i.update_timer() for i in self.Fissure_list]
|
||||||
[i.update_progress() for i in self.Invasion_list]
|
[i.update_progress() for i in self.Invasion_list]
|
||||||
[i.update_timer() for i in self.Alert_list]
|
[i.update_timer() for i in self.Alert_list]
|
||||||
[i.update_timer() for i in self.events_list]
|
[i.update_timer() for i in self.events_list]
|
||||||
[i.update_timer() for i in self.newsblurb_list]
|
[i.update_timer() for i in self.newsblurb_list]
|
||||||
|
|
||||||
|
# parse expiry datestring and calc sortie expiry time delta from now to listed expiry
|
||||||
sortie_eta = round(time.mktime(time.strptime(self.ws.sorties['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()))
|
sortie_eta = round(time.mktime(time.strptime(self.ws.sorties['expiry'], '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()))
|
||||||
if sortie_eta >= 0:
|
if sortie_eta >= 0:
|
||||||
self.SortieResetTimer.setText(f'{str(sortie_eta // 3600) + "h " if sortie_eta // 3600 > 0 else ""}{(sortie_eta // 60) % 60}m {sortie_eta % 60}s')
|
self.SortieResetTimer.setText(f'{str(sortie_eta // 3600) + "h " if sortie_eta // 3600 > 0 else ""}{(sortie_eta // 60) % 60}m {sortie_eta % 60}s')
|
||||||
else:
|
else:
|
||||||
self.SortieResetTimer.setText('Expired')
|
self.SortieResetTimer.setText('Expired')
|
||||||
|
|
||||||
|
# same as sortie, except expiry happens at Monday 00:00 UTC), 3 days for epoch adjust from Wed
|
||||||
|
# % week for weekly timer diff since last Monday
|
||||||
|
# day str listed separately for display formatting
|
||||||
weekly_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) - 3 * 86400) % (7 * 86400)
|
weekly_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) - 3 * 86400) % (7 * 86400)
|
||||||
self.WeeklyResetTimeDayStr.setText(str(weekly_eta // 86400) + 'd')
|
self.WeeklyResetTimeDayStr.setText(str(weekly_eta // 86400) + 'd')
|
||||||
self.WeeklyResetTimeStr.setText(f'{(weekly_eta // 3600) % 24}h {(weekly_eta // 60) % 60}m {weekly_eta % 60}s')
|
self.WeeklyResetTimeStr.setText(f'{(weekly_eta // 3600) % 24}h {(weekly_eta // 60) % 60}m {weekly_eta % 60}s')
|
||||||
|
|
||||||
|
# same as above, bounties reset at given time adjust, 2.5hr cycle
|
||||||
bounty_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) + 120) % (9000)
|
bounty_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) + 120) % (9000)
|
||||||
self.BountyTimeStr.setText(f'{bounty_eta // 3600}h {(bounty_eta // 60) % 60}m {bounty_eta % 60}s')
|
self.BountyTimeStr.setText(f'{bounty_eta // 3600}h {(bounty_eta // 60) % 60}m {bounty_eta % 60}s')
|
||||||
|
|
||||||
|
# baro reset adjust, 2 week cycle in full.
|
||||||
|
# arrives at 2 days left, present < 2 days.
|
||||||
baro_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) + (10*86400 + 13 * 3600)) % (14 * 86400)
|
baro_eta = round(time.mktime(time.strptime('1970-1-1T00:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')) - time.mktime(time.gmtime()) + (10*86400 + 13 * 3600)) % (14 * 86400)
|
||||||
if baro_eta >= 2 * 86400:
|
if baro_eta >= 2 * 86400:
|
||||||
self.BaroStateStr.setText('Baro Arrives in:')
|
self.BaroStateStr.setText('Baro Arrives in:')
|
||||||
|
@ -129,6 +149,7 @@ class App(GUI):
|
||||||
self.network_error()
|
self.network_error()
|
||||||
|
|
||||||
def network_error(self):
|
def network_error(self):
|
||||||
|
# slapped on later, just a dialog box for network error
|
||||||
msg = QMessageBox()
|
msg = QMessageBox()
|
||||||
msg.setIcon(QMessageBox.Critical)
|
msg.setIcon(QMessageBox.Critical)
|
||||||
msg.setText('Network Error')
|
msg.setText('Network Error')
|
||||||
|
|
Loading…
Reference in a new issue