Merge branch 'development' into Remote_Repair_Pane_v2
Conflicts: eos/mathUtils.py service/crest.py
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,7 +49,6 @@ Pyfa.egg-info/
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
@@ -51,8 +51,7 @@ pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||
|
||||
## Resources
|
||||
* Development repository: [https://github.com/pyfa-org/Pyfa](https://github.com/pyfa-org/Pyfa)
|
||||
* XMPP conference: [pyfa@conference.jabber.org](pyfa@conference.jabber.org)
|
||||
* [EVE forum thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609)
|
||||
* [EVE forum thread](https://forums.eveonline.com/default.aspx?g=posts&t=466425)
|
||||
* [EVE University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||
* [EVE Online website](http://www.eveonline.com/)
|
||||
|
||||
|
||||
121
config.py
121
config.py
@@ -1,27 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
# TODO: move all logging back to pyfa.py main loop
|
||||
# We moved it here just to avoid rebuilding windows skeleton for now (any change to pyfa.py needs it)
|
||||
import logging
|
||||
import logging.handlers
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
# Load variable overrides specific to distribution type
|
||||
try:
|
||||
import configforced
|
||||
except ImportError:
|
||||
pyfalog.warning("Failed to import: configforced")
|
||||
configforced = None
|
||||
|
||||
|
||||
# Turns on debug mode
|
||||
debug = False
|
||||
# Defines if our saveddata will be in pyfa root or not
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.26.1"
|
||||
version = "1.27.3"
|
||||
tag = "git"
|
||||
expansionName = "YC118.10"
|
||||
expansionVersion = "1.2"
|
||||
expansionName = "YC119.2"
|
||||
expansionVersion = "1.4"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
pyfaPath = None
|
||||
@@ -30,22 +31,6 @@ saveDB = None
|
||||
gameDB = None
|
||||
|
||||
|
||||
class StreamToLogger(object):
|
||||
"""
|
||||
Fake file-like stream object that redirects writes to a logger instance.
|
||||
From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/
|
||||
"""
|
||||
|
||||
def __init__(self, logger, log_level=logging.INFO):
|
||||
self.logger = logger
|
||||
self.log_level = log_level
|
||||
self.linebuf = ''
|
||||
|
||||
def write(self, buf):
|
||||
for line in buf.rstrip().splitlines():
|
||||
self.logger.log(self.log_level, line.rstrip())
|
||||
|
||||
|
||||
def isFrozen():
|
||||
if hasattr(sys, 'frozen'):
|
||||
return True
|
||||
@@ -58,6 +43,17 @@ def __createDirs(path):
|
||||
os.makedirs(path)
|
||||
|
||||
|
||||
def getPyfaRoot():
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
|
||||
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||
root = unicode(root, sys.getfilesystemencoding())
|
||||
return root
|
||||
|
||||
|
||||
def getDefaultSave():
|
||||
return unicode(os.path.expanduser(os.path.join("~", ".pyfa")), sys.getfilesystemencoding())
|
||||
|
||||
|
||||
def defPaths(customSavePath):
|
||||
global debug
|
||||
global pyfaPath
|
||||
@@ -66,65 +62,42 @@ def defPaths(customSavePath):
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
|
||||
if debug:
|
||||
logLevel = logging.DEBUG
|
||||
else:
|
||||
logLevel = logging.WARN
|
||||
pyfalog.debug("Configuring Pyfa")
|
||||
|
||||
# The main pyfa directory which contains run.py
|
||||
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
||||
pyfaPath = getattr(configforced, "pyfaPath", pyfaPath)
|
||||
if pyfaPath is None:
|
||||
pyfaPath = getPyfaPath()
|
||||
pyfaPath = getPyfaRoot()
|
||||
|
||||
# Where we store the saved fits etc, default is the current users home directory
|
||||
if saveInRoot is True:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
savePath = getPyfaPath("saveddata")
|
||||
savePath = os.path.join(pyfaPath, "saveddata")
|
||||
else:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
if customSavePath is None: # customSavePath is not overriden
|
||||
savePath = os.path.expanduser(os.path.join("~", ".pyfa"))
|
||||
savePath = getDefaultSave()
|
||||
else:
|
||||
savePath = customSavePath
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
if isFrozen():
|
||||
certName = "cacert.pem"
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = getPyfaPath(certName).encode('utf8')
|
||||
os.environ["SSL_CERT_FILE"] = getPyfaPath(certName).encode('utf8')
|
||||
|
||||
loggingFormat = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
|
||||
logging.basicConfig(format=loggingFormat, level=logLevel)
|
||||
handler = logging.handlers.RotatingFileHandler(getSavePath("log.txt"), maxBytes=1000000, backupCount=3)
|
||||
formatter = logging.Formatter(loggingFormat)
|
||||
handler.setFormatter(formatter)
|
||||
logging.getLogger('').addHandler(handler)
|
||||
|
||||
logging.info("Starting pyfa")
|
||||
|
||||
if hasattr(sys, 'frozen'):
|
||||
stdout_logger = logging.getLogger('STDOUT')
|
||||
sl = StreamToLogger(stdout_logger, logging.INFO)
|
||||
sys.stdout = sl
|
||||
|
||||
# This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this.
|
||||
# stderr_logger = logging.getLogger('STDERR')
|
||||
# sl = StreamToLogger(stderr_logger, logging.ERROR)
|
||||
# sys.stderr = sl
|
||||
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')
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = getSavePath("saveddata.db")
|
||||
saveDB = os.path.join(savePath, "saveddata.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
|
||||
# maintenance script
|
||||
gameDB = getPyfaPath("eve.db")
|
||||
gameDB = os.path.join(pyfaPath, "eve.db")
|
||||
|
||||
# DON'T MODIFY ANYTHING BELOW!
|
||||
# DON'T MODIFY ANYTHING BELOW
|
||||
import eos.config
|
||||
|
||||
# Caching modifiers, disable all gamedata caching, its unneeded.
|
||||
@@ -132,41 +105,3 @@ def defPaths(customSavePath):
|
||||
# saveddata db location modifier, shouldn't ever need to touch this
|
||||
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
||||
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
||||
|
||||
|
||||
def getPyfaPath(Append=None):
|
||||
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else sys.argv[0]
|
||||
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||
|
||||
if Append:
|
||||
path = parsePath(root, Append)
|
||||
else:
|
||||
path = parsePath(root)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def getSavePath(Append=None):
|
||||
root = savePath
|
||||
|
||||
if Append:
|
||||
path = parsePath(root, Append)
|
||||
else:
|
||||
path = parsePath(root)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def parsePath(root, Append=None):
|
||||
if Append:
|
||||
path = os.path.join(root, Append)
|
||||
else:
|
||||
path = root
|
||||
|
||||
if type(path) == str: # leave unicode ones alone
|
||||
try:
|
||||
path = path.decode('utf8')
|
||||
except UnicodeDecodeError:
|
||||
path = path.decode('windows-1252')
|
||||
|
||||
return path
|
||||
|
||||
5666
dist_assets/cacert.pem
Normal file
5666
dist_assets/cacert.pem
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,9 @@ from sqlalchemy.orm import sessionmaker
|
||||
|
||||
import migration
|
||||
from eos import config
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ReadOnlyException(Exception):
|
||||
@@ -46,7 +49,9 @@ try:
|
||||
config.gamedata_version = gamedata_session.execute(
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||
).fetchone()[0]
|
||||
except:
|
||||
except Exception as e:
|
||||
pyfalog.warning("Missing gamedata version.")
|
||||
pyfalog.critical(e)
|
||||
config.gamedata_version = None
|
||||
|
||||
saveddata_connectionstring = config.saveddata_connectionstring
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import logging
|
||||
from logbook import Logger
|
||||
import shutil
|
||||
import time
|
||||
|
||||
import config
|
||||
import migrations
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
def getVersion(db):
|
||||
@@ -37,7 +37,7 @@ def update(saveddata_engine):
|
||||
for version in xrange(dbVersion, appVersion):
|
||||
func = migrations.updates[version + 1]
|
||||
if func:
|
||||
logger.info("Applying database update: %d", version + 1)
|
||||
pyfalog.info("Applying database update: {0}", version + 1)
|
||||
func(saveddata_engine)
|
||||
|
||||
# when all is said and done, set version to current
|
||||
|
||||
10
eos/db/migrations/upgrade21.py
Normal file
10
eos/db/migrations/upgrade21.py
Normal file
@@ -0,0 +1,10 @@
|
||||
"""
|
||||
Migration 21
|
||||
|
||||
- Fixes discrepancy in drone table where we may have an amount active that is not equal to the amount in the stack
|
||||
(we don't support activating only 2/5 drones). See GH issue #728
|
||||
"""
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute("UPDATE drones SET amountActive = amount where amountActive > 0 AND amountActive <> amount;")
|
||||
@@ -18,9 +18,9 @@
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.exc import DatabaseError
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class DatabaseCleanup(object):
|
||||
@@ -33,7 +33,7 @@ class DatabaseCleanup(object):
|
||||
results = saveddata_engine.execute(query)
|
||||
return results
|
||||
except DatabaseError:
|
||||
logger.error("Failed to connect to database or error executing query:\n%s", query)
|
||||
pyfalog.error("Failed to connect to database or error executing query:\n{0}", query)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
@@ -41,7 +41,7 @@ class DatabaseCleanup(object):
|
||||
# Find orphaned character skills.
|
||||
# This solves an issue where the character doesn't exist, but skills for that character do.
|
||||
# See issue #917
|
||||
logger.debug("Running database cleanup for character skills.")
|
||||
pyfalog.debug("Running database cleanup for character skills.")
|
||||
query = "SELECT COUNT(*) AS num FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -53,14 +53,14 @@ class DatabaseCleanup(object):
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def OrphanedFitDamagePatterns(saveddata_engine):
|
||||
# Find orphaned damage patterns.
|
||||
# This solves an issue where the damage pattern doesn't exist, but fits reference the pattern.
|
||||
# See issue #777
|
||||
logger.debug("Running database cleanup for orphaned damage patterns attached to fits.")
|
||||
pyfalog.debug("Running database cleanup for orphaned damage patterns attached to fits.")
|
||||
query = "SELECT COUNT(*) AS num FROM fits WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -80,20 +80,20 @@ class DatabaseCleanup(object):
|
||||
rows = uniform_results.fetchall()
|
||||
|
||||
if len(rows) == 0:
|
||||
logger.error("Missing uniform damage pattern.")
|
||||
pyfalog.error("Missing uniform damage pattern.")
|
||||
elif len(rows) > 1:
|
||||
logger.error("More than one uniform damage pattern found.")
|
||||
pyfalog.error("More than one uniform damage pattern found.")
|
||||
else:
|
||||
uniform_damage_pattern_id = rows[0]['ID']
|
||||
update_query = "UPDATE 'fits' SET 'damagePatternID' = {} " \
|
||||
"WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL".format(uniform_damage_pattern_id)
|
||||
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", update_results.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", update_results.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def OrphanedFitCharacterIDs(saveddata_engine):
|
||||
# Find orphaned character IDs. This solves an issue where the character doesn't exist, but fits reference the pattern.
|
||||
logger.debug("Running database cleanup for orphaned characters attached to fits.")
|
||||
pyfalog.debug("Running database cleanup for orphaned characters attached to fits.")
|
||||
query = "SELECT COUNT(*) AS num FROM fits WHERE characterID NOT IN (SELECT ID FROM characters) OR characterID IS NULL"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -113,22 +113,22 @@ class DatabaseCleanup(object):
|
||||
rows = all5_results.fetchall()
|
||||
|
||||
if len(rows) == 0:
|
||||
logger.error("Missing 'All 5' character.")
|
||||
pyfalog.error("Missing 'All 5' character.")
|
||||
elif len(rows) > 1:
|
||||
logger.error("More than one 'All 5' character found.")
|
||||
pyfalog.error("More than one 'All 5' character found.")
|
||||
else:
|
||||
all5_id = rows[0]['ID']
|
||||
update_query = "UPDATE 'fits' SET 'characterID' = " + str(all5_id) + \
|
||||
" WHERE characterID not in (select ID from characters) OR characterID IS NULL"
|
||||
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", update_results.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", update_results.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def NullDamagePatternNames(saveddata_engine):
|
||||
# Find damage patterns that are missing the name.
|
||||
# This solves an issue where the damage pattern ends up with a name that is null.
|
||||
# See issue #949
|
||||
logger.debug("Running database cleanup for missing damage pattern names.")
|
||||
pyfalog.debug("Running database cleanup for missing damage pattern names.")
|
||||
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name IS NULL OR name = ''"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -140,14 +140,14 @@ class DatabaseCleanup(object):
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM damagePatterns WHERE name IS NULL OR name = ''"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def NullTargetResistNames(saveddata_engine):
|
||||
# Find target resists that are missing the name.
|
||||
# This solves an issue where the target resist ends up with a name that is null.
|
||||
# See issue #949
|
||||
logger.debug("Running database cleanup for missing target resist names.")
|
||||
pyfalog.debug("Running database cleanup for missing target resist names.")
|
||||
query = "SELECT COUNT(*) AS num FROM targetResists WHERE name IS NULL OR name = ''"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -159,14 +159,14 @@ class DatabaseCleanup(object):
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM targetResists WHERE name IS NULL OR name = ''"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def OrphanedFitIDItemID(saveddata_engine):
|
||||
# Orphaned items that are missing the fit ID or item ID.
|
||||
# See issue #954
|
||||
for table in ['drones', 'cargo', 'fighters']:
|
||||
logger.debug("Running database cleanup for orphaned %s items.", table)
|
||||
pyfalog.debug("Running database cleanup for orphaned {0} items.", table)
|
||||
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||
table)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
@@ -180,10 +180,10 @@ class DatabaseCleanup(object):
|
||||
query = "DELETE FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||
table)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
for table in ['modules']:
|
||||
logger.debug("Running database cleanup for orphaned %s items.", table)
|
||||
pyfalog.debug("Running database cleanup for orphaned {0} items.", table)
|
||||
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||
table)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
@@ -196,7 +196,7 @@ class DatabaseCleanup(object):
|
||||
if row and row['num']:
|
||||
query = "DELETE FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def NullDamageTargetPatternValues(saveddata_engine):
|
||||
@@ -204,7 +204,7 @@ class DatabaseCleanup(object):
|
||||
# See issue #954
|
||||
for profileType in ['damagePatterns', 'targetResists']:
|
||||
for damageType in ['em', 'thermal', 'kinetic', 'explosive']:
|
||||
logger.debug("Running database cleanup for null %s values. (%s)", profileType, damageType)
|
||||
pyfalog.debug("Running database cleanup for null {0} values. ({1})", profileType, damageType)
|
||||
query = "SELECT COUNT(*) AS num FROM {0} WHERE {1}Amount IS NULL OR {1}Amount = ''".format(profileType,
|
||||
damageType)
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
@@ -218,13 +218,13 @@ class DatabaseCleanup(object):
|
||||
query = "UPDATE '{0}' SET '{1}Amount' = '0' WHERE {1}Amount IS NULL OR Amount = ''".format(profileType,
|
||||
damageType)
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@staticmethod
|
||||
def DuplicateSelectedAmmoName(saveddata_engine):
|
||||
# Orphaned items that are missing the fit ID or item ID.
|
||||
# See issue #954
|
||||
logger.debug("Running database cleanup for duplicated selected ammo profiles.")
|
||||
pyfalog.debug("Running database cleanup for duplicated selected ammo profiles.")
|
||||
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
@@ -236,4 +236,4 @@ class DatabaseCleanup(object):
|
||||
if row and row['num'] > 1:
|
||||
query = "DELETE FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
logger.error("Database corruption found. Cleaning up %d records.", delete.rowcount)
|
||||
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class HandledList(list):
|
||||
@@ -198,7 +198,7 @@ class HandledImplantBoosterList(HandledList):
|
||||
# if needed, remove booster that was occupying slot
|
||||
oldObj = next((m for m in self if m.slot == thing.slot), None)
|
||||
if oldObj:
|
||||
logging.info("Slot %d occupied with %s, replacing with %s", thing.slot, oldObj.item.name, thing.item.name)
|
||||
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name, thing.item.name)
|
||||
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
|
||||
self.remove(oldObj)
|
||||
|
||||
@@ -222,7 +222,7 @@ class HandledProjectedModList(HandledList):
|
||||
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
||||
|
||||
if oldEffect:
|
||||
logging.info("System effect occupied with %s, replacing with %s", oldEffect.item.name, proj.item.name)
|
||||
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||
self.remove(oldEffect)
|
||||
|
||||
HandledList.append(self, proj)
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Reactive Armor Hardener
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
runTime = "late"
|
||||
type = "active"
|
||||
@@ -23,7 +23,7 @@ def handler(fit, module, context):
|
||||
damagePattern.kineticAmount * fit.ship.getModifiedItemAttr('armorKineticDamageResonance'),
|
||||
damagePattern.explosiveAmount * fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'),
|
||||
)
|
||||
# logger.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
|
||||
# pyfalog.debug("Damage Adjusted for Armor Resists: %f/%f/%f/%f", baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
|
||||
|
||||
resistanceShiftAmount = module.getModifiedItemAttr(
|
||||
'resistanceShiftAmount') / 100 # The attribute is in percent and we want a fraction
|
||||
@@ -39,7 +39,7 @@ def handler(fit, module, context):
|
||||
cycleList = []
|
||||
loopStart = -20
|
||||
for num in range(50):
|
||||
# logger.debug("Starting cycle %d.", num)
|
||||
# pyfalog.debug("Starting cycle %d.", num)
|
||||
# The strange order is to emulate the ingame sorting when different types have taken the same amount of damage.
|
||||
# This doesn't take into account stacking penalties. In a few cases fitting a Damage Control causes an inaccurate result.
|
||||
damagePattern_tuples = [
|
||||
@@ -77,7 +77,7 @@ def handler(fit, module, context):
|
||||
RAHResistance[sortedDamagePattern_tuples[1][0]] = sortedDamagePattern_tuples[1][2] + change1
|
||||
RAHResistance[sortedDamagePattern_tuples[2][0]] = sortedDamagePattern_tuples[2][2] + change2
|
||||
RAHResistance[sortedDamagePattern_tuples[3][0]] = sortedDamagePattern_tuples[3][2] + change3
|
||||
# logger.debug("Resistances shifted to %f/%f/%f/%f", RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3])
|
||||
# pyfalog.debug("Resistances shifted to %f/%f/%f/%f", RAHResistance[0], RAHResistance[1], RAHResistance[2], RAHResistance[3])
|
||||
|
||||
# See if the current RAH profile has been encountered before, indicating a loop.
|
||||
for i, val in enumerate(cycleList):
|
||||
@@ -87,7 +87,7 @@ def handler(fit, module, context):
|
||||
abs(RAHResistance[2] - val[2]) <= tolerance and \
|
||||
abs(RAHResistance[3] - val[3]) <= tolerance:
|
||||
loopStart = i
|
||||
# logger.debug("Loop found: %d-%d", loopStart, num)
|
||||
# pyfalog.debug("Loop found: %d-%d", loopStart, num)
|
||||
break
|
||||
if loopStart >= 0:
|
||||
break
|
||||
@@ -95,7 +95,7 @@ def handler(fit, module, context):
|
||||
cycleList.append(list(RAHResistance))
|
||||
|
||||
if loopStart < 0:
|
||||
logger.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: %f/%f/%f/%f",
|
||||
pyfalog.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: {0}/{1}/{2}/{3}",
|
||||
baseDamageTaken[0], baseDamageTaken[1], baseDamageTaken[2], baseDamageTaken[3])
|
||||
|
||||
# Average the profiles in the RAH loop, or the last 20 if it didn't find a loop.
|
||||
@@ -110,7 +110,7 @@ def handler(fit, module, context):
|
||||
average[i] = round(average[i] / numCycles, 3)
|
||||
|
||||
# Set the new resistances
|
||||
# logger.debug("Setting new resist profile: %f/%f/%f/%f", average[0], average[1], average[2],average[3])
|
||||
# pyfalog.debug("Setting new resist profile: %f/%f/%f/%f", average[0], average[1], average[2],average[3])
|
||||
for i, attr in enumerate((
|
||||
'armorEmDamageResonance', 'armorThermalDamageResonance', 'armorKineticDamageResonance',
|
||||
'armorExplosiveDamageResonance')):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceCapNeed
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (465 of 899)
|
||||
# Items from category: Charge (465 of 912)
|
||||
# Charges from group: Frequency Crystal (185 of 185)
|
||||
# Charges from group: Hybrid Charge (209 of 209)
|
||||
type = "passive"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoInfluenceRange
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (571 of 899)
|
||||
# Items from category: Charge (571 of 912)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ammoSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Festival Charges (9 of 9)
|
||||
# Charges from group: Festival Charges (22 of 22)
|
||||
# Charges from group: Interdiction Probe (2 of 2)
|
||||
# Charges from group: Survey Probe (3 of 3)
|
||||
type = "passive"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Used by:
|
||||
# Modules from group: Armor Coating (202 of 202)
|
||||
# Modules from group: Armor Plating Energized (187 of 187)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armorRepairAmountBonusSubcap
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Grade Asklepian (15 of 16)
|
||||
# Implants named like: grade Asklepian (15 of 18)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Data Miners (15 of 16)
|
||||
# Module: QA Cross Protocol Analyzer
|
||||
type = "active"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Automated Targeting System (6 of 6)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Heat Sink (18 of 18)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Tracking Enhancer (10 of 10)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Tracking Enhancer (10 of 10)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Tracking Enhancer (10 of 10)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Magnetic Field Stabilizer (14 of 14)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Value",
|
||||
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Value",
|
||||
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration",
|
||||
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Value",
|
||||
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier",
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Value",
|
||||
src.getModifiedItemAttr("shipBonusICS2"), skill="Industrial Command Ships")
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Ballistic Control system (17 of 17)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
# Modules from group: Reactor Control Unit (22 of 22)
|
||||
# Modules from group: Shield Recharger (4 of 4)
|
||||
# Modules named like: Flux Coil (12 of 12)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# remoteWeaponDisruptEntity
|
||||
# npcEntityWeaponDisruptor
|
||||
#
|
||||
# Used by:
|
||||
# Drones named like: TD (3 of 3)
|
||||
@@ -11,8 +11,6 @@
|
||||
# Modules from group: Smart Bomb (118 of 118)
|
||||
# Modules from group: Warp Disrupt Field Generator (7 of 7)
|
||||
# Modules named like: Ancillary Remote (8 of 8)
|
||||
# Module: QA Remote Armor Repair System - 5 Players
|
||||
# Module: QA Shield Transporter - 5 Players
|
||||
# Module: Reactive Armor Hardener
|
||||
# Module: Target Spectrum Breaker
|
||||
type = "overheat"
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Gyrostabilizer (13 of 13)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# scanStrengthBonusPercentActivate
|
||||
#
|
||||
# Used by:
|
||||
# Module: QA ECCM
|
||||
# Not used by any item
|
||||
type = "active"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# scanStrengthBonusPercentPassive
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: High grade (20 of 61)
|
||||
# Implants named like: High grade (20 of 66)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# setBonusAsklepian
|
||||
#
|
||||
# Used by:
|
||||
# Implants named like: Grade Asklepian (16 of 16)
|
||||
# Implants named like: grade Asklepian Omega (2 of 2)
|
||||
# Implants named like: grade Asklepian (18 of 18)
|
||||
runTime = "early"
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# shieldTransfer
|
||||
#
|
||||
# Used by:
|
||||
# Module: QA Shield Transporter - 5 Players
|
||||
# Not used by any item
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# remoteGuidanceDisruptFalloff
|
||||
# shipModuleGuidanceDisruptor
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Guidance Disruptor I (6 of 6)
|
||||
@@ -1,4 +1,4 @@
|
||||
# remoteTrackingAssistFalloff
|
||||
# shipModuleRemoteTrackingComputer
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Remote Tracking Computer (8 of 8)
|
||||
@@ -1,4 +1,4 @@
|
||||
# remoteTrackingDisruptFalloff
|
||||
# shipModuleTrackingDisruptor
|
||||
#
|
||||
# Used by:
|
||||
# Variations of module: Tracking Disruptor I (6 of 6)
|
||||
@@ -2,7 +2,6 @@
|
||||
#
|
||||
# Used by:
|
||||
# Modules from group: Signal Amplifier (7 of 7)
|
||||
# Module: QA Damage Module
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# standardMissilesSkillBoostMissileVelocityBonus
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Defender Missiles
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Defender Missiles"),
|
||||
"maxVelocity", skill.getModifiedItemAttr("missileVelocityBonus") * skill.level)
|
||||
@@ -3,7 +3,6 @@
|
||||
# Used by:
|
||||
# Implants named like: Inherent Implants 'Noble' Repair Proficiency RP (6 of 6)
|
||||
# Modules named like: Auxiliary Nano Pump (8 of 8)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
# Implant: Imperial Navy Modified 'Noble' Implant
|
||||
type = "passive"
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Used by:
|
||||
# Modules from group: Nanofiber Internal Structure (7 of 7)
|
||||
# Modules from group: Reinforced Bulkhead (8 of 8)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# targetArmorRepair
|
||||
#
|
||||
# Used by:
|
||||
# Module: QA Remote Armor Repair System - 5 Players
|
||||
# Not used by any item
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Not used by any item
|
||||
type = "projected", "active"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
if "projected" in context:
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"trackingSpeed", container.getModifiedItemAttr("trackingSpeedMultiplier"),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"maxRange", container.getModifiedItemAttr("maxRangeMultiplier"),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
fit.modules.filteredItemMultiply(lambda mod: mod.item.requiresSkill("Gunnery"),
|
||||
"falloff", container.getModifiedItemAttr("fallofMultiplier"),
|
||||
stackingPenalties=True, penaltyGroup="postMul")
|
||||
@@ -3,7 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Missile Launcher Heavy (12 of 12)
|
||||
# Modules from group: Missile Launcher Rocket (15 of 15)
|
||||
# Modules named like: Launcher (151 of 151)
|
||||
# Modules named like: Launcher (153 of 153)
|
||||
type = 'active', "projected"
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
# ===============================================================================
|
||||
|
||||
import re
|
||||
import traceback
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
@@ -30,6 +29,9 @@ try:
|
||||
except ImportError:
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Effect(EqBase):
|
||||
"""
|
||||
@@ -45,9 +47,6 @@ class Effect(EqBase):
|
||||
# Filter to change names of effects to valid python method names
|
||||
nameFilter = re.compile("[^A-Za-z0-9]")
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
"""
|
||||
@@ -67,6 +66,8 @@ class Effect(EqBase):
|
||||
if not self.__generated:
|
||||
self.__generateHandler()
|
||||
|
||||
pyfalog.debug("Generating effect: {0} ({1}) [runTime: {2}]", self.name, self.effectID, self.runTime)
|
||||
|
||||
return self.__handler
|
||||
|
||||
@property
|
||||
@@ -141,7 +142,7 @@ class Effect(EqBase):
|
||||
@property
|
||||
def isImplemented(self):
|
||||
"""
|
||||
Wether this effect is implemented in code or not,
|
||||
Whether this effect is implemented in code or not,
|
||||
unimplemented effects simply do nothing at all when run
|
||||
"""
|
||||
return self.handler != effectDummy
|
||||
@@ -182,13 +183,16 @@ class Effect(EqBase):
|
||||
|
||||
t = t if isinstance(t, tuple) or t is None else (t,)
|
||||
self.__type = t
|
||||
except (ImportError, AttributeError):
|
||||
except (ImportError, AttributeError) as e:
|
||||
self.__handler = effectDummy
|
||||
self.__runTime = "normal"
|
||||
self.__activeByDefault = True
|
||||
self.__type = None
|
||||
pyfalog.debug("ImportError or AttributeError generating handler:")
|
||||
pyfalog.debug(e)
|
||||
except Exception as e:
|
||||
traceback.print_exc(e)
|
||||
pyfalog.critical("Exception generating handler:")
|
||||
pyfalog.critical(e)
|
||||
|
||||
self.__generated = True
|
||||
|
||||
@@ -210,9 +214,6 @@ class Item(EqBase):
|
||||
|
||||
MOVE_ATTR_INFO = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def getMoveAttrInfo(cls):
|
||||
info = getattr(cls, "MOVE_ATTR_INFO", None)
|
||||
@@ -453,8 +454,6 @@ class Category(EqBase):
|
||||
|
||||
|
||||
class AlphaClone(EqBase):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
@@ -483,8 +482,6 @@ class Icon(EqBase):
|
||||
|
||||
|
||||
class MarketGroup(EqBase):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return u"MarketGroup(ID={}, name={}, parent={}) at {}".format(
|
||||
@@ -497,9 +494,6 @@ class MetaGroup(EqBase):
|
||||
|
||||
|
||||
class MetaType(EqBase):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ from math import log, sin, radians, exp
|
||||
|
||||
from eos.graph import Graph
|
||||
from eos.saveddata.module import State, Hardpoint
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class FitDpsGraph(Graph):
|
||||
@@ -65,8 +68,9 @@ class FitDpsGraph(Graph):
|
||||
bonus = values[i]
|
||||
val *= 1 + (bonus - 1) * exp(- i ** 2 / 7.1289)
|
||||
data[attr] = val
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Caught exception in calcDPS.")
|
||||
pyfalog.critical(e)
|
||||
|
||||
for mod in fit.modules:
|
||||
dps, _ = mod.damageStats(fit.targetResists)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import reconstructor, validates
|
||||
|
||||
@@ -25,7 +25,7 @@ import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Booster(HandledItem, ItemAttrShortcut):
|
||||
@@ -47,11 +47,11 @@ class Booster(HandledItem, ItemAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
logger.error("Item (id: %d) is not a Booser", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) is not a Booster", self.itemID)
|
||||
return
|
||||
|
||||
self.build()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
@@ -26,7 +26,7 @@ import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Cargo(HandledItem, ItemAttrShortcut):
|
||||
@@ -47,7 +47,7 @@ class Cargo(HandledItem, ItemAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
from itertools import chain
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
@@ -27,7 +27,7 @@ import eos
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledImplantBoosterList
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Character(object):
|
||||
@@ -140,7 +140,17 @@ class Character(object):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.savedName if not self.isDirty else "{} *".format(self.savedName)
|
||||
name = self.savedName
|
||||
|
||||
if self.isDirty:
|
||||
name += " *"
|
||||
|
||||
if self.alphaCloneID:
|
||||
clone = eos.db.getAlphaClone(self.alphaCloneID)
|
||||
type = clone.alphaCloneName.split()[1]
|
||||
name += u' (\u03B1{})'.format(type[0].upper())
|
||||
|
||||
return name
|
||||
|
||||
@name.setter
|
||||
def name(self, name):
|
||||
|
||||
@@ -17,16 +17,17 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from eos.saveddata.ship import Ship
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Citadel(Ship):
|
||||
def validate(self, item):
|
||||
if item.category.name != "Structure":
|
||||
pyfalog.error("Passed item '{0}' (category: {1}) is not under Structure category", item.name, item.category.name)
|
||||
raise ValueError(
|
||||
'Passed item "%s" (category: (%s)) is not under Structure category' % (item.name, item.category.name))
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
@@ -25,7 +25,7 @@ import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@@ -53,11 +53,11 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
logger.error("Item (id: %d) is not a Drone", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) is not a Drone", self.itemID)
|
||||
return
|
||||
|
||||
self.build()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
@@ -27,7 +27,7 @@ from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, C
|
||||
from eos.saveddata.fighterAbility import FighterAbility
|
||||
from eos.saveddata.module import Slot
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@@ -61,11 +61,11 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
logger.error("Item (id: %d) is not a Fighter", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) is not a Fighter", self.itemID)
|
||||
return
|
||||
|
||||
self.build()
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class FighterAbility(object):
|
||||
@@ -59,7 +59,7 @@ class FighterAbility(object):
|
||||
if self.effectID:
|
||||
self.__effect = next((x for x in self.fighter.item.effects.itervalues() if x.ID == self.effectID), None)
|
||||
if self.__effect is None:
|
||||
logger.error("Effect (id: %d) does not exist", self.effectID)
|
||||
pyfalog.error("Effect (id: {0}) does not exist", self.effectID)
|
||||
return
|
||||
|
||||
self.build()
|
||||
|
||||
@@ -33,9 +33,9 @@ from eos.saveddata.character import Character
|
||||
from eos.saveddata.citadel import Citadel
|
||||
from eos.saveddata.module import Module, State, Slot, Hardpoint
|
||||
from utils.timer import Timer
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ImplantLocation(Enum):
|
||||
@@ -84,7 +84,7 @@ class Fit(object):
|
||||
if self.shipID:
|
||||
item = eos.db.getItem(self.shipID)
|
||||
if item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.shipID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.shipID)
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -97,7 +97,7 @@ class Fit(object):
|
||||
# change all instances in source). Remove this at some point
|
||||
self.extraAttributes = self.__ship.itemModifiedAttributes
|
||||
except ValueError:
|
||||
logger.error("Item (id: %d) is not a Ship", self.shipID)
|
||||
pyfalog.error("Item (id: {0}) is not a Ship", self.shipID)
|
||||
return
|
||||
|
||||
if self.modeID and self.__ship:
|
||||
@@ -457,7 +457,7 @@ class Fit(object):
|
||||
self.commandBonuses[warfareBuffID] = (runTime, value, module, effect)
|
||||
|
||||
def __runCommandBoosts(self, runTime="normal"):
|
||||
logger.debug("Applying gang boosts for %r", self)
|
||||
pyfalog.debug("Applying gang boosts for {0}", self)
|
||||
for warfareBuffID in self.commandBonuses.keys():
|
||||
# Unpack all data required to run effect properly
|
||||
effect_runTime, value, thing, effect = self.commandBonuses[warfareBuffID]
|
||||
@@ -639,21 +639,21 @@ class Fit(object):
|
||||
del self.commandBonuses[warfareBuffID]
|
||||
|
||||
def calculateModifiedAttributes(self, targetFit=None, withBoosters=False, dirtyStorage=None):
|
||||
timer = Timer(u'Fit: {}, {}'.format(self.ID, self.name), logger)
|
||||
logger.debug("Starting fit calculation on: %r, withBoosters: %s", self, withBoosters)
|
||||
timer = Timer(u'Fit: {}, {}'.format(self.ID, self.name), pyfalog)
|
||||
pyfalog.debug("Starting fit calculation on: {0}, withBoosters: {1}", self, withBoosters)
|
||||
|
||||
shadow = False
|
||||
if targetFit and not withBoosters:
|
||||
logger.debug("Applying projections to target: %r", targetFit)
|
||||
pyfalog.debug("Applying projections to target: {0}", targetFit)
|
||||
projectionInfo = self.getProjectionInfo(targetFit.ID)
|
||||
logger.debug("ProjectionInfo: %s", projectionInfo)
|
||||
pyfalog.debug("ProjectionInfo: {0}", projectionInfo)
|
||||
if self == targetFit:
|
||||
copied = self # original fit
|
||||
shadow = True
|
||||
# Don't inspect this, we genuinely want to reassign self
|
||||
# noinspection PyMethodFirstArgAssignment
|
||||
self = deepcopy(self)
|
||||
logger.debug("Handling self projection - making shadow copy of fit. %r => %r", copied, self)
|
||||
pyfalog.debug("Handling self projection - making shadow copy of fit. {0} => {1}", copied, self)
|
||||
# we delete the fit because when we copy a fit, flush() is
|
||||
# called to properly handle projection updates. However, we do
|
||||
# not want to save this fit to the database, so simply remove it
|
||||
@@ -688,7 +688,7 @@ class Fit(object):
|
||||
# projection have modifying stuff applied, such as gang boosts and other
|
||||
# local modules that may help
|
||||
if self.__calculated and not projected and not withBoosters:
|
||||
logger.debug("Fit has already been calculated and is not projected, returning: %r", self)
|
||||
pyfalog.debug("Fit has already been calculated and is not projected, returning: {0}", self)
|
||||
return
|
||||
|
||||
for runTime in ("early", "normal", "late"):
|
||||
@@ -739,6 +739,10 @@ class Fit(object):
|
||||
# targetFit.register(item, origin=self)
|
||||
item.calculateModifiedAttributes(targetFit, runTime, False, True)
|
||||
|
||||
if len(self.commandBonuses) > 0:
|
||||
pyfalog.info("Command bonuses applied.")
|
||||
pyfalog.debug(self.commandBonuses)
|
||||
|
||||
if not withBoosters and self.commandBonuses:
|
||||
self.__runCommandBoosts(runTime)
|
||||
|
||||
@@ -756,7 +760,7 @@ class Fit(object):
|
||||
timer.checkpoint('Done with fit calculation')
|
||||
|
||||
if shadow:
|
||||
logger.debug("Delete shadow fit object")
|
||||
pyfalog.debug("Delete shadow fit object")
|
||||
del self
|
||||
|
||||
def fill(self):
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
@@ -25,7 +25,7 @@ import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Implant(HandledItem, ItemAttrShortcut):
|
||||
@@ -46,11 +46,11 @@ class Implant(HandledItem, ItemAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
logger.error("Item (id: %d) is not an Implant", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) is not an Implant", self.itemID)
|
||||
return
|
||||
|
||||
self.build()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
from math import floor
|
||||
@@ -28,7 +28,7 @@ from eos.enum import Enum
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.saveddata.citadel import Citadel
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class State(Enum):
|
||||
@@ -94,11 +94,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
if self.isInvalid:
|
||||
logger.error("Item (id: %d) is not a Module", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) is not a Module", self.itemID)
|
||||
return
|
||||
|
||||
if self.chargeID:
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.eqBase import EqBase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Override(EqBase):
|
||||
@@ -43,13 +43,13 @@ class Override(EqBase):
|
||||
if self.attrID:
|
||||
self.__attr = eos.db.getAttributeInfo(self.attrID)
|
||||
if self.__attr is None:
|
||||
logger.error("Attribute (id: %d) does not exist", self.attrID)
|
||||
pyfalog.error("Attribute (id: {0}) does not exist", self.attrID)
|
||||
return
|
||||
|
||||
if self.itemID:
|
||||
self.__item = eos.db.getItem(self.itemID)
|
||||
if self.__item is None:
|
||||
logger.error("Item (id: %d) does not exist", self.itemID)
|
||||
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
|
||||
return
|
||||
|
||||
@property
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, cappingAttrKeyCache
|
||||
from eos.saveddata.mode import Mode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Ship(ItemAttrShortcut, HandledItem):
|
||||
@@ -63,6 +63,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
|
||||
def validate(self, item):
|
||||
if item.category.name != "Ship":
|
||||
pyfalog.error("Passed item '{0}' (category: {1}) is not under Ship category", item.name, item.category.name)
|
||||
raise ValueError(
|
||||
'Passed item "%s" (category: (%s)) is not under Ship category' % (item.name, item.category.name))
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
# ===============================================================================
|
||||
|
||||
import re
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class TargetResists(object):
|
||||
@@ -43,7 +46,7 @@ class TargetResists(object):
|
||||
type, data = line.rsplit('=', 1)
|
||||
type, data = type.strip(), data.split(',')
|
||||
except:
|
||||
# Data isn't in correct format, continue to next line
|
||||
pyfalog.warning("Data isn't in correct format, continue to next line.")
|
||||
continue
|
||||
|
||||
if type != "TargetResists":
|
||||
@@ -59,6 +62,7 @@ class TargetResists(object):
|
||||
assert 0 <= val <= 100
|
||||
fields["%sAmount" % cls.DAMAGE_TYPES[index]] = val / 100
|
||||
except:
|
||||
pyfalog.warning("Caught unhandled exception in import patterns.")
|
||||
continue
|
||||
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
|
||||
@@ -20,13 +20,15 @@
|
||||
import cStringIO
|
||||
import os.path
|
||||
import zipfile
|
||||
from config import parsePath
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import config
|
||||
|
||||
from logbook import Logger
|
||||
logging = Logger(__name__)
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
@@ -35,8 +37,10 @@ except ImportError:
|
||||
|
||||
class BitmapLoader(object):
|
||||
try:
|
||||
archive = zipfile.ZipFile(config.getPyfaPath('imgs.zip'), 'r')
|
||||
archive = zipfile.ZipFile(os.path.join(config.pyfaPath, 'imgs.zip'), 'r')
|
||||
logging.info("Using zipped image files.")
|
||||
except IOError:
|
||||
logging.info("Using local image files.")
|
||||
archive = None
|
||||
|
||||
cachedBitmaps = OrderedDict()
|
||||
@@ -78,7 +82,7 @@ class BitmapLoader(object):
|
||||
filename = "{0}.png".format(name)
|
||||
|
||||
if cls.archive:
|
||||
path = parsePath(location, filename)
|
||||
path = os.path.join(location, filename)
|
||||
if os.sep != "/" and os.sep in path:
|
||||
path = path.replace(os.sep, "/")
|
||||
|
||||
@@ -89,7 +93,7 @@ class BitmapLoader(object):
|
||||
except KeyError:
|
||||
print("Missing icon file from zip: {0}".format(path))
|
||||
else:
|
||||
path = config.getPyfaPath('imgs' + os.sep + location + os.sep + filename)
|
||||
path = os.path.join(config.pyfaPath, 'imgs' + os.sep + location + os.sep + filename)
|
||||
|
||||
if os.path.exists(path):
|
||||
return wx.Image(path)
|
||||
|
||||
@@ -52,6 +52,7 @@ class AmountChanger(wx.Dialog):
|
||||
def change(self, event):
|
||||
if self.input.GetLineText(0).strip() == '':
|
||||
event.Skip()
|
||||
self.Close()
|
||||
return
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
@@ -68,6 +69,7 @@ class AmountChanger(wx.Dialog):
|
||||
wx.PostEvent(mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
event.Skip()
|
||||
self.Close()
|
||||
|
||||
# checks to make sure it's valid number
|
||||
@staticmethod
|
||||
|
||||
@@ -33,7 +33,7 @@ from gui.builtinViewColumns.state import State
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
import gui.builtinViews.emptyView
|
||||
from gui.utils.exportHtml import exportHtml
|
||||
from logging import getLogger
|
||||
from logbook import Logger
|
||||
from gui.chromeTabs import EVT_NOTEBOOK_PAGE_CHANGED
|
||||
|
||||
from service.fit import Fit
|
||||
@@ -41,7 +41,7 @@ from service.market import Market
|
||||
|
||||
import gui.globalEvents as GE
|
||||
|
||||
logger = getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
# Tab spawning handler
|
||||
@@ -61,8 +61,9 @@ class FitSpawner(gui.multiSwitch.TabSpawner):
|
||||
self.multiSwitch.SetSelection(index)
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=event.fitID))
|
||||
break
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Caught exception in fitSelected")
|
||||
pyfalog.critical(e)
|
||||
if count < 0:
|
||||
startup = getattr(event, "startup", False) # see OpenFitsThread in gui.mainFrame
|
||||
sFit = Fit.getInstance()
|
||||
@@ -278,6 +279,7 @@ class FittingView(d.Display):
|
||||
sFit.refreshFit(self.getActiveFit())
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID))
|
||||
except wx._core.PyDeadObjectError:
|
||||
pyfalog.warning("Caught dead object")
|
||||
pass
|
||||
|
||||
event.Skip()
|
||||
@@ -414,7 +416,7 @@ class FittingView(d.Display):
|
||||
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit()))
|
||||
else:
|
||||
logger.error("Missing module position for: %s", str(getattr(mod2, "ID", "Unknown")))
|
||||
pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown")))
|
||||
|
||||
def generateMods(self):
|
||||
"""
|
||||
@@ -483,7 +485,7 @@ class FittingView(d.Display):
|
||||
|
||||
self.Show(self.activeFitID is not None and self.activeFitID == event.fitID)
|
||||
except wx._core.PyDeadObjectError:
|
||||
pass
|
||||
pyfalog.warning("Caught dead object")
|
||||
finally:
|
||||
event.Skip()
|
||||
|
||||
@@ -636,15 +638,17 @@ class FittingView(d.Display):
|
||||
if 'wxMac' in wx.PlatformInfo:
|
||||
try:
|
||||
self.MakeSnapshot()
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to make snapshot")
|
||||
pyfalog.critical(e)
|
||||
|
||||
def OnShow(self, event):
|
||||
if event.GetShow():
|
||||
try:
|
||||
self.MakeSnapshot()
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to make snapshot")
|
||||
pyfalog.critical(e)
|
||||
event.Skip()
|
||||
|
||||
def Snapshot(self):
|
||||
@@ -669,8 +673,9 @@ class FittingView(d.Display):
|
||||
sFit = Fit.getInstance()
|
||||
try:
|
||||
fit = sFit.getFit(self.activeFitID)
|
||||
except:
|
||||
return
|
||||
except Exception as e:
|
||||
pyfalog.critical("Failed to get fit")
|
||||
pyfalog.critical(e)
|
||||
|
||||
if fit is None:
|
||||
return
|
||||
|
||||
@@ -33,6 +33,8 @@ from service.fit import Fit
|
||||
from service.character import Character
|
||||
from service.network import AuthenticationError, TimeoutError
|
||||
from service.market import Market
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CharacterTextValidor(BaseValidator):
|
||||
@@ -55,6 +57,7 @@ class CharacterTextValidor(BaseValidator):
|
||||
|
||||
return True
|
||||
except ValueError, e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -628,11 +631,16 @@ class APIView(wx.Panel):
|
||||
try:
|
||||
activeChar = self.charEditor.entityEditor.getActiveEntity()
|
||||
list = sChar.apiCharList(activeChar.ID, self.inputID.GetLineText(0), self.inputKey.GetLineText(0))
|
||||
except AuthenticationError:
|
||||
self.stStatus.SetLabel("Authentication failure. Please check keyID and vCode combination.")
|
||||
except TimeoutError:
|
||||
self.stStatus.SetLabel("Request timed out. Please check network connectivity and/or proxy settings.")
|
||||
except AuthenticationError, e:
|
||||
msg = "Authentication failure. Please check keyID and vCode combination."
|
||||
pyfalog.info(msg)
|
||||
self.stStatus.SetLabel(msg)
|
||||
except TimeoutError, e:
|
||||
msg = "Request timed out. Please check network connectivity and/or proxy settings."
|
||||
pyfalog.info(msg)
|
||||
self.stStatus.SetLabel(msg)
|
||||
except Exception, e:
|
||||
pyfalog.error(e)
|
||||
self.stStatus.SetLabel("Error:\n%s" % e.message)
|
||||
else:
|
||||
self.charChoice.Clear()
|
||||
@@ -655,6 +663,7 @@ class APIView(wx.Panel):
|
||||
sChar.apiFetch(activeChar.ID, charName)
|
||||
self.stStatus.SetLabel("Successfully fetched %s\'s skills from EVE API." % charName)
|
||||
except Exception, e:
|
||||
pyfalog.error("Unable to retrieve {0}\'s skills. Error message:\n{1}", charName, e)
|
||||
self.stStatus.SetLabel("Unable to retrieve %s\'s skills. Error message:\n%s" % (charName, e))
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import gui.globalEvents as GE
|
||||
import gui.mainFrame
|
||||
from service.character import Character
|
||||
from service.fit import Fit
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CharacterSelection(wx.Panel):
|
||||
@@ -112,9 +114,10 @@ class CharacterSelection(wx.Panel):
|
||||
if charName:
|
||||
try:
|
||||
sChar.apiFetch(self.getActiveCharacter(), charName)
|
||||
except:
|
||||
except Exception as e:
|
||||
# can we do a popup, notifying user of API error?
|
||||
pass
|
||||
pyfalog.error("API fetch error")
|
||||
pyfalog.error(e)
|
||||
self.refreshCharacterList()
|
||||
|
||||
def charChanged(self, event):
|
||||
|
||||
@@ -25,9 +25,11 @@ import gui.utils.colorUtils as colorUtils
|
||||
import gui.utils.drawUtils as drawUtils
|
||||
import gui.utils.fonts as fonts
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
from logbook import Logger
|
||||
from service.fit import Fit
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
_PageChanging, EVT_NOTEBOOK_PAGE_CHANGING = wx.lib.newevent.NewEvent()
|
||||
_PageChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent()
|
||||
_PageAdding, EVT_NOTEBOOK_PAGE_ADDING = wx.lib.newevent.NewEvent()
|
||||
@@ -1093,8 +1095,9 @@ class PFTabsContainer(wx.Panel):
|
||||
self.previewTab = tab
|
||||
self.previewTimer.Start(500, True)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Exception caught in CheckTabPreview.")
|
||||
pyfalog.critical(e)
|
||||
|
||||
def CheckAddHighlighted(self, x, y):
|
||||
"""
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ContextMenu(object):
|
||||
@@ -121,7 +121,7 @@ class ContextMenu(object):
|
||||
|
||||
debug_end = len(cls._ids)
|
||||
if debug_end - debug_start:
|
||||
logger.debug("%d new IDs created for this menu" % (debug_end - debug_start))
|
||||
pyfalog.debug("{0} new IDs created for this menu", (debug_end - debug_start))
|
||||
|
||||
return rootMenu if empty is False else None
|
||||
|
||||
@@ -180,27 +180,27 @@ class ContextMenu(object):
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
from gui.builtinContextMenus import ( # noqa: E402,F401
|
||||
ammoPattern,
|
||||
amount,
|
||||
cargo,
|
||||
changeAffectingSkills,
|
||||
damagePattern,
|
||||
droneRemoveStack,
|
||||
droneSplit,
|
||||
factorReload,
|
||||
fighterAbilities,
|
||||
implantSets,
|
||||
itemRemove,
|
||||
itemStats,
|
||||
marketJump,
|
||||
metaSwap,
|
||||
moduleAmmoPicker,
|
||||
moduleGlobalAmmoPicker,
|
||||
openFit,
|
||||
priceClear,
|
||||
# moduleGlobalAmmoPicker,
|
||||
moduleAmmoPicker,
|
||||
itemStats,
|
||||
damagePattern,
|
||||
marketJump,
|
||||
droneSplit,
|
||||
itemRemove,
|
||||
droneRemoveStack,
|
||||
ammoPattern,
|
||||
project,
|
||||
factorReload,
|
||||
whProjector,
|
||||
cargo,
|
||||
shipJump,
|
||||
changeAffectingSkills,
|
||||
tacticalMode,
|
||||
targetResists,
|
||||
whProjector
|
||||
priceClear,
|
||||
amount,
|
||||
metaSwap,
|
||||
implantSets,
|
||||
fighterAbilities,
|
||||
)
|
||||
|
||||
@@ -14,6 +14,9 @@ from eos.db import getItem
|
||||
from gui.display import Display
|
||||
import gui.globalEvents as GE
|
||||
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest, CrestModes
|
||||
|
||||
@@ -147,7 +150,9 @@ class CrestFittings(wx.Frame):
|
||||
self.fitTree.populateSkillTree(fittings)
|
||||
del waitDialog
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection")
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
def importFitting(self, event):
|
||||
selection = self.fitView.fitSelection
|
||||
@@ -173,7 +178,9 @@ class CrestFittings(wx.Frame):
|
||||
try:
|
||||
sCrest.delFitting(self.getActiveCharacter(), data['fittingID'])
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection")
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
|
||||
class ExportToEve(wx.Frame):
|
||||
@@ -281,9 +288,12 @@ class ExportToEve(wx.Frame):
|
||||
text = json.loads(res.text)
|
||||
self.statusbar.SetStatusText(text['message'], 1)
|
||||
except ValueError:
|
||||
pyfalog.warning("Value error on loading JSON.")
|
||||
self.statusbar.SetStatusText("", 1)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.statusbar.SetStatusText("Connection error, please check your internet connection", 1)
|
||||
msg = "Connection error, please check your internet connection"
|
||||
pyfalog.error(msg)
|
||||
self.statusbar.SetStatusText(msg)
|
||||
|
||||
|
||||
class CrestMgmt(wx.Dialog):
|
||||
@@ -405,8 +415,9 @@ class FittingsTreeView(wx.Panel):
|
||||
cargo = Cargo(getItem(item['type']['id']))
|
||||
cargo.amount = item['quantity']
|
||||
list.append(cargo)
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Exception caught in displayFit")
|
||||
pyfalog.critical(e)
|
||||
|
||||
self.parent.fitView.fitSelection = selection
|
||||
self.parent.fitView.update(list)
|
||||
|
||||
@@ -147,6 +147,7 @@ class DroneView(Display):
|
||||
def _merge(self, src, dst):
|
||||
sFit = Fit.getInstance()
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
|
||||
if sFit.mergeDrones(fitID, self.drones[src], self.drones[dst]):
|
||||
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
|
||||
|
||||
|
||||
94
gui/errorDialog.py
Normal file
94
gui/errorDialog.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
#
|
||||
# pyfa is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyfa is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
import wx
|
||||
import sys
|
||||
import gui.utils.fonts as fonts
|
||||
import config
|
||||
|
||||
|
||||
class ErrorFrame(wx.Frame):
|
||||
|
||||
def __init__(self, exception, tb):
|
||||
wx.Frame.__init__(self, None, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 400),
|
||||
style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER | wx.STAY_ON_TOP)
|
||||
|
||||
desc = "pyfa has experienced an unexpected error. Below is the " \
|
||||
"Traceback that contains crucial information about how this " \
|
||||
"error was triggered. Please contact the developers with " \
|
||||
"the information provided through the EVE Online forums " \
|
||||
"or file a GitHub issue."
|
||||
|
||||
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
|
||||
|
||||
if 'wxMSW' in wx.PlatformInfo:
|
||||
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
headSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.headingText = wx.StaticText(self, wx.ID_ANY, "Error!", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE)
|
||||
self.headingText.SetFont(wx.Font(14, 74, 90, 92, False))
|
||||
|
||||
headSizer.Add(self.headingText, 1, wx.ALL, 5)
|
||||
mainSizer.Add(headSizer, 0, wx.EXPAND, 5)
|
||||
|
||||
mainSizer.Add(wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
descSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.descText = wx.TextCtrl(self, wx.ID_ANY, desc, wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.TE_AUTO_URL | wx.TE_MULTILINE | wx.TE_READONLY | wx.BORDER_NONE | wx.TRANSPARENT_WINDOW)
|
||||
self.descText.SetFont(wx.Font(fonts.BIG, wx.SWISS, wx.NORMAL, wx.NORMAL))
|
||||
descSizer.Add(self.descText, 1, wx.ALL, 5)
|
||||
mainSizer.Add(descSizer, 1, wx.EXPAND, 5)
|
||||
|
||||
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "EVE Forums Thread", "https://forums.eveonline.com/default.aspx?g=posts&t=466425",
|
||||
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
|
||||
|
||||
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
|
||||
|
||||
self.eveForums = wx.HyperlinkCtrl(self, wx.ID_ANY, "Github Issues", "https://github.com/pyfa-org/Pyfa/issues",
|
||||
wx.DefaultPosition, wx.DefaultSize, wx.HL_DEFAULT_STYLE)
|
||||
|
||||
mainSizer.Add(self.eveForums, 0, wx.ALL, 2)
|
||||
|
||||
# mainSizer.AddSpacer((0, 5), 0, wx.EXPAND, 5)
|
||||
|
||||
self.errorTextCtrl = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_DONTWRAP)
|
||||
self.errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
|
||||
mainSizer.Add(self.errorTextCtrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
|
||||
|
||||
self.errorTextCtrl.AppendText("pyfa root: ")
|
||||
self.errorTextCtrl.AppendText(config.pyfaPath or "Unknown")
|
||||
self.errorTextCtrl.AppendText('\n')
|
||||
self.errorTextCtrl.AppendText("save path: ")
|
||||
self.errorTextCtrl.AppendText(config.savePath or "Unknown")
|
||||
self.errorTextCtrl.AppendText('\n')
|
||||
self.errorTextCtrl.AppendText("fs encoding: ")
|
||||
self.errorTextCtrl.AppendText(sys.getfilesystemencoding())
|
||||
self.errorTextCtrl.AppendText('\n\n')
|
||||
self.errorTextCtrl.AppendText(tb)
|
||||
|
||||
self.SetSizer(mainSizer)
|
||||
mainSizer.Layout()
|
||||
self.Layout()
|
||||
|
||||
self.Centre(wx.BOTH)
|
||||
|
||||
self.Show()
|
||||
@@ -18,8 +18,7 @@
|
||||
# =============================================================================
|
||||
|
||||
import os
|
||||
import logging
|
||||
import imp
|
||||
from logbook import Logger
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
@@ -30,19 +29,31 @@ import gui.mainFrame
|
||||
import gui.globalEvents as GE
|
||||
from gui.graph import Graph
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from config import parsePath
|
||||
|
||||
# Don't actually import the thing, since it takes for fucking ever
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
try:
|
||||
imp.find_module('matplotlib')
|
||||
import matplotlib as mpl
|
||||
|
||||
mpl_version = int(mpl.__version__[0])
|
||||
if mpl_version >= 2:
|
||||
mpl.use('wxagg')
|
||||
mplImported = True
|
||||
else:
|
||||
mplImported = False
|
||||
from matplotlib.patches import Patch
|
||||
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
graphFrame_enabled = True
|
||||
mplImported = True
|
||||
except ImportError:
|
||||
Patch = mpl = Canvas = Figure = None
|
||||
graphFrame_enabled = False
|
||||
mplImported = False
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class GraphFrame(wx.Frame):
|
||||
@@ -73,7 +84,7 @@ class GraphFrame(wx.Frame):
|
||||
|
||||
self.legendFix = False
|
||||
if not graphFrame_enabled:
|
||||
logger.info("Problems importing matplotlib; continuing without graphs")
|
||||
pyfalog.info("Problems importing matplotlib; continuing without graphs")
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -81,7 +92,7 @@ class GraphFrame(wx.Frame):
|
||||
except:
|
||||
cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
|
||||
|
||||
cache_file = parsePath(cache_dir, 'fontList.cache')
|
||||
cache_file = os.path.join(cache_dir, 'fontList.cache')
|
||||
|
||||
if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file):
|
||||
# remove matplotlib font cache, see #234
|
||||
@@ -244,6 +255,7 @@ class GraphFrame(wx.Frame):
|
||||
self.subplot.plot(x, y)
|
||||
legend.append(fit.name)
|
||||
except:
|
||||
pyfalog.warning("Invalid values in '{0}'", fit.name)
|
||||
self.SetStatusText("Invalid values in '%s'" % fit.name)
|
||||
self.canvas.draw()
|
||||
return
|
||||
@@ -282,7 +294,7 @@ class GraphFrame(wx.Frame):
|
||||
selected_color = legend_colors[i]
|
||||
except:
|
||||
selected_color = None
|
||||
legend2.append(self.Patch(color=selected_color, label=i_name), )
|
||||
legend2.append(Patch(color=selected_color, label=i_name), )
|
||||
|
||||
if len(legend2) > 0:
|
||||
leg = self.subplot.legend(handles=legend2)
|
||||
|
||||
193
gui/itemStats.py
193
gui/itemStats.py
@@ -62,13 +62,13 @@ class ItemStatsDialog(wx.Dialog):
|
||||
):
|
||||
|
||||
wx.Dialog.__init__(
|
||||
self,
|
||||
gui.mainFrame.MainFrame.getInstance(),
|
||||
wx.ID_ANY,
|
||||
title="Item stats",
|
||||
pos=pos,
|
||||
size=size,
|
||||
style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU
|
||||
self,
|
||||
gui.mainFrame.MainFrame.getInstance(),
|
||||
wx.ID_ANY,
|
||||
title="Item stats",
|
||||
pos=pos,
|
||||
size=size,
|
||||
style=wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU
|
||||
)
|
||||
|
||||
empty = getattr(victim, "isEmpty", False)
|
||||
@@ -197,6 +197,10 @@ class ItemStatsContainer(wx.Panel):
|
||||
self.affectedby = ItemAffectedBy(self.nbContainer, stuff, item)
|
||||
self.nbContainer.AddPage(self.affectedby, "Affected by")
|
||||
|
||||
if config.debug:
|
||||
self.properties = ItemProperties(self.nbContainer, stuff, item, context)
|
||||
self.nbContainer.AddPage(self.properties, "Properties")
|
||||
|
||||
self.nbContainer.Bind(wx.EVT_LEFT_DOWN, self.mouseHit)
|
||||
self.SetSizer(mainSizer)
|
||||
self.Layout()
|
||||
@@ -256,7 +260,7 @@ class ItemDescription(wx.Panel):
|
||||
# Strip URLs
|
||||
desc = re.sub("<( *)a(.*?)>(?P<inside>.*?)<( *)/( *)a( *)>", "\g<inside>", desc)
|
||||
desc = "<body bgcolor='" + bgcolor.GetAsString(wx.C2S_HTML_SYNTAX) + "' text='" + fgcolor.GetAsString(
|
||||
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
|
||||
wx.C2S_HTML_SYNTAX) + "' >" + desc + "</body>"
|
||||
|
||||
self.description.SetPage(desc)
|
||||
|
||||
@@ -358,13 +362,13 @@ class ItemParams(wx.Panel):
|
||||
writer = csv.writer(exportFile, delimiter=',')
|
||||
|
||||
writer.writerow(
|
||||
[
|
||||
"ID",
|
||||
"Internal Name",
|
||||
"Friendly Name",
|
||||
"Modified Value",
|
||||
"Base Value",
|
||||
]
|
||||
[
|
||||
"ID",
|
||||
"Internal Name",
|
||||
"Friendly Name",
|
||||
"Modified Value",
|
||||
"Base Value",
|
||||
]
|
||||
)
|
||||
|
||||
for attribute in self.attrValues:
|
||||
@@ -395,13 +399,13 @@ class ItemParams(wx.Panel):
|
||||
attribute_modified_value = self.attrValues[attribute]
|
||||
|
||||
writer.writerow(
|
||||
[
|
||||
attribute_id,
|
||||
attribute_name,
|
||||
attribute_displayname,
|
||||
attribute_modified_value,
|
||||
attribute_value,
|
||||
]
|
||||
[
|
||||
attribute_id,
|
||||
attribute_name,
|
||||
attribute_displayname,
|
||||
attribute_modified_value,
|
||||
attribute_value,
|
||||
]
|
||||
)
|
||||
|
||||
def PopulateList(self):
|
||||
@@ -496,17 +500,19 @@ class ItemParams(wx.Panel):
|
||||
attribute = Attribute.getInstance().getAttributeInfo(value)
|
||||
return "%s (%d)" % (attribute.name.capitalize(), value)
|
||||
|
||||
trans = {"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"),
|
||||
"Sizeclass": (lambda: value, ""),
|
||||
"Absolute Percent": (lambda: (value * 100), unitName),
|
||||
"Milliseconds": (lambda: value / 1000.0, unitName),
|
||||
"typeID": (itemIDCallback, ""),
|
||||
"groupID": (groupIDCallback, ""),
|
||||
"attributeID": (attributeIDCallback, "")}
|
||||
trans = {
|
||||
"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"),
|
||||
"Sizeclass" : (lambda: value, ""),
|
||||
"Absolute Percent" : (lambda: (value * 100), unitName),
|
||||
"Milliseconds" : (lambda: value / 1000.0, unitName),
|
||||
"typeID" : (itemIDCallback, ""),
|
||||
"groupID" : (groupIDCallback, ""),
|
||||
"attributeID" : (attributeIDCallback, "")
|
||||
}
|
||||
|
||||
override = trans.get(unitDisplayName)
|
||||
if override is not None:
|
||||
@@ -689,17 +695,18 @@ class ItemCompare(wx.Panel):
|
||||
attribute = Attribute.getInstance().getAttributeInfo(value)
|
||||
return "%s (%d)" % (attribute.name.capitalize(), value)
|
||||
|
||||
trans = {"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"),
|
||||
"Sizeclass": (lambda: value, ""),
|
||||
"Absolute Percent": (lambda: (value * 100), unitName),
|
||||
"Milliseconds": (lambda: value / 1000.0, unitName),
|
||||
"typeID": (itemIDCallback, ""),
|
||||
"groupID": (groupIDCallback, ""),
|
||||
"attributeID": (attributeIDCallback, "")}
|
||||
trans = {
|
||||
"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"),
|
||||
"Sizeclass" : (lambda: value, ""),
|
||||
"Absolute Percent" : (lambda: (value * 100), unitName),
|
||||
"Milliseconds" : (lambda: value / 1000.0, unitName),
|
||||
"typeID" : (itemIDCallback, ""),
|
||||
"groupID" : (groupIDCallback, ""),
|
||||
"attributeID" : (attributeIDCallback, "")
|
||||
}
|
||||
|
||||
override = trans.get(unitDisplayName)
|
||||
if override is not None:
|
||||
@@ -849,7 +856,7 @@ class ItemEffects(wx.Panel):
|
||||
If effect file does not exist, create it
|
||||
"""
|
||||
|
||||
file_ = config.getPyfaPath(os.path.join("eos", "effects", "%s.py" % event.GetText().lower()))
|
||||
file_ = os.path.join(config.pyfaPath, "eos", "effects", "%s.py" % event.GetText().lower())
|
||||
|
||||
if not os.path.isfile(file_):
|
||||
open(file_, 'a').close()
|
||||
@@ -1067,7 +1074,7 @@ class ItemAffectedBy(wx.Panel):
|
||||
item = afflictor.item
|
||||
|
||||
items[attrName].append(
|
||||
(type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False)))
|
||||
(type(afflictor), afflictor, item, modifier, amount, getattr(afflictor, "projected", False)))
|
||||
|
||||
# Make sure projected fits are on top
|
||||
rootOrder = container.keys()
|
||||
@@ -1295,3 +1302,97 @@ class ItemAffectedBy(wx.Panel):
|
||||
treeitem = self.affectedBy.AppendItem(child, display, attrIcon)
|
||||
self.affectedBy.SetPyData(treeitem, saved)
|
||||
self.treeItems.append(treeitem)
|
||||
|
||||
|
||||
class ItemProperties(wx.Panel):
|
||||
def __init__(self, parent, stuff, item, context=None):
|
||||
wx.Panel.__init__(self, parent)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.paramList = AutoListCtrl(self, wx.ID_ANY,
|
||||
style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES | wx.NO_BORDER)
|
||||
mainSizer.Add(self.paramList, 1, wx.ALL | wx.EXPAND, 0)
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
self.toggleView = 1
|
||||
self.stuff = stuff
|
||||
self.item = item
|
||||
self.attrInfo = {}
|
||||
self.attrValues = {}
|
||||
self._fetchValues()
|
||||
|
||||
self.m_staticline = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
|
||||
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)
|
||||
bSizer.Add(self.totalAttrsLabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT)
|
||||
|
||||
mainSizer.Add(bSizer, 0, wx.ALIGN_RIGHT)
|
||||
|
||||
self.PopulateList()
|
||||
|
||||
def _fetchValues(self):
|
||||
if self.stuff is None:
|
||||
self.attrInfo.clear()
|
||||
self.attrValues.clear()
|
||||
self.attrInfo.update(self.item.attributes)
|
||||
self.attrValues.update(self.item.attributes)
|
||||
elif self.stuff.item == self.item:
|
||||
self.attrInfo.clear()
|
||||
self.attrValues.clear()
|
||||
self.attrInfo.update(self.stuff.item.attributes)
|
||||
self.attrValues.update(self.stuff.itemModifiedAttributes)
|
||||
elif self.stuff.charge == self.item:
|
||||
self.attrInfo.clear()
|
||||
self.attrValues.clear()
|
||||
self.attrInfo.update(self.stuff.charge.attributes)
|
||||
self.attrValues.update(self.stuff.chargeModifiedAttributes)
|
||||
# When item for stats window no longer exists, don't change anything
|
||||
else:
|
||||
return
|
||||
|
||||
def PopulateList(self):
|
||||
self.paramList.InsertColumn(0, "Attribute")
|
||||
self.paramList.InsertColumn(1, "Current Value")
|
||||
self.paramList.SetColumnWidth(0, 110)
|
||||
self.paramList.SetColumnWidth(1, 1500)
|
||||
self.paramList.setResizeColumn(0)
|
||||
|
||||
if self.stuff:
|
||||
names = dir(self.stuff)
|
||||
else:
|
||||
names = dir(self.item)
|
||||
|
||||
names = [a for a in names if not (a.startswith('__') and a.endswith('__'))]
|
||||
|
||||
idNameMap = {}
|
||||
idCount = 0
|
||||
for name in names:
|
||||
try:
|
||||
if self.stuff:
|
||||
attrName = name.title()
|
||||
value = getattr(self.stuff, name)
|
||||
else:
|
||||
attrName = name.title()
|
||||
value = getattr(self.item, name)
|
||||
except Exception as e:
|
||||
# TODO: Add logging to this.
|
||||
# We couldn't get a property for some reason. Skip it for now.
|
||||
print(e)
|
||||
continue
|
||||
|
||||
index = self.paramList.InsertStringItem(sys.maxint, attrName)
|
||||
# index = self.paramList.InsertImageStringItem(sys.maxint, attrName)
|
||||
idNameMap[idCount] = attrName
|
||||
self.paramList.SetItemData(index, idCount)
|
||||
idCount += 1
|
||||
|
||||
valueUnit = str(value)
|
||||
|
||||
self.paramList.SetStringItem(index, 1, valueUnit)
|
||||
|
||||
self.paramList.SortItems(lambda id1, id2: cmp(idNameMap[id1], idNameMap[id2]))
|
||||
self.paramList.RefreshRows()
|
||||
self.totalAttrsLabel.SetLabel("%d attributes. " % idCount)
|
||||
self.Layout()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
import sqlalchemy
|
||||
# noinspection PyPackageRequirements
|
||||
@@ -94,7 +94,7 @@ except ImportError as e:
|
||||
print("Error loading Attribute Editor: %s.\nAccess to Attribute Editor is disabled." % e.message)
|
||||
disableOverrideEditor = True
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
# dummy panel(no paint no erasebk)
|
||||
@@ -145,6 +145,7 @@ class MainFrame(wx.Frame):
|
||||
return cls.__instance if cls.__instance is not None else MainFrame()
|
||||
|
||||
def __init__(self, title="pyfa"):
|
||||
pyfalog.debug("Initialize MainFrame")
|
||||
self.title = title
|
||||
wx.Frame.__init__(self, None, wx.ID_ANY, self.title)
|
||||
|
||||
@@ -399,7 +400,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showDamagePatternEditor>.")
|
||||
|
||||
def showImplantSetEditor(self, event):
|
||||
ImplantSetEditorDlg(self)
|
||||
@@ -427,7 +428,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
return
|
||||
|
||||
with open(path, "w", encoding="utf-8") as openfile:
|
||||
@@ -437,7 +438,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <showExportDialog>.")
|
||||
|
||||
def showPreferenceDialog(self, event):
|
||||
dlg = PreferenceDialog(self)
|
||||
@@ -734,7 +735,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
fits = Port().importFitFromBuffer(clipboard, self.getActiveFit())
|
||||
except:
|
||||
logger.error("Attempt to import failed:\n%s", clipboard)
|
||||
pyfalog.error("Attempt to import failed:\n{0}", clipboard)
|
||||
else:
|
||||
self._openAfterImport(fits)
|
||||
|
||||
@@ -754,7 +755,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <exportToClipboard>.")
|
||||
|
||||
def exportSkillsNeeded(self, event):
|
||||
""" Exports skills needed for active fit and active character """
|
||||
@@ -811,7 +812,7 @@ class MainFrame(wx.Frame):
|
||||
try:
|
||||
dlg.Destroy()
|
||||
except PyDeadObjectError:
|
||||
logger.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
|
||||
pyfalog.error("Tried to destroy an object that doesn't exist in <fileImportDialog>.")
|
||||
|
||||
def backupToXml(self, event):
|
||||
""" Back up all fits to EVE XML file """
|
||||
|
||||
@@ -26,6 +26,9 @@ import gui.graphFrame
|
||||
import gui.globalEvents as GE
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest
|
||||
from service.crest import CrestModes
|
||||
@@ -33,6 +36,7 @@ if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION
|
||||
|
||||
class MainMenuBar(wx.MenuBar):
|
||||
def __init__(self, mainFrame):
|
||||
pyfalog.debug("Initialize MainMenuBar")
|
||||
self.characterEditorId = wx.NewId()
|
||||
self.damagePatternEditorId = wx.NewId()
|
||||
self.targetResistsEditorId = wx.NewId()
|
||||
@@ -166,6 +170,7 @@ class MainMenuBar(wx.MenuBar):
|
||||
self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged)
|
||||
|
||||
def fitChanged(self, event):
|
||||
pyfalog.debug("fitChanged triggered")
|
||||
enable = event.fitID is not None
|
||||
self.Enable(wx.ID_SAVEAS, enable)
|
||||
self.Enable(wx.ID_COPY, enable)
|
||||
|
||||
@@ -26,6 +26,9 @@ import gui.PFSearchBox as SBox
|
||||
from gui.cachingImageList import CachingImageList
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
ItemSelected, ITEM_SELECTED = wx.lib.newevent.NewEvent()
|
||||
|
||||
@@ -56,6 +59,7 @@ class MetaButton(wx.ToggleButton):
|
||||
class MarketBrowser(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
pyfalog.debug("Initialize marketBrowser")
|
||||
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetSizer(vbox)
|
||||
|
||||
@@ -134,6 +138,7 @@ class SearchBox(SBox.PFSearchBox):
|
||||
class MarketTree(wx.TreeCtrl):
|
||||
def __init__(self, parent, marketBrowser):
|
||||
wx.TreeCtrl.__init__(self, parent, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
|
||||
pyfalog.debug("Initialize marketTree")
|
||||
self.root = self.AddRoot("root")
|
||||
|
||||
self.imageList = CachingImageList(16, 16)
|
||||
@@ -182,7 +187,9 @@ class MarketTree(wx.TreeCtrl):
|
||||
iconId = self.addImage(sMkt.getIconByMarketGroup(childMktGrp))
|
||||
try:
|
||||
childId = self.AppendItem(root, childMktGrp.name, iconId, data=wx.TreeItemData(childMktGrp.ID))
|
||||
except:
|
||||
except Exception as e:
|
||||
pyfalog.debug("Error appending item.")
|
||||
pyfalog.debug(e)
|
||||
continue
|
||||
if sMkt.marketGroupHasTypesCheck(childMktGrp) is False:
|
||||
self.AppendItem(childId, "dummy")
|
||||
@@ -226,6 +233,7 @@ class ItemView(Display):
|
||||
|
||||
def __init__(self, parent, marketBrowser):
|
||||
Display.__init__(self, parent)
|
||||
pyfalog.debug("Initialize ItemView")
|
||||
marketBrowser.Bind(wx.EVT_TREE_SEL_CHANGED, self.selectionMade)
|
||||
|
||||
self.unfilteredStore = set()
|
||||
@@ -252,6 +260,7 @@ class ItemView(Display):
|
||||
self.metaMap = self.makeReverseMetaMap()
|
||||
|
||||
# Fill up recently used modules set
|
||||
pyfalog.debug("Fill up recently used modules set")
|
||||
for itemID in self.sMkt.serviceMarketRecentlyUsedModules["pyfaMarketRecentlyUsedModules"]:
|
||||
self.recentlyUsedModules.add(self.sMkt.getItem(itemID))
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ from wx.lib.intctrl import IntCtrl
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
|
||||
from service.damagePattern import DamagePattern, ImportError
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class DmgPatternTextValidor(BaseValidator):
|
||||
@@ -47,6 +50,7 @@ class DmgPatternTextValidor(BaseValidator):
|
||||
|
||||
return True
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -256,9 +260,13 @@ class DmgPatternEditorDlg(wx.Dialog):
|
||||
sDP.importPatterns(text)
|
||||
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
|
||||
except ImportError as e:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception:
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
except Exception as e:
|
||||
msg = "Could not import from clipboard: unknown errors"
|
||||
pyfalog.warning(msg)
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally:
|
||||
self.entityEditor.refreshEntityList()
|
||||
else:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import csv
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
@@ -21,7 +21,7 @@ import gui.PFSearchBox as SBox
|
||||
from gui.marketBrowser import SearchBox
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class AttributeEditor(wx.Frame):
|
||||
@@ -270,7 +270,7 @@ class AttributeGrid(wxpg.PropertyGrid):
|
||||
|
||||
self.itemView.updateItems()
|
||||
|
||||
logger.debug('%s changed to "%s"' % (p.GetName(), p.GetValueAsString()))
|
||||
pyfalog.debug('{0} changed to "{1}"', p.GetName(), p.GetValueAsString())
|
||||
|
||||
def OnPropGridSelect(self, event):
|
||||
pass
|
||||
|
||||
@@ -23,6 +23,9 @@ from service.targetResists import TargetResists
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class TargetResistsTextValidor(BaseValidator):
|
||||
@@ -45,6 +48,7 @@ class TargetResistsTextValidor(BaseValidator):
|
||||
|
||||
return True
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -230,10 +234,14 @@ class ResistsEditorDlg(wx.Dialog):
|
||||
|
||||
except ValueError:
|
||||
editObj.SetForegroundColour(wx.RED)
|
||||
self.stNotice.SetLabel("Incorrect Formatting (decimals only)")
|
||||
msg = "Incorrect Formatting (decimals only)"
|
||||
pyfalog.warning(msg)
|
||||
self.stNotice.SetLabel(msg)
|
||||
except AssertionError:
|
||||
editObj.SetForegroundColour(wx.RED)
|
||||
self.stNotice.SetLabel("Incorrect Range (must be 0-100)")
|
||||
msg = "Incorrect Range (must be 0-100)"
|
||||
pyfalog.warning(msg)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally: # Refresh for color changes to take effect immediately
|
||||
self.Refresh()
|
||||
|
||||
@@ -271,9 +279,13 @@ class ResistsEditorDlg(wx.Dialog):
|
||||
sTR.importPatterns(text)
|
||||
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
|
||||
except ImportError as e:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception:
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
except Exception as e:
|
||||
msg = "Could not import from clipboard:"
|
||||
pyfalog.warning(msg)
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(msg)
|
||||
finally:
|
||||
self.entityEditor.refreshEntityList()
|
||||
else:
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
# =============================================================================
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
@@ -26,7 +26,7 @@ from gui.builtinViews.implantEditor import BaseImplantEditorView
|
||||
from gui.utils.clipboard import toClipboard, fromClipboard
|
||||
from gui.builtinViews.entityEditor import EntityEditor, BaseValidator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class ImplantTextValidor(BaseValidator):
|
||||
@@ -49,6 +49,7 @@ class ImplantTextValidor(BaseValidator):
|
||||
|
||||
return True
|
||||
except ValueError as e:
|
||||
pyfalog.error(e)
|
||||
wx.MessageBox(u"{}".format(e), "Error")
|
||||
textCtrl.SetFocus()
|
||||
return False
|
||||
@@ -198,9 +199,10 @@ class ImplantSetEditorDlg(wx.Dialog):
|
||||
self.stNotice.SetLabel("Patterns successfully imported from clipboard")
|
||||
self.showInput(False)
|
||||
except ImportError as e:
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel(str(e))
|
||||
except Exception as e:
|
||||
logging.exception("Unhandled Exception")
|
||||
pyfalog.error(e)
|
||||
self.stNotice.SetLabel("Could not import from clipboard: unknown errors")
|
||||
finally:
|
||||
self.updateChoices()
|
||||
|
||||
@@ -21,6 +21,8 @@ import gui.utils.animEffects as animEffects
|
||||
from gui.PFListPane import PFListPane
|
||||
from gui.contextMenu import ContextMenu
|
||||
from gui.bitmapLoader import BitmapLoader
|
||||
from logbook import Logger
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
FitRenamed, EVT_FIT_RENAMED = wx.lib.newevent.NewEvent()
|
||||
FitSelected, EVT_FIT_SELECTED = wx.lib.newevent.NewEvent()
|
||||
@@ -684,6 +686,7 @@ class ShipBrowser(wx.Panel):
|
||||
self.lpane.Freeze()
|
||||
self.lpane.RemoveAllChildren()
|
||||
|
||||
pyfalog.debug("Populate ship category list.")
|
||||
if len(self.categoryList) == 0:
|
||||
# set cache of category list
|
||||
self.categoryList = list(sMkt.getShipRoot())
|
||||
@@ -692,7 +695,8 @@ class ShipBrowser(wx.Panel):
|
||||
# set map & cache of fittings per category
|
||||
for cat in self.categoryList:
|
||||
itemIDs = [x.ID for x in cat.items]
|
||||
self.categoryFitCache[cat.ID] = sFit.countFitsWithShip(itemIDs) > 1
|
||||
num = sFit.countFitsWithShip(itemIDs)
|
||||
self.categoryFitCache[cat.ID] = num > 0
|
||||
|
||||
for ship in self.categoryList:
|
||||
if self.filterShipsWithNoFits and not self.categoryFitCache[ship.ID]:
|
||||
@@ -938,7 +942,7 @@ class ShipBrowser(wx.Panel):
|
||||
|
||||
if fits:
|
||||
for fit in fits:
|
||||
shipTrait = fit.ship.traits.traitText if (fit.ship.traits is not None) else ""
|
||||
shipTrait = fit.ship.item.traits.traitText if (fit.ship.item.traits is not None) else ""
|
||||
# empty string if no traits
|
||||
|
||||
self.lpane.AddWidget(FitItem(
|
||||
|
||||
@@ -4,7 +4,12 @@ import time
|
||||
import wx
|
||||
from service.settings import HTMLExportSettings
|
||||
from service.fit import Fit
|
||||
from service.port import Port
|
||||
from service.market import Market
|
||||
from logbook import Logger
|
||||
from eos.db import getFit
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class exportHtml(object):
|
||||
@@ -184,6 +189,7 @@ class exportHtmlThread(threading.Thread):
|
||||
groupFits = 0
|
||||
for ship in ships:
|
||||
fits = sFit.getFitsWithShip(ship.ID)
|
||||
|
||||
if len(fits) > 0:
|
||||
groupFits += len(fits)
|
||||
|
||||
@@ -192,10 +198,11 @@ class exportHtmlThread(threading.Thread):
|
||||
return
|
||||
fit = fits[0]
|
||||
try:
|
||||
dnaFit = sFit.exportDna(fit[0])
|
||||
dnaFit = Port.exportDna(getFit(fit[0]))
|
||||
HTMLgroup += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + ship.name + ": " + \
|
||||
fit[1] + '</a></li>\n'
|
||||
except:
|
||||
pyfalog.warning("Failed to export line")
|
||||
pass
|
||||
finally:
|
||||
if self.callback:
|
||||
@@ -214,10 +221,12 @@ class exportHtmlThread(threading.Thread):
|
||||
if self.stopRunning:
|
||||
return
|
||||
try:
|
||||
dnaFit = sFit.exportDna(fit[0])
|
||||
dnaFit = Port.exportDna(getFit(fit[0]))
|
||||
print dnaFit
|
||||
HTMLship += ' <li><a data-dna="' + dnaFit + '" target="_blank">' + fit[
|
||||
1] + '</a></li>\n'
|
||||
except:
|
||||
pyfalog.warning("Failed to export line")
|
||||
continue
|
||||
finally:
|
||||
if self.callback:
|
||||
@@ -266,10 +275,11 @@ class exportHtmlThread(threading.Thread):
|
||||
if self.stopRunning:
|
||||
return
|
||||
try:
|
||||
dnaFit = sFit.exportDna(fit[0])
|
||||
dnaFit = Port.exportDna(getFit(fit[0]))
|
||||
HTML += '<a class="outOfGameBrowserLink" target="_blank" href="' + dnaUrl + dnaFit + '">' + ship.name + ': ' + \
|
||||
fit[1] + '</a><br> \n'
|
||||
except:
|
||||
pyfalog.error("Failed to export line")
|
||||
continue
|
||||
finally:
|
||||
if self.callback:
|
||||
|
||||
182
pyfa.py
182
pyfa.py
@@ -19,11 +19,17 @@
|
||||
# ==============================================================================
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import config
|
||||
|
||||
from optparse import OptionParser, BadOptionError, AmbiguousOptionError
|
||||
|
||||
from logbook import TimedRotatingFileHandler, Logger, StreamHandler, NestedSetup, FingersCrossedHandler, NullHandler, \
|
||||
CRITICAL, ERROR, WARNING, DEBUG, INFO
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class PassThroughOptionParser(OptionParser):
|
||||
"""
|
||||
@@ -36,9 +42,30 @@ class PassThroughOptionParser(OptionParser):
|
||||
try:
|
||||
OptionParser._process_args(self, largs, rargs, values)
|
||||
except (BadOptionError, AmbiguousOptionError) as e:
|
||||
pyfalog.error("Bad startup option passed.")
|
||||
largs.append(e.opt_str)
|
||||
|
||||
|
||||
class LoggerWriter:
|
||||
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 not in {'\n', ' '}:
|
||||
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)
|
||||
|
||||
|
||||
# Parse command line options
|
||||
usage = "usage: %prog [--root]"
|
||||
parser = PassThroughOptionParser(usage=usage)
|
||||
@@ -47,9 +74,23 @@ parser.add_option("-w", "--wx28", action="store_true", dest="force28", help="For
|
||||
parser.add_option("-d", "--debug", action="store_true", dest="debug", help="Set logger to debug level.", default=False)
|
||||
parser.add_option("-t", "--title", action="store", dest="title", help="Set Window Title", default=None)
|
||||
parser.add_option("-s", "--savepath", action="store", dest="savepath", help="Set the folder for savedata", default=None)
|
||||
parser.add_option("-l", "--logginglevel", action="store", dest="logginglevel", help="Set desired logging level [Critical|Error|Warning|Info|Debug]", default="Error")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.logginglevel == "Critical":
|
||||
options.logginglevel = CRITICAL
|
||||
elif options.logginglevel == "Error":
|
||||
options.logginglevel = ERROR
|
||||
elif options.logginglevel == "Warning":
|
||||
options.logginglevel = WARNING
|
||||
elif options.logginglevel == "Info":
|
||||
options.logginglevel = INFO
|
||||
elif options.logginglevel == "Debug":
|
||||
options.logginglevel = DEBUG
|
||||
else:
|
||||
options.logginglevel = ERROR
|
||||
|
||||
if not hasattr(sys, 'frozen'):
|
||||
|
||||
if sys.version_info < (2, 6) or sys.version_info > (3, 0):
|
||||
@@ -114,14 +155,6 @@ if __name__ == "__main__":
|
||||
options.title = "pyfa %s%s - Python Fitting Assistant" % (config.version, "" if config.tag.lower() != 'git' else " (git)")
|
||||
|
||||
config.debug = options.debug
|
||||
# convert to unicode if it is set
|
||||
if options.savepath is not None:
|
||||
options.savepath = unicode(options.savepath)
|
||||
config.defPaths(options.savepath)
|
||||
|
||||
# Basic logging initialization
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
|
||||
# Import everything
|
||||
# noinspection PyPackageRequirements
|
||||
@@ -129,17 +162,128 @@ if __name__ == "__main__":
|
||||
import os
|
||||
import os.path
|
||||
|
||||
import eos.db
|
||||
# noinspection PyUnresolvedReferences
|
||||
import service.prefetch # noqa: F401
|
||||
from gui.mainFrame import MainFrame
|
||||
try:
|
||||
# convert to unicode if it is set
|
||||
if options.savepath is not None:
|
||||
options.savepath = unicode(options.savepath)
|
||||
config.defPaths(options.savepath)
|
||||
|
||||
# Make sure the saveddata db exists
|
||||
if not os.path.exists(config.savePath):
|
||||
os.mkdir(config.savePath)
|
||||
# Basic logging initialization
|
||||
|
||||
eos.db.saveddata_meta.create_all()
|
||||
# Logging levels:
|
||||
'''
|
||||
logbook.CRITICAL
|
||||
logbook.ERROR
|
||||
logbook.WARNING
|
||||
logbook.INFO
|
||||
logbook.DEBUG
|
||||
logbook.NOTSET
|
||||
'''
|
||||
|
||||
pyfa = wx.App(False)
|
||||
MainFrame(options.title)
|
||||
pyfa.MainLoop()
|
||||
if options.debug:
|
||||
savePath_filename = "Pyfa_debug.log"
|
||||
else:
|
||||
savePath_filename = "Pyfa.log"
|
||||
|
||||
savePath_Destination = os.path.join(config.savePath, savePath_filename)
|
||||
|
||||
try:
|
||||
if options.debug:
|
||||
logging_mode = "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=options.logginglevel
|
||||
),
|
||||
TimedRotatingFileHandler(
|
||||
savePath_Destination,
|
||||
level=0,
|
||||
backup_count=3,
|
||||
bubble=True,
|
||||
date_format='%Y-%m-%d',
|
||||
),
|
||||
])
|
||||
else:
|
||||
logging_mode = "User"
|
||||
logging_setup = NestedSetup([
|
||||
# make sure we never bubble up to the stderr handler
|
||||
# if we run out of setup handling
|
||||
NullHandler(),
|
||||
FingersCrossedHandler(
|
||||
TimedRotatingFileHandler(
|
||||
savePath_Destination,
|
||||
level=0,
|
||||
backup_count=3,
|
||||
bubble=False,
|
||||
date_format='%Y-%m-%d',
|
||||
),
|
||||
action_level=ERROR,
|
||||
buffer_size=1000,
|
||||
# pull_information=True,
|
||||
# reset=False,
|
||||
)
|
||||
])
|
||||
except:
|
||||
logging_mode = "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
|
||||
)
|
||||
])
|
||||
|
||||
import eos.db
|
||||
# noinspection PyUnresolvedReferences
|
||||
import service.prefetch # noqa: F401
|
||||
|
||||
# Make sure the saveddata db exists
|
||||
if not os.path.exists(config.savePath):
|
||||
os.mkdir(config.savePath)
|
||||
|
||||
eos.db.saveddata_meta.create_all()
|
||||
|
||||
except Exception, e:
|
||||
import traceback
|
||||
from gui.errorDialog import ErrorFrame
|
||||
|
||||
tb = traceback.format_exc()
|
||||
|
||||
pyfa = wx.App(False)
|
||||
ErrorFrame(e, tb)
|
||||
pyfa.MainLoop()
|
||||
sys.exit()
|
||||
|
||||
with logging_setup.threadbound():
|
||||
# Don't redirect if frozen
|
||||
if not hasattr(sys, 'frozen'):
|
||||
# Output all stdout (print) messages as warnings
|
||||
try:
|
||||
sys.stdout = LoggerWriter(pyfalog.warning)
|
||||
except ValueError, Exception:
|
||||
pyfalog.critical("Cannot access log file. Continuing without writing stdout to log.")
|
||||
|
||||
if not options.debug:
|
||||
# Output all stderr (stacktrace) messages as critical
|
||||
try:
|
||||
sys.stderr = LoggerWriter(pyfalog.critical)
|
||||
except ValueError, Exception:
|
||||
pyfalog.critical("Cannot access log file. Continuing without writing stderr to log.")
|
||||
|
||||
pyfalog.info("Starting Pyfa")
|
||||
pyfalog.info("Running in logging mode: {0}", logging_mode)
|
||||
|
||||
if hasattr(sys, 'frozen') and options.debug:
|
||||
pyfalog.critical("Running in frozen mode with debug turned on. Forcing all output to be written to log.")
|
||||
|
||||
from gui.mainFrame import MainFrame
|
||||
|
||||
pyfa = wx.App(False)
|
||||
MainFrame(options.title)
|
||||
pyfa.MainLoop()
|
||||
|
||||
83
pyfa.spec
Normal file
83
pyfa.spec
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- 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
|
||||
|
||||
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', '.' ),
|
||||
]
|
||||
|
||||
import_these = []
|
||||
|
||||
# Walk eos.effects and add all effects so we can import them properly
|
||||
for root, folders, files in os.walk("eos/effects"):
|
||||
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=['C:\\Users\\Ebag333\\Documents\\GitHub\\Ebag333\\Pyfa'],
|
||||
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,
|
||||
debug=False,
|
||||
console=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='pyfa',
|
||||
icon='dist_assets/win/pyfa.ico',
|
||||
onefile=False,
|
||||
)
|
||||
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
onefile=False,
|
||||
name='pyfa',
|
||||
icon='dist_assets/win/pyfa.ico',
|
||||
)
|
||||
@@ -1,3 +1,4 @@
|
||||
logbook
|
||||
matplotlib
|
||||
PyYAML
|
||||
python-dateutil
|
||||
|
||||
9
requirements_build_OSx.txt
Normal file
9
requirements_build_OSx.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
PyInstaller >= 3.2.1
|
||||
cycler >= 0.10.0
|
||||
functools32 >= 3.2.3
|
||||
future >= 0.16.0
|
||||
numpy >= 1.12.
|
||||
pyparsing >= 2.1.10
|
||||
pypiwin32 >= 219
|
||||
pytz >= 2016.10
|
||||
six >= 1.10.0
|
||||
8
requirements_build_linux.txt
Normal file
8
requirements_build_linux.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
PyInstaller >= 3.2.1
|
||||
cycler >= 0.10.0
|
||||
functools32 >= 3.2.3
|
||||
future >= 0.16.0
|
||||
numpy >= 1.12.
|
||||
pyparsing >= 2.1.10
|
||||
pytz >= 2016.10
|
||||
six
|
||||
10
requirements_build_windows.txt
Normal file
10
requirements_build_windows.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
PyInstaller >= 3.2.1
|
||||
cycler >= 0.10.0
|
||||
functools32 >= 3.2.3
|
||||
future >= 0.16.0
|
||||
numpy >= 1.12.
|
||||
pyparsing >= 2.1.10
|
||||
pypiwin32 >= 219
|
||||
pytz >= 2016.10
|
||||
six >= 1.10.0
|
||||
tornado
|
||||
BIN
scripts/upx.exe
Normal file
BIN
scripts/upx.exe
Normal file
Binary file not shown.
@@ -20,7 +20,7 @@
|
||||
import copy
|
||||
import itertools
|
||||
import json
|
||||
import logging
|
||||
from logbook import Logger
|
||||
import threading
|
||||
from codecs import open
|
||||
from xml.etree import ElementTree
|
||||
@@ -39,7 +39,7 @@ from eos.saveddata.character import Character as es_Character
|
||||
from eos.saveddata.module import Slot as es_Slot, Module as es_Module
|
||||
from eos.saveddata.fighter import Fighter as es_Fighter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CharacterImportThread(threading.Thread):
|
||||
@@ -72,7 +72,7 @@ class CharacterImportThread(threading.Thread):
|
||||
charFile = open(path, mode='r').read()
|
||||
doc = minidom.parseString(charFile)
|
||||
if doc.documentElement.tagName not in ("SerializableCCPCharacter", "SerializableUriCharacter"):
|
||||
logger.error("Incorrect EVEMon XML sheet")
|
||||
pyfalog.error("Incorrect EVEMon XML sheet")
|
||||
raise RuntimeError("Incorrect EVEMon XML sheet")
|
||||
name = doc.getElementsByTagName("name")[0].firstChild.nodeValue
|
||||
skill_els = doc.getElementsByTagName("skill")
|
||||
@@ -84,16 +84,17 @@ class CharacterImportThread(threading.Thread):
|
||||
"level": int(skill.getAttribute("level")),
|
||||
})
|
||||
else:
|
||||
logger.error("Attempted to import unknown skill %s (ID: %s) (Level: %s)",
|
||||
skill.getAttribute("name"),
|
||||
skill.getAttribute("typeID"),
|
||||
skill.getAttribute("level"),
|
||||
)
|
||||
pyfalog.error(
|
||||
"Attempted to import unknown skill {0} (ID: {1}) (Level: {2})",
|
||||
skill.getAttribute("name"),
|
||||
skill.getAttribute("typeID"),
|
||||
skill.getAttribute("level"),
|
||||
)
|
||||
char = sCharacter.new(name + " (EVEMon)")
|
||||
sCharacter.apiUpdateCharSheet(char.ID, skills)
|
||||
except Exception, e:
|
||||
logger.error("Exception on character import:")
|
||||
logger.error(e)
|
||||
pyfalog.error("Exception on character import:")
|
||||
pyfalog.error(e)
|
||||
continue
|
||||
|
||||
wx.CallAfter(self.callback)
|
||||
@@ -304,7 +305,7 @@ class Character(object):
|
||||
@staticmethod
|
||||
def rename(char, newName):
|
||||
if char.name in ("All 0", "All 5"):
|
||||
logger.info("Cannot rename built in characters.")
|
||||
pyfalog.info("Cannot rename built in characters.")
|
||||
else:
|
||||
char.name = newName
|
||||
eos.db.commit()
|
||||
@@ -404,7 +405,7 @@ class Character(object):
|
||||
def addImplant(charID, itemID):
|
||||
char = eos.db.getCharacter(charID)
|
||||
if char.ro:
|
||||
logger.error("Trying to add implant to read-only character")
|
||||
pyfalog.error("Trying to add implant to read-only character")
|
||||
return
|
||||
|
||||
implant = es_Implant(eos.db.getItem(itemID))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
from logbook import Logger
|
||||
import logging
|
||||
import threading
|
||||
import copy
|
||||
@@ -14,7 +15,7 @@ from service.settings import CRESTSettings
|
||||
from service.server import StoppableHTTPServer, AuthHandler
|
||||
from service.pycrest.eve import EVE
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Servers(Enum):
|
||||
@@ -152,17 +153,17 @@ class Crest(object):
|
||||
|
||||
def logout(self):
|
||||
"""Logout of implicit character"""
|
||||
logging.debug("Character logout")
|
||||
pyfalog.debug("Character logout")
|
||||
self.implicitCharacter = None
|
||||
wx.PostEvent(self.mainFrame, GE.SsoLogout(type=self.settings.get('mode')))
|
||||
|
||||
def stopServer(self):
|
||||
logging.debug("Stopping Server")
|
||||
pyfalog.debug("Stopping Server")
|
||||
self.httpd.stop()
|
||||
self.httpd = None
|
||||
|
||||
def startServer(self):
|
||||
logging.debug("Starting server")
|
||||
pyfalog.debug("Starting server")
|
||||
if self.httpd:
|
||||
self.stopServer()
|
||||
time.sleep(1)
|
||||
@@ -182,10 +183,10 @@ class Crest(object):
|
||||
raise Exception("Could not parse out querystring parameters.")
|
||||
|
||||
if message['state'][0] != self.state:
|
||||
logger.warn("OAUTH state mismatch")
|
||||
pyfalog.warn("OAUTH state mismatch")
|
||||
raise Exception("OAUTH State Mismatch.")
|
||||
|
||||
logger.debug("Handling CREST login with: %s" % message)
|
||||
pyfalog.debug("Handling CREST login with: {0}", message)
|
||||
|
||||
if 'access_token' in message: # implicit
|
||||
eve = copy.deepcopy(self.eve)
|
||||
@@ -199,7 +200,7 @@ class Crest(object):
|
||||
eve()
|
||||
info = eve.whoami()
|
||||
|
||||
logger.debug("Got character info: %s" % info)
|
||||
pyfalog.debug("Got character info: {0}", info)
|
||||
|
||||
self.implicitCharacter = CrestChar(info['CharacterID'], info['CharacterName'])
|
||||
self.implicitCharacter.eve = eve
|
||||
@@ -212,7 +213,7 @@ class Crest(object):
|
||||
eve()
|
||||
info = eve.whoami()
|
||||
|
||||
logger.debug("Got character info: %s" % info)
|
||||
pyfalog.debug("Got character info: {0}", info)
|
||||
|
||||
# check if we have character already. If so, simply replace refresh_token
|
||||
char = self.getCrestCharacter(int(info['CharacterID']))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
import copy
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
import eos.db
|
||||
from eos.saveddata.booster import Booster as es_Booster
|
||||
@@ -36,7 +36,7 @@ from service.character import Character
|
||||
from service.damagePattern import DamagePattern
|
||||
from service.settings import SettingsProvider
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class Fit(object):
|
||||
@@ -50,6 +50,7 @@ class Fit(object):
|
||||
return cls.instance
|
||||
|
||||
def __init__(self):
|
||||
pyfalog.debug("Initialize Fit class")
|
||||
self.pattern = DamagePattern.getInstance().getDamagePattern("Uniform")
|
||||
self.targetResists = None
|
||||
self.character = saveddata_Character.getAll5()
|
||||
@@ -727,7 +728,13 @@ class Fit(object):
|
||||
fit.drones.remove(d1)
|
||||
|
||||
d2.amount += d1.amount
|
||||
d2.amountActive += d1.amountActive if d1.amountActive > 0 else -d2.amountActive
|
||||
d2.amountActive += d1.amountActive
|
||||
|
||||
# If we have less than the total number of drones active, make them all active. Fixes #728
|
||||
# This could be removed if we ever add an enhancement to make drone stacks partially active.
|
||||
if d2.amount > d2.amountActive:
|
||||
d2.amountActive = d2.amount
|
||||
|
||||
eos.db.commit()
|
||||
self.recalc(fit)
|
||||
return True
|
||||
@@ -1016,7 +1023,7 @@ class Fit(object):
|
||||
self.recalc(fit)
|
||||
|
||||
def recalc(self, fit, withBoosters=True):
|
||||
logger.debug("=" * 10 + "recalc" + "=" * 10)
|
||||
pyfalog.info("=" * 10 + "recalc" + "=" * 10)
|
||||
if fit.factorReload is not self.serviceFittingOptions["useGlobalForceReload"]:
|
||||
fit.factorReload = self.serviceFittingOptions["useGlobalForceReload"]
|
||||
fit.clear()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import re
|
||||
import threading
|
||||
import logging
|
||||
from logbook import Logger
|
||||
import Queue
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
@@ -41,7 +41,7 @@ try:
|
||||
except ImportError:
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
# Event which tells threads dependent on Market that it's initialized
|
||||
mktRdy = threading.Event()
|
||||
@@ -50,6 +50,7 @@ mktRdy = threading.Event()
|
||||
class ShipBrowserWorkerThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
pyfalog.debug("Initialize ShipBrowserWorkerThread.")
|
||||
self.name = "ShipBrowser"
|
||||
|
||||
def run(self):
|
||||
@@ -73,24 +74,29 @@ class ShipBrowserWorkerThread(threading.Thread):
|
||||
cache[id_] = set_
|
||||
|
||||
wx.CallAfter(callback, (id_, set_))
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Callback failed.")
|
||||
pyfalog.critical(e)
|
||||
finally:
|
||||
try:
|
||||
queue.task_done()
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Queue task done failed.")
|
||||
pyfalog.critical(e)
|
||||
|
||||
|
||||
class PriceWorkerThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.name = "PriceWorker"
|
||||
pyfalog.debug("Initialize PriceWorkerThread.")
|
||||
|
||||
def run(self):
|
||||
pyfalog.debug("Run start")
|
||||
self.queue = Queue.Queue()
|
||||
self.wait = {}
|
||||
self.processUpdates()
|
||||
pyfalog.debug("Run end")
|
||||
|
||||
def processUpdates(self):
|
||||
queue = self.queue
|
||||
@@ -125,6 +131,7 @@ class SearchWorkerThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.name = "SearchWorker"
|
||||
pyfalog.debug("Initialize SearchWorkerThread.")
|
||||
|
||||
def run(self):
|
||||
self.cv = threading.Condition()
|
||||
@@ -440,7 +447,7 @@ class Market(object):
|
||||
else:
|
||||
raise TypeError("Need Item object, integer, float or string as argument")
|
||||
except:
|
||||
logger.error("Could not get item: %s", identity)
|
||||
pyfalog.error("Could not get item: {0}", identity)
|
||||
raise
|
||||
|
||||
return item
|
||||
@@ -833,8 +840,9 @@ class Market(object):
|
||||
def cb():
|
||||
try:
|
||||
callback(requests)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Callback failed.")
|
||||
pyfalog.critical(e)
|
||||
eos.db.commit()
|
||||
|
||||
self.priceWorkerThread.trigger(requests, cb)
|
||||
@@ -849,8 +857,9 @@ class Market(object):
|
||||
def cb():
|
||||
try:
|
||||
callback(item)
|
||||
except:
|
||||
pass
|
||||
except Exception as e:
|
||||
pyfalog.critical("Callback failed.")
|
||||
pyfalog.critical(e)
|
||||
|
||||
self.priceWorkerThread.setToWait(item.ID, cb)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import re
|
||||
import os
|
||||
import xml.dom
|
||||
import logging
|
||||
from logbook import Logger
|
||||
import collections
|
||||
import json
|
||||
import threading
|
||||
@@ -50,7 +50,7 @@ from service.market import Market
|
||||
if 'wxMac' not in wx.PlatformInfo or ('wxMac' in wx.PlatformInfo and wx.VERSION >= (3, 0)):
|
||||
from service.crest import Crest
|
||||
|
||||
logger = logging.getLogger("pyfa.service.port")
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
@@ -134,21 +134,21 @@ class Port(object):
|
||||
savebom = bom
|
||||
|
||||
if codec_found is None:
|
||||
logger.info("Unicode BOM not found in file %s.", path)
|
||||
pyfalog.info("Unicode BOM not found in file {0}.", path)
|
||||
attempt_codecs = (defcodepage, "utf-8", "utf-16", "cp1252")
|
||||
|
||||
for page in attempt_codecs:
|
||||
try:
|
||||
logger.info("Attempting to decode file %s using %s page.", path, page)
|
||||
pyfalog.info("Attempting to decode file {0} using {1} page.", path, page)
|
||||
srcString = unicode(srcString, page)
|
||||
codec_found = page
|
||||
logger.info("File %s decoded using %s page.", path, page)
|
||||
pyfalog.info("File {0} decoded using {1} page.", path, page)
|
||||
except UnicodeDecodeError:
|
||||
logger.info("Error unicode decoding %s from page %s, trying next codec", path, page)
|
||||
pyfalog.info("Error unicode decoding {0} from page {1}, trying next codec", path, page)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
logger.info("Unicode BOM detected in %s, using %s page.", path, codec_found)
|
||||
pyfalog.info("Unicode BOM detected in {0}, using {1} page.", path, codec_found)
|
||||
srcString = unicode(srcString[len(savebom):], codec_found)
|
||||
|
||||
else:
|
||||
@@ -166,9 +166,10 @@ class Port(object):
|
||||
fits += fitsImport
|
||||
except xml.parsers.expat.ExpatError:
|
||||
return False, "Malformed XML in %s" % path
|
||||
except Exception:
|
||||
logger.exception("Unknown exception processing: %s", path)
|
||||
return False, "Unknown Error while processing %s" % path
|
||||
except Exception as e:
|
||||
pyfalog.critical("Unknown exception processing: {0}", path)
|
||||
pyfalog.critical(e)
|
||||
return False, "Unknown Error while processing {0}" % path
|
||||
|
||||
IDs = []
|
||||
numFits = len(fits)
|
||||
@@ -340,6 +341,7 @@ class Port(object):
|
||||
except ValueError:
|
||||
f.ship = Citadel(sMkt.getItem(fit['ship']['id']))
|
||||
except:
|
||||
pyfalog.warning("Caught exception in importCrest")
|
||||
return None
|
||||
|
||||
items = fit['items']
|
||||
@@ -365,6 +367,7 @@ class Port(object):
|
||||
m = Module(item)
|
||||
# When item can't be added to any slot (unknown item or just charge), ignore it
|
||||
except ValueError:
|
||||
pyfalog.debug("Item can't be added to any slot (unknown item or just charge)")
|
||||
continue
|
||||
# Add subsystems before modules to make sure T3 cruisers have subsystems installed
|
||||
if item.category.name == "Subsystem":
|
||||
@@ -377,6 +380,7 @@ class Port(object):
|
||||
moduleList.append(m)
|
||||
|
||||
except:
|
||||
pyfalog.warning("Could not process module.")
|
||||
continue
|
||||
|
||||
# Recalc to get slot numbers correct for T3 cruisers
|
||||
@@ -405,6 +409,7 @@ class Port(object):
|
||||
string = string[string.index(str(id_)):]
|
||||
break
|
||||
except:
|
||||
pyfalog.warning("Exception caught in importDna")
|
||||
pass
|
||||
string = string[:string.index("::") + 2]
|
||||
info = string.split(":")
|
||||
@@ -422,7 +427,7 @@ class Port(object):
|
||||
return s_[:10] + "..."
|
||||
return s_
|
||||
|
||||
logger.exception("Couldn't import ship data %r", [logtransform(s) for s in info])
|
||||
pyfalog.exception("Couldn't import ship data {0}", [logtransform(s) for s in info])
|
||||
return None
|
||||
|
||||
moduleList = []
|
||||
@@ -449,6 +454,7 @@ class Port(object):
|
||||
try:
|
||||
m = Module(item)
|
||||
except:
|
||||
pyfalog.warning("Exception caught in importDna")
|
||||
continue
|
||||
# Add subsystems before modules to make sure T3 cruisers have subsystems installed
|
||||
if item.category.name == "Subsystem":
|
||||
@@ -497,6 +503,7 @@ class Port(object):
|
||||
fit.ship = Citadel(ship)
|
||||
fit.name = fitName
|
||||
except:
|
||||
pyfalog.warning("Exception caught in importEft")
|
||||
return
|
||||
|
||||
# maintain map of drones and their quantities
|
||||
@@ -537,6 +544,7 @@ class Port(object):
|
||||
item = sMkt.getItem(modName, eager="group.category")
|
||||
except:
|
||||
# if no data can be found (old names)
|
||||
pyfalog.warning("no data can be found (old names)")
|
||||
continue
|
||||
|
||||
if item.category.name == "Drone":
|
||||
@@ -563,7 +571,7 @@ class Port(object):
|
||||
elif "boosterness" in item.attributes:
|
||||
fit.boosters.append(Booster(item))
|
||||
else:
|
||||
logger.error("Failed to import implant: %s", line)
|
||||
pyfalog.error("Failed to import implant: {0}", line)
|
||||
# elif item.category.name == "Subsystem":
|
||||
# try:
|
||||
# subsystem = Module(item)
|
||||
@@ -689,6 +697,7 @@ class Port(object):
|
||||
try:
|
||||
droneItem = sMkt.getItem(droneName, eager="group.category")
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
continue
|
||||
if droneItem.category.name == "Drone":
|
||||
# Add drone to the fitting
|
||||
@@ -710,6 +719,7 @@ class Port(object):
|
||||
try:
|
||||
implantItem = sMkt.getItem(entityData, eager="group.category")
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
continue
|
||||
if implantItem.category.name != "Implant":
|
||||
continue
|
||||
@@ -725,6 +735,7 @@ class Port(object):
|
||||
try:
|
||||
boosterItem = sMkt.getItem(entityData, eager="group.category")
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
continue
|
||||
# All boosters have implant category
|
||||
if boosterItem.category.name != "Implant":
|
||||
@@ -745,6 +756,7 @@ class Port(object):
|
||||
try:
|
||||
item = sMkt.getItem(cargoName)
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
continue
|
||||
# Add Cargo to the fitting
|
||||
c = Cargo(item)
|
||||
@@ -758,6 +770,7 @@ class Port(object):
|
||||
try:
|
||||
modItem = sMkt.getItem(modName)
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
continue
|
||||
|
||||
# Create module
|
||||
@@ -779,6 +792,7 @@ class Port(object):
|
||||
if chargeItem.category.name == "Charge":
|
||||
m.charge = chargeItem
|
||||
except:
|
||||
pyfalog.warning("Cannot get item.")
|
||||
pass
|
||||
# Append module to fit
|
||||
moduleList.append(m)
|
||||
@@ -797,6 +811,7 @@ class Port(object):
|
||||
wx.CallAfter(callback, None)
|
||||
# Skip fit silently if we get an exception
|
||||
except Exception:
|
||||
pyfalog.error("Caught exception on fit.")
|
||||
pass
|
||||
|
||||
return fits
|
||||
@@ -821,6 +836,7 @@ class Port(object):
|
||||
except ValueError:
|
||||
f.ship = Citadel(sMkt.getItem(shipType))
|
||||
except:
|
||||
pyfalog.warning("Caught exception on importXml")
|
||||
continue
|
||||
hardwares = fitting.getElementsByTagName("hardware")
|
||||
moduleList = []
|
||||
@@ -830,6 +846,7 @@ class Port(object):
|
||||
try:
|
||||
item = sMkt.getItem(moduleName, eager="group.category")
|
||||
except:
|
||||
pyfalog.warning("Caught exception on importXml")
|
||||
continue
|
||||
if item:
|
||||
if item.category.name == "Drone":
|
||||
@@ -852,6 +869,7 @@ class Port(object):
|
||||
m = Module(item)
|
||||
# When item can't be added to any slot (unknown item or just charge), ignore it
|
||||
except ValueError:
|
||||
pyfalog.warning("item can't be added to any slot (unknown item or just charge), ignore it")
|
||||
continue
|
||||
# Add subsystems before modules to make sure T3 cruisers have subsystems installed
|
||||
if item.category.name == "Subsystem":
|
||||
@@ -865,6 +883,7 @@ class Port(object):
|
||||
moduleList.append(m)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pyfalog.warning("Keyboard Interrupt")
|
||||
continue
|
||||
|
||||
# Recalc to get slot numbers correct for T3 cruisers
|
||||
@@ -1171,7 +1190,7 @@ class FitImportThread(threading.Thread):
|
||||
success, result = sPort.importFitFromFiles(self.paths, self.callback)
|
||||
|
||||
if not success: # there was an error during processing
|
||||
logger.error("Error while processing file import: %s", result)
|
||||
pyfalog.error("Error while processing file import: {0}", result)
|
||||
wx.CallAfter(self.callback, -2, result)
|
||||
else: # Send done signal to GUI
|
||||
wx.CallAfter(self.callback, -1, result)
|
||||
|
||||
@@ -25,9 +25,9 @@ from eos.db import migration
|
||||
from eos.db.saveddata.loadDefaultDatabaseValues import DefaultDatabaseValues
|
||||
from eos.db.saveddata.databaseRepair import DatabaseCleanup
|
||||
|
||||
import logging
|
||||
from logbook import Logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
# Make sure the saveddata db exists
|
||||
if config.savePath and not os.path.exists(config.savePath):
|
||||
@@ -35,14 +35,16 @@ if config.savePath and not os.path.exists(config.savePath):
|
||||
|
||||
if config.saveDB and os.path.isfile(config.saveDB):
|
||||
# If database exists, run migration after init'd database
|
||||
pyfalog.debug("Run database migration.")
|
||||
db.saveddata_meta.create_all()
|
||||
migration.update(db.saveddata_engine)
|
||||
# Import default database values
|
||||
# Import values that must exist otherwise Pyfa breaks
|
||||
pyfalog.debug("Import Required Database Values.")
|
||||
DefaultDatabaseValues.importRequiredDefaults()
|
||||
|
||||
# Finds and fixes database corruption issues.
|
||||
logging.debug("Starting database validation.")
|
||||
pyfalog.debug("Starting database validation.")
|
||||
database_cleanup_instance = DatabaseCleanup()
|
||||
database_cleanup_instance.OrphanedCharacterSkills(db.saveddata_engine)
|
||||
database_cleanup_instance.OrphanedFitCharacterIDs(db.saveddata_engine)
|
||||
@@ -52,7 +54,7 @@ if config.saveDB and os.path.isfile(config.saveDB):
|
||||
database_cleanup_instance.OrphanedFitIDItemID(db.saveddata_engine)
|
||||
database_cleanup_instance.NullDamageTargetPatternValues(db.saveddata_engine)
|
||||
database_cleanup_instance.DuplicateSelectedAmmoName(db.saveddata_engine)
|
||||
logging.debug("Completed database validation.")
|
||||
pyfalog.debug("Completed database validation.")
|
||||
|
||||
else:
|
||||
# If database does not exist, do not worry about migration. Simply
|
||||
|
||||
@@ -24,6 +24,10 @@ from xml.dom import minidom
|
||||
from eos import db
|
||||
from service.network import Network, TimeoutError
|
||||
from service.fit import Fit
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
VALIDITY = 24 * 60 * 60 # Price validity period, 24 hours
|
||||
REREQUEST = 4 * 60 * 60 # Re-request delay for failed fetches, 4 hours
|
||||
@@ -114,6 +118,7 @@ class Price(object):
|
||||
# If getting or processing data returned any errors
|
||||
except TimeoutError:
|
||||
# Timeout error deserves special treatment
|
||||
pyfalog.warning("Price fetch timout")
|
||||
for typeID in priceMap.keys():
|
||||
priceobj = priceMap[typeID]
|
||||
priceobj.time = time.time() + TIMEOUT
|
||||
@@ -121,6 +126,7 @@ class Price(object):
|
||||
del priceMap[typeID]
|
||||
except:
|
||||
# all other errors will pass and continue onward to the REREQUEST delay
|
||||
pyfalog.warning("Caught exception in fetchPrices")
|
||||
pass
|
||||
|
||||
# if we get to this point, then we've got an error. Set to REREQUEST delay
|
||||
|
||||
@@ -1,12 +1 @@
|
||||
import logging
|
||||
|
||||
|
||||
class NullHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
pass
|
||||
|
||||
|
||||
logger = logging.getLogger('pycrest')
|
||||
logger.addHandler(NullHandler())
|
||||
|
||||
version = "0.0.1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import base64
|
||||
import logging
|
||||
from logbook import Logger
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
@@ -20,7 +20,7 @@ except ImportError: # pragma: no cover
|
||||
# noinspection PyPep8Naming
|
||||
import cPickle as pickle
|
||||
|
||||
logger = logging.getLogger("pycrest.eve")
|
||||
pyfalog = Logger(__name__)
|
||||
cache_re = re.compile(r'max-age=([0-9]+)')
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class FileCache(APICache):
|
||||
os.mkdir(self.path, 0o700)
|
||||
|
||||
def _getpath(self, key):
|
||||
return config.parsePath(self.path, str(hash(key)) + '.cache')
|
||||
return os.path.join(self.path, str(hash(key)) + '.cache')
|
||||
|
||||
def put(self, key, value):
|
||||
with open(self._getpath(key), 'wb') as f:
|
||||
@@ -58,6 +58,7 @@ class FileCache(APICache):
|
||||
with open(self._getpath(key), 'rb') as f:
|
||||
return pickle.loads(zlib.decompress(f.read()))
|
||||
except IOError as ex:
|
||||
pyfalog.debug("IO error opening zip file. (May not exist yet)")
|
||||
if ex.errno == 2: # file does not exist (yet)
|
||||
return None
|
||||
else:
|
||||
@@ -69,6 +70,8 @@ class FileCache(APICache):
|
||||
try:
|
||||
os.unlink(self._getpath(key))
|
||||
except OSError as ex:
|
||||
pyfalog.debug("Caught exception in invalidate")
|
||||
pyfalog.debug(ex)
|
||||
if ex.errno == 2: # does not exist
|
||||
pass
|
||||
else:
|
||||
@@ -116,7 +119,7 @@ class APIConnection(object):
|
||||
self.cache = DictCache()
|
||||
|
||||
def get(self, resource, params=None):
|
||||
logger.debug('Getting resource %s', resource)
|
||||
pyfalog.debug('Getting resource {0}', resource)
|
||||
if params is None:
|
||||
params = {}
|
||||
|
||||
@@ -136,18 +139,18 @@ class APIConnection(object):
|
||||
key = (resource, frozenset(self._session.headers.items()), frozenset(prms.items()))
|
||||
cached = self.cache.get(key)
|
||||
if cached and cached['cached_until'] > time.time():
|
||||
logger.debug('Cache hit for resource %s (params=%s)', resource, prms)
|
||||
pyfalog.debug('Cache hit for resource {0} (params={1})', resource, prms)
|
||||
return cached
|
||||
elif cached:
|
||||
logger.debug('Cache stale for resource %s (params=%s)', resource, prms)
|
||||
pyfalog.debug('Cache stale for resource {0} (params={1})', resource, prms)
|
||||
self.cache.invalidate(key)
|
||||
else:
|
||||
logger.debug('Cache miss for resource %s (params=%s', resource, prms)
|
||||
pyfalog.debug('Cache miss for resource {0} (params={1})', resource, prms)
|
||||
|
||||
logger.debug('Getting resource %s (params=%s)', resource, prms)
|
||||
pyfalog.debug('Getting resource {0} (params={1})', resource, prms)
|
||||
res = self._session.get(resource, params=prms)
|
||||
if res.status_code != 200:
|
||||
raise APIException("Got unexpected status code from server: %i" % res.status_code)
|
||||
raise APIException("Got unexpected status code from server: {0}" % res.status_code)
|
||||
|
||||
ret = res.json()
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import BaseHTTPServer
|
||||
import urlparse
|
||||
import socket
|
||||
import logging
|
||||
import threading
|
||||
from logbook import Logger
|
||||
|
||||
from service.settings import CRESTSettings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
# noinspection PyPep8
|
||||
HTML = '''
|
||||
@@ -34,6 +33,7 @@ HTML = '''
|
||||
<h1>pyfa</h1>
|
||||
{0}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function extractFromHash(name, hash) {{
|
||||
var match = hash.match(new RegExp(name + "=([^&]+)"));
|
||||
@@ -42,13 +42,24 @@ function extractFromHash(name, hash) {{
|
||||
|
||||
var hash = window.location.hash;
|
||||
var token = extractFromHash("access_token", hash);
|
||||
var step2 = extractFromHash("step2", hash);
|
||||
|
||||
if (token){{
|
||||
var redirect = window.location.origin.concat('/?', window.location.hash.substr(1));
|
||||
window.location = redirect;
|
||||
function doRedirect() {{
|
||||
if (token){{
|
||||
// implicit authentication
|
||||
var redirect = window.location.origin.concat('/?', window.location.hash.substr(1), '&step=2');
|
||||
window.location = redirect;
|
||||
}}
|
||||
else {{
|
||||
// user-defined
|
||||
var redirect = window.location.href + '&step=2';
|
||||
window.location = redirect;
|
||||
}}
|
||||
}}
|
||||
else {{
|
||||
console.log("do nothing");
|
||||
|
||||
// do redirect if we are not already on step 2
|
||||
if (window.location.href.indexOf('step=2') == -1) {{
|
||||
setTimeout(doRedirect(), 1000);
|
||||
}}
|
||||
</script>
|
||||
</body>
|
||||
@@ -61,14 +72,20 @@ class AuthHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
if self.path == "/favicon.ico":
|
||||
return
|
||||
|
||||
parsed_path = urlparse.urlparse(self.path)
|
||||
parts = urlparse.parse_qs(parsed_path.query)
|
||||
|
||||
msg = ""
|
||||
|
||||
step2 = 'step' in parts
|
||||
|
||||
try:
|
||||
self.server.callback(parts)
|
||||
msg = "If you see this message then it means you should be logged into CREST. You may close this window and return to the application."
|
||||
if step2:
|
||||
self.server.callback(parts)
|
||||
msg = "If you see this message then it means you should be logged into CREST. You may close this window and return to the application."
|
||||
else:
|
||||
# For implicit mode, we have to serve up the page which will take the hash and redirect useing a querystring
|
||||
msg = "Processing response from EVE Online"
|
||||
except Exception, ex:
|
||||
msg = "<h2>Error</h2>\n<p>{}</p>".format(ex.message)
|
||||
finally:
|
||||
@@ -76,7 +93,9 @@ class AuthHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
self.wfile.write(HTML.format(msg))
|
||||
|
||||
self.server.stop()
|
||||
if step2:
|
||||
# Only stop once if we've received something in the querystring
|
||||
self.server.stop()
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
@@ -90,7 +109,7 @@ class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
|
||||
|
||||
# Allow listening for x seconds
|
||||
sec = self.settings.get('timeout')
|
||||
logger.debug("Running server for %d seconds", sec)
|
||||
pyfalog.debug("Running server for {0} seconds", sec)
|
||||
|
||||
self.socket.settimeout(1)
|
||||
self.max_tries = sec / self.socket.gettimeout()
|
||||
@@ -104,16 +123,17 @@ class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
|
||||
sock.settimeout(None)
|
||||
return sock, addr
|
||||
except socket.timeout:
|
||||
pyfalog.warning("Server timed out waiting for connection")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.run = False
|
||||
|
||||
def handle_timeout(self):
|
||||
# logger.debug("Number of tries: %d" % self.tries)
|
||||
pyfalog.debug("Number of tries: {0}", self.tries)
|
||||
self.tries += 1
|
||||
if self.tries == self.max_tries:
|
||||
logger.debug("Server timed out waiting for connection")
|
||||
pyfalog.debug("Server timed out waiting for connection")
|
||||
self.stop()
|
||||
|
||||
def serve(self, callback=None):
|
||||
@@ -122,6 +142,7 @@ class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
|
||||
try:
|
||||
self.handle_request()
|
||||
except TypeError:
|
||||
pyfalog.debug("Caught exception in serve")
|
||||
pass
|
||||
|
||||
self.server_close()
|
||||
|
||||
@@ -25,7 +25,7 @@ import config
|
||||
|
||||
|
||||
class SettingsProvider(object):
|
||||
BASE_PATH = config.getSavePath("settings")
|
||||
BASE_PATH = os.path.join(config.savePath, 'settings')
|
||||
settings = {}
|
||||
_instance = None
|
||||
|
||||
@@ -44,7 +44,7 @@ class SettingsProvider(object):
|
||||
|
||||
s = self.settings.get(area)
|
||||
if s is None:
|
||||
p = config.parsePath(self.BASE_PATH, area)
|
||||
p = os.path.join(self.BASE_PATH, area)
|
||||
|
||||
if not os.path.exists(p):
|
||||
info = {}
|
||||
|
||||
@@ -29,6 +29,9 @@ import dateutil.parser
|
||||
import config
|
||||
from service.network import Network
|
||||
from service.settings import UpdateSettings
|
||||
from logbook import Logger
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CheckUpdateThread(threading.Thread):
|
||||
@@ -83,6 +86,7 @@ class CheckUpdateThread(threading.Thread):
|
||||
wx.CallAfter(self.callback, release) # Singularity -> Singularity
|
||||
break
|
||||
except:
|
||||
pyfalog.warning("Caught exception in run")
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
|
||||
12
tests/test_modules/eos/test_mathUtils.py
Normal file
12
tests/test_modules/eos/test_mathUtils.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from eos.mathUtils import floorFloat
|
||||
|
||||
|
||||
def test_floorFloat():
|
||||
assert type(floorFloat(1)) is not float
|
||||
assert type(floorFloat(1)) is int
|
||||
assert type(floorFloat(1.1)) is not float
|
||||
assert type(floorFloat(1.1)) is int
|
||||
assert floorFloat(1.1) == 1
|
||||
assert floorFloat(1.9) == 1
|
||||
assert floorFloat(1.5) == 1
|
||||
assert floorFloat(-1.5) == -2
|
||||
9
tests/test_modules/gui/test_aboutData.py
Normal file
9
tests/test_modules/gui/test_aboutData.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from gui.aboutData import versionString, licenses, developers, credits, description
|
||||
|
||||
|
||||
def test_aboutData():
|
||||
assert versionString.__len__() > 0
|
||||
assert licenses.__len__() > 0
|
||||
assert developers.__len__() > 0
|
||||
assert credits.__len__() > 0
|
||||
assert description.__len__() > 0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user