Fix the server docker image build

This commit is contained in:
2026-02-28 20:47:53 +01:00
parent 564ba1d85d
commit 5c01ecb2d1
11 changed files with 87 additions and 35 deletions

View File

@@ -2,8 +2,8 @@ FROM python:3.12-slim
WORKDIR /app WORKDIR /app
COPY requirements.txt . COPY requirements-server.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements-server.txt
COPY . . COPY . .
EXPOSE 9123 EXPOSE 9123

View File

@@ -49,4 +49,12 @@ fi
echo "" echo ""
echo "Build complete! dist/pyfa/pyfa.exe (GUI), dist/pyfa/pyfa-server.exe (POST /simulate :9123)" echo "Build complete! dist/pyfa/pyfa.exe (GUI), dist/pyfa/pyfa-server.exe (POST /simulate :9123)"
echo "Docker image: ${IMAGE_BASE}:${COMMIT_SHA} (and :latest)" echo ""
echo "Docker image built as:"
echo " - ${IMAGE_BASE}:${COMMIT_SHA}"
echo " - ${IMAGE_BASE}:latest"
if [ -n "$TAGS" ]; then
while IFS= read -r tag; do
[ -n "$tag" ] && echo " - ${IMAGE_BASE}:${tag}"
done <<< "$TAGS"
fi

View File

@@ -1,7 +1,6 @@
import os import os
import sys import sys
import yaml import yaml
import wx
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \ from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
StreamHandler, TimedRotatingFileHandler, WARNING StreamHandler, TimedRotatingFileHandler, WARNING
@@ -67,20 +66,34 @@ LOGLEVEL_MAP = {
CATALOG = 'lang' CATALOG = 'lang'
slotColourMapDark = { def get_slotColourMapDark():
FittingSlot.LOW: wx.Colour(44, 36, 19), # yellow = low slots 24/13 import wx
FittingSlot.MED: wx.Colour(28, 39, 51), # blue = mid slots 8.1/9.5 return {
FittingSlot.HIGH: wx.Colour(53, 31, 34), # red = high slots 6.5/11.5 FittingSlot.LOW: wx.Colour(44, 36, 19), # yellow = low slots 24/13
FittingSlot.RIG: '', FittingSlot.MED: wx.Colour(28, 39, 51), # blue = mid slots 8.1/9.5
FittingSlot.SUBSYSTEM: ''} FittingSlot.HIGH: wx.Colour(53, 31, 34), # red = high slots 6.5/11.5
errColorDark = wx.Colour(70, 20, 20) FittingSlot.RIG: '',
slotColourMap = { FittingSlot.SUBSYSTEM: ''}
FittingSlot.LOW: wx.Colour(250, 235, 204), # yellow = low slots
FittingSlot.MED: wx.Colour(188, 215, 241), # blue = mid slots
FittingSlot.HIGH: wx.Colour(235, 204, 209), # red = high slots def get_errColorDark():
FittingSlot.RIG: '', import wx
FittingSlot.SUBSYSTEM: ''} return wx.Colour(70, 20, 20)
errColor = wx.Colour(204, 51, 51)
def get_slotColourMap():
import wx
return {
FittingSlot.LOW: wx.Colour(250, 235, 204), # yellow = low slots
FittingSlot.MED: wx.Colour(188, 215, 241), # blue = mid slots
FittingSlot.HIGH: wx.Colour(235, 204, 209), # red = high slots
FittingSlot.RIG: '',
FittingSlot.SUBSYSTEM: ''}
def get_errColor():
import wx
return wx.Colour(204, 51, 51)
def getClientSecret(): def getClientSecret():

View File

@@ -3,7 +3,7 @@ from logbook import Logger
import gui.builtinMarketBrowser.pfSearchBox as SBox import gui.builtinMarketBrowser.pfSearchBox as SBox
import gui.globalEvents as GE import gui.globalEvents as GE
from config import slotColourMap, slotColourMapDark from config import get_slotColourMap, get_slotColourMapDark
from eos.saveddata.module import Module from eos.saveddata.module import Module
from eos.const import FittingSlot from eos.const import FittingSlot
from gui.builtinMarketBrowser.events import ItemSelected, RECENTLY_USED_MODULES, CHARGES_FOR_FIT from gui.builtinMarketBrowser.events import ItemSelected, RECENTLY_USED_MODULES, CHARGES_FOR_FIT
@@ -412,7 +412,7 @@ class ItemView(Display):
def columnBackground(self, colItem, item): def columnBackground(self, colItem, item):
if self.sFit.serviceFittingOptions["colorFitBySlot"]: if self.sFit.serviceFittingOptions["colorFitBySlot"]:
colorMap = slotColourMapDark if isDark() else slotColourMap colorMap = get_slotColourMapDark() if isDark() else get_slotColourMap()
return colorMap.get(Module.calculateSlot(item)) or self.GetBackgroundColour() return colorMap.get(Module.calculateSlot(item)) or self.GetBackgroundColour()
else: else:
return self.GetBackgroundColour() return self.GetBackgroundColour()

