Compare commits

...

124 Commits

Author SHA1 Message Date
blitzmann
5571bae8b2 Fix situation in which event propagation was not working properly for structures 2018-02-17 12:47:07 -05:00
blitzmann
8b2cfe44f2 Merge remote-tracking branch 'origin/master' into test-3
# Conflicts:
#	config.py
#	eos/saveddata/fighter.py
2018-02-17 12:31:58 -05:00
blitzmann
82e3db1ffb Centralize version string getting. Still trying to work out how we should handle automatic version increments so we don't have to modify files all the time. Remove version file from repo (should only be a thing when building binaries) 2018-02-17 11:10:42 -05:00
blitzmann
e779bb84e2 Fix for #1383. Due to the changed mechanics of None in py3, getModifiedItemAttr was defaulted to 0 instead of None. This adds an explicit default of None when trying to find the allowed drone group attribute 2018-02-17 10:53:29 -05:00
blitzmann
0456cb2f96 Merge remote-tracking branch 'origin/master' into test-3 2018-02-16 22:26:10 -05:00
blitzmann
cafd92f169 add a todo 2018-02-16 22:26:02 -05:00
blitzmann
05f08970c9 fix character editor not spawning on OSX 2018-02-16 20:40:51 -05:00
blitzmann
da0f89ef91 Merge commit 'refs/tags/v1.35.0^{}' into test-3 2018-02-14 22:25:45 -05:00
blitzmann
efc3f1ba7d Don't display console for windows application 2018-02-14 22:23:42 -05:00
blitzmann
c6e715aa5c Merge branch 'master' into test-3 2018-02-14 22:07:33 -05:00
blitzmann
0e93136157 Merge branch 'release/v1.35.0' 2018-02-14 22:07:20 -05:00
blitzmann
23f0f48c80 Use a special dev database for py3 branch 2018-02-14 01:16:49 -05:00
blitzmann
33618f12f7 Fix issue when error happens before wx is even initialized traceback is never set 2018-02-11 23:22:37 -05:00
blitzmann
5f0ce58c29 Merge branch 'master' into test-3
# Conflicts:
#	gui/builtinShipBrowser/fitItem.py
#	service/port.py
2018-02-11 21:29:17 -05:00
blitzmann
c329f5eeb8 Bump up the wxPython requirement to 4.0.1 2018-02-11 21:22:35 -05:00
blitzmann
320a0230f4 fix version data file in mac spec file 2018-02-11 12:32:34 -05:00
blitzmann
50dd74dbe8 Add packaging requirement, and use it's PEP 440 version parsing for version comparisons. 2018-02-10 00:59:25 -05:00
blitzmann
9c355d8f96 update requirements 2018-02-09 18:53:14 -05:00
blitzmann
2e8d7d3610 add markdown2 to requirements.txt 2018-02-01 23:09:08 -05:00
blitzmann
3179016aed Enhance the update modal to show a web view with html-rendered markdown of release ntoes 2018-02-01 21:58:29 -05:00
blitzmann
9f7e4e0dc0 Fix issue with market search (None / int comparison) 2018-01-10 21:39:50 -05:00
blitzmann
29d175c7b3 Fix for error that happens when switching to/from firepower/mining 2018-01-10 00:51:21 -05:00
blitzmann
40ce7b7c0b Merge branch 'master' into test-3
# Conflicts:
#	.gitignore
#	eos/saveddata/character.py
#	service/network.py
#	service/price.py
2017-12-10 22:36:15 -05:00
blitzmann
2936b88c3d code cleanup 2017-11-27 21:05:06 -05:00
blitzmann
2365112292 Some file cleanup 2017-11-26 18:36:20 -05:00
blitzmann
1daef5354d remove old wx test file 2017-11-26 18:31:48 -05:00
blitzmann
6f19d45c6d fix mac spec 2017-11-26 18:29:03 -05:00
blitzmann
ac7908c62c rearrange spec files 2017-11-26 18:15:33 -05:00
blitzmann
c000b19986 Finish pulling all the cruft out of pyfa.py relating to logging and error handling. All that is now done in separate areas.
Also finally did some major reworking on the error dialog. Now it doesn't spawn a new wxApp and wxFrame for each and every error - attaches to MainFrame and sticks around, having exceptions append to it rather than spawn a new one. In the case that an error happens before MainFrame is available, it spins up a new wxApp. Yay cleanup!
2017-11-26 03:57:00 -05:00
blitzmann
1da127c898 Working commit to better handle errors 2017-11-26 01:54:36 -05:00
blitzmann
fcdf55632f working commit to try to clean up pyfa.py and re-implement version checking 2017-11-26 01:08:02 -05:00
blitzmann
dd3bc66896 Remove old py<2.6 OrderedDict compat module 2017-11-25 22:40:23 -05:00
blitzmann
da67cdba9b Get a mailmap working for properish tracking of authors 2017-11-25 20:34:03 -05:00
blitzmann
8850da6cdb OS X bundling puts it all into one file, which is extracted. We need to make sure the script knows of the actual path 2017-11-25 20:11:05 -05:00
blitzmann
7d46d7e22d fix crash dealing with CREST fitting window's cache timer 2017-11-25 17:31:19 -05:00
blitzmann
b3157303cd Reenable error dialog and remove versioning info - want to look into a more uniform way of doing this if possible, and the requirements are all changing. 2017-11-25 13:49:48 -05:00
blitzmann
65e17119af Deprecation fix 2017-11-25 13:12:26 -05:00
blitzmann
3c405f51d8 Remove platform-specific CREST checks (add for mac-deprecated client) 2017-11-24 17:27:44 -05:00
blitzmann
337f0a9c8a Fix stretchspacers 2017-11-24 17:23:04 -05:00
blitzmann
53936a3e66 Fix additional panel note toggling correctly 2017-11-24 12:44:00 -05:00
blitzmann
30a6e29b39 Fix slight sizing issue with toggle panel header arrow 2017-11-24 12:30:46 -05:00
blitzmann
f3dc3bc654 Fix tabs not disabling. It was primarily an issue with event propagation not being handled correctly, as well as some missing helper code in chrome_tabs 2017-11-24 12:22:21 -05:00
blitzmann
0a935cf149 fix gtk warnings 2017-11-24 02:02:09 -05:00
blitzmann
5697da7ec2 fix upgrade 2017-11-24 01:23:04 -05:00
blitzmann
a7086b78cb Fix an issue with with Cap Power Relay using an effect without an expecting source attribute. Used to work, but with changes to getModifiedItemAttr need to default these to None 2017-11-24 00:55:23 -05:00
blitzmann
e032c9c5b1 fix item stats dialog 2017-11-23 22:48:37 -05:00
blitzmann
46b0aded03 fixes 2017-11-23 22:43:41 -05:00
blitzmann
d23398ce29 fix for boosters 2017-11-23 20:51:03 -05:00
blitzmann
5e0a5da6d5 more post-merge work 2017-11-23 12:51:43 -05:00
blitzmann
6e112b9ed5 Fix issues with merge 2017-11-23 11:38:08 -05:00
blitzmann
b30b3fcbf1 Merge branch 'master' into test-3
Conflicts:
	eos/gamedata.py
	eos/saveddata/booster.py
	eos/saveddata/character.py
	gui/builtinAdditionPanes/commandView.py
	gui/builtinContextMenus/commandFits.py
	gui/builtinMarketBrowser/itemView.py
	gui/builtinMarketBrowser/marketTree.py
	gui/builtinPreferenceViews/pyfaGeneralPreferences.py
	gui/builtinShipBrowser/categoryItem.py
	gui/builtinShipBrowser/fitItem.py
	gui/builtinShipBrowser/navigationPanel.py
	gui/builtinShipBrowser/raceSelector.py
	gui/builtinShipBrowser/shipItem.py
	gui/builtinStatsViews/priceViewFull.py
	gui/builtinViews/fittingView.py
	gui/characterEditor.py
	gui/characterSelection.py
	gui/chromeTabs.py
	gui/crestFittings.py
	gui/itemStats.py
	gui/mainFrame.py
	scripts/itemDiff.py
	service/price.py
2017-11-23 11:19:05 -05:00
blitzmann
4a33365195 Add some debug and fix indentation issue causing fit deletion to crash open fittings views 2017-11-22 01:45:31 -05:00
blitzmann
5d5646df79 Fix BlankPage having binding issue 2017-11-22 01:45:06 -05:00
blitzmann
405a965046 Fix issue with loading fighters 2017-11-22 01:44:48 -05:00
blitzmann
4138088d4a Do not create a new fitting view every time we switch fits. 2017-11-21 23:46:50 -05:00
blitzmann
de44e6f932 Get rid of some annoying messages 2017-11-21 23:46:33 -05:00
blitzmann
d4df989427 Remove handlers from unbind (see https://github.com/wxWidgets/Phoenix/issues/624) 2017-11-21 23:04:51 -05:00
blitzmann
6c8b143936 Tentative .spec file for linux 2017-11-21 00:32:45 -05:00
blitzmann
0f94557699 Use wx.AutoBufferedPaintDC instead of wx.BufferedPaintDC (helps with drawing on linux) 2017-11-21 00:05:52 -05:00
blitzmann
a52b9e58e9 Testing some stuff out 2017-11-18 19:01:05 -05:00
blitzmann
0d8904d59f Fix None comparison operation 2017-11-16 01:35:26 -05:00
blitzmann
d956cb7861 use a different image to denote changed skills 2017-11-16 01:31:28 -05:00
blitzmann
e848cec815 Fix dirty skill indicator (* instead of blue text). Need to get a different icon working for those. Remove debugging prints() 2017-11-16 01:20:38 -05:00
blitzmann
ce8f1d385d Better fix for broken Entity Editor Validation 2017-11-15 21:43:36 -05:00
blitzmann
90e338b969 Fix for broken Entity Editor Validation 2017-11-14 00:07:12 -05:00
blitzmann
1978f5cb92 Test validator stuff 2017-11-13 22:45:12 -05:00
blitzmann
979bc494f0 deprecation 2017-11-13 22:29:58 -05:00
blitzmann
cc9b6ea04b More deprecation fixes 2017-11-13 00:18:24 -05:00
blitzmann
8cbb327659 Fix bug that caused race image to not appear in fitting tab 2017-11-12 23:58:30 -05:00
blitzmann
1fc9b2941d Add spac file for mac 2017-11-12 13:43:19 -05:00
blitzmann
e9be07f281 Rename pyfa.spec to pyfa-win.spec 2017-11-12 13:17:16 -05:00
blitzmann
df7dc30e7e Write out git version information to a file, use in about box, remove all the other stuff until I can format it correctly 2017-11-12 13:13:38 -05:00
blitzmann
d0235f6d93 Fix market browser meta filtering 2017-11-12 12:00:24 -05:00
blitzmann
de646cf252 Have a noticeable message show up (currently prints for everything, should restrict to only beta builds) 2017-11-12 02:30:15 -05:00
blitzmann
21838f2d9a Fix issue with pyinstaller not bundling required DLLs when building on Windows 10 / Python >= 3.5 2017-11-12 02:15:15 -05:00
blitzmann
266398b1de Get some things working for pyinstaller 2017-11-12 00:14:45 -05:00
blitzmann
0cc646bab9 Fix gauge resetting to 0 each time (should figure out how to utilize the existing set range and value, but for now this works) 2017-11-05 02:29:58 -05:00
blitzmann
cebca64e5e Fix CREST stuff 2017-11-05 01:43:39 -05:00
blitzmann
bd0de82a8e remove repo version of FloatSpin, go with wx bundled version 2017-11-05 01:10:22 -05:00
blitzmann
0f5ae8d9b6 Fix delete fix (renamed MiddleDown to MiddleIsDown) 2017-11-05 01:03:14 -05:00
blitzmann
5ae7805bb1 Fix ammo picker 2017-11-05 01:54:19 -04:00
blitzmann
6a382c4445 More tweaks to getModifiedItemAttr and fix deprecation warning 2017-11-05 01:51:19 -04:00
blitzmann
3b0c8b6117 Fix Racks having a CPU and Power value of 0 2017-11-04 18:32:26 -04:00
blitzmann
0e1e4cad6d Fix a few more deprecation warnings 2017-11-04 18:24:18 -04:00
blitzmann
e0b92198b0 Fix deprecation warnings 2017-11-04 18:20:54 -04:00
blitzmann
ce3b94696a Make sure getModifiedItemAttr always returns an int, unless otherwise wanting None
In py2, you could compare None to an int and it would always be less than. Unfortunately in py3, this is no longer the case. Returning getModifiedItemAttr as 0 allows us to not do a huge refactor.
2017-11-04 18:20:00 -04:00
blitzmann
56f34873a6 bleh 2017-10-08 22:51:06 -04:00
blitzmann
2afc8b1abe Get rack headers bold again (courtesy of @RobinD42 - https://github.com/wxWidgets/Phoenix/issues/525) 2017-09-25 01:58:31 -04:00
blitzmann
3b716e6e5e fix py2app setup file 2017-07-07 00:22:58 -04:00
blitzmann
961b389b40 test 2017-07-06 23:41:55 -04:00
Ryan Holmes
0527a506ac fix broken events preventing additions panels to not work 2017-07-03 01:46:46 -04:00
Ryan Holmes
1082d8a173 fix fix fix 2017-07-02 23:45:28 -04:00
Ryan Holmes
7ae41b71b2 Fix some deprecated things and a bug or two 2017-07-02 23:26:44 -04:00
Ryan Holmes
de5a734919 About dialog (looks like shit x_x) 2017-07-02 16:42:22 -04:00
Ryan Holmes
987c55ed8f Get preferences dialog up and running 2017-07-02 16:32:39 -04:00
Ryan Holmes
57783fe80f More work on character editor 2017-07-02 15:28:42 -04:00
Ryan Holmes
f24c2ddd22 Get skill list in character editor showing. Mostly doesn't work still 2017-07-02 14:12:00 -04:00
Ryan Holmes
f16e14e0b4 Fix gauges again, convert remaining IconFromBitmap > Icon 2017-06-14 15:05:12 -04:00
Ryan Holmes
729c46ab00 Revert "Remove EVT_ERASE_BACKGROUND events - pretty sure these were there for older versions of wx where the background wasn't erased properly"
This does help prevent flickering on resizing. Need to research more before removing them

This reverts commit 8c5c7fba29.
2017-06-14 03:57:57 -04:00
Ryan Holmes
3b546de070 More deprecated fixes, and re-enable a working stats view 2017-06-14 03:51:40 -04:00
Ryan Holmes
ba64f75f88 Add some missing features to the gauge (and the background erase event, which apparently is needed to prevent flickering. Still need to access if this is something I need to be concerned about in other areas) 2017-06-14 03:44:38 -04:00
Ryan Holmes
4b8f2ce9e7 Deprecation stuff 2017-06-14 01:07:18 -04:00
Ryan Holmes
8c5c7fba29 Remove EVT_ERASE_BACKGROUND events - pretty sure these were there for older versions of wx where the background wasn't erased properly 2017-06-14 01:02:27 -04:00
Ryan Holmes
bec26d5d05 Fix unable to close window 2017-06-14 00:53:22 -04:00
Ryan Holmes
8f369daf1e InsertStringItem > InsertItem 2017-06-14 00:46:38 -04:00
Ryan Holmes
43cbdc1e57 Fix issue with crashing (set weight not working as intended?) 2017-06-14 00:46:13 -04:00
Ryan Holmes
cf4d0706ae Fix column headers, and disable event posting which was causing crash 2017-06-14 00:09:30 -04:00
Ryan Holmes
2857eff884 Fix a few None comparison operations... python 3 has changed this. I'm sure there's going to be a lot of these issues popping up.
Oh, and now we get a hard crash when opening a fit. Yey!
2017-06-13 23:57:27 -04:00
Ryan Holmes
050f1b4add Fixed some missing chrome tab stuff, as well as more conversion issues 2017-06-13 15:18:40 -04:00
Ryan Holmes
2bbcd96ce3 Even more fixes 2017-06-13 15:01:30 -04:00
Ryan Holmes
1cbd8ee901 Fix some deprecated stuff 2017-06-12 21:31:37 -04:00
Ryan Holmes
7e86cb0f84 OMG I HAVE A SHIP BROWSER NOW :3 (replace old instances of GetSuitableColor with GetSuitable) 2017-06-12 21:25:07 -04:00
Ryan Holmes
0e7dccccfe Remove stat panels for now. I HAVE A FRAME SPAWNING OMG 2017-06-12 21:16:21 -04:00
Ryan Holmes
9d75dea31a "Fix" more spacers 2017-06-12 21:14:45 -04:00
Ryan Holmes
610f501608 "Color Correction" 2017-06-12 21:11:10 -04:00
Ryan Holmes
361f7fc5bb misc fixes 2017-06-12 21:09:50 -04:00
Ryan Holmes
951b35a345 PyDeadObjectError fixes and PFNotebook -> ChromeNotebook renaming 2017-06-12 20:50:05 -04:00
Ryan Holmes
6c317d56ee touch up the gauge code 2017-06-12 20:45:58 -04:00
Ryan Holmes
2acb3e759e Touch up toggle panel 2017-06-12 20:42:03 -04:00
Ryan Holmes
9712ec4fbf Fix up some stuff, migrate to cleaned up chrome tabs 2017-06-12 20:38:00 -04:00
Ryan Holmes
ae0da59ed2 Clean up draw and color utils 2017-06-12 18:14:29 -04:00
Ryan Holmes
8e4db5a8c3 Do some renaming of some files 2017-06-12 18:08:07 -04:00
Ryan Holmes
7f392006d1 comment out most of the fluff in pyfa.py. Need to come back to this and get it all working 2017-06-12 16:37:15 -04:00
Ryan Holmes
828b18d0fd py2to3 automatic conversion. Woot! 2017-06-12 16:12:45 -04:00
229 changed files with 4625 additions and 6399 deletions

2
.gitignore vendored
View File

@@ -118,3 +118,5 @@ ENV/
.idea
eos.iml
gitversion
.version
/.version

14
.mailmap Normal file
View File

@@ -0,0 +1,14 @@
cncfanatics <diego.duclos@gmail.com> cncfanatics <cncfanatics@titanium.(none)>
blitzmann <holmes.ryan.90@gmail.com>
blitzmann <holmes.ryan.90@gmail.com> blitzmann <ryan.xgamer99@gmail.com>
blitzmann <holmes.ryan.90@gmail.com>
blitzmann <holmes.ryan.90@gmail.com> blitzman <ryan.xgamer99@gmail.com>
blitzmann <holmes.ryan.90@gmail.com> Ryan Holmes <ryan.holmes.90@gmail.com>
blitzmann <holmes.ryan.90@gmail.com>
Corollax <corollax@gmail.com> Corollax <corollax@corollax-laptop.(none)>
Corollax <corollax@gmail.com> Corollax <corollax@corollax-N76VM.(none)>
Mr. Nukealizer <mr.nukealizer@gmail.com> Mr. Nukealizer <MrNukealizer@users.noreply.github.com>
DarkPhoenix <phoenix@mail.ru>
Sakari Orisi <sakari@evefit.org>
Will Wykeham <will@wykeham.net> Will Wykeham <will.wykeham@paconsulting.com>
OISumeko <camerongrout@gmail.com> OISumeko <cameron@sporadic.co.nz>

View File

@@ -36,13 +36,8 @@ The following is a list of pyfa packages available for certain distributions. Pl
### Dependencies
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
* Python 2.7
* `wxPython` 2.8/3.0
* `sqlalchemy` >= 1.0.5
* `dateutil`
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
* `requests`
* `logbook` >= 1.0.0
* Python 3.6
* Requirements as listed in `requirements.txt`
## Bug Reporting
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).

View File

@@ -28,7 +28,7 @@ def DBInMemory_test():
gamedataCache = True
saveddataCache = True
gamedata_version = ""
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(unicode(__file__))), "..", "eve.db"))
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(str(__file__))), "..", "eve.db"))
saveddata_connectionstring = 'sqlite:///:memory:'
class ReadOnlyException(Exception):
@@ -100,8 +100,8 @@ def DBInMemory():
import eos.db
# Output debug info to help us troubleshoot Travis
print(eos.db.saveddata_engine)
print(eos.db.gamedata_engine)
print((eos.db.saveddata_engine))
print((eos.db.gamedata_engine))
helper = {
'config': eos.config,

View File

@@ -41,7 +41,7 @@ def CurseFit(DB, Gamedata, Saveddata):
mod.state = Saveddata['State'].ONLINE
# Add 5 neuts
for _ in xrange(5):
for _ in range(5):
fit.modules.append(mod)
return fit
@@ -60,7 +60,7 @@ def HeronFit(DB, Gamedata, Saveddata):
mod.state = Saveddata['State'].ONLINE
# Add 5 neuts
for _ in xrange(4):
for _ in range(4):
fit.modules.append(mod)
return fit

View File

@@ -94,8 +94,8 @@ def GetUnicodePath(root, file=None, codec=None):
path = os.path.join(path, file)
if codec:
path = unicode(path, codec)
path = str(path, codec)
else:
path = unicode(path)
path = str(path)
return path

146
config.py
View File

@@ -1,7 +1,8 @@
import os
import sys
from logbook import Logger
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
StreamHandler, TimedRotatingFileHandler, WARNING
pyfalog = Logger(__name__)
@@ -19,8 +20,8 @@ debug = False
saveInRoot = False
# Version data
version = "1.35.1"
tag = "Stable"
version = "2.0.x"
tag = "git"
expansionName = "YC120.2"
expansionVersion = "1.2"
evemonMinVersion = "4081"
@@ -30,6 +31,16 @@ savePath = None
saveDB = None
gameDB = None
logPath = None
loggingLevel = None
logging_setup = None
LOGLEVEL_MAP = {
"critical": CRITICAL,
"error": ERROR,
"warning": WARNING,
"info": INFO,
"debug": DEBUG,
}
def isFrozen():
@@ -45,23 +56,35 @@ def __createDirs(path):
def getPyfaRoot():
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
if hasattr(sys, '_MEIPASS'):
return sys._MEIPASS
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else __file__
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
root = unicode(root, sys.getfilesystemencoding())
root = root
return root
def getVersion():
if os.path.isfile(os.path.join(pyfaPath, '.version')):
with open(os.path.join(pyfaPath, '.version')) as f:
gitVersion = f.readline()
return gitVersion
# if no version file exists, then user is running from source or not an official build
return version + " (git)"
def getDefaultSave():
return unicode(os.path.expanduser(os.path.join("~", ".pyfa")), sys.getfilesystemencoding())
return os.path.expanduser(os.path.join("~", ".pyfa"))
def defPaths(customSavePath):
def defPaths(customSavePath=None):
global debug
global pyfaPath
global savePath
global saveDB
global gameDB
global saveInRoot
global logPath
pyfalog.debug("Configuring Pyfa")
@@ -86,12 +109,12 @@ def defPaths(customSavePath):
__createDirs(savePath)
if isFrozen():
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem").encode('utf8')
os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem").encode('utf8')
# if isFrozen():
# os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
# os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
# The database where we store all the fits etc
saveDB = os.path.join(savePath, "saveddata.db")
saveDB = os.path.join(savePath, "saveddata-py3-dev.db")
# The database where the static EVE data from the datadump is kept.
# This is not the standard sqlite datadump but a modified version created by eos
@@ -100,6 +123,13 @@ def defPaths(customSavePath):
if not gameDB:
gameDB = os.path.join(pyfaPath, "eve.db")
if debug:
logFile = "pyfa_debug.log"
else:
logFile = "pyfa.log"
logPath = os.path.join(savePath, logFile)
# DON'T MODIFY ANYTHING BELOW
import eos.config
@@ -109,6 +139,100 @@ def defPaths(customSavePath):
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
print(eos.config.saveddata_connectionstring)
print(eos.config.gamedata_connectionstring)
# initialize the settings
from service.settings import EOSSettings
eos.config.settings = EOSSettings.getInstance().EOSSettings # this is kind of confusing, but whatever
def defLogging():
global debug
global logPath
global loggingLevel
global logging_setup
try:
if debug:
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
StreamHandler(
sys.stdout,
bubble=False,
level=loggingLevel
),
TimedRotatingFileHandler(
logPath,
level=0,
backup_count=3,
bubble=True,
date_format='%Y-%m-%d',
),
])
else:
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
FingersCrossedHandler(
TimedRotatingFileHandler(
logPath,
level=0,
backup_count=3,
bubble=False,
date_format='%Y-%m-%d',
),
action_level=ERROR,
buffer_size=1000,
# pull_information=True,
# reset=False,
)
])
except:
print("Critical error attempting to setup logging. Falling back to console only.")
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
StreamHandler(
sys.stdout,
bubble=False
)
])
with logging_setup.threadbound():
# Output all stdout (print) messages as warnings
try:
sys.stdout = LoggerWriter(pyfalog.warning)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
# Output all stderr (stacktrace) messages as critical
try:
sys.stderr = LoggerWriter(pyfalog.critical)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
class LoggerWriter(object):
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level
def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message.strip() != '':
self.level(message.replace("\n", ""))
def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level(sys.stderr)

