From 9929510e53a33e3afc7a517d52b11d4a96c1a476 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Fri, 23 Oct 2015 19:14:43 -0400 Subject: [PATCH] More work on CREST stuff. Now implicit character can GET and POST fits. --- gui/crestFittings.py | 81 +++++++++++++++++++++++++------------- gui/mainFrame.py | 8 ++-- gui/mainMenuBar.py | 19 ++++++++- gui/utils/repeatedTimer.py | 25 ++++++++++++ pycrest/eve.py | 2 +- service/crest.py | 17 +++++++- service/port.py | 3 +- 7 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 gui/utils/repeatedTimer.py diff --git a/gui/crestFittings.py b/gui/crestFittings.py index 297589606..39af6ae4d 100644 --- a/gui/crestFittings.py +++ b/gui/crestFittings.py @@ -1,21 +1,16 @@ -import json -import thread - import wx -from wx.lib.pubsub import pub import service import gui.display as d from eos.types import Cargo from eos.db import getItem -from service.server import * -import config import time +import json class CrestFittings(wx.Frame): def __init__(self, parent): - wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition, size=wx.Size( 550,450 ), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) + wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Browse EVE Fittings", pos=wx.DefaultPosition, size=wx.Size( 550,450 ), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)) @@ -23,16 +18,21 @@ class CrestFittings(wx.Frame): mainSizer = wx.BoxSizer(wx.VERTICAL) sCrest = service.Crest.getInstance() - self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, []) - chars = sCrest.getCrestCharacters() - for char in chars: - self.charChoice.Append(char.name, char.ID) - characterSelectSizer = wx.BoxSizer( wx.HORIZONTAL ) - self.charChoice.SetSelection(0) + if sCrest.settings.get('mode') == 0: + self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s"%sCrest.implicitCharacter.name, wx.DefaultPosition, wx.DefaultSize) + self.stLogged.Wrap( -1 ) + + characterSelectSizer.Add( self.stLogged, 0, wx.ALL, 5 ) + else: + self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, []) + chars = sCrest.getCrestCharacters() + for char in chars: + self.charChoice.Append(char.name, char.ID) + self.charChoice.SetSelection(0) + characterSelectSizer.Add( self.charChoice, 1, wx.ALL, 5 ) - characterSelectSizer.Add( self.charChoice, 1, wx.ALL, 5 ) self.fetchBtn = wx.Button( self, wx.ID_ANY, u"Fetch Fits", wx.DefaultPosition, wx.DefaultSize, 5 ) characterSelectSizer.Add( self.fetchBtn, 0, wx.ALL, 5 ) mainSizer.Add( characterSelectSizer, 0, wx.EXPAND, 5 ) @@ -59,19 +59,31 @@ class CrestFittings(wx.Frame): self.fetchBtn.Bind(wx.EVT_BUTTON, self.fetchFittings) self.importBtn.Bind(wx.EVT_BUTTON, self.importFitting) + pub.subscribe(self.ssoLogout, 'logout_success') + self.SetSizer(mainSizer) self.Layout() self.Centre(wx.BOTH) + def ssoLogout(self, message): + self.Close() + def getActiveCharacter(self): + sCrest = service.Crest.getInstance() + + if sCrest.settings.get('mode') == 0: + return sCrest.implicitCharacter.ID + selection = self.charChoice.GetCurrentSelection() return self.charChoice.GetClientData(selection) if selection is not None else None def fetchFittings(self, event): sCrest = service.Crest.getInstance() + waitDialog = wx.BusyInfo("Fetching fits, please wait...", parent=self) fittings = sCrest.getFittings(self.getActiveCharacter()) self.fitTree.populateSkillTree(fittings) + del waitDialog def importFitting(self, event): selection = self.fitView.fitSelection @@ -84,22 +96,29 @@ class CrestFittings(wx.Frame): class ExportToEve(wx.Frame): def __init__(self, parent): - wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition, size=(wx.Size(500,100)), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) + wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Export fit to EVE", pos=wx.DefaultPosition, size=(wx.Size(350,100)), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.mainFrame = parent self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)) sCrest = service.Crest.getInstance() + mainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, []) - chars = sCrest.getCrestCharacters() - for char in chars: - self.charChoice.Append(char.name, char.ID) + if sCrest.settings.get('mode') == 0: + self.stLogged = wx.StaticText(self, wx.ID_ANY, "Currently logged in as %s"%sCrest.implicitCharacter.name, wx.DefaultPosition, wx.DefaultSize) + self.stLogged.Wrap( -1 ) - mainSizer = wx.BoxSizer( wx.HORIZONTAL ) - self.charChoice.SetSelection(0) + mainSizer.Add( self.stLogged, 0, wx.ALL, 5 ) + else: + self.charChoice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, []) + chars = sCrest.getCrestCharacters() + for char in chars: + self.charChoice.Append(char.name, char.ID) + self.charChoice.SetSelection(0) + mainSizer.Add( self.charChoice, 1, wx.ALL, 5 ) + + self.charChoice.SetSelection(0) - mainSizer.Add( self.charChoice, 1, wx.ALL, 5 ) self.exportBtn = wx.Button( self, wx.ID_ANY, u"Export Fit", wx.DefaultPosition, wx.DefaultSize, 5 ) mainSizer.Add( self.exportBtn, 0, wx.ALL, 5 ) @@ -109,6 +128,7 @@ class ExportToEve(wx.Frame): self.statusbar.SetFieldsCount(2) self.statusbar.SetStatusWidths([100, -1]) + pub.subscribe(self.ssoLogout, 'logout_success') self.SetSizer(mainSizer) self.SetStatusBar(self.statusbar) @@ -116,7 +136,15 @@ class ExportToEve(wx.Frame): self.Centre(wx.BOTH) + def ssoLogout(self, message): + self.Close() + def getActiveCharacter(self): + sCrest = service.Crest.getInstance() + + if sCrest.settings.get('mode') == 0: + return sCrest.implicitCharacter.ID + selection = self.charChoice.GetCurrentSelection() return self.charChoice.GetClientData(selection) if selection is not None else None @@ -177,7 +205,9 @@ class CrestCharacterInfo(wx.Dialog): self.pic.SetBitmap(wx.ImageFromStream(self.char.img).ConvertToBitmap()) self.Layout() self.bitmapSet = True - self.coutdownText.SetLabel(time.strftime("%H:%M:%S", t)) + newLabel = time.strftime("%H:%M:%S", t if t >= 0 else 0) + if self.coutdownText.Label != newLabel: + self.coutdownText.SetLabel(time.strftime("%H:%M:%S", t)) def logout(self, event): sCrest = service.Crest.getInstance() @@ -220,7 +250,6 @@ class FittingsTreeView(wx.Panel): shipID = tree.AppendItem(root, name) for fit in fits: fitId = tree.AppendItem(shipID, fit['name']) - print type(fit) tree.SetPyData(fitId, json.dumps(fit)) tree.SortChildren(root) @@ -237,6 +266,7 @@ class FittingsTreeView(wx.Panel): list.append(cargo) except: pass + self.parent.fitView.fitSelection = selection self.parent.fitView.update(list) @@ -246,6 +276,3 @@ class FitView(d.Display): def __init__(self, parent): d.Display.__init__(self, parent, style=wx.LC_SINGLE_SEL) - self.fitSelection = None - #self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem) - #self.Bind(wx.EVT_KEY_UP, self.kbEvent) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 7c58c1853..6dbfed3aa 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -496,15 +496,17 @@ class MainFrame(wx.Frame): def showCharacterMgmt(self, type): if type == 0: - print "login type is implicit" dlg=CrestCharacterInfo(self) dlg.Show() def ssoLogin(self, event): sCrest = service.Crest.getInstance() if sCrest.settings.get('mode') == 0: # Implicit, go directly to login - uri = sCrest.startServer() - wx.LaunchDefaultBrowser(uri) + if sCrest.implicitCharacter is not None: + self.showCharacterMgmt(type=0) + else: + uri = sCrest.startServer() + wx.LaunchDefaultBrowser(uri) else: dlg=CrestCharacterInfo(self) dlg.Show() diff --git a/gui/mainMenuBar.py b/gui/mainMenuBar.py index 1af6e88e5..924c82540 100644 --- a/gui/mainMenuBar.py +++ b/gui/mainMenuBar.py @@ -25,6 +25,8 @@ import gui.graphFrame import gui.globalEvents as GE import service +from wx.lib.pubsub import setupkwargs +from wx.lib.pubsub import pub class MainMenuBar(wx.MenuBar): def __init__(self): @@ -47,6 +49,8 @@ class MainMenuBar(wx.MenuBar): self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.sCrest = service.Crest.getInstance() + wx.MenuBar.__init__(self) # File menu @@ -109,7 +113,10 @@ class MainMenuBar(wx.MenuBar): # CREST Menu crestMenu = wx.Menu() self.Append(crestMenu, "&CREST") - crestMenu.Append(self.ssoLoginId, "Login To EVE") + if self.sCrest.settings.get('mode') != 0: + crestMenu.Append(self.ssoLoginId, "Manage Characters") + else: + crestMenu.Append(self.ssoLoginId, "Login to EVE") crestMenu.Append(self.eveFittingsId, "Browse EVE Fittings") crestMenu.Append(self.exportToEveId, "Export To EVE") @@ -125,6 +132,8 @@ class MainMenuBar(wx.MenuBar): helpMenu.Append( self.mainFrame.widgetInspectMenuID, "Open Widgets Inspect tool", "Open Widgets Inspect tool") self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged) + pub.subscribe(self.ssoLogin, 'login_success') + pub.subscribe(self.ssoLogout, 'logout_success') def fitChanged(self, event): enable = event.fitID is not None @@ -142,3 +151,11 @@ class MainMenuBar(wx.MenuBar): self.Enable(self.revertCharId, char.isDirty) event.Skip() + + def ssoLogin(self, type): + if self.sCrest.settings.get('mode') == 0: + self.SetLabel(self.ssoLoginId, "Character Info") + + def ssoLogout(self, message): + if self.sCrest.settings.get('mode') == 0: + self.SetLabel(self.ssoLoginId, "Login to EVE") diff --git a/gui/utils/repeatedTimer.py b/gui/utils/repeatedTimer.py new file mode 100644 index 000000000..be141156b --- /dev/null +++ b/gui/utils/repeatedTimer.py @@ -0,0 +1,25 @@ +from threading import Timer + +class RepeatedTimer(object): + def __init__(self, interval, function, *args, **kwargs): + self._timer = None + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.is_running = False + + def _run(self): + self.is_running = False + self.start() + self.function(*self.args, **self.kwargs) + + def start(self): + if not self.is_running: + self._timer = Timer(self.interval, self._run) + self._timer.start() + self.is_running = True + + def stop(self): + self._timer.cancel() + self.is_running = False diff --git a/pycrest/eve.py b/pycrest/eve.py index d74f89567..0e1ec412e 100644 --- a/pycrest/eve.py +++ b/pycrest/eve.py @@ -271,7 +271,7 @@ class AuthedConnection(EVE): return self # for backwards compatibility def get(self, resource, params=None): - if int(time.time()) >= self.expires: + if self.refresh_token and int(time.time()) >= self.expires: self.refresh() return super(self.__class__, self).get(resource, params) diff --git a/service/crest.py b/service/crest.py index c37eb1f53..d52fe27e2 100644 --- a/service/crest.py +++ b/service/crest.py @@ -5,6 +5,7 @@ import copy import service from service.server import * import uuid +from gui.utils.repeatedTimer import RepeatedTimer from wx.lib.pubsub import setupkwargs from wx.lib.pubsub import pub @@ -31,6 +32,8 @@ class Crest(): self.scopes = ['characterFittingsRead', 'characterFittingsWrite'] self.state = None + self.ssoTimer = RepeatedTimer(1, self.logout) + # Base EVE connection that is copied to all characters self.eve = pycrest.EVE( client_id=self.settings.get('clientID'), @@ -55,6 +58,11 @@ class Crest(): ''' Get character, and modify to include the eve connection ''' + if self.settings.get('mode') == 0: + if self.implicitCharacter.ID != charID: + raise ValueError("CharacterID does not match currently logged in character.") + return self.implicitCharacter + char = eos.db.getCrestCharacter(charID) if not hasattr(char, "eve"): char.eve = copy.copy(self.eve) @@ -78,6 +86,8 @@ class Crest(): def logout(self): self.implicitCharacter = None + self.ssoTimer.stop() + wx.CallAfter(pub.sendMessage, 'logout_success', message=None) def startServer(self): thread.start_new_thread(self.httpd.serve, ()) @@ -89,6 +99,7 @@ class Crest(): return if message['state'][0] != self.state: + print "state mismatch" return print "handling login by making characters and stuff" @@ -100,13 +111,17 @@ class Crest(): access_token=message['access_token'][0], expires_in=int(message['expires_in'][0]) ) + self.ssoTimer.interval = int(message['expires_in'][0]) + self.ssoTimer.start() + eve() info = eve.whoami() self.implicitCharacter = CrestUser(info['CharacterID'], info['CharacterName']) self.implicitCharacter.eve = eve self.implicitCharacter.fetchImage() - wx.CallAfter(pub.sendMessage, 'login_success', type=0) + print self.implicitCharacter.eve, self.implicitCharacter.eve.refresh_token + wx.CallAfter(pub.sendMessage, 'login_success', type=0) elif 'code' in message: print "handle authentication code" diff --git a/service/port.py b/service/port.py index 6951a3765..fc7d308b7 100644 --- a/service/port.py +++ b/service/port.py @@ -54,8 +54,9 @@ class Port(object): nested_dict = lambda: collections.defaultdict(nested_dict) fit = nested_dict() + sCrest = service.Crest.getInstance() + eve = sCrest.eve - eve = config.pycrest_eve # max length is 50 characters name = ofit.name[:47] + '...' if len(ofit.name) > 50 else ofit.name fit['name'] = name