View File

@@ -42,7 +42,7 @@ from gui.utils.staticHelpers import DragDropHelper
from gui.utils.dark import isDark from gui.utils.dark import isDark
from service.fit import Fit from service.fit import Fit
from service.market import Market from service.market import Market
from config import slotColourMap, slotColourMapDark, errColor, errColorDark from config import get_slotColourMap, get_slotColourMapDark, get_errColor, get_errColorDark
from gui.fitCommands.helpers import getSimilarModPositions from gui.fitCommands.helpers import getSimilarModPositions
pyfalog = Logger(__name__) pyfalog = Logger(__name__)
@@ -766,9 +766,9 @@ class FittingView(d.Display):
def slotColour(self, slot): def slotColour(self, slot):
if isDark(): if isDark():
return slotColourMapDark.get(slot) or self.GetBackgroundColour() return get_slotColourMapDark().get(slot) or self.GetBackgroundColour()
else: else:
return slotColourMap.get(slot) or self.GetBackgroundColour() return get_slotColourMap().get(slot) or self.GetBackgroundColour()
def refresh(self, stuff): def refresh(self, stuff):
""" """
@@ -812,7 +812,7 @@ class FittingView(d.Display):
hasRestrictionOverriden = not hasRestrictionOverriden hasRestrictionOverriden = not hasRestrictionOverriden
if slotMap[mod.slot] or hasRestrictionOverriden: # Color too many modules as red if slotMap[mod.slot] or hasRestrictionOverriden: # Color too many modules as red
self.SetItemBackgroundColour(i, errColorDark if isDark() else errColor) self.SetItemBackgroundColour(i, get_errColorDark() if isDark() else get_errColor())
elif sFit.serviceFittingOptions["colorFitBySlot"]: # Color by slot it enabled elif sFit.serviceFittingOptions["colorFitBySlot"]: # Color by slot it enabled
self.SetItemBackgroundColour(i, self.slotColour(mod.slot)) self.SetItemBackgroundColour(i, self.slotColour(mod.slot))

View File

@@ -63,7 +63,8 @@ IMAGE_NAME="${IMAGE_NAME:-pyfa-server}"
COMMIT_SHA=$(git rev-parse --short HEAD) COMMIT_SHA=$(git rev-parse --short HEAD)
IMAGE_BASE="${DOCKER_REPO}/${IMAGE_NAME}" IMAGE_BASE="${DOCKER_REPO}/${IMAGE_NAME}"
echo "Pushing Docker image..." echo ""
echo "Pushing Docker images..."
docker push "${IMAGE_BASE}:${COMMIT_SHA}" docker push "${IMAGE_BASE}:${COMMIT_SHA}"
docker push "${IMAGE_BASE}:latest" docker push "${IMAGE_BASE}:latest"
TAGS=$(git tag --points-at HEAD 2>/dev/null || true) TAGS=$(git tag --points-at HEAD 2>/dev/null || true)
@@ -73,4 +74,15 @@ if [ -n "$TAGS" ]; then
done <<< "$TAGS" done <<< "$TAGS"
fi fi
echo "Release complete! ${ZIP} uploaded to ${TAG}, Docker image pushed" echo ""
echo "Docker image pushed as:"
echo " - ${IMAGE_BASE}:${COMMIT_SHA}"
echo " - ${IMAGE_BASE}:latest"
if [ -n "$TAGS" ]; then
while IFS= read -r tag; do
[ -n "$tag" ] && echo " - ${IMAGE_BASE}:${tag}"
done <<< "$TAGS"
fi
echo ""
echo "Release complete! ${ZIP} uploaded to ${TAG}"

14
requirements-server.txt Normal file
View File

@@ -0,0 +1,14 @@
logbook==1.7.0.post0
numpy==1.26.2
matplotlib==3.8.2
python-dateutil==2.8.2
requests==2.31.0
sqlalchemy==1.4.50
cryptography==42.0.4
markdown2==2.4.11
packaging==23.2
roman==4.1
beautifulsoup4==4.12.2
pyyaml==6.0.1
python-jose==3.3.0
requests-cache==1.1.1

View File