View File

@@ -0,0 +1,70 @@
# -*- mode: python -*-
import os
from itertools import chain
import subprocess
label = subprocess.check_output([
"git", "describe", "--tags"]).strip()
with open('gitversion', 'w+') as f:
f.write(label.decode())
block_cipher = None
added_files = [
( 'imgs/gui/*.png', 'imgs/gui' ),
( 'imgs/gui/*.gif', 'imgs/gui' ),
( 'imgs/icons/*.png', 'imgs/icons' ),
( 'imgs/renders/*.png', 'imgs/renders' ),
( 'dist_assets/win/pyfa.ico', '.' ),
( 'dist_assets/cacert.pem', '.' ),
( 'eve.db', '.' ),
( 'README.md', '.' ),
( 'LICENSE', '.' ),
( 'gitversion', '.' ),
]
import_these = []
# Walk directories that do dynamic importing
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
for file_ in files:
if file_.endswith(".py") and not file_.startswith("_"):
mod_name = "{}.{}".format(
root.replace("/", "."),
file_.split(".py")[0],
)
import_these.append(mod_name)
a = Analysis(['pyfa.py'],
pathex=[],
binaries=[],
datas=added_files,
hiddenimports=import_these,
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='pyfa',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='pyfa')

73
dist_assets/mac/pyfa.spec Normal file
View File

@@ -0,0 +1,73 @@
# -*- mode: python -*-
import os
from itertools import chain
import subprocess
import requests.certs
label = subprocess.check_output([
"git", "describe", "--tags"]).strip()
with open('.version', 'w+') as f:
f.write(label.decode())
block_cipher = None
added_files = [
('../../imgs/gui/*.png', 'imgs/gui'),
('../../imgs/gui/*.gif', 'imgs/gui'),
('../../imgs/icons/*.png', 'imgs/icons'),
('../../imgs/renders/*.png', 'imgs/renders'),
('../../dist_assets/win/pyfa.ico', '.'),
(requests.certs.where(), '.'), # is this needed anymore?
('../../eve.db', '.'),
('../../README.md', '.'),
('../../LICENSE', '.'),
('../../.version', '.'),
]
import_these = []
# Walk directories that do dynamic importing
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
for file_ in files:
if file_.endswith(".py") and not file_.startswith("_"):
mod_name = "{}.{}".format(
root.replace("/", "."),
file_.split(".py")[0],
)
import_these.append(mod_name)
a = Analysis([r'../../pyfa.py'],
pathex=[],
binaries=[],
datas=added_files,
hiddenimports=import_these,
hookspath=['dist_assets/pyinstaller_hooks'],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='pyfa',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False ,
icon='dist_assets/mac/pyfa.icns',
)
app = BUNDLE(exe,
name='pyfa.app',
icon=None,
bundle_identifier=None)

View File

@@ -0,0 +1,78 @@
# This apes hook-matplotlib.backends.py, but REMOVES backends, all but
# the ones in the list below.
# Courtesy of https://github.com/bpteague/cytoflow/blob/70f9291/packaging/hook-matplotlib.backends.py
KEEP = ["WXAgg", "WX", "agg"]
from PyInstaller.compat import is_darwin
from PyInstaller.utils.hooks import (
eval_statement, exec_statement, logger)
def get_matplotlib_backend_module_names():
"""
List the names of all matplotlib backend modules importable under the
current Python installation.
Returns
----------
list
List of the fully-qualified names of all such modules.
"""
# Statement safely importing a single backend module.
import_statement = """
import os, sys
# Preserve stdout.
sys_stdout = sys.stdout
try:
# Redirect output printed by this importation to "/dev/null", preventing
# such output from being erroneously interpreted as an error.
with open(os.devnull, 'w') as dev_null:
sys.stdout = dev_null
__import__('%s')
# If this is an ImportError, print this exception's message without a traceback.
# ImportError messages are human-readable and require no additional context.
except ImportError as exc:
sys.stdout = sys_stdout
print(exc)
# Else, print this exception preceded by a traceback. traceback.print_exc()
# prints to stderr rather than stdout and must not be called here!
except Exception:
sys.stdout = sys_stdout
import traceback
print(traceback.format_exc())
"""
# List of the human-readable names of all available backends.
backend_names = eval_statement(
'import matplotlib; print(matplotlib.rcsetup.all_backends)')
# List of the fully-qualified names of all importable backend modules.
module_names = []
# If the current system is not OS X and the "CocoaAgg" backend is available,
# remove this backend from consideration. Attempting to import this backend
# on non-OS X systems halts the current subprocess without printing output
# or raising exceptions, preventing its reliable detection.
if not is_darwin and 'CocoaAgg' in backend_names:
backend_names.remove('CocoaAgg')
# For safety, attempt to import each backend in a unique subprocess.
for backend_name in backend_names:
if backend_name in KEEP:
continue
module_name = 'matplotlib.backends.backend_%s' % backend_name.lower()
stdout = exec_statement(import_statement % module_name)
# If no output was printed, this backend is importable.
if not stdout:
module_names.append(module_name)
logger.info(' Matplotlib backend "%s": removed' % backend_name)
return module_names
# Freeze all importable backends, as PyInstaller is unable to determine exactly
# which backends are required by the current program.
e=get_matplotlib_backend_module_names()
print(e)
excludedimports = e

View File

@@ -1,35 +1,36 @@
# -*- mode: python -*-
# Note: This script is provided AS-IS for those that may be interested.
# pyfa does not currently support pyInstaller (or any other build process) 100% at the moment
# Command line to build:
# (Run from directory where pyfa.py and pyfa.spec lives.)
# c:\Python27\scripts\pyinstaller.exe --clean --noconfirm --windowed --upx-dir=.\scripts\upx.exe pyfa.spec
# Don't forget to change the path to where your pyfa.py and pyfa.spec lives
# pathex=['C:\\Users\\Ebag333\\Documents\\GitHub\\Ebag333\\Pyfa'],
import os
from itertools import chain
import subprocess
import requests.certs
label = subprocess.check_output([
"git", "describe", "--tags"]).strip()
with open('.version', 'w+') as f:
f.write(label.decode())
block_cipher = None
added_files = [
( 'imgs/gui/*.png', 'imgs/gui' ),
( 'imgs/gui/*.gif', 'imgs/gui' ),
( 'imgs/icons/*.png', 'imgs/icons' ),
( 'imgs/renders/*.png', 'imgs/renders' ),
( 'dist_assets/win/pyfa.ico', '.' ),
( 'dist_assets/cacert.pem', '.' ),
( 'eve.db', '.' ),
( 'README.md', '.' ),
( 'LICENSE', '.' ),
('../../imgs/gui/*.png', 'imgs/gui'),
('../../imgs/gui/*.gif', 'imgs/gui'),
('../../imgs/icons/*.png', 'imgs/icons'),
('../../imgs/renders/*.png', 'imgs/renders'),
('../../dist_assets/win/pyfa.ico', '.'),
(requests.certs.where(), '.'), # is this needed anymore?
('../../eve.db', '.'),
('../../README.md', '.'),
('../../LICENSE', '.'),
('../../.version', '.'),
]
import_these = []
# Walk eos.effects and add all effects so we can import them properly
for root, folders, files in os.walk("eos/effects"):
# Walk directories that do dynamic importing
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
for file_ in files:
if file_.endswith(".py") and not file_.startswith("_"):
mod_name = "{}.{}".format(
@@ -38,25 +39,24 @@ for root, folders, files in os.walk("eos/effects"):
)
import_these.append(mod_name)
a = Analysis(
['pyfa.py'],
pathex=['C:\\projects\\pyfa\\'],
a = Analysis(['../../pyfa.py'],
pathex=[
# Need this, see https://github.com/pyinstaller/pyinstaller/issues/1566
# To get this, download and install windows 10 SDK
# If not building on Windows 10, this might be optional
r'C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86'],
binaries=[],
datas=added_files,
hiddenimports=import_these,
hookspath=[],
hookspath=['dist_assets/pyinstaller_hooks'],
runtime_hooks=[],
excludes=[],
excludes=['Tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
)
cipher=block_cipher)
pyz = PYZ(
a.pure,
a.zipped_data,
cipher=block_cipher,
)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
@@ -67,7 +67,6 @@ exe = EXE(pyz,
upx=True,
name='pyfa',
icon='dist_assets/win/pyfa.ico',
onefile=False,
)
coll = COLLECT(
@@ -77,7 +76,6 @@ coll = COLLECT(
a.datas,
strip=False,
upx=True,
onefile=False,
name='pyfa',
icon='dist_assets/win/pyfa.ico',
)
)

View File

@@ -1,6 +1,7 @@
import heapq
import time
from math import sqrt, exp
from functools import reduce
DAY = 24 * 60 * 60 * 1000
@@ -87,7 +88,7 @@ class CapSimulator(object):
mods[(duration, capNeed, clipSize, disableStagger)] = 1
# Loop over grouped modules, configure staggering and push to the simulation state
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
for (duration, capNeed, clipSize, disableStagger), amount in mods.items():
if self.stagger and not disableStagger:
if clipSize == 0:
duration = int(duration / amount)
@@ -192,7 +193,7 @@ class CapSimulator(object):
# calculate EVE's stability value
try:
avgDrain = reduce(float.__add__, map(lambda x: x[2] / x[1], self.state), 0.0)
avgDrain = reduce(float.__add__, [x[2] / x[1] for x in self.state], 0.0)
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity) / capCapacity)) ** 2
except ValueError:
self.cap_stable_eve = 0.0

View File

