Merge branch 'test-3' into esi
# Conflicts: # requirements.txt
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
# Submit a bug report bug report or feature request
|
||||
<!--
|
||||
|
||||
Submit a bug report bug report or feature request
|
||||
|
||||
Here you can inform pyfa developers of potential bugs or suggest features / improvements to the project. Please check
|
||||
to make sure that the bug hasn't been reported or feature requested before submitting. If you have general questions
|
||||
about the project and want to reach out to the developers personally, please check out out our [Slack]
|
||||
(https://pyfainvite.azurewebsites.net/).
|
||||
|
||||
---
|
||||
-->
|
||||
|
||||
## Bug Report
|
||||
|
||||
|
||||
@@ -36,13 +36,8 @@ The following is a list of pyfa packages available for certain distributions. Pl
|
||||
### Dependencies
|
||||
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
||||
|
||||
* Python 2.7
|
||||
* `wxPython` 2.8/3.0
|
||||
* `sqlalchemy` >= 1.0.5
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
|
||||
* `requests`
|
||||
* `logbook` >= 1.0.0
|
||||
* Python 3.6
|
||||
* Requirements as listed in `requirements.txt`
|
||||
|
||||
## Bug Reporting
|
||||
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
||||
|
||||
@@ -23,7 +23,7 @@ added_files = [
|
||||
('../../eve.db', '.'),
|
||||
('../../README.md', '.'),
|
||||
('../../LICENSE', '.'),
|
||||
('../../gitversion', '.'),
|
||||
('../../.version', '.'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ def handler(fit, src, context, **kwargs):
|
||||
amount = src.getModifiedItemAttr("powerTransferAmount")
|
||||
time = src.getModifiedItemAttr("duration")
|
||||
|
||||
if 'effect' in kwargs:
|
||||
if 'effect' in kwargs and "projected" in context:
|
||||
amount *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
|
||||
if "projected" in context:
|
||||
|
||||
@@ -11,13 +11,14 @@ displayName = "ECM"
|
||||
prefix = "fighterAbilityECM"
|
||||
|
||||
type = "projected", "active"
|
||||
grouped = True
|
||||
|
||||
|
||||
def handler(fit, module, context, **kwargs):
|
||||
if "projected" not in context:
|
||||
return
|
||||
# jam formula: 1 - (1- (jammer str/ship str))^(# of jam mods with same str))
|
||||
strModifier = 1 - module.getModifiedItemAttr("{}Strength{}".format(prefix, fit.scanType)) / fit.scanStrength
|
||||
strModifier = 1 - (module.getModifiedItemAttr("{}Strength{}".format(prefix, fit.scanType)) * module.amountActive) / fit.scanStrength
|
||||
|
||||
if 'effect' in kwargs:
|
||||
strModifier *= ModifiedAttributeDict.getResistance(fit, kwargs['effect'])
|
||||
|
||||
@@ -9,11 +9,12 @@ from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
displayName = "Energy Neutralizer"
|
||||
prefix = "fighterAbilityEnergyNeutralizer"
|
||||
type = "active", "projected"
|
||||
grouped = True
|
||||
|
||||
|
||||
def handler(fit, src, context, **kwargs):
|
||||
if "projected" in context:
|
||||
amount = src.getModifiedItemAttr("{}Amount".format(prefix))
|
||||
amount = src.getModifiedItemAttr("{}Amount".format(prefix)) * src.amountActive
|
||||
time = src.getModifiedItemAttr("{}Duration".format(prefix))
|
||||
|
||||
if 'effect' in kwargs:
|
||||
|
||||
@@ -14,7 +14,8 @@ runTime = "late"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.boostItemAttr("maxVelocity", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSpeedBonus"))
|
||||
module.boostItemAttr("maxVelocity", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSpeedBonus"),
|
||||
stackingPenalties=True)
|
||||
module.boostItemAttr("signatureRadius",
|
||||
module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSignatureRadiusBonus"),
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -6,13 +6,12 @@ effects, and thus this effect file contains some custom information useful only
|
||||
|
||||
# User-friendly name for the ability
|
||||
displayName = "Stasis Webifier"
|
||||
|
||||
prefix = "fighterAbilityStasisWebifier"
|
||||
|
||||
type = "active", "projected"
|
||||
grouped = True
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
if "projected" not in context:
|
||||
return
|
||||
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty".format(prefix)))
|
||||
fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty".format(prefix)) * src.amountActive)
|
||||
|
||||
@@ -8,9 +8,10 @@ effects, and thus this effect file contains some custom information useful only
|
||||
displayName = "Warp Disruption"
|
||||
prefix = "fighterAbilityWarpDisruption"
|
||||
type = "active", "projected"
|
||||
grouped = True
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
if "projected" not in context:
|
||||
return
|
||||
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("{}PointStrength".format(prefix)))
|
||||
fit.ship.increaseItemAttr("warpScrambleStatus", src.getModifiedItemAttr("{}PointStrength".format(prefix)) * src.amountActive)
|
||||
|
||||
@@ -6,15 +6,15 @@ type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"structureDamageAmount", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"shieldBonus", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"armorDamageAmount", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"armorHP", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"shieldCapacity", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Repair Drone Operation"),
|
||||
fit.drones.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Drone Operation"),
|
||||
"hp", src.getModifiedItemAttr("shipBonusRole2"))
|
||||
|
||||
@@ -271,17 +271,19 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
projected = False
|
||||
|
||||
for ability in self.abilities:
|
||||
if ability.active:
|
||||
effect = ability.effect
|
||||
if effect.runTime == runTime and effect.activeByDefault and \
|
||||
((projected and effect.isType("projected")) or not projected):
|
||||
if ability.grouped:
|
||||
if not ability.active:
|
||||
continue
|
||||
|
||||
effect = ability.effect
|
||||
if effect.runTime == runTime and effect.activeByDefault and \
|
||||
((projected and effect.isType("projected")) or not projected):
|
||||
if ability.grouped:
|
||||
effect.handler(fit, self, context)
|
||||
else:
|
||||
i = 0
|
||||
while i != self.amountActive:
|
||||
effect.handler(fit, self, context)
|
||||
else:
|
||||
i = 0
|
||||
while i != self.amountActive:
|
||||
effect.handler(fit, self, context)
|
||||
i += 1
|
||||
i += 1
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Fighter(self.item)
|
||||
|
||||
@@ -362,12 +362,13 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
self.deleted = True
|
||||
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
|
||||
# need to delete from import cache before actually deleting fit
|
||||
if self.shipBrowser.GetActiveStage() == 5:
|
||||
if fit in self.shipBrowser.lastdata: # remove fit from import cache
|
||||
self.shipBrowser.lastdata.remove(fit)
|
||||
for x in self.shipBrowser.lastdata: # remove fit from import cache
|
||||
if x[0] == self.fitID:
|
||||
self.shipBrowser.lastdata.remove(x)
|
||||
break
|
||||
|
||||
sFit.deleteFit(self.fitID)
|
||||
|
||||
@@ -376,7 +377,7 @@ class FitItem(SFItem.SFBrowserItem):
|
||||
|
||||
# todo: would a simple RefreshList() work here instead of posting that a stage has been selected?
|
||||
if self.shipBrowser.GetActiveStage() == 5:
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata))
|
||||
wx.PostEvent(self.shipBrowser, ImportSelected(fits=self.shipBrowser.lastdata, recent=self.shipBrowser.recentFits))
|
||||
elif self.shipBrowser.GetActiveStage() == 4:
|
||||
wx.PostEvent(self.shipBrowser, SearchSelected(text=self.shipBrowser.navpanel.lastSearch, back=True))
|
||||
else:
|
||||
|
||||
@@ -242,8 +242,8 @@ class MainFrame(wx.Frame):
|
||||
self.titleTimer = wx.Timer(self)
|
||||
self.Bind(wx.EVT_TIMER, self.updateTitle, self.titleTimer)
|
||||
|
||||
def ShowUpdateBox(self, release):
|
||||
dlg = UpdateDialog(self, release)
|
||||
def ShowUpdateBox(self, release, version):
|
||||
dlg = UpdateDialog(self, release, version)
|
||||
dlg.ShowModal()
|
||||
|
||||
def LoadPreviousOpenFits(self):
|
||||
|
||||
@@ -22,12 +22,33 @@ import wx
|
||||
# noinspection PyPackageRequirements
|
||||
import dateutil.parser
|
||||
from service.settings import UpdateSettings as svc_UpdateSettings
|
||||
import wx.html2
|
||||
import webbrowser
|
||||
import re
|
||||
import markdown2
|
||||
|
||||
# HTML template. We link to a bootstrap cdn for quick and easy css, and include some additional teaks.
|
||||
html_tmpl = """
|
||||
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css' rel='stylesheet' />
|
||||
<style>
|
||||
body {{ padding: 10px; font-size:0.87em }}
|
||||
p , li {{ text-align: justify; }}
|
||||
h2 {{ text-align: center; margin: 0; }}
|
||||
.date {{ text-align: right; }}
|
||||
hr {{ border: #000 1px solid; }}
|
||||
</style>
|
||||
<h2>pyfa {0}</h2>
|
||||
<div class="date"><small>{1}</small></div>
|
||||
<hr>
|
||||
{2}
|
||||
{3}
|
||||
"""
|
||||
|
||||
|
||||
class UpdateDialog(wx.Dialog):
|
||||
def __init__(self, parent, release):
|
||||
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Pyfa Update", pos=wx.DefaultPosition,
|
||||
size=wx.Size(400, 300), style=wx.DEFAULT_DIALOG_STYLE)
|
||||
def __init__(self, parent, release, version):
|
||||
wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="pyfa Update Available", pos=wx.DefaultPosition,
|
||||
size=wx.Size(550, 450), style=wx.DEFAULT_DIALOG_STYLE)
|
||||
|
||||
self.UpdateSettings = svc_UpdateSettings.getInstance()
|
||||
self.releaseInfo = release
|
||||
@@ -35,51 +56,28 @@ class UpdateDialog(wx.Dialog):
|
||||
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
headSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.headingText = wx.StaticText(self, wx.ID_ANY, "Pyfa Update Available!", wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.ALIGN_CENTRE)
|
||||
self.headingText.Wrap(-1)
|
||||
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)
|
||||
|
||||
versionSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
if self.releaseInfo['prerelease']:
|
||||
self.releaseText = wx.StaticText(self, wx.ID_ANY, "Pre-release", wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.ALIGN_RIGHT)
|
||||
self.releaseText.SetFont(wx.Font(12, 74, 90, 92, False))
|
||||
self.releaseText.SetForegroundColour(wx.Colour(230, 0, 0))
|
||||
else:
|
||||
self.releaseText = wx.StaticText(self, wx.ID_ANY, "Stable", wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.ALIGN_RIGHT)
|
||||
self.releaseText.SetFont(wx.Font(12, 74, 90, 90, False))
|
||||
|
||||
self.releaseText.Wrap(-1)
|
||||
|
||||
versionSizer.Add(self.releaseText, 1, wx.ALL, 5)
|
||||
|
||||
self.versionText = wx.StaticText(self, wx.ID_ANY, self.releaseInfo['tag_name'], wx.DefaultPosition,
|
||||
wx.DefaultSize, wx.ALIGN_LEFT)
|
||||
self.versionText.Wrap(-1)
|
||||
self.versionText.SetFont(wx.Font(12, 74, 90, 90, False))
|
||||
|
||||
versionSizer.Add(self.versionText, 1, wx.ALL, 5)
|
||||
|
||||
mainSizer.Add(versionSizer, 0, wx.EXPAND, 0)
|
||||
|
||||
releaseDate = dateutil.parser.parse(self.releaseInfo['published_at'])
|
||||
notesSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.notesTextCtrl = wx.TextCtrl(self, wx.ID_ANY, str(releaseDate.date()) + ":\n\n" + self.releaseInfo['body'],
|
||||
wx.DefaultPosition, wx.DefaultSize,
|
||||
wx.TE_AUTO_URL | wx.TE_MULTILINE | wx.TE_READONLY | wx.DOUBLE_BORDER | wx.TRANSPARENT_WINDOW)
|
||||
self.browser = wx.html2.WebView.New(self)
|
||||
self.browser.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self.OnNewWindow)
|
||||
|
||||
notesSizer.Add(self.notesTextCtrl, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
|
||||
link_patterns = [
|
||||
(re.compile("#(\d+)", re.I), r"https://github.com/pyfa-org/Pyfa/issues/\1"),
|
||||
(re.compile("@(\w+)", re.I), r"https://github.com/\1")
|
||||
]
|
||||
|
||||
markdowner = markdown2.Markdown(
|
||||
extras=['cuddled-lists', 'fenced-code-blocks', 'target-blank-links', 'toc', 'link-patterns'],
|
||||
link_patterns=link_patterns)
|
||||
|
||||
self.browser.SetPage(html_tmpl.format(
|
||||
self.releaseInfo['tag_name'],
|
||||
releaseDate.strftime('%B %d, %Y'),
|
||||
"<p class='text-danger'><b>This is a pre-release, be prepared for unstable features</b></p>" if version.is_prerelease else "",
|
||||
markdowner.convert(self.releaseInfo['body'])
|
||||
),"")
|
||||
|
||||
notesSizer.Add(self.browser, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 5)
|
||||
mainSizer.Add(notesSizer, 1, wx.EXPAND, 5)
|
||||
|
||||
self.supressCheckbox = wx.CheckBox(self, wx.ID_ANY, "Don't remind me again for this release",
|
||||
@@ -117,6 +115,10 @@ class UpdateDialog(wx.Dialog):
|
||||
def OnClose(self, e):
|
||||
self.Close()
|
||||
|
||||
def OnNewWindow(self, event):
|
||||
url = event.GetURL()
|
||||
webbrowser.open(url)
|
||||
|
||||
def SuppressChange(self, e):
|
||||
if self.supressCheckbox.IsChecked():
|
||||
self.UpdateSettings.set('version', self.releaseInfo['tag_name'])
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
wxPython >= 4.0.0b2
|
||||
wxPython >= 4.0.1
|
||||
logbook >= 1.0.0
|
||||
matplotlib >= 2.0.0
|
||||
python-dateutil
|
||||
urllib3
|
||||
requests == 2.0.0
|
||||
sqlalchemy == 1.0.5
|
||||
esipy == 0.3.0
|
||||
requests >= 2.0.0
|
||||
sqlalchemy >= 1.0.5
|
||||
esipy == 0.3.0
|
||||
markdown2
|
||||
packaging
|
||||
@@ -54,13 +54,14 @@ from collections import OrderedDict
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
EFT_SLOT_ORDER = [Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM]
|
||||
EFT_SLOT_ORDER = [Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM, Slot.SERVICE]
|
||||
INV_FLAGS = {
|
||||
Slot.LOW: 11,
|
||||
Slot.MED: 19,
|
||||
Slot.HIGH: 27,
|
||||
Slot.RIG: 92,
|
||||
Slot.SUBSYSTEM: 125
|
||||
Slot.SUBSYSTEM: 125,
|
||||
Slot.SERVICE: 164
|
||||
}
|
||||
|
||||
INV_FLAG_CARGOBAY = 5
|
||||
|
||||
@@ -30,6 +30,8 @@ import config
|
||||
from service.network import Network
|
||||
from service.settings import UpdateSettings
|
||||
from logbook import Logger
|
||||
from packaging.version import Version
|
||||
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -46,7 +48,7 @@ class CheckUpdateThread(threading.Thread):
|
||||
network = Network.getInstance()
|
||||
|
||||
try:
|
||||
response = network.request('https://api.github.com/repos/pyfa-org/Pyfa/releases', network.UPDATE)
|
||||
response = network.request('https://api.github.com/repos/blitzmann/Pyfa/releases', network.UPDATE)
|
||||
jsonResponse = json.loads(response.read())
|
||||
jsonResponse.sort(
|
||||
key=lambda x: calendar.timegm(dateutil.parser.parse(x['published_at']).utctimetuple()),
|
||||
@@ -54,8 +56,11 @@ class CheckUpdateThread(threading.Thread):
|
||||
)
|
||||
|
||||
for release in jsonResponse:
|
||||
rVersion = Version(release['tag_name'])
|
||||
cVersion = Version(config.version)
|
||||
|
||||
# Suppress pre releases
|
||||
if release['prerelease'] and self.settings.get('prerelease'):
|
||||
if rVersion.is_prerelease and self.settings.get('prerelease'):
|
||||
continue
|
||||
|
||||
# Handle use-case of updating to suppressed version
|
||||
@@ -66,24 +71,9 @@ class CheckUpdateThread(threading.Thread):
|
||||
if release['tag_name'] == self.settings.get('version'):
|
||||
break
|
||||
|
||||
# Set the release version that we will be comparing with.
|
||||
if release['prerelease']:
|
||||
rVersion = release['tag_name'].replace('singularity-', '', 1)
|
||||
else:
|
||||
rVersion = release['tag_name'].replace('v', '', 1)
|
||||
if rVersion > cVersion:
|
||||
wx.CallAfter(self.callback, release, rVersion)
|
||||
|
||||
if config.tag is 'git' and \
|
||||
not release['prerelease'] and \
|
||||
self.versiontuple(rVersion) >= self.versiontuple(config.version):
|
||||
wx.CallAfter(self.callback, release) # git (dev/Singularity) -> Stable
|
||||
elif config.expansionName is not "Singularity":
|
||||
if release['prerelease']:
|
||||
wx.CallAfter(self.callback, release) # Stable -> Singularity
|
||||
elif self.versiontuple(rVersion) > self.versiontuple(config.version):
|
||||
wx.CallAfter(self.callback, release) # Stable -> Stable
|
||||
else:
|
||||
if release['prerelease'] and rVersion > config.expansionVersion:
|
||||
wx.CallAfter(self.callback, release) # Singularity -> Singularity
|
||||
break
|
||||
except Exception as e:
|
||||
pyfalog.error("Caught exception in run")
|
||||
|
||||
Reference in New Issue
Block a user