@@ -28,12 +28,8 @@ from xml.etree import ElementTree
from xml.dom import minidom from xml.dom import minidom
import gzip import gzip
# noinspection PyPackageRequirements
import wx
import config import config
import eos.db import eos.db
from service.esi import Esi
from eos.saveddata.implant import Implant as es_Implant from eos.saveddata.implant import Implant as es_Implant
from eos.saveddata.character import Character as es_Character, Skill from eos.saveddata.character import Character as es_Character, Skill
@@ -42,7 +38,12 @@ from eos.const import FittingSlot as es_Slot
from eos.saveddata.fighter import Fighter as es_Fighter from eos.saveddata.fighter import Fighter as es_Fighter
pyfalog = Logger(__name__) pyfalog = Logger(__name__)
_t = wx.GetTranslation
def _t(s):
import wx
return wx.GetTranslation(s)
class CharacterImportThread(threading.Thread): class CharacterImportThread(threading.Thread):
@@ -97,6 +98,7 @@ class CharacterImportThread(threading.Thread):
pyfalog.error(e) pyfalog.error(e)
continue continue
import wx
wx.CallAfter(self.callback) wx.CallAfter(self.callback)
def stop(self): def stop(self):
@@ -132,6 +134,7 @@ class SkillBackupThread(threading.Thread):
with open(path, mode='w', encoding='utf-8') as backupFile: with open(path, mode='w', encoding='utf-8') as backupFile:
backupFile.write(backupData) backupFile.write(backupData)
import wx
wx.CallAfter(self.callback) wx.CallAfter(self.callback)
def stop(self): def stop(self):
@@ -386,6 +389,7 @@ class Character:
def apiFetchCallback(self, guiCallback, e=None): def apiFetchCallback(self, guiCallback, e=None):
eos.db.commit() eos.db.commit()
import wx
wx.CallAfter(guiCallback, e) wx.CallAfter(guiCallback, e)
@staticmethod @staticmethod
@@ -501,6 +505,7 @@ class UpdateAPIThread(threading.Thread):
try: try:
char = eos.db.getCharacter(self.charID) char = eos.db.getCharacter(self.charID)
from service.esi import Esi
sEsi = Esi.getInstance() sEsi = Esi.getInstance()
sChar = Character.getInstance() sChar = Character.getInstance()
ssoChar = sChar.getSsoCharacter(char.ID) ssoChar = sChar.getSsoCharacter(char.ID)

View File

@@ -22,7 +22,6 @@ import datetime
from time import time from time import time
from weakref import WeakSet from weakref import WeakSet
import wx
from logbook import Logger from logbook import Logger
import eos.db import eos.db
@@ -235,6 +234,7 @@ class Fit:
@classmethod @classmethod
def getCommandProcessor(cls, fitID): def getCommandProcessor(cls, fitID):
if fitID not in cls.processors: if fitID not in cls.processors:
import wx
cls.processors[fitID] = wx.CommandProcessor(maxCommands=100) cls.processors[fitID] = wx.CommandProcessor(maxCommands=100)
return cls.processors[fitID] return cls.processors[fitID]

View File

@@ -38,7 +38,6 @@ from service.port.eft import (
isValidImplantImport, isValidBoosterImport) isValidImplantImport, isValidBoosterImport)
from service.port.esi import exportESI, importESI from service.port.esi import exportESI, importESI
from service.port.multibuy import exportMultiBuy from service.port.multibuy import exportMultiBuy
from service.port.shipstats import exportFitStats
from service.port.xml import importXml, exportXml from service.port.xml import importXml, exportXml
from service.port.muta import parseMutant, parseDynamicItemString, fetchDynamicItem from service.port.muta import parseMutant, parseDynamicItemString, fetchDynamicItem
@@ -346,4 +345,5 @@ class Port:
@staticmethod @staticmethod
def exportFitStats(fit, callback=None): def exportFitStats(fit, callback=None):
return exportFitStats(fit, callback=callback) from service.port.shipstats import exportFitStats as _exportFitStats
return _exportFitStats(fit, callback=callback)

View File

@@ -24,7 +24,6 @@ import urllib.error
import urllib.parse import urllib.parse
import json import json
from collections import namedtuple from collections import namedtuple
import wx
from logbook import Logger from logbook import Logger
@@ -582,6 +581,7 @@ class LocaleSettings:
@classmethod @classmethod
def supported_languages(cls): def supported_languages(cls):
"""Requires the application to be initialized, otherwise wx.Translation isn't set.""" """Requires the application to be initialized, otherwise wx.Translation isn't set."""
import wx
pyfalog.info(f'using "{config.CATALOG}" to fetch languages, relatively base path "{os.getcwd()}"') pyfalog.info(f'using "{config.CATALOG}" to fetch languages, relatively base path "{os.getcwd()}"')
return {x: wx.Locale.FindLanguageInfo(x) for x in wx.Translations.Get().GetAvailableTranslations(config.CATALOG)} return {x: wx.Locale.FindLanguageInfo(x) for x in wx.Translations.Get().GetAvailableTranslations(config.CATALOG)}