@@ -11,14 +11,14 @@ debug = False
gamedataCache = True
saveddataCache = True
gamedata_version = ""
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "eve.db"))
pyfalog.debug("Gamedata connection string: {0}", gamedata_connectionstring)
if istravis is True or hasattr(sys, '_called_from_test'):
# Running in Travis. Run saveddata database in memory.
saveddata_connectionstring = 'sqlite:///:memory:'
else:
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
saveddata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata-py3-db.db"))
pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring)
@@ -28,4 +28,4 @@ settings = {
}
# Autodetect path, only change if the autodetection bugs out.
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
path = dirname(__file__)

View File

@@ -22,7 +22,7 @@ import threading
from sqlalchemy import MetaData, create_engine
from sqlalchemy.orm import sessionmaker
import migration
from . import migration
from eos import config
from logbook import Logger

View File

@@ -81,7 +81,7 @@ def getItem(lookfor, eager=None):
item = gamedata_session.query(Item).get(lookfor)
else:
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
if lookfor in itemNameMap:
id = itemNameMap[lookfor]
if eager is None:
@@ -154,7 +154,7 @@ def getGroup(lookfor, eager=None):
group = gamedata_session.query(Group).get(lookfor)
else:
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
if lookfor in groupNameMap:
id = groupNameMap[lookfor]
if eager is None:
@@ -181,7 +181,7 @@ def getCategory(lookfor, eager=None):
else:
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
Category.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
if lookfor in categoryNameMap:
id = categoryNameMap[lookfor]
if eager is None:
@@ -210,7 +210,7 @@ def getMetaGroup(lookfor, eager=None):
else:
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
MetaGroup.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
if lookfor in metaGroupNameMap:
id = metaGroupNameMap[lookfor]
if eager is None:
@@ -245,7 +245,7 @@ def getMarketGroup(lookfor, eager=None):
def getItemsByCategory(filter, where=None, eager=None):
if isinstance(filter, int):
filter = Category.ID == filter
elif isinstance(filter, basestring):
elif isinstance(filter, str):
filter = Category.name == filter
else:
raise TypeError("Need integer or string as argument")
@@ -257,7 +257,7 @@ def getItemsByCategory(filter, where=None, eager=None):
@cachedQuery(3, "where", "nameLike", "join")
def searchItems(nameLike, where=None, join=None, eager=None):
if not isinstance(nameLike, basestring):
if not isinstance(nameLike, str):
raise TypeError("Need string as argument")
if join is None:
@@ -268,7 +268,7 @@ def searchItems(nameLike, where=None, join=None, eager=None):
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
for token in nameLike.split(' '):
token_safe = u"%{0}%".format(sqlizeString(token))
token_safe = "%{0}%".format(sqlizeString(token))
if where is not None:
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
else:
@@ -279,12 +279,12 @@ def searchItems(nameLike, where=None, join=None, eager=None):
@cachedQuery(3, "where", "nameLike", "join")
def searchSkills(nameLike, where=None, eager=None):
if not isinstance(nameLike, basestring):
if not isinstance(nameLike, str):
raise TypeError("Need string as argument")
items = gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category)
for token in nameLike.split(' '):
token_safe = u"%{0}%".format(sqlizeString(token))
token_safe = "%{0}%".format(sqlizeString(token))
if where is not None:
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16, where))
else:
@@ -322,7 +322,7 @@ def getVariations(itemids, groupIDs=None, where=None, eager=None):
@cachedQuery(1, "attr")
def getAttributeInfo(attr, eager=None):
if isinstance(attr, basestring):
if isinstance(attr, str):
filter = AttributeInfo.name == attr
elif isinstance(attr, int):
filter = AttributeInfo.ID == attr
@@ -337,7 +337,7 @@ def getAttributeInfo(attr, eager=None):
@cachedQuery(1, "field")
def getMetaData(field):
if isinstance(field, basestring):
if isinstance(field, str):
data = gamedata_session.query(MetaData).get(field)
else:
raise TypeError("Need string as argument")
@@ -367,7 +367,7 @@ def getRequiredFor(itemID, attrMapping):
skillToLevelClauses = []
for attrSkill, attrLevel in attrMapping.iteritems():
for attrSkill, attrLevel in attrMapping.items():
skillToLevelClauses.append(and_(Attribute1.attributeID == attrSkill, Attribute2.attributeID == attrLevel))
queryOr = or_(*skillToLevelClauses)

View File

@@ -3,7 +3,7 @@ import shutil
import time
import config
import migrations
from . import migrations
pyfalog = Logger(__name__)
@@ -34,7 +34,7 @@ def update(saveddata_engine):
shutil.copyfile(config.saveDB, toFile)
for version in xrange(dbVersion, appVersion):
for version in range(dbVersion, appVersion):
func = migrations.updates[version + 1]
if func:
pyfalog.info("Applying database update: {0}", version + 1)

View File

@@ -15,7 +15,27 @@ updates = {}
appVersion = 0
prefix = __name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
# load modules to work based with and without pyinstaller
# from: https://github.com/webcomics/dosage/blob/master/dosagelib/loader.py
# see: https://github.com/pyinstaller/pyinstaller/issues/1905
# load modules using iter_modules()
# (should find all filters in normal build, but not pyinstaller)
module_names = [m[1] for m in pkgutil.iter_modules(__path__, prefix)]
# special handling for PyInstaller
importers = map(pkgutil.get_importer, __path__)
toc = set()
for i in importers:
if hasattr(i, 'toc'):
toc |= i.toc
for elm in toc:
if elm.startswith(prefix):
module_names.append(elm)
for modname in module_names:
# loop through python files, extracting update number and function, and
# adding it to a list
modname_tail = modname.rsplit('.', 1)[-1]

View File

@@ -91,7 +91,7 @@ def upgrade(saveddata_engine):
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;")
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -108,7 +108,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -332,7 +332,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -60,7 +60,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -29,7 +29,7 @@ def upgrade(saveddata_engine):
"targetResists": 2
}
for table in tables.keys():
for table in list(tables.keys()):
# midnight brain, there's probably a much more simple way to do this, but fuck it
if tables[table] > 0:

View File

@@ -4204,7 +4204,7 @@ conversion2 = {
def upgrade(saveddata_engine):
# First we want to get a list of fittings that are completely fitted out with subsystems
oldItems = [str(x) for x in conversion2.iterkeys()]
oldItems = [str(x) for x in conversion2.keys()]
# I can't figure out a way to get IN operator to work when supplying a list using a parameterized query. So I'm
# doing it the shitty way by formatting the SQL string. Don't do this kids!
@@ -4239,7 +4239,7 @@ def upgrade(saveddata_engine):
# if something fails, fuck it, we tried. It'll default to the generic conversion below
continue
for oldItem, newItem in conversion2.iteritems():
for oldItem, newItem in conversion2.items():
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(newItem, oldItem))
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',

View File

@@ -133,7 +133,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -17,7 +17,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert ships
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?',
(replacement_item, retired_item))

View File

@@ -77,7 +77,7 @@ CONVERSIONS = {
def upgrade(saveddata_engine):
# Convert modules
for replacement_item, list in CONVERSIONS.iteritems():
for replacement_item, list in CONVERSIONS.items():
for retired_item in list:
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
(replacement_item, retired_item))

View File

@@ -109,9 +109,9 @@ if configVal is True:
if type not in queryCache:
return
functionCache = queryCache[type]
for _, localCache in functionCache.iteritems():
for _, localCache in functionCache.items():
toDelete = set()
for cacheKey, info in localCache.iteritems():
for cacheKey, info in localCache.items():
IDs = info[1]
if ID in IDs:
toDelete.add(cacheKey)
@@ -156,7 +156,7 @@ def getUser(lookfor, eager=None):
eager = processEager(eager)
with sd_lock:
user = saveddata_session.query(User).options(*eager).filter(User.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
user = saveddata_session.query(User).options(*eager).filter(User.username == lookfor).first()
@@ -175,7 +175,7 @@ def getCharacter(lookfor, eager=None):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(Character).options(*eager).filter(Character.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(Character).options(*eager).filter(
@@ -337,7 +337,7 @@ def clearPrices():
def getMiscData(field):
if isinstance(field, basestring):
if isinstance(field, str):
with sd_lock:
data = saveddata_session.query(MiscData).get(field)
else:
@@ -391,7 +391,7 @@ def getDamagePattern(lookfor, eager=None):
with sd_lock:
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
DamagePattern.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
@@ -412,7 +412,7 @@ def getTargetResists(lookfor, eager=None):
with sd_lock:
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
TargetResists.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
@@ -433,7 +433,7 @@ def getImplantSet(lookfor, eager=None):
with sd_lock:
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(
TargetResists.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.name == lookfor).first()
@@ -443,10 +443,10 @@ def getImplantSet(lookfor, eager=None):
def searchFits(nameLike, where=None, eager=None):
if not isinstance(nameLike, basestring):
if not isinstance(nameLike, str):
raise TypeError("Need string as argument")
# Prepare our string for request
nameLike = u"%{0}%".format(sqlizeString(nameLike))
nameLike = "%{0}%".format(sqlizeString(nameLike))
# Add any extra components to the search to our where clause
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
@@ -484,7 +484,7 @@ def getCrestCharacter(lookfor, eager=None):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
elif isinstance(lookfor, basestring):
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
@@ -515,8 +515,8 @@ def removeInvalid(fits):
invalids = [f for f in fits if f.isInvalid]
if invalids:
map(fits.remove, invalids)
map(saveddata_session.delete, invalids)
list(map(fits.remove, invalids))
list(map(saveddata_session.delete, invalids))
saveddata_session.commit()
return fits
@@ -547,4 +547,4 @@ def commit():
except Exception:
saveddata_session.rollback()
exc_info = sys.exc_info()
raise exc_info[0], exc_info[1], exc_info[2]
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])

View File

@@ -39,7 +39,7 @@ def processEager(eager):
return tuple()
else:
l = []
if isinstance(eager, basestring):
if isinstance(eager, str):
eager = (eager,)
for e in eager:
@@ -50,7 +50,7 @@ def processEager(eager):
def _replacements(eagerString):
splitEager = eagerString.split(".")
for i in xrange(len(splitEager)):
for i in range(len(splitEager)):
part = splitEager[i]
replacement = replace.get(part)
if replacement:

View File

@@ -115,7 +115,7 @@ class HandledList(list):
class HandledModuleList(HandledList):
def append(self, mod):
emptyPosition = float("Inf")
for i in xrange(len(self)):
for i in range(len(self)):
currMod = self[i]
if currMod.isEmpty and not mod.isEmpty and currMod.slot == mod.slot:
currPos = mod.position or i
@@ -149,7 +149,7 @@ class HandledModuleList(HandledList):
oldPos = mod.position
mod.position = None
for i in xrange(oldPos, len(self)):
for i in range(oldPos, len(self)):
self[i].position -= 1
def toDummy(self, index):

View File

@@ -10,4 +10,6 @@ type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("capacitorCapacity", module.getModifiedItemAttr("capacitorCapacityMultiplier"))
# We default this to None as there are times when the source attribute doesn't exist (for example, Cap Power Relay).
# It will return 0 as it doesn't exist, which would nullify whatever the target attribute is
fit.ship.multiplyItemAttr("capacitorCapacity", module.getModifiedItemAttr("capacitorCapacityMultiplier", None))

View File

@@ -6,6 +6,6 @@ type = "active"
def handler(fit, module, context):
for x in xrange(1, 4):
for x in range(1, 4):
value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x))
module.multiplyItemAttr("warfareBuff{}Value".format(x), value)

View File

@@ -8,7 +8,7 @@ type = "passive"
def handler(fit, container, context):
level = container.level if "skill" in context else 1
for i in xrange(5):
for i in range(5):
attr = "boosterEffectChance{0}".format(i + 1)
fit.boosters.filteredItemBoost(lambda booster: attr in booster.itemModifiedAttributes,
attr, container.getModifiedItemAttr("boosterChanceBonus") * level)

View File

@@ -16,7 +16,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))

View File

@@ -7,7 +7,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))

View File

@@ -7,7 +7,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))

View File

@@ -7,7 +7,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))

View File

@@ -7,7 +7,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x))

View File

@@ -6,7 +6,7 @@ type = "active", "gang"
def handler(fit, module, context, **kwargs):
for x in xrange(1, 5):
for x in range(1, 5):
if module.getModifiedItemAttr("warfareBuff{}ID".format(x)):
value = module.getModifiedItemAttr("warfareBuff{}Value".format(x))
id = module.getModifiedItemAttr("warfareBuff{}ID".format(x))

View File

@@ -9,4 +9,6 @@ type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("powerOutput", module.getModifiedItemAttr("powerOutputMultiplier"))
# We default this to None as there are times when the source attribute doesn't exist (for example, Cap Power Relay).
# It will return 0 as it doesn't exist, which would nullify whatever the target attribute is
fit.ship.multiplyItemAttr("powerOutput", module.getModifiedItemAttr("powerOutputMultiplier", None))

View File

@@ -9,4 +9,6 @@ type = "passive"
def handler(fit, module, context):
fit.ship.multiplyItemAttr("shieldCapacity", module.getModifiedItemAttr("shieldCapacityMultiplier"))
# We default this to None as there are times when the source attribute doesn't exist (for example, Cap Power Relay).
# It will return 0 as it doesn't exist, which would nullify whatever the target attribute is
fit.ship.multiplyItemAttr("shieldCapacity", module.getModifiedItemAttr("shieldCapacityMultiplier", None))

View File

@@ -4,5 +4,5 @@ runTime = "late"
def handler(fit, module, context):
for x in xrange(1, 4):
for x in range(1, 4):
module.boostChargeAttr("warfareBuff{}Multiplier".format(x), module.getModifiedItemAttr("commandBurstStrengthBonus"))

View File

@@ -58,7 +58,7 @@ def rel_listener(target, value, initiator):
if not target or (isinstance(value, Module) and value.isEmpty):
return
print "{} has had a relationship change :D".format(target)
print("{} has had a relationship change :D".format(target))
target.modified = datetime.datetime.now()

View File

@@ -22,13 +22,10 @@ import re
from sqlalchemy.orm import reconstructor
import eos.db
from eqBase import EqBase
from .eqBase import EqBase
from eos.saveddata.price import Price as types_Price
from collections import OrderedDict
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
from logbook import Logger
@@ -160,8 +157,6 @@ class Effect(EqBase):
if it doesn't, set dummy values and add a dummy handler
"""
pyfalog.debug("Generate effect handler for {}".format(self.name))
try:
self.__effectModule = effectModule = __import__('eos.effects.' + self.handlerName, fromlist=True)
self.__handler = getattr(effectModule, "handler", effectDummy)
@@ -258,7 +253,7 @@ class Item(EqBase):
return default
def isType(self, type):
for effect in self.effects.itervalues():
for effect in self.effects.values():
if effect.isType(type):
return True
@@ -299,7 +294,7 @@ class Item(EqBase):
self.__requiredSkills = requiredSkills
# Map containing attribute IDs we may need for required skills
# { requiredSkillX : requiredSkillXLevel }
combinedAttrIDs = set(self.srqIDMap.iterkeys()).union(set(self.srqIDMap.itervalues()))
combinedAttrIDs = set(self.srqIDMap.keys()).union(set(self.srqIDMap.values()))
# Map containing result of the request
# { attributeID : attributeValue }
skillAttrs = {}
@@ -309,7 +304,7 @@ class Item(EqBase):
attrVal = attrInfo[2]
skillAttrs[attrID] = attrVal
# Go through all attributeID pairs
for srqIDAtrr, srqLvlAttr in self.srqIDMap.iteritems():
for srqIDAtrr, srqLvlAttr in self.srqIDMap.items():
# Check if we have both in returned result
if srqIDAtrr in skillAttrs and srqLvlAttr in skillAttrs:
skillID = int(skillAttrs[srqIDAtrr])
@@ -383,7 +378,7 @@ class Item(EqBase):
race = None
# Check primary and secondary required skills' races
if race is None:
skillRaces = tuple(filter(lambda rid: rid, (s.raceID for s in tuple(self.requiredSkills.keys()))))
skillRaces = tuple([rid for rid in (s.raceID for s in tuple(self.requiredSkills.keys())) if rid])
if sum(skillRaces) in map:
race = map[sum(skillRaces)]
if race == "angelserp":
@@ -405,7 +400,7 @@ class Item(EqBase):
if self.__assistive is None:
assistive = False
# Go through all effects and find first assistive
for effect in self.effects.itervalues():
for effect in self.effects.values():
if effect.isAssistance is True:
# If we find one, stop and mark item as assistive
assistive = True
@@ -420,7 +415,7 @@ class Item(EqBase):
if self.__offensive is None:
offensive = False
# Go through all effects and find first offensive
for effect in self.effects.itervalues():
for effect in self.effects.values():
if effect.isOffensive is True:
# If we find one, stop and mark item as offensive
offensive = True
@@ -429,8 +424,8 @@ class Item(EqBase):
return self.__offensive
def requiresSkill(self, skill, level=None):
for s, l in self.requiredSkills.iteritems():
if isinstance(skill, basestring):
for s, l in self.requiredSkills.items():
if isinstance(skill, str):
if s.name == skill and (level is None or l == level):
return True
@@ -468,7 +463,7 @@ class Item(EqBase):
return self.__price
def __repr__(self):
return u"Item(ID={}, name={}) at {}".format(
return "Item(ID={}, name={}) at {}".format(
self.ID, self.name, hex(id(self))
)
@@ -522,9 +517,9 @@ class Icon(EqBase):
class MarketGroup(EqBase):
def __repr__(self):
return u"MarketGroup(ID={}, name={}, parent={}) at {}".format(
return "MarketGroup(ID={}, name={}, parent={}) at {}".format(
self.ID, self.name, getattr(self.parent, "name", None), self.name, hex(id(self))
).encode('utf8')
)
class MetaGroup(EqBase):

View File

@@ -25,7 +25,7 @@ class Graph(object):
self.fit = fit
self.data = {}
if data is not None:
for name, d in data.iteritems():
for name, d in data.items():
self.setData(Data(name, d))
self.function = function
@@ -39,7 +39,7 @@ class Graph(object):
def getIterator(self):
pointNames = []
pointIterators = []
for data in self.data.itervalues():
for data in self.data.values():
pointNames.append(data.name)
pointIterators.append(data)
@@ -48,7 +48,7 @@ class Graph(object):
def _iterator(self, pointNames, pointIterators):
for pointValues in itertools.product(*pointIterators):
point = {}
for i in xrange(len(pointValues)):
for i in range(len(pointValues)):
point[pointNames[i]] = pointValues[i]
yield point, self.function(point)
@@ -61,12 +61,12 @@ class Data(object):
self.data = self.parseString(dataString)
def parseString(self, dataString):
if not isinstance(dataString, basestring):
if not isinstance(dataString, str):
return Constant(dataString),
dataList = []
for data in dataString.split(";"):
if isinstance(data, basestring) and "-" in data:
if isinstance(data, str) and "-" in data:
# Dealing with a range
dataList.append(Range(data, self.step))
else:
@@ -85,7 +85,7 @@ class Data(object):
class Constant(object):
def __init__(self, const):
if isinstance(const, basestring):
if isinstance(const, str):
self.value = None if const == "" else float(const)
else:
self.value = const

View File

@@ -63,10 +63,10 @@ class FitDpsGraph(Graph):
ew['signatureRadius'].sort(key=abssort)
ew['velocity'].sort(key=abssort)
for attr, values in ew.iteritems():
for attr, values in ew.items():
val = data[attr]
try:
for i in xrange(len(values)):
for i in range(len(values)):
bonus = values[i]
val *= 1 + (bonus - 1) * exp(- i ** 2 / 7.1289)
data[attr] = val

View File

@@ -28,23 +28,17 @@ cappingAttrKeyCache = {}
class ItemAttrShortcut(object):
def getModifiedItemAttr(self, key, default=None):
def getModifiedItemAttr(self, key, default=0):
return_value = self.itemModifiedAttributes.get(key)
if return_value is None and default is not None:
return_value = default
return return_value
return return_value or default
class ChargeAttrShortcut(object):
def getModifiedChargeAttr(self, key, default=None):
def getModifiedChargeAttr(self, key, default=0):
return_value = self.chargeModifiedAttributes.get(key)
if return_value is None and default is not None:
return_value = default
return return_value
return return_value or default
class ModifiedAttributeDict(collections.MutableMapping):
@@ -165,9 +159,9 @@ class ModifiedAttributeDict(collections.MutableMapping):
def __len__(self):
keys = set()
keys.update(self.original.iterkeys())
keys.update(self.__modified.iterkeys())
keys.update(self.__intermediary.iterkeys())
keys.update(iter(self.original.keys()))
keys.update(iter(self.__modified.keys()))
keys.update(iter(self.__intermediary.keys()))
return len(keys)
def __calculateValue(self, key):
@@ -231,11 +225,11 @@ class ModifiedAttributeDict(collections.MutableMapping):
val *= multiplier
# Each group is penalized independently
# Things in different groups will not be stack penalized between each other
for penalizedMultipliers in penalizedMultiplierGroups.itervalues():
for penalizedMultipliers in penalizedMultiplierGroups.values():
# A quick explanation of how this works:
# 1: Bonuses and penalties are calculated seperately, so we'll have to filter each of them
l1 = filter(lambda _val: _val > 1, penalizedMultipliers)
l2 = filter(lambda _val: _val < 1, penalizedMultipliers)
l1 = [_val for _val in penalizedMultipliers if _val > 1]
l2 = [_val for _val in penalizedMultipliers if _val < 1]
# 2: The most significant bonuses take the smallest penalty,
# This means we'll have to sort
abssort = lambda _val: -abs(_val - 1)
@@ -245,7 +239,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
# Any module after the first takes penalties according to:
# 1 + (multiplier - 1) * math.exp(- math.pow(i, 2) / 7.1289)
for l in (l1, l2):
for i in xrange(len(l)):
for i in range(len(l)):
bonus = l[i]
val *= 1 + (bonus - 1) * exp(- i ** 2 / 7.1289)
val += postIncrease
@@ -388,7 +382,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
"""Force value to attribute and prohibit any changes to it"""
self.__forced[attributeName] = value
self.__placehold(attributeName)
self.__afflict(attributeName, u"\u2263", value)
self.__afflict(attributeName, "\u2263", value)
@staticmethod
def getResistance(fit, effect):

View File

@@ -116,7 +116,7 @@ class Booster(HandledItem, ItemAttrShortcut):
if not self.active:
return
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and \
(effect.isType("passive") or effect.isType("boosterSideEffect")):
if effect.isType("boosterSideEffect") and effect not in self.activeSideEffectEffects:

View File

@@ -39,7 +39,7 @@ class BoosterSideEffect(object):
self.__effect = None
if self.effectID:
self.__effect = next((x for x in self.booster.item.effects.itervalues() if x.ID == self.effectID), None)
self.__effect = next((x for x in self.booster.item.effects.values() if x.ID == self.effectID), None)
if self.__effect is None:
pyfalog.error("Effect (id: {0}) does not exist", self.effectID)
return

View File

@@ -77,8 +77,8 @@ class Cargo(HandledItem, ItemAttrShortcut):
"amount": lambda _val: isinstance(_val, int)
}
if key == "amount" and val > sys.maxint:
val = sys.maxint
if key == "amount" and val > sys.maxsize:
val = sys.maxsize
if not map[key](val):
raise ValueError(str(val) + " is not a valid value for " + key)

View File

@@ -158,7 +158,7 @@ class Character(object):
name += " *"
if self.alphaCloneID:
name += u' (\u03B1)'
name += ' (\u03B1)'
return name
@@ -195,7 +195,7 @@ class Character(object):
del self.__skillIdMap[skill.itemID]
def getSkill(self, item):
if isinstance(item, basestring):
if isinstance(item, str):
item = self.getSkillNameMap()[item]
elif isinstance(item, int):
item = self.getSkillIDMap()[item]
@@ -278,7 +278,7 @@ class Character(object):
map = {
"ID" : lambda _val: isinstance(_val, int),
"name" : lambda _val: True,
"apiKey" : lambda _val: _val is None or (isinstance(_val, basestring) and len(_val) > 0),
"apiKey" : lambda _val: _val is None or (isinstance(_val, str) and len(_val) > 0),
"ownerID": lambda _val: isinstance(_val, int) or _val is None
}
@@ -340,13 +340,13 @@ class Skill(HandledItem):
elif self.character.name == "All 0":
self.activeLevel = self.__level = 0
elif self.character.alphaClone:
return min(self.activeLevel, self.character.alphaClone.getSkillLevel(self)) or 0
return min(self.activeLevel or 0, self.character.alphaClone.getSkillLevel(self) or 0)
return self.activeLevel or 0
def setLevel(self, level, persist=False, ignoreRestrict=False):
if (level < 0 or level > 5) and level is not None:
if level is not None and (level < 0 or level > 5):
raise ValueError(str(level) + " is not a valid value for level")
if hasattr(self, "_Skill__ro") and self.__ro is True:
@@ -358,9 +358,9 @@ class Skill(HandledItem):
# which affects performance. Should have a checkSkillLevels() or something that is more efficient for bulk.
if not ignoreRestrict and eos.config.settings['strictSkillLevels']:
start = time.time()
for item, rlevel in self.item.requiredFor.iteritems():
for item, rlevel in self.item.requiredFor.items():
if item.group.category.ID == 16: # Skill category
if level < rlevel:
if level is None or level < rlevel:
skill = self.character.getSkill(item.ID)
# print "Removing skill: {}, Dependant level: {}, Required level: {}".format(skill, level, rlevel)
skill.setLevel(None, persist)
@@ -388,7 +388,7 @@ class Skill(HandledItem):
if key in self.item.attributes:
return self.item.attributes[key].value
else:
return None
return 0
def calculateModifiedAttributes(self, fit, runTime):
if self.__suppressed: # or not self.learned - removed for GH issue 101
@@ -398,7 +398,7 @@ class Skill(HandledItem):
if item is None:
return
for effect in item.effects.itervalues():
for effect in item.effects.values():
if effect.runTime == runTime and \
effect.isType("passive") and \
(not fit.isStructure or effect.isType("structure")) and \

View File

@@ -73,7 +73,8 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__chargeModifiedAttributes = ModifiedAttributeDict()
chargeID = self.getModifiedItemAttr("entityMissileTypeID")
# pheonix todo: check the attribute itself, not the modified. this will always return 0 now.
chargeID = self.getModifiedItemAttr("entityMissileTypeID", None)
if chargeID is not None:
charge = eos.db.getItem(int(chargeID))
self.__charge = charge
@@ -102,7 +103,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
@property
def cycleTime(self):
return max(self.getModifiedItemAttr("duration"), 0)
return max(self.getModifiedItemAttr("duration", 0), 0)
@property
def dealsDamage(self):
@@ -138,8 +139,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
cycleTime = self.getModifiedItemAttr(attr)
volley = sum(
map(lambda d: (getter("%sDamage" % d) or 0) * (1 - getattr(targetResists, "%sAmount" % d, 0)),
self.DAMAGE_TYPES))
[(getter("%sDamage" % d) or 0) * (1 - getattr(targetResists, "%sAmount" % d, 0)) for d in self.DAMAGE_TYPES])
volley *= self.amountActive
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
self.__volley = volley
@@ -155,7 +155,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
getter = self.getModifiedItemAttr
cycleTime = self.getModifiedItemAttr(attr)
volley = sum(map(lambda d: getter(d), self.MINING_ATTRIBUTES)) * self.amountActive
volley = sum([getter(d) for d in self.MINING_ATTRIBUTES]) * self.amountActive
self.__miningyield = volley / (cycleTime / 1000.0)
else:
self.__miningyield = 0
@@ -168,7 +168,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
"energyDestabilizationRange", "empFieldRange",
"ecmBurstRange", "maxRange")
for attr in attrs:
maxRange = self.getModifiedItemAttr(attr)
maxRange = self.getModifiedItemAttr(attr, None)
if maxRange is not None:
return maxRange
if self.charge is not None:
@@ -184,7 +184,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def falloff(self):
attrs = ("falloff", "falloffEffectiveness")
for attr in attrs:
falloff = self.getModifiedItemAttr(attr)
falloff = self.getModifiedItemAttr(attr, None)
if falloff is not None:
return falloff
@@ -236,7 +236,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
context = ("drone",)
projected = False
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and \
effect.activeByDefault and \
((projected is True and effect.isType("projected")) or
@@ -251,7 +251,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
i += 1
if self.charge:
for effect in self.charge.effects.itervalues():
for effect in self.charge.effects.values():
if effect.runTime == runTime and effect.activeByDefault:
effect.handler(fit, self, ("droneCharge",))
@@ -263,8 +263,8 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def fits(self, fit):
fitDroneGroupLimits = set()
for i in xrange(1, 3):
groneGrp = fit.ship.getModifiedItemAttr("allowedDroneGroup%d" % i)
for i in range(1, 3):
groneGrp = fit.ship.getModifiedItemAttr("allowedDroneGroup%d" % i, None)
if groneGrp is not None:
fitDroneGroupLimits.add(int(groneGrp))
if len(fitDroneGroupLimits) == 0:

View File

@@ -98,7 +98,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def __getAbilities(self):
"""Returns list of FighterAbilities that are loaded with data"""
return [FighterAbility(effect) for effect in self.item.effects.values()]
return [FighterAbility(effect) for effect in list(self.item.effects.values())]
def __calculateSlot(self, item):
types = {
@@ -110,7 +110,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
"StandupHeavy": Slot.FS_HEAVY
}
for t, slot in types.iteritems():
for t, slot in types.items():
if self.getModifiedItemAttr("fighterSquadronIs{}".format(t)):
return slot
@@ -202,12 +202,12 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
"energyDestabilizationRange", "empFieldRange",
"ecmBurstRange", "maxRange")
for attr in attrs:
maxRange = self.getModifiedItemAttr(attr)
maxRange = self.getModifiedItemAttr(attr, None)
if maxRange is not None:
return maxRange
if self.charge is not None:
delay = self.getModifiedChargeAttr("explosionDelay")
speed = self.getModifiedChargeAttr("maxVelocity")
delay = self.getModifiedChargeAttr("explosionDelay", None)
speed = self.getModifiedChargeAttr("maxVelocity", None)
if delay is not None and speed is not None:
return delay / 1000.0 * speed
@@ -218,7 +218,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def falloff(self):
attrs = ("falloff", "falloffEffectiveness")
for attr in attrs:
falloff = self.getModifiedItemAttr(attr)
falloff = self.getModifiedItemAttr(attr, None)
if falloff is not None:
return falloff

View File

@@ -57,7 +57,7 @@ class FighterAbility(object):
self.__effect = None
if self.effectID:
self.__effect = next((x for x in self.fighter.item.effects.itervalues() if x.ID == self.effectID), None)
self.__effect = next((x for x in self.fighter.item.effects.values() if x.ID == self.effectID), None)
if self.__effect is None:
pyfalog.error("Effect (id: {0}) does not exist", self.effectID)
return
@@ -127,8 +127,8 @@ class FighterAbility(object):
if self.attrPrefix == "fighterAbilityLaunchBomb":
# bomb calcs
volley = sum(map(lambda attr: (self.fighter.getModifiedChargeAttr("%sDamage" % attr) or 0) * (
1 - getattr(targetResists, "%sAmount" % attr, 0)), self.DAMAGE_TYPES))
volley = sum([(self.fighter.getModifiedChargeAttr("%sDamage" % attr) or 0) * (
1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES])
else:
volley = sum(map(lambda d2, d:
(self.fighter.getModifiedItemAttr(

View File

@@ -258,11 +258,11 @@ class Fit(object):
def projectedFits(self):
# only in extreme edge cases will the fit be invalid, but to be sure do
# not return them.
return [fit for fit in self.__projectedFits.values() if not fit.isInvalid]
return [fit for fit in list(self.__projectedFits.values()) if not fit.isInvalid]
@property
def commandFits(self):
return [fit for fit in self.__commandFits.values() if not fit.isInvalid]
return [fit for fit in list(self.__commandFits.values()) if not fit.isInvalid]
def getProjectionInfo(self, fitID):
return self.projectedOnto.get(fitID, None)
@@ -492,7 +492,7 @@ class Fit(object):
def __runCommandBoosts(self, runTime="normal"):
pyfalog.debug("Applying gang boosts for {0}", repr(self))
for warfareBuffID in self.commandBonuses.keys():
for warfareBuffID in list(self.commandBonuses.keys()):
# Unpack all data required to run effect properly
effect_runTime, value, thing, effect = self.commandBonuses[warfareBuffID]
@@ -676,7 +676,7 @@ class Fit(object):
def __resetDependentCalcs(self):
self.calculated = False
for value in self.projectedOnto.values():
for value in list(self.projectedOnto.values()):
if value.victim_fit: # removing a self-projected fit causes victim fit to be None. @todo: look into why. :3
value.victim_fit.calculated = False
@@ -707,14 +707,14 @@ class Fit(object):
self.__resetDependentCalcs()
# For fits that are under local's Command, we do the same thing
for value in self.boostedOnto.values():
for value in list(self.boostedOnto.values()):
# apparently this is a thing that happens when removing a command fit from a fit and then switching to
# that command fit. Same as projected clears, figure out why.
if value.boosted_fit:
value.boosted_fit.__resetDependentCalcs()
if targetFit and type == CalcType.PROJECTED:
pyfalog.debug(u"Calculating projections from {0} to target {1}", repr(self), repr(targetFit))
pyfalog.debug("Calculating projections from {0} to target {1}", repr(self), repr(targetFit))
projectionInfo = self.getProjectionInfo(targetFit.ID)
# Start applying any command fits that we may have.
@@ -756,7 +756,7 @@ class Fit(object):
# Loop through our run times here. These determine which effects are run in which order.
for runTime in ("early", "normal", "late"):
pyfalog.debug("Run time: {0}", runTime)
# pyfalog.debug("Run time: {0}", runTime)
# Items that are unrestricted. These items are run on the local fit
# first and then projected onto the target fit it one is designated
u = [
@@ -795,7 +795,7 @@ class Fit(object):
# targetFit.register(item, origin=self)
item.calculateModifiedAttributes(targetFit, runTime, False, True)
pyfalog.debug("Command Bonuses: {}".format(self.commandBonuses))
# pyfalog.debug("Command Bonuses: {}".format(self.commandBonuses))
# If we are calculating our local or projected fit and have command bonuses, apply them
if type != CalcType.COMMAND and self.commandBonuses:
@@ -838,7 +838,7 @@ class Fit(object):
for item in c:
if item is not None:
# apply effects onto target fit x amount of times
for _ in xrange(projectionInfo.amount):
for _ in range(projectionInfo.amount):
targetFit.register(item, origin=self)
item.calculateModifiedAttributes(targetFit, runTime, True)
@@ -854,7 +854,7 @@ class Fit(object):
for slotType in (Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM, Slot.SERVICE):
amount = self.getSlotsFree(slotType, True)
if amount > 0:
for _ in xrange(int(amount)):
for _ in range(int(amount)):
self.modules.append(Module.buildEmpty(slotType))
if amount < 0:
@@ -870,7 +870,7 @@ class Fit(object):
self.modules.remove(mod)
def unfill(self):
for i in xrange(len(self.modules) - 1, -1, -1):
for i in range(len(self.modules) - 1, -1, -1):
mod = self.modules[i]
if mod.isEmpty:
del self.modules[i]
@@ -878,7 +878,7 @@ class Fit(object):
@property
def modCount(self):
x = 0
for i in xrange(len(self.modules) - 1, -1, -1):
for i in range(len(self.modules) - 1, -1, -1):
mod = self.modules[i]
if not mod.isEmpty:
x += 1
@@ -1488,11 +1488,11 @@ class Fit(object):
return copy_ship
def __repr__(self):
return u"Fit(ID={}, ship={}, name={}) at {}".format(
return "Fit(ID={}, ship={}, name={}) at {}".format(
self.ID, self.ship.item.name, self.name, hex(id(self))
).encode('utf8')
)
def __str__(self):
return u"{} ({})".format(
return "{} ({})".format(
self.name, self.ship.item.name
).encode('utf8')
)

View File

@@ -93,7 +93,7 @@ class Implant(HandledItem, ItemAttrShortcut):
return
if not self.active:
return
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and effect.isType("passive") and effect.activeByDefault:
effect.handler(fit, self, ("implant",))

View File

@@ -50,6 +50,6 @@ class Mode(ItemAttrShortcut, HandledItem):
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
if self.item:
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and effect.activeByDefault:
effect.handler(fit, self, context=("module",))

View File

@@ -182,7 +182,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
@property
def numShots(self):
if self.charge is None:
return None
return -1
if self.__chargeCycles is None and self.charge:
numCharges = self.numCharges
# Usual ammo like projectiles and missiles
@@ -217,7 +217,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
armorRep = self.getModifiedItemAttr("armorDamageAmount") or 0
shieldRep = self.getModifiedItemAttr("shieldBonus") or 0
if not cycles or (not armorRep and not shieldRep):
return None
return 0
hp = round((armorRep + shieldRep) * cycles)
return hp
@@ -255,7 +255,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
"ecmBurstRange", "warpScrambleRange", "cargoScanRange",
"shipScanRange", "surveyScanRange")
for attr in attrs:
maxRange = self.getModifiedItemAttr(attr)
maxRange = self.getModifiedItemAttr(attr, None)
if maxRange is not None:
return maxRange
if self.charge is not None:
@@ -284,7 +284,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def falloff(self):
attrs = ("falloffEffectiveness", "falloff", "shipScanFalloff")
for attr in attrs:
falloff = self.getModifiedItemAttr(attr)
falloff = self.getModifiedItemAttr(attr, None)
if falloff is not None:
return falloff
@@ -333,9 +333,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
else:
func = self.getModifiedItemAttr
volley = sum(map(
lambda attr: (func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)),
self.DAMAGE_TYPES))
volley = sum([(func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES])
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
if volley:
cycleTime = self.cycleTime
@@ -415,19 +413,19 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
fitsOnType = set()
fitsOnGroup = set()
shipType = self.getModifiedItemAttr("fitsToShipType")
shipType = self.getModifiedItemAttr("fitsToShipType", None)
if shipType is not None:
fitsOnType.add(shipType)
for attr in self.itemModifiedAttributes.keys():
for attr in list(self.itemModifiedAttributes.keys()):
if attr.startswith("canFitShipType"):
shipType = self.getModifiedItemAttr(attr)
shipType = self.getModifiedItemAttr(attr, None)
if shipType is not None:
fitsOnType.add(shipType)
for attr in self.itemModifiedAttributes.keys():
for attr in list(self.itemModifiedAttributes.keys()):
if attr.startswith("canFitShipGroup"):
shipGroup = self.getModifiedItemAttr(attr)
shipGroup = self.getModifiedItemAttr(attr, None)
if shipGroup is not None:
fitsOnGroup.add(shipGroup)
@@ -459,7 +457,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
return False
# Check max group fitted
max = self.getModifiedItemAttr("maxGroupFitted")
max = self.getModifiedItemAttr("maxGroupFitted", None)
if max is not None:
current = 0 # if self.owner != fit else -1 # Disabled, see #1278
for mod in fit.modules:
@@ -472,11 +470,10 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
# Check this only if we're told to do so
if hardpointLimit:
if self.hardpoint == Hardpoint.TURRET:
if (fit.ship.getModifiedItemAttr('turretSlotsLeft') or 0) - fit.getHardpointsUsed(Hardpoint.TURRET) < 1:
if fit.ship.getModifiedItemAttr('turretSlotsLeft') - fit.getHardpointsUsed(Hardpoint.TURRET) < 1:
return False
elif self.hardpoint == Hardpoint.MISSILE:
if (fit.ship.getModifiedItemAttr('launcherSlotsLeft') or 0) - fit.getHardpointsUsed(
Hardpoint.MISSILE) < 1:
if fit.ship.getModifiedItemAttr('launcherSlotsLeft') - fit.getHardpointsUsed(Hardpoint.MISSILE) < 1:
return False
return True
@@ -506,7 +503,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
return True
# Check if the local module is over it's max limit; if it's not, we're fine
maxGroupActive = self.getModifiedItemAttr("maxGroupActive")
maxGroupActive = self.getModifiedItemAttr("maxGroupActive", None)
if maxGroupActive is None and projectedOnto is None:
return True
@@ -554,7 +551,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
chargeGroup = charge.groupID
for i in range(5):
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i))
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None)
if itemChargeGroup is None:
continue
if itemChargeGroup == chargeGroup:
@@ -565,7 +562,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def getValidCharges(self):
validCharges = set()
for i in range(5):
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i))
itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None)
if itemChargeGroup is not None:
g = eos.db.getGroup(int(itemChargeGroup), eager=("items.icon", "items.attributes"))
if g is None:
@@ -586,7 +583,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if item is None:
return Hardpoint.NONE
for effectName, slot in effectHardpointMap.iteritems():
for effectName, slot in effectHardpointMap.items():
if effectName in item.effects:
return slot
@@ -604,7 +601,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
}
if item is None:
return None
for effectName, slot in effectSlotMap.iteritems():
for effectName, slot in effectSlotMap.items():
if effectName in item.effects:
return slot
if item.group.name == "Effect Beacon":
@@ -658,7 +655,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if self.charge is not None:
# fix for #82 and it's regression #106
if not projected or (self.projected and not forceProjected) or gang:
for effect in self.charge.effects.itervalues():
for effect in self.charge.effects.values():
if effect.runTime == runTime and \
effect.activeByDefault and \
(effect.isType("offline") or
@@ -677,7 +674,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if self.item:
if self.state >= State.OVERHEATED:
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and \
effect.isType("overheat") \
and not forceProjected \
@@ -685,7 +682,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
and ((gang and effect.isType("gang")) or not gang):
effect.handler(fit, self, context)
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and \
effect.activeByDefault and \
(effect.isType("offline") or
@@ -744,13 +741,12 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
@property
def rawCycleTime(self):
speed = max(
self.getModifiedItemAttr("speed"), # Most weapons
self.getModifiedItemAttr("duration"), # Most average modules
self.getModifiedItemAttr("durationSensorDampeningBurstProjector"),
self.getModifiedItemAttr("durationTargetIlluminationBurstProjector"),
self.getModifiedItemAttr("durationECMJammerBurstProjector"),
self.getModifiedItemAttr("durationWeaponDisruptionBurstProjector"),
0, # Return 0 if none of the above are valid
self.getModifiedItemAttr("speed", 0), # Most weapons
self.getModifiedItemAttr("duration", 0), # Most average modules
self.getModifiedItemAttr("durationSensorDampeningBurstProjector", 0),
self.getModifiedItemAttr("durationTargetIlluminationBurstProjector", 0),
self.getModifiedItemAttr("durationECMJammerBurstProjector", 0),
self.getModifiedItemAttr("durationWeaponDisruptionBurstProjector", 0)
)
return speed
@@ -785,7 +781,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def __repr__(self):
if self.item:
return u"Module(ID={}, name={}) at {}".format(
return "Module(ID={}, name={}) at {}".format(
self.item.ID, self.item.name, hex(id(self))
)
else:

View File

@@ -87,7 +87,7 @@ class Ship(ItemAttrShortcut, HandledItem):
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
if forceProjected:
return
for effect in self.item.effects.itervalues():
for effect in self.item.effects.values():
if effect.runTime == runTime and \
effect.isType("passive") and \
effect.activeByDefault:

View File

@@ -33,7 +33,7 @@ class User(object):
def encodeAndSetPassword(self, pw):
h = hashlib.new("sha256")
salt = "".join([random.choice(string.letters) for _ in xrange(32)])
salt = "".join([random.choice(string.letters) for _ in range(32)])
h.update(pw)
h.update(salt)
self.password = ("%s%s" % (h.hexdigest(), salt))
@@ -45,14 +45,14 @@ class User(object):
h = hashlib.new("sha256")
h.update(pw)
h.update(salt)
return self.password == (u"%s%s" % (h.hexdigest(), salt))
return self.password == ("%s%s" % (h.hexdigest(), salt))
@validates("ID", "username", "password", "admin")
def validator(self, key, val):
map = {
"ID" : lambda _val: isinstance(_val, int),
"username": lambda _val: isinstance(_val, basestring),
"password": lambda _val: isinstance(_val, basestring) and len(_val) == 96,
"username": lambda _val: isinstance(_val, str),
"password": lambda _val: isinstance(_val, str) and len(_val) == 96,
"admin" : lambda _val: isinstance(_val, bool)
}

View File

@@ -20,7 +20,7 @@
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from gui.builtinAdditionPanes.boosterView import BoosterView
from gui.builtinAdditionPanes.cargoView import CargoView
from gui.builtinAdditionPanes.commandView import CommandView
@@ -29,22 +29,22 @@ from gui.builtinAdditionPanes.fighterView import FighterView
from gui.builtinAdditionPanes.implantView import ImplantView
from gui.builtinAdditionPanes.notesView import NotesView
from gui.builtinAdditionPanes.projectedView import ProjectedView
from gui.chromeTabs import PFNotebook
from gui.pyfatogglepanel import TogglePanel
from gui.chrome_tabs import ChromeNotebook
from gui.toggle_panel import TogglePanel
class AdditionsPane(TogglePanel):
def __init__(self, parent):
TogglePanel.__init__(self, parent, forceLayout=1)
TogglePanel.__init__(self, parent, force_layout=1)
self.SetLabel("Additions")
pane = self.GetContentPane()
pane = self.GetContentPanel()
baseSizer = wx.BoxSizer(wx.HORIZONTAL)
pane.SetSizer(baseSizer)
self.notebook = PFNotebook(pane, False)
self.notebook = ChromeNotebook(pane, False)
self.notebook.SetMinSize((-1, 1000))
baseSizer.Add(self.notebook, 1, wx.EXPAND)
@@ -59,28 +59,28 @@ class AdditionsPane(TogglePanel):
notesImg = BitmapLoader.getImage("skill_small", "gui")
self.drone = DroneView(self.notebook)
self.notebook.AddPage(self.drone, "Drones", tabImage=droneImg, showClose=False)
self.notebook.AddPage(self.drone, "Drones", image=droneImg, closeable=False)
self.fighter = FighterView(self.notebook)
self.notebook.AddPage(self.fighter, "Fighters", tabImage=fighterImg, showClose=False)
self.notebook.AddPage(self.fighter, "Fighters", image=fighterImg, closeable=False)
self.cargo = CargoView(self.notebook)
self.notebook.AddPage(self.cargo, "Cargo", tabImage=cargoImg, showClose=False)
self.notebook.AddPage(self.cargo, "Cargo", image=cargoImg, closeable=False)
self.implant = ImplantView(self.notebook)
self.notebook.AddPage(self.implant, "Implants", tabImage=implantImg, showClose=False)
self.notebook.AddPage(self.implant, "Implants", image=implantImg, closeable=False)
self.booster = BoosterView(self.notebook)
self.notebook.AddPage(self.booster, "Boosters", tabImage=boosterImg, showClose=False)
self.notebook.AddPage(self.booster, "Boosters", image=boosterImg, closeable=False)
self.projectedPage = ProjectedView(self.notebook)
self.notebook.AddPage(self.projectedPage, "Projected", tabImage=projectedImg, showClose=False)
self.notebook.AddPage(self.projectedPage, "Projected", image=projectedImg, closeable=False)
self.gangPage = CommandView(self.notebook)
self.notebook.AddPage(self.gangPage, "Command", tabImage=gangImg, showClose=False)
self.notebook.AddPage(self.gangPage, "Command", image=gangImg, closeable=False)
self.notes = NotesView(self.notebook)
self.notebook.AddPage(self.notes, "Notes", tabImage=notesImg, showClose=False)
self.notebook.AddPage(self.notes, "Notes", image=notesImg, closeable=False)
self.notebook.SetSelection(0)
@@ -92,19 +92,16 @@ class AdditionsPane(TogglePanel):
def getName(self, idx):
return self.PANES[idx]
def toggleContent(self, event):
TogglePanel.toggleContent(self, event)
h = self.headerPanel.GetSize()[1] + 4
def ToggleContent(self, event):
TogglePanel.ToggleContent(self, event)
h = self.header_panel.GetSize()[1] + 4
if self.IsCollapsed():
self.old_pos = self.parent.GetSashPosition()
self.parent.SetMinimumPaneSize(h)
self.parent.SetSashPosition(h * -1, True)
# only available in >= wx2.9
if getattr(self.parent, "SetSashInvisible", None):
self.parent.SetSashInvisible(True)
self.parent.SetSashInvisible(True)
else:
if getattr(self.parent, "SetSashInvisible", None):
self.parent.SetSashInvisible(False)
self.parent.SetSashInvisible(False)
self.parent.SetMinimumPaneSize(200)
self.parent.SetSashPosition(self.old_pos, True)

View File

@@ -17,9 +17,10 @@
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================
import cStringIO
import io
import os.path
import zipfile
from collections import OrderedDict
# noinspection PyPackageRequirements
import wx
@@ -29,23 +30,18 @@ import config
from logbook import Logger
logging = Logger(__name__)
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
class BitmapLoader(object):
try:
archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r')
logging.info("Using zipped image files.")
except IOError:
except (IOError, TypeError):
logging.info("Using local image files.")
archive = None
cachedBitmaps = OrderedDict()
dontUseCachedBitmaps = False
max_bmps = 500
cached_bitmaps = OrderedDict()
dont_use_cached_bitmaps = False
max_cached_bitmaps = 500
@classmethod
def getStaticBitmap(cls, name, parent, location):
@@ -55,25 +51,25 @@ class BitmapLoader(object):
@classmethod
def getBitmap(cls, name, location):
if cls.dontUseCachedBitmaps:
if cls.dont_use_cached_bitmaps:
img = cls.getImage(name, location)
if img is not None:
return img.ConvertToBitmap()
path = "%s%s" % (name, location)
if len(cls.cachedBitmaps) == cls.max_bmps:
cls.cachedBitmaps.popitem(False)
if len(cls.cached_bitmaps) == cls.max_cached_bitmaps:
cls.cached_bitmaps.popitem(False)
if path not in cls.cachedBitmaps:
if path not in cls.cached_bitmaps:
img = cls.getImage(name, location)
if img is not None:
bmp = img.ConvertToBitmap()
else:
bmp = None
cls.cachedBitmaps[path] = bmp
cls.cached_bitmaps[path] = bmp
else:
bmp = cls.cachedBitmaps[path]
bmp = cls.cached_bitmaps[path]
return bmp
@@ -88,14 +84,14 @@ class BitmapLoader(object):
try:
img_data = cls.archive.read(path)
sbuf = cStringIO.StringIO(img_data)
sbuf = io.StringIO(img_data)
return wx.ImageFromStream(sbuf)
except KeyError:
print("Missing icon file from zip: {0}".format(path))
print(("Missing icon file from zip: {0}".format(path)))
else:
path = os.path.join(config.pyfaPath, 'imgs' + os.sep + location + os.sep + filename)
if os.path.exists(path):
return wx.Image(path)
else:
print("Missing icon file: {0}".format(path))
print(("Missing icon file: {0}".format(path)))

View File

@@ -28,12 +28,12 @@ from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
class BoosterViewDrop(wx.PyDropTarget):
class BoosterViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(BoosterViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -131,6 +131,7 @@ class BoosterView(d.Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addBooster(fitID, event.itemID)

View File

@@ -28,12 +28,12 @@ from service.fit import Fit
from service.market import Market
class CargoViewDrop(wx.PyDropTarget):
class CargoViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(CargoViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -88,7 +88,7 @@ class CargoView(d.Display):
row = event.GetIndex()
if row != -1:
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "cargo:" + str(row)
data.SetText(dataStr)
@@ -119,14 +119,14 @@ class CargoView(d.Display):
module = fit.modules[modIdx]
if dstRow != -1: # we're swapping with cargo
if mstate.CmdDown(): # if copying, append to cargo
if mstate.cmdDown: # if copying, append to cargo
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID)
else: # else, move / swap
sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.position, dstRow)
else: # dragging to blank spot, append
sFit.addCargo(self.mainFrame.getActiveFit(), module.item.ID)
if not mstate.CmdDown(): # if not copying, remove module
if not mstate.cmdDown: # if not copying, remove module
sFit.removeModule(self.mainFrame.getActiveFit(), module.position)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="moddel", typeID=module.item.ID))

View File

@@ -43,12 +43,12 @@ class DummyEntry(object):
self.item = DummyItem(txt)
class CommandViewDrop(wx.PyDropTarget):
class CommandViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(CommandViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -119,7 +119,7 @@ class CommandView(d.Display):
def startDrag(self, event):
row = event.GetIndex()
if row != -1 and isinstance(self.get(row), es_Drone):
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "command:" + str(self.GetItemData(row))
data.SetText(dataStr)
@@ -136,6 +136,8 @@ class CommandView(d.Display):
sFit = Fit.getInstance()
fit = sFit.getFit(event.fitID)
CommandFits.populateFits(event)
self.Parent.Parent.DisablePage(self, not fit or fit.isStructure)
# Clear list and get out if current fitId is None
@@ -167,6 +169,8 @@ class CommandView(d.Display):
self.update(stuff)
event.Skip()
def get(self, row):
if row == -1:
return None

View File

@@ -21,6 +21,7 @@
import wx
import gui.globalEvents as GE
import gui.mainFrame
from gui.builtinMarketBrowser.events import ItemSelected, ITEM_SELECTED
from gui.display import Display
from gui.builtinViewColumns.state import State
@@ -30,12 +31,12 @@ from service.fit import Fit
from service.market import Market
class DroneViewDrop(wx.PyDropTarget):
class DroneViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(DroneViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -66,6 +67,8 @@ class DroneView(Display):
self.hoveredRow = None
self.hoveredColumn = None
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
self.mainFrame.Bind(ITEM_SELECTED, self.addItem)
self.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
@@ -101,7 +104,7 @@ class DroneView(Display):
if self.DEFAULT_COLS[col] == "Miscellanea":
tooltip = self.activeColumns[col].getToolTip(mod)
if tooltip is not None:
self.SetToolTipString(tooltip)
self.SetToolTip(tooltip)
else:
self.SetToolTip(None)
else:
@@ -123,7 +126,7 @@ class DroneView(Display):
def startDrag(self, event):
row = event.GetIndex()
if row != -1:
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "drone:" + str(row)
data.SetText(dataStr)
@@ -207,6 +210,7 @@ class DroneView(Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addDrone(fitID, event.itemID)

View File

@@ -32,12 +32,12 @@ from service.fit import Fit
from service.market import Market
class FighterViewDrop(wx.PyDropTarget):
class FighterViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(FighterViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -60,7 +60,7 @@ class FighterView(wx.Panel):
mainSizer.Add(self.fighterDisplay, 1, wx.EXPAND, 0)
textSizer = wx.BoxSizer(wx.HORIZONTAL)
textSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
textSizer.AddStretchSpacer()
for x in self.labels:
lbl = wx.StaticText(self, wx.ID_ANY, x.capitalize())
@@ -75,7 +75,7 @@ class FighterView(wx.Panel):
lbl = wx.StaticText(self, wx.ID_ANY, "0")
setattr(self, "label%sTotal" % (x.capitalize()), lbl)
textSizer.Add(lbl, 0, wx.ALIGN_CENTER)
textSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
textSizer.AddStretchSpacer()
mainSizer.Add(textSizer, 0, wx.EXPAND, 5)
@@ -97,7 +97,7 @@ class FighterView(wx.Panel):
slot = getattr(Slot, "F_{}".format(x.upper()))
used = fit.getSlotsUsed(slot)
total = fit.getNumSlots(slot)
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings_GetColour(
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings.GetColour(
wx.SYS_COLOUR_WINDOWTEXT)
lbl = getattr(self, "label%sUsed" % x.capitalize())
@@ -110,6 +110,8 @@ class FighterView(wx.Panel):
self.Refresh()
event.Skip()
class FighterDisplay(d.Display):
DEFAULT_COLS = ["State",
@@ -166,7 +168,7 @@ class FighterDisplay(d.Display):
if self.DEFAULT_COLS[col] == "Miscellanea":
tooltip = self.activeColumns[col].getToolTip(mod)
if tooltip is not None:
self.SetToolTipString(tooltip)
self.SetToolTip(tooltip)
else:
self.SetToolTip(None)
else:
@@ -188,7 +190,7 @@ class FighterDisplay(d.Display):
def startDrag(self, event):
row = event.GetIndex()
if row != -1:
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "fighter:" + str(row)
data.SetText(dataStr)

View File

@@ -41,12 +41,12 @@ class ImplantView(wx.Panel):
mainSizer.Add(self.implantDisplay, 1, wx.EXPAND, 0)
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
radioSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
radioSizer.AddStretchSpacer()
self.rbFit = wx.RadioButton(self, id=wx.ID_ANY, label="Use Fit-specific Implants", style=wx.RB_GROUP)
self.rbChar = wx.RadioButton(self, id=wx.ID_ANY, label="Use Character Implants")
radioSizer.Add(self.rbFit, 0, wx.ALL, 5)
radioSizer.Add(self.rbChar, 0, wx.ALL, 5)
radioSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
radioSizer.AddStretchSpacer()
mainSizer.Add(radioSizer, 0, wx.EXPAND, 5)
@@ -71,6 +71,8 @@ class ImplantView(wx.Panel):
self.rbFit.Enable(fit is not None)
self.rbChar.Enable(fit is not None)
event.Skip()
def OnRadioSelect(self, event):
fitID = self.mainFrame.getActiveFit()
sFit = Fit.getInstance()
@@ -150,6 +152,7 @@ class ImplantDisplay(d.Display):
fit = sFit.getFit(fitID)
if not fit or fit.isStructure:
event.Skip()
return
trigger = sFit.addImplant(fitID, event.itemID)

View File

@@ -40,6 +40,8 @@ class NotesView(wx.Panel):
self.lastFitId = event.fitID
self.editNotes.SetValue(fit.notes or "")
event.Skip()
def onText(self, event):
# delay the save so we're not writing to sqlite on every keystroke
self.saveTimer.Stop() # cancel the existing timer

View File

@@ -47,12 +47,12 @@ class DummyEntry(object):
self.item = DummyItem(txt)
class ProjectedViewDrop(wx.PyDropTarget):
class ProjectedViewDrop(wx.DropTarget):
def __init__(self, dropFn, *args, **kwargs):
super(ProjectedViewDrop, self).__init__(*args, **kwargs)
self.dropFn = dropFn
# this is really transferring an EVE itemID
self.dropData = wx.PyTextDataObject()
self.dropData = wx.TextDataObject()
self.SetDataObject(self.dropData)
def OnData(self, x, y, t):
@@ -132,7 +132,7 @@ class ProjectedView(d.Display):
def startDrag(self, event):
row = event.GetIndex()
if row != -1 and isinstance(self.get(row), es_Drone):
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "projected:" + str(self.GetItemData(row))
data.SetText(dataStr)
@@ -222,6 +222,8 @@ class ProjectedView(d.Display):
self.update(stuff)
event.Skip()
def get(self, row):
if row == -1:
return None

View File

@@ -47,7 +47,7 @@ class AmountChanger(wx.Dialog):
bSizer1.Add(self.input, 1, wx.ALL, 5)
self.input.Bind(wx.EVT_CHAR, self.onChar)
self.input.Bind(wx.EVT_TEXT_ENTER, self.change)
self.button = wx.Button(self, wx.ID_OK, u"Done")
self.button = wx.Button(self, wx.ID_OK, "Done")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.SetSizer(bSizer1)

View File

@@ -3,7 +3,7 @@ from gui.contextMenu import ContextMenu
import gui.mainFrame
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from eos.saveddata.character import Skill
import gui.globalEvents as GE
from service.fit import Fit
@@ -49,7 +49,7 @@ class ChangeAffectingSkills(ContextMenu):
if cont[attrName] == 0:
continue
for fit, afflictors in cont.getAfflictions(attrName).iteritems():
for fit, afflictors in cont.getAfflictions(attrName).items():
for afflictor, modifier, amount, used in afflictors:
# only add Skills
if not isinstance(afflictor, Skill):
@@ -89,12 +89,12 @@ class ChangeAffectingSkills(ContextMenu):
if bitmap is not None:
skillItem.SetBitmap(bitmap)
for i in xrange(-1, 6):
for i in range(-1, 6):
levelItem = self.addSkill(rootMenu if msw else grandSub, skill, i)
grandSub.AppendItem(levelItem)
grandSub.Append(levelItem)
if (not skill.learned and i == -1) or (skill.learned and skill.level == i):
levelItem.Check(True)
sub.AppendItem(skillItem)
sub.Append(skillItem)
return sub

View File

@@ -30,6 +30,7 @@ class CommandFits(ContextMenu):
if evt is None or not ids.isdisjoint(cls.commandTypeIDs):
# we are adding or removing an item that defines a command fit. Need to refresh fit list
cls.populateFits(evt)
evt.Skip()
@classmethod
def populateFits(cls, evt):
@@ -50,7 +51,7 @@ class CommandFits(ContextMenu):
return "Command Fits"
def addFit(self, menu, fit, includeShip=False):
label = fit.name if not includeShip else u"({}) {}".format(fit.ship.item.name, fit.name)
label = fit.name if not includeShip else "({}) {}".format(fit.ship.item.name, fit.name)
id = ContextMenu.nextID()
self.fitMenuItemIds[id] = fit
menuItem = wx.MenuItem(menu, id, label)
@@ -67,7 +68,7 @@ class CommandFits(ContextMenu):
if len(self.__class__.commandFits) < 15:
for fit in sorted(self.__class__.commandFits, key=lambda x: x.name):
menuItem = self.addFit(rootMenu if msw else sub, fit, True)
sub.AppendItem(menuItem)
sub.Append(menuItem)
else:
typeDict = {}
@@ -84,9 +85,9 @@ class CommandFits(ContextMenu):
for fit in sorted(typeDict[ship], key=lambda x: x.name):
fitItem = self.addFit(rootMenu if msw else grandSub, fit, False)
grandSub.AppendItem(fitItem)
grandSub.Append(fitItem)
sub.AppendItem(shipItem)
sub.Append(shipItem)
return sub

View File

@@ -3,15 +3,12 @@ import gui.mainFrame
import gui.globalEvents as GE
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from service.fit import Fit
from service.damagePattern import DamagePattern as import_DamagePattern
from service.settings import ContextMenuSettings
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
from collections import OrderedDict
class DamagePattern(ContextMenu):
@@ -52,7 +49,7 @@ class DamagePattern(ContextMenu):
self.singles.append(pattern)
# return list of names, with singles first followed by submenu names
self.m = map(lambda p: p.name, self.singles) + self.subMenus.keys()
self.m = [p.name for p in self.singles] + list(self.subMenus.keys())
return self.m
def addPattern(self, rootMenu, pattern):
@@ -96,7 +93,7 @@ class DamagePattern(ContextMenu):
# Items that have a parent
for pattern in self.subMenus[self.m[i]]:
sub.AppendItem(self.addPattern(rootMenu if msw else sub, pattern))
sub.Append(self.addPattern(rootMenu if msw else sub, pattern))
return sub

View File

@@ -45,7 +45,7 @@ class DroneSpinner(wx.Dialog):
bSizer1.Add(self.spinner, 1, wx.ALL, 5)
self.button = wx.Button(self, wx.ID_OK, u"Split")
self.button = wx.Button(self, wx.ID_OK, "Split")
bSizer1.Add(self.button, 0, wx.ALL, 5)
self.SetSizer(bSizer1)

View File

@@ -3,7 +3,7 @@ import gui.mainFrame
import gui.globalEvents as GE
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from service.fit import Fit
from service.settings import ContextMenuSettings

View File

@@ -44,7 +44,7 @@ class FighterAbility(ContextMenu):
if not ability.effect.isImplemented:
continue
menuItem = self.addAbility(rootMenu if msw else sub, ability)
sub.AppendItem(menuItem)
sub.Append(menuItem)
menuItem.Check(ability.active)
return sub

View File

@@ -61,7 +61,7 @@ class ImplantSets(ContextMenu):
mitem = wx.MenuItem(rootMenu, id, set.name)
bindmenu.Bind(wx.EVT_MENU, self.handleSelection, mitem)
self.idmap[id] = set
m.AppendItem(mitem)
m.Append(mitem)
return m

View File

@@ -47,7 +47,7 @@ class ItemStats(ContextMenu):
mstate = wx.GetMouseState()
reuse = False
if mstate.CmdDown():
if mstate.cmdDown:
reuse = True
if self.mainFrame.GetActiveStatsWindow() is None and reuse:

View File

@@ -91,7 +91,7 @@ class MetaSwap(ContextMenu):
# Sort items by metalevel, and group within that metalevel
items = list(self.variations)
print context
print(context)
if "implantItem" in context:
# sort implants based on name
items.sort(key=lambda x: x.name)
@@ -116,14 +116,14 @@ class MetaSwap(ContextMenu):
if thisgroup != group and context not in ("implantItem", "boosterItem"):
group = thisgroup
id = ContextMenu.nextID()
m.Append(id, u'%s' % group)
m.Append(id, '%s' % group)
m.Enable(id, False)
id = ContextMenu.nextID()
mitem = wx.MenuItem(rootMenu, id, item.name)
bindmenu.Bind(wx.EVT_MENU, self.handleModule, mitem)
self.moduleLookup[id] = item
m.AppendItem(mitem)
m.Append(mitem)
return m
def handleModule(self, event):

View File

@@ -9,7 +9,7 @@ from eos.saveddata.module import Hardpoint
import gui.mainFrame
import gui.globalEvents as GE
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from service.settings import ContextMenuSettings
@@ -50,7 +50,7 @@ class ModuleAmmoPicker(ContextMenu):
return False
self.modules = modules
self.charges = list(filter(lambda charge: Market.getInstance().getPublicityByItem(charge), validCharges))
self.charges = list([charge for charge in validCharges if Market.getInstance().getPublicityByItem(charge)])
return len(self.charges) > 0
def getText(self, itmContext, selection):
@@ -58,9 +58,9 @@ class ModuleAmmoPicker(ContextMenu):
def turretSorter(self, charge):
damage = 0
range_ = (self.module.getModifiedItemAttr("maxRange") or 0) * \
range_ = (self.module.getModifiedItemAttr("maxRange")) * \
(charge.getAttribute("weaponRangeMultiplier") or 1)
falloff = (self.module.getModifiedItemAttr("falloff") or 0) * \
falloff = (self.module.getModifiedItemAttr("falloff")) * \
(charge.getAttribute("fallofMultiplier") or 1)
for type_ in self.DAMAGE_TYPES:
d = charge.getAttribute("%sDamage" % type_)
@@ -108,7 +108,7 @@ class ModuleAmmoPicker(ContextMenu):
def nameSorter(self, charge):
parts = charge.name.split(" ")
return map(self.numericConverter, parts)
return list(map(self.numericConverter, parts))
def addCharge(self, menu, charge):
id_ = ContextMenu.nextID()
@@ -127,7 +127,7 @@ class ModuleAmmoPicker(ContextMenu):
@staticmethod
def addSeperator(m, text):
id_ = ContextMenu.nextID()
m.Append(id_, u'%s' % text)
m.Append(id_, '%s' % text)
m.Enable(id_, False)
def getSubMenu(self, context, selection, rootMenu, i, pitem):
@@ -137,7 +137,7 @@ class ModuleAmmoPicker(ContextMenu):
hardpoint = self.module.hardpoint
moduleName = self.module.item.name
# Make sure we do not consider mining turrets as combat turrets
if hardpoint == Hardpoint.TURRET and self.module.getModifiedItemAttr("miningAmount") is None:
if hardpoint == Hardpoint.TURRET and self.module.getModifiedItemAttr("miningAmount", None) is None:
self.addSeperator(m, "Long Range")
items = []
range_ = None
@@ -170,15 +170,15 @@ class ModuleAmmoPicker(ContextMenu):
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
sub.AppendItem(self.addCharge(rootMenu if msw else sub, base))
sub.Append(self.addCharge(rootMenu if msw else sub, base))
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
sub.Append(self.addCharge(rootMenu if msw else sub, charge))
if sub is not None:
self.addSeperator(sub, "More Damage")
for item in items:
m.AppendItem(item)
m.Append(item)
self.addSeperator(m, "Short Range")
elif hardpoint == Hardpoint.MISSILE and moduleName != 'Festival Launcher':
@@ -203,23 +203,23 @@ class ModuleAmmoPicker(ContextMenu):
sub.Bind(wx.EVT_MENU, self.handleAmmoSwitch)
self.addSeperator(sub, "Less Damage")
item.SetSubMenu(sub)
m.AppendItem(item)
m.Append(item)
if charge.name not in ("Light Defender Missile I", "Heavy Defender Missile I"):
sub.AppendItem(self.addCharge(rootMenu if msw else sub, charge))
sub.Append(self.addCharge(rootMenu if msw else sub, charge))
else:
defender = charge
if defender is not None:
m.AppendItem(self.addCharge(rootMenu if msw else m, defender))
m.Append(self.addCharge(rootMenu if msw else m, defender))
if sub is not None:
self.addSeperator(sub, "More Damage")
else:
self.charges.sort(key=self.nameSorter)
for charge in self.charges:
m.AppendItem(self.addCharge(rootMenu if msw else m, charge))
m.Append(self.addCharge(rootMenu if msw else m, charge))
m.AppendItem(self.addCharge(rootMenu if msw else m, None))
m.Append(self.addCharge(rootMenu if msw else m, None))
return m
def handleAmmoSwitch(self, event):

View File

@@ -35,7 +35,7 @@ class PriceOptions(ContextMenu):
for option in self.optionList:
menuItem = self.addOption(rootMenu if msw else sub, option)
sub.AppendItem(menuItem)
sub.Append(menuItem)
menuItem.Check(self.settings.get(option.lower()))
return sub

View File

@@ -38,15 +38,15 @@ class TabbedFits(ContextMenu):
else:
bindmenu = m
for page in self.mainFrame.fitMultiSwitch.pages:
for page in self.mainFrame.fitMultiSwitch._pages:
if isinstance(page, BlankPage):
continue
fit = sFit.getFit(page.activeFitID, basic=True)
id = ContextMenu.nextID()
mitem = wx.MenuItem(rootMenu, id, u"{}: {}".format(fit.ship.item.name, fit.name))
mitem = wx.MenuItem(rootMenu, id, "{}: {}".format(fit.ship.item.name, fit.name))
bindmenu.Bind(wx.EVT_MENU, self.handleSelection, mitem)
self.fitLookup[id] = fit
m.AppendItem(mitem)
m.Append(mitem)
return m

View File

@@ -49,7 +49,7 @@ class TacticalMode(ContextMenu):
for mode in self.modes:
menuItem = self.addMode(rootMenu if msw else sub, mode)
sub.AppendItem(menuItem)
sub.Append(menuItem)
menuItem.Check(self.currMode.item == mode.item)
return sub

View File

@@ -3,15 +3,11 @@ import gui.mainFrame
import gui.globalEvents as GE
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from service.targetResists import TargetResists as svc_TargetResists
from service.fit import Fit
from service.settings import ContextMenuSettings
try:
from collections import OrderedDict
except ImportError:
from utils.compat import OrderedDict
from collections import OrderedDict
class TargetResists(ContextMenu):
@@ -87,15 +83,15 @@ class TargetResists(ContextMenu):
else:
self.singles.append(pattern)
sub.AppendItem(self.addPattern(rootMenu if msw else sub, None)) # Add reset
sub.Append(self.addPattern(rootMenu if msw else sub, None)) # Add reset
sub.AppendSeparator()
# Single items, no parent
for pattern in self.singles:
sub.AppendItem(self.addPattern(rootMenu if msw else sub, pattern))
sub.Append(self.addPattern(rootMenu if msw else sub, pattern))
# Items that have a parent
for menuName, patterns in self.subMenus.items():
for menuName, patterns in list(self.subMenus.items()):
# Create parent item for root menu that is simply name of parent
item = wx.MenuItem(rootMenu, ContextMenu.nextID(), menuName)
@@ -108,8 +104,8 @@ class TargetResists(ContextMenu):
# Append child items to child menu
for pattern in patterns:
grandSub.AppendItem(self.addPattern(rootMenu if msw else grandSub, pattern))
sub.AppendItem(item) # finally, append parent item to root menu
grandSub.Append(self.addPattern(rootMenu if msw else grandSub, pattern))
sub.Append(item) # finally, append parent item to root menu
return sub

View File

@@ -34,7 +34,7 @@ class WhProjector(ContextMenu):
subItem = wx.MenuItem(sub, wx.ID_ANY, swType)
grandSub = wx.Menu()
subItem.SetSubMenu(grandSub)
sub.AppendItem(subItem)
sub.Append(subItem)
for swData in sorted(effdata[swType], key=lambda tpl: tpl[2]):
wxid = ContextMenu.nextID()
@@ -45,7 +45,7 @@ class WhProjector(ContextMenu):
rootMenu.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
else:
grandSub.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
grandSub.AppendItem(grandSubItem)
grandSub.Append(grandSubItem)
return sub
def handleSelection(self, event):

View File

@@ -18,7 +18,7 @@
# =============================================================================
from gui.graph import Graph
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from eos.graph.fitDps import FitDpsGraph as FitDps
from eos.graph import Data
import gui.mainFrame
@@ -54,7 +54,7 @@ class FitDpsGraph(Graph):
def getIcons(self):
icons = {}
sAttr = Attribute.getInstance()
for key, attrName in self.propertyAttributeMap.iteritems():
for key, attrName in self.propertyAttributeMap.items():
iconFile = sAttr.getAttributeInfo(attrName).icon.iconFile
bitmap = BitmapLoader.getBitmap(iconFile, "icons")
if bitmap:
@@ -69,7 +69,7 @@ class FitDpsGraph(Graph):
fitDps.clearData()
variable = None
for fieldName, value in fields.iteritems():
for fieldName, value in fields.items():
d = Data(fieldName, value)
if not d.isConstant():
if variable is None:

View File

@@ -14,7 +14,7 @@ from eos.saveddata.fit import Fit
import gui.mainFrame
from gui.contextMenu import ContextMenu
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
class ItemAffectedBy(wx.Panel):
@@ -43,17 +43,17 @@ class ItemAffectedBy(wx.Panel):
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
bSizer = wx.BoxSizer(wx.HORIZONTAL)
self.toggleExpandBtn = wx.ToggleButton(self, wx.ID_ANY, u"Expand All", wx.DefaultPosition, wx.DefaultSize, 0)
self.toggleExpandBtn = wx.ToggleButton(self, wx.ID_ANY, "Expand All", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.toggleExpandBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.toggleNameBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle Names", wx.DefaultPosition, wx.DefaultSize, 0)
self.toggleNameBtn = wx.ToggleButton(self, wx.ID_ANY, "Toggle Names", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.toggleNameBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle View", wx.DefaultPosition, wx.DefaultSize, 0)
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, "Toggle View", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL)
if stuff is not None:
self.refreshBtn = wx.Button(self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT)
self.refreshBtn = wx.Button(self, wx.ID_ANY, "Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT)
bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshTree)
@@ -74,9 +74,9 @@ class ItemAffectedBy(wx.Panel):
def spawnMenu(self, item):
self.affectedBy.SelectItem(item)
stuff = self.affectedBy.GetPyData(item)
stuff = self.affectedBy.GetItemData(item)
# String is set as data when we are dealing with attributes, not stuff containers
if stuff is None or isinstance(stuff, basestring):
if stuff is None or isinstance(stuff, str):
return
contexts = []
@@ -109,10 +109,10 @@ class ItemAffectedBy(wx.Panel):
self.Freeze()
for item in self.treeItems:
change = self.affectedBy.GetPyData(item)
change = self.affectedBy.GetItemData(item)
display = self.affectedBy.GetItemText(item)
self.affectedBy.SetItemText(item, change)
self.affectedBy.SetPyData(item, display)
self.affectedBy.SetItemData(item, display)
self.Thaw()
@@ -141,7 +141,7 @@ class ItemAffectedBy(wx.Panel):
# sheri was here
del self.treeItems[:]
root = self.affectedBy.AddRoot("WINPWNZ0R")
self.affectedBy.SetPyData(root, None)
self.affectedBy.SetItemData(root, None)
self.imageList = wx.ImageList(16, 16)
self.affectedBy.SetImageList(self.imageList)
@@ -185,7 +185,7 @@ class ItemAffectedBy(wx.Panel):
if attributes[attrName] == (attributes.getOriginal(attrName, 0)):
continue
for fit, afflictors in attributes.getAfflictions(attrName).iteritems():
for fit, afflictors in attributes.getAfflictions(attrName).items():
for afflictor, modifier, amount, used in afflictors:
if not used or afflictor.item is None:
@@ -216,7 +216,7 @@ class ItemAffectedBy(wx.Panel):
(type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False)))
# Make sure projected fits are on top
rootOrder = container.keys()
rootOrder = list(container.keys())
rootOrder.sort(key=lambda x: self.ORDER.index(type(x)))
# Now, we take our created dictionary and start adding stuff to our tree
@@ -230,7 +230,7 @@ class ItemAffectedBy(wx.Panel):
parent = child
attributes = container[thing]
attrOrder = sorted(attributes.keys(), key=self.sortAttrDisplayName)
attrOrder = sorted(list(attributes.keys()), key=self.sortAttrDisplayName)
for attrName in attrOrder:
attrInfo = self.stuff.item.attributes.get(attrName)
@@ -257,7 +257,7 @@ class ItemAffectedBy(wx.Panel):
# this is the attribute node
child = self.affectedBy.AppendItem(parent, display, attrIcon)
self.affectedBy.SetPyData(child, saved)
self.affectedBy.SetItemData(child, saved)
self.treeItems.append(child)
items = attributes[attrName]
@@ -284,12 +284,12 @@ class ItemAffectedBy(wx.Panel):
penalized += "(penalized)"
if 'r' in attrModifier:
penalized += "(resisted)"
attrModifier = "*"
attrModifier = "*"
# this is the Module node, the attribute will be attached to this
display = "%s %s %.2f %s" % (displayStr, attrModifier, attrAmount, penalized)
treeItem = self.affectedBy.AppendItem(child, display, itemIcon)
self.affectedBy.SetPyData(treeItem, afflictor)
self.affectedBy.SetItemData(treeItem, afflictor)
def buildModuleView(self, root):
"""
@@ -314,7 +314,7 @@ class ItemAffectedBy(wx.Panel):
if attributes[attrName] == (attributes.getOriginal(attrName, 0)):
continue
for fit, afflictors in attributes.getAfflictions(attrName).iteritems():
for fit, afflictors in attributes.getAfflictions(attrName).items():
for afflictor, modifier, amount, used in afflictors:
if not used or getattr(afflictor, 'item', None) is None:
continue
@@ -350,7 +350,7 @@ class ItemAffectedBy(wx.Panel):
info[2].append((attrName, modifier, amount))
# Make sure projected fits are on top
rootOrder = container.keys()
rootOrder = list(container.keys())
rootOrder.sort(key=lambda x: self.ORDER.index(type(x)))
# Now, we take our created dictionary and start adding stuff to our tree
@@ -364,7 +364,7 @@ class ItemAffectedBy(wx.Panel):
parent = child
items = container[thing]
order = items.keys()
order = list(items.keys())
order.sort(key=lambda x: (self.ORDER.index(items[x][0]), x))
for itemName in order:
@@ -389,7 +389,7 @@ class ItemAffectedBy(wx.Panel):
# this is the Module node, the attribute will be attached to this
child = self.affectedBy.AppendItem(parent, displayStr, itemIcon)
self.affectedBy.SetPyData(child, afflictors.pop())
self.affectedBy.SetItemData(child, afflictors.pop())
if counter > 0:
attributes = []
@@ -416,7 +416,7 @@ class ItemAffectedBy(wx.Panel):
penalized += "(penalized)"
if 'r' in attrModifier:
penalized += "(resisted)"
attrModifier = "*"
attrModifier = "*"
attributes.append((attrName, (displayName if displayName != "" else attrName), attrModifier,
attrAmount, penalized, attrIcon))
@@ -443,5 +443,5 @@ class ItemAffectedBy(wx.Panel):
saved = "%s %s %.2f %s" % (attrName, attrModifier, attrAmount, penalized)
treeitem = self.affectedBy.AppendItem(child, display, attrIcon)
self.affectedBy.SetPyData(treeitem, saved)
self.affectedBy.SetItemData(treeitem, saved)
self.treeItems.append(treeitem)

View File

@@ -5,9 +5,9 @@ import config
# noinspection PyPackageRequirements
import wx
from helpers import AutoListCtrl
from .helpers import AutoListCtrl
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
from service.market import Market
from service.attribute import Attribute
from gui.utils.numberFormatter import formatAmount
@@ -34,19 +34,19 @@ class ItemParams(wx.Panel):
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
bSizer = wx.BoxSizer(wx.HORIZONTAL)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, " ", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle view mode", wx.DefaultPosition, wx.DefaultSize,
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, "Toggle view mode", wx.DefaultPosition, wx.DefaultSize,
0)
bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.exportStatsBtn = wx.ToggleButton(self, wx.ID_ANY, u"Export Item Stats", wx.DefaultPosition, wx.DefaultSize,
self.exportStatsBtn = wx.ToggleButton(self, wx.ID_ANY, "Export Item Stats", wx.DefaultPosition, wx.DefaultSize,
0)
bSizer.Add(self.exportStatsBtn, 0, wx.ALIGN_CENTER_VERTICAL)
if stuff is not None:
self.refreshBtn = wx.Button(self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT)
self.refreshBtn = wx.Button(self, wx.ID_ANY, "Refresh", wx.DefaultPosition, wx.DefaultSize, wx.BU_EXACTFIT)
bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshValues)
@@ -166,7 +166,7 @@ class ItemParams(wx.Panel):
self.imageList = wx.ImageList(16, 16)
self.paramList.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL)
names = list(self.attrValues.iterkeys())
names = list(self.attrValues.keys())
names.sort()
idNameMap = {}
@@ -203,7 +203,7 @@ class ItemParams(wx.Panel):
else:
attrIcon = self.imageList.Add(BitmapLoader.getBitmap("7_15", "icons"))
index = self.paramList.InsertImageStringItem(sys.maxint, attrName, attrIcon)
index = self.paramList.InsertItem(sys.maxsize, attrName, attrIcon)
idNameMap[idCount] = attrName
self.paramList.SetItemData(index, idCount)
idCount += 1
@@ -222,11 +222,12 @@ class ItemParams(wx.Panel):
else:
valueUnitDefault = formatAmount(valueDefault, 3, 0, 0)
self.paramList.SetStringItem(index, 1, valueUnit)
self.paramList.SetItem(index, 1, valueUnit)
if self.stuff is not None:
self.paramList.SetStringItem(index, 2, valueUnitDefault)
self.paramList.SortItems(lambda id1, id2: cmp(idNameMap[id1], idNameMap[id2]))
self.paramList.SetItem(index, 2, valueUnitDefault)
# @todo: pheonix, this lamda used cmp() which no longer exists in py3. Probably a better way to do this in the
# long run, take a look
self.paramList.SortItems(lambda id1, id2: (idNameMap[id1] > idNameMap[id2]) - (idNameMap[id1] < idNameMap[id2]))
self.paramList.RefreshRows()
self.totalAttrsLabel.SetLabel("%d attributes. " % idCount)
self.Layout()
@@ -252,7 +253,7 @@ class ItemParams(wx.Panel):
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent" : (
lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume" : (lambda: value, u"m\u00B3"),
"Volume" : (lambda: value, "m\u00B3"),
"Sizeclass" : (lambda: value, ""),
"Absolute Percent" : (lambda: (value * 100), unitName),
"Milliseconds" : (lambda: value / 1000.0, unitName),
@@ -266,7 +267,7 @@ class ItemParams(wx.Panel):
v = override[0]()
if isinstance(v, str):
fvalue = v
elif isinstance(v, (int, float, long)):
elif isinstance(v, (int, float)):
fvalue = formatAmount(v, 3, 0, 0)
else:
fvalue = v

View File

@@ -3,7 +3,7 @@ import sys
# noinspection PyPackageRequirements
import wx
from helpers import AutoListCtrl
from .helpers import AutoListCtrl
from service.price import Price as ServicePrice
from service.market import Market
from service.attribute import Attribute
@@ -30,17 +30,17 @@ class ItemCompare(wx.Panel):
self.sortReverse = False
self.item = item
self.items = sorted(items,
key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else None)
key=lambda x: x.attributes['metaLevel'].value if 'metaLevel' in x.attributes else 0)
self.attrs = {}
# get a dict of attrName: attrInfo of all unique attributes across all items
for item in self.items:
for attr in item.attributes.keys():
for attr in list(item.attributes.keys()):
if item.attributes[attr].info.displayName:
self.attrs[attr] = item.attributes[attr].info
# Process attributes for items and find ones that differ
for attr in self.attrs.keys():
for attr in list(self.attrs.keys()):
value = None
for item in self.items:
@@ -65,14 +65,14 @@ class ItemCompare(wx.Panel):
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
bSizer = wx.BoxSizer(wx.HORIZONTAL)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, " ", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, u"Toggle view mode", wx.DefaultPosition,
self.toggleViewBtn = wx.ToggleButton(self, wx.ID_ANY, "Toggle view mode", wx.DefaultPosition,
wx.DefaultSize, 0)
bSizer.Add(self.toggleViewBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.refreshBtn = wx.Button(self, wx.ID_ANY, u"Refresh", wx.DefaultPosition, wx.DefaultSize,
self.refreshBtn = wx.Button(self, wx.ID_ANY, "Refresh", wx.DefaultPosition, wx.DefaultSize,
wx.BU_EXACTFIT)
bSizer.Add(self.refreshBtn, 0, wx.ALIGN_CENTER_VERTICAL)
self.refreshBtn.Bind(wx.EVT_BUTTON, self.RefreshValues)
@@ -109,7 +109,7 @@ class ItemCompare(wx.Panel):
def processPrices(self, prices):
for i, price in enumerate(prices):
self.paramList.SetStringItem(i, len(self.attrs) + 1, formatAmount(price.value, 3, 3, 9, currency=True))
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(price.value, 3, 3, 9, currency=True))
def PopulateList(self, sort=None):
@@ -126,7 +126,7 @@ class ItemCompare(wx.Panel):
try:
# Remember to reduce by 1, because the attrs array
# starts at 0 while the list has the item name as column 0.
attr = str(self.attrs.keys()[sort - 1])
attr = str(list(self.attrs.keys())[sort - 1])
func = lambda _val: _val.attributes[attr].value if attr in _val.attributes else None
except IndexError:
# Clicked on a column that's not part of our array (price most likely)
@@ -147,7 +147,7 @@ class ItemCompare(wx.Panel):
self.paramList.SetColumnWidth(len(self.attrs) + 1, 60)
for item in self.items:
i = self.paramList.InsertStringItem(sys.maxint, item.name)
i = self.paramList.InsertItem(sys.maxsize, item.name)
for x, attr in enumerate(self.attrs.keys()):
if attr in item.attributes:
info = self.attrs[attr]
@@ -159,10 +159,10 @@ class ItemCompare(wx.Panel):
else:
valueUnit = formatAmount(value, 3, 0, 0)
self.paramList.SetStringItem(i, x + 1, valueUnit)
self.paramList.SetItem(i, x + 1, valueUnit)
# Add prices
self.paramList.SetStringItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True))
self.paramList.SetItem(i, len(self.attrs) + 1, formatAmount(item.price.price, 3, 3, 9, currency=True))
self.paramList.RefreshRows()
self.Layout()
@@ -185,7 +185,7 @@ class ItemCompare(wx.Panel):
"Inverse Absolute Percent" : (lambda: (1 - value) * 100, unitName),
"Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName),
"Modifier Percent" : (lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName),
"Volume" : (lambda: value, u"m\u00B3"),
"Volume" : (lambda: value, "m\u00B3"),
"Sizeclass" : (lambda: value, ""),
"Absolute Percent" : (lambda: (value * 100), unitName),
"Milliseconds" : (lambda: value / 1000.0, unitName),
@@ -199,7 +199,7 @@ class ItemCompare(wx.Panel):
v = override[0]()
if isinstance(v, str):
fvalue = v
elif isinstance(v, (int, float, long)):
elif isinstance(v, (int, float)):
fvalue = formatAmount(v, 3, 0, 0)
else:
fvalue = v

View File

@@ -1,7 +1,7 @@
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
class ItemDependents(wx.Panel):
@@ -19,7 +19,7 @@ class ItemDependents(wx.Panel):
self.SetSizer(mainSizer)
self.root = self.reqTree.AddRoot("WINRARZOR")
self.reqTree.SetPyData(self.root, None)
self.reqTree.SetItemData(self.root, None)
self.imageList = wx.ImageList(16, 16)
self.reqTree.SetImageList(self.imageList)
@@ -32,7 +32,7 @@ class ItemDependents(wx.Panel):
def getFullSkillTree(self, parentSkill, parent, sbIconId):
levelToItems = {}
for item, level in parentSkill.requiredFor.iteritems():
for item, level in parentSkill.requiredFor.items():
if level not in levelToItems:
levelToItems[level] = []
levelToItems[level].append(item)

View File

@@ -11,8 +11,8 @@ class ItemDescription(wx.Panel):
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(mainSizer)
bgcolor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
fgcolor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
bgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
fgcolor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
self.description = wx.html.HtmlWindow(self)

View File

@@ -6,7 +6,7 @@ import config
# noinspection PyPackageRequirements
import wx
from helpers import AutoListCtrl
from .helpers import AutoListCtrl
class ItemEffects(wx.Panel):
@@ -47,11 +47,11 @@ class ItemEffects(wx.Panel):
item = self.item
effects = item.effects
names = list(effects.iterkeys())
names = list(effects.keys())
names.sort()
for name in names:
index = self.effectList.InsertStringItem(sys.maxint, name)
index = self.effectList.InsertItem(sys.maxsize, name)
if effects[name].isImplemented:
if effects[name].activeByDefault:
@@ -72,11 +72,11 @@ class ItemEffects(wx.Panel):
else:
effectRunTime = ""
self.effectList.SetStringItem(index, 1, activeByDefault)
self.effectList.SetStringItem(index, 2, effectTypeText)
self.effectList.SetItem(index, 1, activeByDefault)
self.effectList.SetItem(index, 2, effectTypeText)
if config.debug:
self.effectList.SetStringItem(index, 3, effectRunTime)
self.effectList.SetStringItem(index, 4, str(effects[name].ID))
self.effectList.SetItem(index, 3, effectRunTime)
self.effectList.SetItem(index, 4, str(effects[name].ID))
self.effectList.RefreshRows()
self.Layout()

View File

@@ -3,7 +3,7 @@ import sys
# noinspection PyPackageRequirements
import wx
from helpers import AutoListCtrl
from .helpers import AutoListCtrl
class ItemProperties(wx.Panel):
@@ -27,7 +27,7 @@ class ItemProperties(wx.Panel):
mainSizer.Add(self.m_staticline, 0, wx.EXPAND)
bSizer = wx.BoxSizer(wx.HORIZONTAL)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, u" ", wx.DefaultPosition, wx.DefaultSize, 0)
self.totalAttrsLabel = wx.StaticText(self, wx.ID_ANY, " ", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT)
@@ -79,7 +79,7 @@ class ItemProperties(wx.Panel):
attrName = name.title()
value = getattr(self.item, name)
index = self.paramList.InsertStringItem(sys.maxint, attrName)
index = self.paramList.InsertItem(sys.maxsize, attrName)
# index = self.paramList.InsertImageStringItem(sys.maxint, attrName)
idNameMap[idCount] = attrName
self.paramList.SetItemData(index, idCount)
@@ -87,13 +87,13 @@ class ItemProperties(wx.Panel):
valueUnit = str(value)
self.paramList.SetStringItem(index, 1, valueUnit)
self.paramList.SetItem(index, 1, valueUnit)
except:
# TODO: Add logging to this.
# We couldn't get a property for some reason. Skip it for now.
continue
self.paramList.SortItems(lambda id1, id2: cmp(idNameMap[id1], idNameMap[id2]))
self.paramList.SortItems(lambda id1, id2: (idNameMap[id1] > idNameMap[id2]) - (idNameMap[id1] < idNameMap[id2]))
self.paramList.RefreshRows()
self.totalAttrsLabel.SetLabel("%d attributes. " % idCount)
self.Layout()

View File

@@ -1,7 +1,7 @@
# noinspection PyPackageRequirements
import wx
from gui.bitmapLoader import BitmapLoader
from gui.bitmap_loader import BitmapLoader
class ItemRequirements(wx.Panel):
@@ -19,7 +19,7 @@ class ItemRequirements(wx.Panel):
self.SetSizer(mainSizer)
self.root = self.reqTree.AddRoot("WINRARZOR")
self.reqTree.SetPyData(self.root, None)
self.reqTree.SetItemData(self.root, None)
self.imageList = wx.ImageList(16, 16)
self.reqTree.SetImageList(self.imageList)
@@ -32,7 +32,7 @@ class ItemRequirements(wx.Panel):
self.Layout()
def getFullSkillTree(self, parentSkill, parent, sbIconId):
for skill, level in parentSkill.requiredSkills.iteritems():
for skill, level in parentSkill.requiredSkills.items():
child = self.reqTree.AppendItem(parent, "%s %s" % (skill.name, self.romanNb[int(level)]), sbIconId)
if skill.ID not in self.skillIdHistory:
self.getFullSkillTree(skill, child, sbIconId)

View File

@@ -9,7 +9,7 @@ from gui.utils.staticHelpers import DragDropHelper
from logbook import Logger
import events
from gui.builtinMarketBrowser.events import RECENTLY_USED_MODULES, MAX_RECENTLY_USED_MODULES, ItemSelected
pyfalog = Logger(__name__)
@@ -66,7 +66,7 @@ class ItemView(Display):
row = self.GetFirstSelected()
if row != -1:
data = wx.PyTextDataObject()
data = wx.TextDataObject()
dataStr = "market:" + str(self.active[row].ID)
pyfalog.debug("Dragging from market: " + dataStr)
@@ -89,10 +89,10 @@ class ItemView(Display):
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
wx.PostEvent(self.mainFrame, events.ItemSelected(itemID=self.active[sel].ID))
wx.PostEvent(self.mainFrame, ItemSelected(itemID=self.active[sel].ID))
def storeRecentlyUsedMarketItem(self, itemID):
if len(self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]) > events.MAX_RECENTLY_USED_MODULES:
if len(self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]) > MAX_RECENTLY_USED_MODULES:
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].pop(0)
self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"].append(itemID)
@@ -103,8 +103,8 @@ class ItemView(Display):
sel = self.marketView.GetSelection()
if sel.IsOk():
# Get data field of the selected item (which is a marketGroup ID if anything was selected)
seldata = self.marketView.GetPyData(sel)
if seldata is not None and seldata != events.RECENTLY_USED_MODULES:
seldata = self.marketView.GetItemData(sel)
if seldata is not None and seldata != RECENTLY_USED_MODULES:
# If market group treeview item doesn't have children (other market groups or dummies),
# then it should have items in it and we want to request them
if self.marketView.ItemHasChildren(sel) is False:
@@ -117,7 +117,7 @@ class ItemView(Display):
items = set()
else:
# If method was called but selection wasn't actually made or we have a hit on recently used modules
if seldata == events.RECENTLY_USED_MODULES:
if seldata == RECENTLY_USED_MODULES:
items = self.recentlyUsedModules
else:
items = set()
@@ -126,7 +126,7 @@ class ItemView(Display):
self.updateItemStore(items)
# Set toggle buttons / use search mode flag if recently used modules category is selected (in order to have all modules listed and not filtered)
if seldata is not events.RECENTLY_USED_MODULES:
if seldata is not RECENTLY_USED_MODULES:
self.setToggles()
else:
self.marketBrowser.searchMode = True
@@ -204,13 +204,14 @@ class ItemView(Display):
try:
mktgrpid = sMkt.getMarketGroupByItem(item).ID
except AttributeError:
mktgrpid = None
print("unable to find market group for", item.name)
mktgrpid = -1
print(("unable to find market group for", item.name))
parentname = sMkt.getParentItemByItem(item).name
# Get position of market group
metagrpid = sMkt.getMetaGroupIdByItem(item)
metatab = self.metaMap.get(metagrpid)
metalvl = self.metalvls.get(item.ID, 0)
return catname, mktgrpid, parentname, metatab, metalvl, item.name
def contextMenu(self, event):
@@ -266,7 +267,7 @@ class ItemView(Display):
"""
revmap = {}
i = 0
for mgids in self.sMkt.META_MAP.itervalues():
for mgids in self.sMkt.META_MAP.values():
for mgid in mgids:
revmap[mgid] = i
i += 1

View File

@@ -1,7 +1,7 @@
import wx
from gui.cachingImageList import CachingImageList
import gui.builtinMarketBrowser.events as events
from gui.builtinMarketBrowser.events import RECENTLY_USED_MODULES
from logbook import Logger
@@ -24,7 +24,7 @@ class MarketTree(wx.TreeCtrl):
sMkt = self.sMkt
for mktGrp in sMkt.getMarketRoot():
iconId = self.addImage(sMkt.getIconByMarketGroup(mktGrp))
childId = self.AppendItem(self.root, mktGrp.name, iconId, data=wx.TreeItemData(mktGrp.ID))
childId = self.AppendItem(self.root, mktGrp.name, iconId, data=mktGrp.ID)
# All market groups which were never expanded are dummies, here we assume
# that all root market groups are expandable
self.AppendItem(childId, "dummy")
@@ -32,7 +32,7 @@ class MarketTree(wx.TreeCtrl):
# Add recently used modules node
rumIconId = self.addImage("market_small", "gui")
self.AppendItem(self.root, "Recently Used Modules", rumIconId, data=wx.TreeItemData(events.RECENTLY_USED_MODULES))
self.AppendItem(self.root, "Recently Used Modules", rumIconId, data=RECENTLY_USED_MODULES)
# Bind our lookup method to when the tree gets expanded
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.expandLookup)
@@ -52,14 +52,14 @@ class MarketTree(wx.TreeCtrl):
self.Delete(child)
# And add real market group contents
sMkt = self.sMkt
currentMktGrp = sMkt.getMarketGroup(self.GetPyData(root), eager="children")
currentMktGrp = sMkt.getMarketGroup(self.GetItemData(root), eager="children")
for childMktGrp in sMkt.getMarketGroupChildren(currentMktGrp):
# If market should have items but it doesn't, do not show it
if sMkt.marketGroupValidityCheck(childMktGrp) is False:
continue
iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp))
try:
childId = self.AppendItem(root, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
childId = self.AppendItem(root, childMktGrp.name, iconId, data=childMktGrp.ID)
except Exception as e:
pyfalog.debug("Error appending item.")
pyfalog.debug(e)
@@ -88,7 +88,7 @@ class MarketTree(wx.TreeCtrl):
for i in range(len(jumpList) - 1, -1, -1):
target = jumpList[i]
child, cookie = self.GetFirstChild(item)
while self.GetItemPyData(child) != target:
while self.GetItemData(child) != target:
child, cookie = self.GetNextChild(item, cookie)
item = child

View File

@@ -1,7 +1,7 @@
# noinspection PyPackageRequirements
import wx
import gui.utils.colorUtils as colorUtils
import gui.utils.drawUtils as drawUtils
import gui.utils.color as colorUtils
import gui.utils.draw as drawUtils
SearchButton, EVT_SEARCH_BTN = wx.lib.newevent.NewEvent()
CancelButton, EVT_CANCEL_BTN = wx.lib.newevent.NewEvent()
@@ -59,6 +59,8 @@ class PFSearchBox(wx.Window):
self.EditBox.Bind(wx.EVT_TEXT, self.OnText)
self.EditBox.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.SetMinSize(size)
def OnText(self, event):
@@ -224,10 +226,10 @@ class PFSearchBox(wx.Window):
self.EditBox.SetSize((self.cancelButtonX - self.padding - self.editX, -1))
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
dc = wx.AutoBufferedPaintDC(self)
bkColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
sepColor = colorUtils.GetSuitableColor(bkColor, 0.2)
bkColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
sepColor = colorUtils.GetSuitable(bkColor, 0.2)
rect = self.GetRect()
if self.resized:

View File

@@ -1,5 +1,5 @@
from gui.bitmapLoader import BitmapLoader
from pfSearchBox import PFSearchBox
from gui.bitmap_loader import BitmapLoader
from .pfSearchBox import PFSearchBox
class SearchBox(PFSearchBox):

View File

@@ -1,6 +1,3 @@
# noinspection PyPackageRequirements
import wx
__all__ = [
"pyfaGeneralPreferences",
"pyfaHTMLExportPreferences",
@@ -10,7 +7,6 @@ __all__ = [
"pyfaLoggingPreferences",
"pyfaEnginePreferences",
"pyfaStatViewPreferences",
"pyfaCrestPreferences"
]
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
__all__.append("pyfaCrestPreferences")

View File

@@ -50,7 +50,7 @@ class DummyView(PreferenceView):
def initHeader(self, panel):
headerSizer = wx.BoxSizer(wx.VERTICAL)
self.stTitle = wx.StaticText(panel, wx.ID_ANY, u"Dummy", wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle = wx.StaticText(panel, wx.ID_ANY, "Dummy", wx.DefaultPosition, wx.DefaultSize, 0)
self.stTitle.Wrap(-1)
self.stTitle.SetFont(wx.Font(14, 70, 90, 90, False, wx.EmptyString))
headerSizer.Add(self.stTitle, 0, wx.ALL, 5)
@@ -60,10 +60,10 @@ class DummyView(PreferenceView):
def initContent(self, panel):
contentSizer = wx.BoxSizer(wx.VERTICAL)
self.m_checkBox2 = wx.CheckBox(panel, wx.ID_ANY, u"Check Me!", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_checkBox2 = wx.CheckBox(panel, wx.ID_ANY, "Check Me!", wx.DefaultPosition, wx.DefaultSize, 0)
contentSizer.Add(self.m_checkBox2, 0, wx.ALL, 5)
self.m_radioBtn2 = wx.RadioButton(panel, wx.ID_ANY, u"RadioBtn", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_radioBtn2 = wx.RadioButton(panel, wx.ID_ANY, "RadioBtn", wx.DefaultPosition, wx.DefaultSize, 0)
contentSizer.Add(self.m_radioBtn2, 0, wx.ALL, 5)
self.m_slider2 = wx.Slider(panel, wx.ID_ANY, 50, 0, 100, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL)
@@ -80,14 +80,13 @@ class DummyView(PreferenceView):
def initFooter(self, panel):
footerSizer = wx.BoxSizer(wx.HORIZONTAL)
footerSizer.AddSpacer((0, 0), 1, wx.EXPAND, 5)
self.btnRestore = wx.Button(panel, wx.ID_ANY, u"Restore", wx.DefaultPosition, wx.DefaultSize, 0)
footerSizer.AddStretchSpacer()
self.btnRestore = wx.Button(panel, wx.ID_ANY, "Restore", wx.DefaultPosition, wx.DefaultSize, 0)
self.btnRestore.Enable(False)
footerSizer.Add(self.btnRestore, 0, wx.ALL, 5)
self.btnApply = wx.Button(panel, wx.ID_ANY, u"Apply", wx.DefaultPosition, wx.DefaultSize, 0)
self.btnApply = wx.Button(panel, wx.ID_ANY, "Apply", wx.DefaultPosition, wx.DefaultSize, 0)
footerSizer.Add(self.btnApply, 0, wx.ALL, 5)
return footerSizer

Some files were not shown because too many files have changed in this diff Show More