Compare commits

...

126 Commits

Author SHA1 Message Date
DarkPhoenix
62bde4b8c9 Bump version 2023-12-04 16:35:05 +06:00
DarkPhoenix
43967b70ae Add tiff lib 2023-12-04 15:58:21 +06:00
DarkPhoenix
782c007200 Add libjpeg dependency 2023-12-04 08:51:17 +06:00
DarkPhoenix
5812d333d9 Keep pyfa source in /opt/ 2023-12-04 08:36:00 +06:00
DarkPhoenix
c461bf469e Adjust path to artifact 2023-12-04 08:18:12 +06:00
DarkPhoenix
d5c8c92b48 Build linux binaries first 2023-12-04 08:08:47 +06:00
DarkPhoenix
1abffd6c5d Fix file extension 2023-12-04 08:08:00 +06:00
DarkPhoenix
a824cc5e48 Fix path to python, and disable debugging once again 2023-12-04 08:06:18 +06:00
DarkPhoenix
db7afffd65 Re-enable debugging again 2023-12-04 07:42:22 +06:00
DarkPhoenix
4d02a1292f A few minor fixes, and disable ssh 2023-12-04 07:16:12 +06:00
DarkPhoenix
00f72294d4 Fix variable name 2023-12-04 06:55:52 +06:00
DarkPhoenix
0d45be0597 Add missing dependency 2023-12-04 06:52:57 +06:00
DarkPhoenix
f60090fc79 Move lots of preprocessing out of appimg recipe (to support calculation of app version) 2023-12-04 06:39:28 +06:00
DarkPhoenix
713807df13 Get pip since provided python doesn't have it 2023-12-04 05:53:30 +06:00
DarkPhoenix
c020bd8898 More progress on linux build job 2023-12-04 05:29:11 +06:00
DarkPhoenix
39ee8586d4 Do build process using system interpreter, then install dependencies into bundled one 2023-12-04 04:59:04 +06:00
DarkPhoenix
653a1585dc Use appdir variable instead of "hardcoded" path 2023-12-04 04:03:01 +06:00
DarkPhoenix
2dcf011020 Move script to execute after runtime 2023-12-04 02:26:45 +06:00
DarkPhoenix
555e72a27a Another attempt to bundle python with appimg 2023-12-04 00:57:09 +06:00
DarkPhoenix
85e740d75a Add keys to repositories 2023-12-03 23:41:47 +06:00
DarkPhoenix
d604ed300a Fetch full repo right away 2023-12-03 22:15:05 +06:00
DarkPhoenix
3aea4e5f23 Remove empty section 2023-12-03 21:50:51 +06:00
DarkPhoenix
a54adddc74 Use python package from repo 2023-12-03 21:50:35 +06:00
DarkPhoenix
dda397fea3 Use AppDir variable instead of BuildDir 2023-12-03 17:03:31 +06:00
Anton Vorobyov
3cd718350e Merge pull request #2545 from Grange-Nagy/dep_facelift
fix infinite redraws on macos
2023-12-03 14:01:38 +04:00
Grange Nagy
e87860a700 Merge branch 'pyfa-org:dep_facelift' into dep_facelift 2023-12-03 02:24:54 -05:00
Grange Nagy
451d21eaa0 let go of drag object 2023-12-03 02:24:13 -05:00
Grange Nagy
718f9ef859 allow fit drag bmp to be smaller 2023-12-03 02:18:51 -05:00
Grange Nagy
193adc4ba5 fix fit drag bitmap causing redraws on macos 2023-12-03 01:47:32 -05:00
Grange Nagy
cdfa52e9ed remove drag rendering entirely for now 2023-12-02 21:53:31 -05:00
Anton Vorobyov
2752b288ad Merge pull request #2544 from Grange-Nagy/dep_facelift
fix runtime bitmap scaling error on macos sonoma
2023-12-03 06:49:06 +04:00
DarkPhoenix
8dce968780 Add one dependency just to detect bundle arch 2023-12-03 08:46:12 +06:00
Grange Nagy
b889da7e68 fix runtime bitmap scaling error on mac 2023-12-02 18:09:02 -05:00
DarkPhoenix
0dd7dea708 More work on new appimage build process 2023-12-02 11:16:31 +06:00
DarkPhoenix
8af1c8da7d Add script which extracts config values 2023-12-02 01:09:46 +06:00
DarkPhoenix
8d4f83156d Strip python appimage from linux build 2023-12-01 18:44:46 +06:00
DarkPhoenix
798bdf3fe0 Enable SSH for debugging 2023-12-01 17:25:42 +06:00
DarkPhoenix
a7cf4aab76 Specify architecture 2023-12-01 03:43:36 +06:00
DarkPhoenix
d910e324f3 Specify apt architecture 2023-12-01 01:49:01 +06:00
DarkPhoenix
d800db5ccb Do not specify package name 2023-12-01 00:56:56 +06:00
DarkPhoenix
6c5d0a3e4f Try to make use of AppImageBuilder for linux 2023-12-01 00:41:00 +06:00
DarkPhoenix
9389a0421f Merge branch 'master' into dep_facelift 2023-12-01 00:13:09 +06:00
DarkPhoenix
6f3ab6cee8 Remove evemarketer price source, add evetycoon 2023-12-01 00:11:50 +06:00
DarkPhoenix
258dcd49a0 Merge branch 'master' into dep_facelift 2023-11-30 23:05:34 +06:00
DarkPhoenix
eda53e9318 Merge branch 'master' into dep_facelift 2023-11-30 22:32:43 +06:00
DarkPhoenix
cfecacacf9 Add appimagebuilder spec file 2023-11-30 17:39:10 +06:00
DarkPhoenix
a9112c04a3 Set it up to debug manually 2023-11-30 06:44:13 +06:00
DarkPhoenix
5f2a74691c Fix python appimage download command 2023-11-30 06:23:25 +06:00
DarkPhoenix
17c22df0f4 Update debug key 2023-11-30 06:08:39 +06:00
DarkPhoenix
c53bc82929 Try out new package tool 2023-11-30 05:51:45 +06:00
DarkPhoenix
7113f41b9a Try adding libjpeg (current appimage fails to launch due to this dep) 2023-11-30 05:02:58 +06:00
DarkPhoenix
aa66d63085 Do not hardcode python version for startup script 2023-11-30 04:28:49 +06:00
DarkPhoenix
140ee70dc3 Update python appimage 2023-11-30 03:50:18 +06:00
DarkPhoenix
5023a6cbae Try to fix binary distributive of wx on linux 2023-11-30 03:20:56 +06:00
DarkPhoenix
aafa77baed Try to fix binary distributive of wx on linux 2023-11-30 02:48:51 +06:00
DarkPhoenix
16dabd57ca Attempt to fix macos pyinstaller 2023-11-30 02:10:48 +06:00
DarkPhoenix
8668d2dd55 Try to fix binary distributive of wx on linux 2023-11-30 02:09:52 +06:00
DarkPhoenix
5c5f37a9ae Use binary distributive of wx on linux 2023-11-30 00:19:15 +06:00
DarkPhoenix
621c36f1cd Use newer pyinstaller on macos 2023-11-29 23:27:17 +06:00
DarkPhoenix
be2cc523c2 Fix skill level suffix 2023-11-29 23:03:32 +06:00
DarkPhoenix
bd83c403a1 Fix spec file again 2023-11-29 22:51:10 +06:00
DarkPhoenix
043f533a10 Move contents-directory specification to spec file 2023-11-29 22:31:09 +06:00
DarkPhoenix
57a23affd0 Adapt to changes in pyinstaller 2023-11-29 21:47:16 +06:00
DarkPhoenix
b678152ac6 Change pyinstaller command for windows 2023-11-29 20:50:14 +06:00
DarkPhoenix
747bbc8200 Revert to python 3.11 2023-11-29 20:36:25 +06:00
DarkPhoenix
871cf42d88 Fix crowdin script on newer python versions 2023-11-29 20:16:17 +06:00
DarkPhoenix
28533d60d3 Update appveyor images 2023-11-29 20:07:39 +06:00
DarkPhoenix
ca12b3c94f Pin older sqlalchemy 2023-11-29 20:01:44 +06:00
DarkPhoenix
81e449dd83 Merge branch 'master' into dep_facelift 2023-11-14 20:13:50 +06:00
DarkPhoenix
9b216b5d48 Merge branch 'master' into dep_facelift 2023-11-14 18:54:35 +06:00
DarkPhoenix
061ab27286 Merge branch 'singularity' into dep_facelift 2023-11-13 21:45:51 +06:00
DarkPhoenix
6d13ab8bcb Merge branch 'master' into dep_facelift 2023-10-31 00:06:47 +06:00
DarkPhoenix
115ea9a36c Merge branch 'master' into dep_facelift 2023-10-31 00:02:35 +06:00
DarkPhoenix
c56f274a5f Merge branch 'singularity' into dep_facelift 2023-10-23 06:46:36 +06:00
DarkPhoenix
96214eaa27 Merge branch 'singularity' into dep_facelift 2023-10-19 05:46:01 +06:00
DarkPhoenix
2fef60eaaa Merge branch 'master' into dep_facelift 2023-10-10 02:59:39 +06:00
DarkPhoenix
807622a1ec Merge branch 'master' into dep_facelift 2023-09-19 23:56:38 +03:00
DarkPhoenix
d126b62d63 Merge branch 'master' into dep_facelift 2023-09-10 17:30:53 +06:00
DarkPhoenix
9e50de96f3 Merge branch 'master' into dep_facelift 2023-09-10 17:27:49 +06:00
DarkPhoenix
e67083a79b Add effects for new AT ships 2023-09-10 09:11:42 +06:00
DarkPhoenix
b103e576d2 Merge branch 'master' into dep_facelift 2023-09-10 08:42:32 +06:00
DarkPhoenix
b472adb404 Merge branch 'master' into dep_facelift 2023-06-14 01:09:58 +06:00
DarkPhoenix
7e5150be8c Merge branch 'master' into dep_facelift 2023-06-14 01:05:32 +06:00
DarkPhoenix
261d510ccb Merge branch 'master' into dep_facelift 2023-06-13 22:07:40 +06:00
DarkPhoenix
858b0b243a Merge branch 'singularity' into dep_facelift 2023-06-11 06:41:09 +06:00
DarkPhoenix
53385f2458 Merge branch 'singularity' into dep_facelift 2023-06-11 04:28:36 +06:00
DarkPhoenix
7d3371c379 Merge branch 'singularity' into dep_facelift 2023-06-11 00:29:49 +06:00
Anton Vorobyov
d94116ea1c Merge branch 'master' into dep_facelift 2023-05-23 01:11:07 +06:00
DarkPhoenix
b21b756fa6 Merge branch 'singularity' into dep_facelift 2022-10-25 01:53:45 +04:00
DarkPhoenix
492adb4dfd Merge branch 'singularity' into dep_facelift 2022-10-25 01:33:18 +04:00
DarkPhoenix
5fa7b2c86a Merge branch 'master' into dep_facelift 2022-10-23 10:19:39 +04:00
DarkPhoenix
f6120f09ac Bump version 2022-10-23 07:58:00 +04:00
DarkPhoenix
4995c7994f Merge branch 'master' into dep_facelift 2022-10-22 21:36:54 +04:00
DarkPhoenix
620ce89a05 Merge branch 'master' into dep_facelift 2022-10-21 23:09:03 +04:00
DarkPhoenix
73dc056e61 Fix creating of new implant sets / damage patterns / target profiles on new wx 2022-10-21 07:21:57 +04:00
DarkPhoenix
97625d11ab Merge branch 'master' into dep_facelift 2022-10-15 07:12:26 +04:00
DarkPhoenix
21bd4272d9 Merge branch 'master' into dep_facelift 2022-09-30 20:52:40 +04:00
DarkPhoenix
332c91d661 Merge branch 'master' into dep_facelift 2022-09-30 20:50:36 +04:00
DarkPhoenix
719125657f Merge branch 'master' into dep_facelift 2022-09-30 17:50:31 +04:00
DarkPhoenix
9621a54257 Merge branch 'master' into dep_facelift 2022-09-30 16:50:07 +04:00
DarkPhoenix
bfc580cf7c Merge branch 'master' into dep_facelift 2022-08-29 15:49:54 +04:00
DarkPhoenix
fd2f76ee41 Merge branch 'master' into dep_facelift 2022-08-29 02:53:09 +04:00
DarkPhoenix
9e01d15e60 Merge branch 'master' into dep_facelift 2022-08-29 02:32:12 +04:00
DarkPhoenix
23ee164a76 Merge branch 'master' into dep_facelift 2022-07-13 00:58:29 +04:00
DarkPhoenix
99ddc36027 Merge branch 'master' into dep_facelift 2022-07-10 02:52:44 +04:00
DarkPhoenix
a33f48a83b Merge branch 'master' into dep_facelift 2022-07-04 22:32:43 +04:00
DarkPhoenix
11c060103a Merge branch 'master' into dep_facelift 2022-07-04 05:55:43 +04:00
DarkPhoenix
ac6b6f70eb Merge branch 'master' into dep_facelift 2022-07-04 05:24:52 +04:00
DarkPhoenix
baf10b24d6 Merge branch 'master' into dep_facelift 2022-07-04 04:09:49 +04:00
DarkPhoenix
0ab485115c Merge branch 'master' into dep_facelift 2022-06-27 01:13:26 +04:00
DarkPhoenix
f8895a14c5 Merge branch 'master' into dep_facelift 2022-05-05 21:54:14 +04:00
DarkPhoenix
22eabcea8d Merge branch 'master' into dep_facelift 2022-05-05 21:17:17 +04:00
DarkPhoenix
ccd3498594 Even more fixes for silent coercion, which is no more 2022-05-05 18:41:17 +04:00
DarkPhoenix
71d088b90a More fixes for silent coercion, which is no more 2022-04-24 02:19:26 +04:00
DarkPhoenix
17712d8b7d More fixes for silent coercion, which is no more 2022-04-20 15:58:46 +04:00
DarkPhoenix
4a224ea9a5 Fix preferences panel 2022-04-20 15:25:52 +04:00
DarkPhoenix
6664b5620a Fix type casts for graphs
See #2391 for more info
2022-04-20 15:23:03 +04:00
DarkPhoenix
a98e898bd8 Cast coordinates passed to various wx objects into ints
See #2391 for more info
2022-04-20 02:12:46 +04:00
DarkPhoenix
e98ae5de39 Cast colors into ints before passing to wx
See #2391 for more info
2022-04-20 01:26:52 +04:00
DarkPhoenix
a51fbbc238 Merge branch 'master' into dep_facelift
# Conflicts:
#	.appveyor.yml
#	requirements.txt
2022-04-20 00:42:04 +04:00
DarkPhoenix
f9b4c7b5ea Merge branch 'singularity' into dep_facelift 2022-03-01 13:23:03 +03:00
DarkPhoenix
4e83f52532 Silence more SQLAlchemy warnings 2022-02-22 23:54:33 +03:00
DarkPhoenix
ec0b543393 Silence some of SQLAlchemy warnings 2022-02-22 23:45:09 +03:00
DarkPhoenix
cff94a12ee Set a few gamedata relations view-only
New sqlalchemy complains about them, and we never set them via those relations anyway
2022-02-22 01:12:02 +03:00
DarkPhoenix
da39975ba8 Update requirements specified in CI specification 2022-02-21 23:26:27 +03:00
DarkPhoenix
82515343ee Update requirements to "latest" version of every package 2022-02-21 23:00:25 +03:00
43 changed files with 292 additions and 276 deletions

View File

@@ -1,76 +1,48 @@
image:
- Visual Studio 2019
- Ubuntu
- macos
clone_depth: 1
- Ubuntu2204
- Visual Studio 2022
- macos-catalina
for:
-
matrix:
only:
- image: Ubuntu
- image: Ubuntu2204
environment:
APPVEYOR_SSH_KEY: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJDW/+oYNGOiPvwuwAL9tc/LQgg58aosIVpMYfepQZ20V+VZnHpZh8IRDA8Jo5xht19p2PksA+hFgqA0kpKtrSkuiWdE8rATQItfk4gf7yB0yGasJGGQZYazy9k/9XtmYkq2HHOOeEqdxvrICddJQ88MLCLT9lJENSUP/YS/yGcjZFXVxE11pTeIcqlCRU+3eYa1v7BeNvXIKNhZoK5orXWrtuH3cy8jrSns/u70aYfJ6B2jA8CnWnDbuvpeQtEY61SQqlKUsSArNa8NAsXj41wr3Ar9gAG9330w7EMTqlutk8HZO35uHI0q5qinUhaQYufPPrVkb2L/N+ZCfu0fnh appveyor"
APPIMAGE_TOOL: appimagetool-x86_64.AppImage
PYTHON_APPIMAGE: python3.7.17-cp37-cp37m-manylinux2014_x86_64.AppImage
APPVEYOR_SSH_KEY: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDhb96UEXy8yOy/f+riX/8kKbNx/lOfIZ4pP4Cw3Gj3DmnTwEnxtRtyc+xtaxOsKbt+7+EAXFpCzYX+jHMhtd0QtWB7dbey8DBg31g0f8C5EPquqROibVbhzr/F3f6/d52FFfq6Y/CWaAvLjezvipr+zOOsIFcVusqtXdPJQ/LtUJ0LS5d4lFiw5ELHSxHIpqwGwyb7PbR3ufEFoqbr8eYiCH+vlBob72ArPfo2f3u0sMvpGYmjVVu2jj4FEY2h89sLrGyFdNWBoyumRhkb38+WSAuyPa/Y21+g+S8sRzIlkwbxicGNMtrMIi6zHEIGAgA06Sw2psP807h730PPOVaWjUcU3ojNW8hH3nPizF74pT82+iP7/fFC4PXLP+tBa+8OoHC5yiO7QKUKprMSqVa1qOm8fHbrzglplKJXfzSfUtSE+AQ+HtHhuUWKI+0LBLDrsOJwI5hbsPOAuiZ5I3VfqfAOck6SH9TcmlapVmQEypc7d7oeeUtZSOuIWKXp068= dfx@aw"
APPIMAGE_TOOL: appimage-builder-x86_64.AppImage
DEPLOY_DIR: AppDir/opt/pyfa
# APPVEYOR_SSH_BLOCK: true
# APPVEYOR_SSH_BLOCK: true
cache:
- /home/appveyor/.cache/pip -> requirements.txt
init:
- sh: curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
# init:
# - sh: curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
install:
- sh: git fetch --prune --unshallow # to fix the version dump issues
- sh: sudo DEBIAN_FRONTEND=noninteractive sed -i '/postgres/d' /etc/apt/sources.list # As of 2023-11-14, postgres repo fail to update, but we don't need them anyway
- sh: sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
- sh: sudo DEBIAN_FRONTEND=noninteractive apt-get -y install python3.7-dev libgtk-3-dev python3-pip libwebkit2gtk-4.0-dev
# AppImage dependencies
- sh: sudo DEBIAN_FRONTEND=noninteractive apt-get -y install libfuse2
# Preparation script dependencies
- sh: sudo DEBIAN_FRONTEND=noninteractive apt-get -y install python3-wxgtk4.0 python3-sqlalchemy python3-logbook
before_build:
- sh: mkdir build && cd build
- sh: curl -LO https://github.com/AppImage/AppImageKit/releases/download/13/$APPIMAGE_TOOL && chmod +x $APPIMAGE_TOOL
- sh: curl -LO https://github.com/niess/python-appimage/releases/download/python3.7/$PYTHON_APPIMAGE && chmod +x $PYTHON_APPIMAGE
build_script:
# Prepare Python base AppImage, stripping Python metadata
- sh: ./$PYTHON_APPIMAGE --appimage-extract
- sh: mv squashfs-root AppDir
- sh: rm AppDir/python*.desktop
- sh: rm AppDir/usr/share/applications/*.desktop
- sh: rm AppDir/usr/share/metainfo/*.appdata.xml
- sh: unlink AppDir/AppRun
- sh: mkdir -p $DEPLOY_DIR
# run install pyfa packages and any other requirements
- sh: AppDir/usr/bin/python -s -m pip install -U pip setuptools==41.6.0 wheel pathlib2
- sh: AppDir/usr/bin/python -s -m pip install -r ../requirements.txt
# Speedup, but causes runtime incompatiblities
#- sh: AppDir/usr/bin/python -s -m pip install -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 -r ../requirements.txt
# Run scripts to prep pyfa data and build database
- sh: cd ../
# Prepare pyfa data
- sh: find locale/ -type f -name "*.po" -exec msgen "{}" -o "{}" \;
- sh: build/AppDir/usr/bin/python scripts/compile_lang.py
- sh: build/AppDir/usr/bin/python scripts/dump_crowdin_progress.py
- sh: build/AppDir/usr/bin/python db_update.py
- sh: export PYFA_VERSION="$(python3.7 scripts/dump_version.py)"
# Copy pyfa files to host
- sh: cp -r eos graphs gui imgs locale service utils eve.db config.py pyfa.py db_update.py README.md LICENSE version.yml ./build/$DEPLOY_DIR
- sh: find ./build/$DEPLOY_DIR | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
# Copy static AppImage files
- sh: cd dist_assets/linux
- sh: chmod +x AppRun
- sh: cp AppRun pyfa.desktop ../../build/AppDir/
- sh: cp pyfa.desktop ../../build/AppDir/usr/share/applications/
- sh: cp pyfa.appdata.xml ../../build/AppDir/usr/share/metainfo/
- sh: chmod +x pyfa && cp pyfa ../../build/AppDir/usr/bin
- sh: cd ../../
# Package it all up
- sh: mkdir dist
- sh: ./build/$APPIMAGE_TOOL build/AppDir dist/pyfa-$PYFA_VERSION-linux.AppImage
- sh: python3 -B scripts/compile_lang.py
- sh: python3 -B scripts/dump_crowdin_progress.py
- sh: python3 -B db_update.py
- sh: export PYFA_VERSION="$(python3 -B scripts/dump_version.py)"
- sh: mkdir build
# Download packaging tool
- sh: curl -o $APPIMAGE_TOOL -L https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage
- sh: chmod +x $APPIMAGE_TOOL
build_script:
- sh: mkdir -p AppDir/opt/pyfa
- sh: cp -r eos graphs gui imgs locale service utils eve.db config.py pyfa.py db_update.py README.md LICENSE version.yml AppDir/opt/pyfa/
- sh: mkdir -p AppDir/usr/share/icons/hicolor/64x64/apps/
- sh: cp imgs/gui/pyfa64.png AppDir/usr/share/icons/hicolor/64x64/apps/pyfa.png
- sh: ./$APPIMAGE_TOOL --recipe dist_assets/linux/AppImageBuilder.yml
after_build:
- sh: ls -la build
- sh: ls -la
artifacts:
- path: dist/pyfa-$PYFA_VERSION-linux.AppImage
- path: pyfa-$PYFA_VERSION-linux.AppImage
deploy:
tag: $PYFA_VERSION
release: pyfa $PYFA_VERSION
@@ -86,17 +58,15 @@ for:
-
matrix:
only:
- image: Visual Studio 2019
- image: Visual Studio 2022
environment:
PYTHON: "C:\\Python37-x64"
PYTHON: "C:\\Python311-x64"
# Should be enabled only for build process debugging
# init:
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
cache:
- C:\users\appveyor\appdata\local\pip\cache\ -> requirements.txt
install:
- cmd: git fetch --prune --unshallow # to fix the version dump issues
- ps: echo("OS version:")
- ps: "[System.Environment]::OSVersion.Version"
@@ -132,10 +102,8 @@ for:
# pip will build them from source using the MSVC compiler matching the
# target Python version and architecture
- ps: echo("Install pip requirements:")
# This one is needed to build wxpython 4.0.6 on windows
- cmd: "python -m pip install pathlib2"
- cmd: "python -m pip install -r requirements.txt"
- cmd: "python -m pip install PyInstaller==3.6"
- cmd: "python -m pip install PyInstaller"
before_build:
# directory that will contain the built files
- ps: $env:PYFA_DIST_DIR = "c:\projects\$env:APPVEYOR_PROJECT_SLUG\dist"
@@ -151,7 +119,7 @@ for:
# Build gamedata DB
- cmd: "python db_update.py"
# Build command for PyInstaller
- cmd: "python -m PyInstaller --noupx --clean --windowed --noconsole -y pyfa.spec"
- cmd: "python -m PyInstaller --clean -y pyfa.spec"
# Copy over manifest (See pyfa-org/pyfa#1622)
- ps: xcopy /y dist_assets\win\pyfa.exe.manifest $env:PYFA_DIST_DIR\pyfa\
# InnoScript EXE building. This is in a separate script because I don't feel like copying over the logic to AppVeyor script right now...
@@ -178,16 +146,15 @@ for:
-
matrix:
only:
- image: macos
- image: macos-catalina
environment:
APPVEYOR_SSH_KEY: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJDW/+oYNGOiPvwuwAL9tc/LQgg58aosIVpMYfepQZ20V+VZnHpZh8IRDA8Jo5xht19p2PksA+hFgqA0kpKtrSkuiWdE8rATQItfk4gf7yB0yGasJGGQZYazy9k/9XtmYkq2HHOOeEqdxvrICddJQ88MLCLT9lJENSUP/YS/yGcjZFXVxE11pTeIcqlCRU+3eYa1v7BeNvXIKNhZoK5orXWrtuH3cy8jrSns/u70aYfJ6B2jA8CnWnDbuvpeQtEY61SQqlKUsSArNa8NAsXj41wr3Ar9gAG9330w7EMTqlutk8HZO35uHI0q5qinUhaQYufPPrVkb2L/N+ZCfu0fnh appveyor"
cache:
- /Users/appveyor/Library/Caches/pip/ -> requirements.txt
init:
# - sh: curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
- sh: source ~/venv3.7/bin/activate
- sh: source ~/venv3.11/bin/activate
install:
- sh: git fetch --prune --unshallow # to fix the version dump issues
- sh: bash scripts/osx-setup.sh
build_script:
- sh: bash scripts/osx-translations.sh

View File

@@ -0,0 +1,51 @@
version: 1
AppDir:
path: ./AppDir
app_info:
id: pyfa
name: pyfa
icon: pyfa
version: '{{PYFA_VERSION}}'
exec: usr/bin/python3.11
exec_args: "-s $APPDIR/opt/pyfa/pyfa.py $@"
apt:
arch: [ amd64 ]
sources:
- sourceline: 'deb http://us.archive.ubuntu.com/ubuntu jammy main restricted universe multiverse'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c'
- sourceline: 'deb http://us.archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c'
- sourceline: 'deb http://us.archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c'
- sourceline: 'deb http://us.archive.ubuntu.com/ubuntu jammy-security main restricted universe multiverse'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x871920d1991bc93c'
- sourceline: 'deb https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy main'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xf23c5a6cf475977595c89f51ba6932366a755776'
include:
- python3.11
# wx dependencies
- libjpeg-turbo8
- libtiff5
exclude: []
after_bundle:
# Install python dependencies to bundled interpreter
- export PYTHONHOME="AppDir/usr"
- export PYTHONPATH="AppDir/usr/lib/python3.11/site-packages"
- curl -L https://bootstrap.pypa.io/get-pip.py -o get-pip.py
- AppDir/usr/bin/python3.11 get-pip.py
- AppDir/usr/bin/python3.11 -s -m pip install -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-22.04 -r requirements.txt
runtime:
env:
PYTHONHOME: '${APPDIR}/usr'
PYTHONPATH: '${APPDIR}/usr/lib/python3.11/site-packages'
AppImage:
sign-key: None
arch: x86_64
file_name: 'pyfa-{{PYFA_VERSION}}-linux.AppImage'

View File

@@ -1,3 +1,3 @@
#! /bin/bash
${APPDIR}/usr/bin/python3.7 -s "${APPDIR}/opt/pyfa/pyfa.py" "$@"
${APPDIR}/usr/bin/python3 -s "${APPDIR}/opt/pyfa/pyfa.py" "$@"

View File

@@ -42,10 +42,10 @@ CloseApplications=yes
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile={#MyAppDir}\LICENSE
LicenseFile={#MyAppDir}\app\LICENSE
OutputDir={#MyOutputDir}
OutputBaseFilename={#MyOutputFile}
SetupIconFile={#MyAppDir}\pyfa.ico
SetupIconFile={#MyAppDir}\app\pyfa.ico
SolidCompression=yes
[Languages]

View File

@@ -51,7 +51,7 @@ mapper(DynamicItemAttribute, dynamicAttributes_table,
properties={"info": relation(AttributeInfo, lazy=False)})
mapper(DynamicItemItem, dynamicApplicable_table, properties={
"mutaplasmid": relation(DynamicItem),
"mutaplasmid": relation(DynamicItem, viewonly=True),
})
DynamicItemAttribute.ID = association_proxy("info", "attributeID")

View File

@@ -69,7 +69,8 @@ props = {
primaryjoin=dynamicApplicable_table.c.applicableTypeID == items_table.c.typeID,
secondaryjoin=dynamicApplicable_table.c.typeID == DynamicItem.typeID,
secondary=dynamicApplicable_table,
backref="applicableItems"
backref="applicableItems",
viewonly=True
)
}

View File

@@ -175,12 +175,13 @@ mapper(es_Fit, fits_table,
collection_class=HandledModuleList,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False), # noqa
order_by=modules_table.c.position,
overlaps='owner',
cascade='all, delete, delete-orphan'),
"_Fit__projectedModules": relation(
Module,
collection_class=HandledProjectedModList,
overlaps='owner, _Fit__modules',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)), # noqa
"owner": relation(
User,
@@ -190,37 +191,37 @@ mapper(es_Fit, fits_table,
"_Fit__boosters": relation(
Booster,
collection_class=HandledBoosterList,
cascade='all, delete, delete-orphan',
single_parent=True),
overlaps='owner',
cascade='all, delete, delete-orphan'),
"_Fit__drones": relation(
Drone,
collection_class=HandledDroneCargoList,
overlaps='owner',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)), # noqa
"_Fit__fighters": relation(
Fighter,
collection_class=HandledDroneCargoList,
overlaps='owner',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)), # noqa
"_Fit__cargo": relation(
Cargo,
collection_class=HandledDroneCargoList,
overlaps='owner',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
"_Fit__projectedDrones": relation(
Drone,
collection_class=HandledProjectedDroneList,
overlaps='owner, _Fit__drones',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)), # noqa
"_Fit__projectedFighters": relation(
Fighter,
collection_class=HandledProjectedDroneList,
overlaps='owner, _Fit__fighters',
cascade='all, delete, delete-orphan',
single_parent=True,
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)), # noqa
"_Fit__implants": relation(
Implant,

View File

@@ -114,7 +114,7 @@ class GraphFrame(AuxiliaryFrame):
newW = max(curW, bestW)
newH = max(curH, bestH)
if newW > curW or newH > curH:
newSize = wx.Size(newW, newH)
newSize = wx.Size(round(newW), round(newH))
self.SetSize(newSize)
self.SetMinSize(newSize)

View File

@@ -39,7 +39,7 @@ class VectorPicker(wx.Window):
self._directionOnly = kwargs.pop('directionOnly', False)
super().__init__(*args, **kwargs)
self._fontsize = max(1, float(kwargs.pop('fontsize', 8 / self.GetContentScaleFactor())))
self._font = wx.Font(self._fontsize, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)
self._font = wx.Font(round(self._fontsize), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)
self._angle = 0
self.__length = 1
self._left = False
@@ -76,7 +76,7 @@ class VectorPicker(wx.Window):
self.__length = newLength
def DoGetBestSize(self):
return wx.Size(self._size, self._size)
return wx.Size(round(self._size), round(self._size))
def AcceptsFocusFromKeyboard(self):
return False
@@ -121,35 +121,37 @@ class VectorPicker(wx.Window):
radius = min(width, height) / 2 - 2
dc.SetBrush(wx.WHITE_BRUSH)
dc.DrawCircle(radius + 2, radius + 2, radius)
dc.DrawCircle(round(radius + 2), round(radius + 2), round(radius))
a = math.radians(self._angle + self._offset)
x = math.cos(a) * radius
y = math.sin(a) * radius
# See PR #2260 on why this is needed
pointRadius = 2 / self.GetContentScaleFactor() if 'wxGTK' in wx.PlatformInfo else 2
dc.DrawLine(radius + 2, radius + 2, radius + 2 + x * self._length, radius + 2 - y * self._length)
dc.DrawLine(
round(radius + 2), round(radius + 2),
round(radius + 2 + x * self._length), round(radius + 2 - y * self._length))
dc.SetBrush(wx.BLACK_BRUSH)
dc.DrawCircle(radius + 2 + x * self._length, radius + 2 - y * self._length, pointRadius)
dc.DrawCircle(round(radius + 2 + x * self._length), round(radius + 2 - y * self._length), round(pointRadius))
if self._label:
labelText = self._label
labelTextW, labelTextH = dc.GetTextExtent(labelText)
labelTextX = (radius * 2 + 4 - labelTextW) if (self._labelpos & 1) else 0
labelTextY = (radius * 2 + 4 - labelTextH) if (self._labelpos & 2) else 0
dc.DrawText(labelText, labelTextX, labelTextY)
dc.DrawText(labelText, round(labelTextX), round(labelTextY))
if not self._directionOnly:
lengthText = '%d%%' % (100 * self._length,)
lengthTextW, lengthTextH = dc.GetTextExtent(lengthText)
lengthTextX = radius + 2 + x / 2 - y / 3 - lengthTextW / 2
lengthTextY = radius + 2 - y / 2 - x / 3 - lengthTextH / 2
dc.DrawText(lengthText, lengthTextX, lengthTextY)
dc.DrawText(lengthText, round(lengthTextX), round(lengthTextY))
angleText = '%d\u00B0' % (self._angle,)
angleTextW, angleTextH = dc.GetTextExtent(angleText)
angleTextX = radius + 2 - x / 2 - angleTextW / 2
angleTextY = radius + 2 + y / 2 - angleTextH / 2
dc.DrawText(angleText, angleTextX, angleTextY)
dc.DrawText(angleText, round(angleTextX), round(angleTextY))
def OnEraseBackground(self, event):
pass

View File

@@ -212,7 +212,7 @@ class AttributeGauge(wx.Window):
for x in range(1, 20):
dc.SetBrush(wx.Brush(wx.LIGHT_GREY))
dc.SetPen(wx.Pen(wx.LIGHT_GREY))
dc.DrawRectangle(x * 10, 1, 1, rect.height)
dc.DrawRectangle(round(x * 10), 1, 1, round(rect.height))
dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
@@ -222,19 +222,19 @@ class AttributeGauge(wx.Window):
if value >= 0:
padding = (half if is_even else math.ceil(half - 1)) + 1
dc.DrawRectangle(padding, 1, w, rect.height)
dc.DrawRectangle(round(padding), 1, round(w), round(rect.height))
else:
padding = half - w + 1 if is_even else math.ceil(half) - (w - 1)
dc.DrawRectangle(padding, 1, w, rect.height)
dc.DrawRectangle(round(padding), 1, round(w), round(rect.height))
if self.leading_edge and (self.edge_on_neutral or value != 0):
dc.SetPen(wx.Pen(wx.WHITE))
dc.SetBrush(wx.Brush(wx.WHITE))
if value > 0:
dc.DrawRectangle(min(padding + w, rect.width), 1, 1, rect.height)
dc.DrawRectangle(round(min(padding + w, rect.width)), 1, 1, round(rect.height))
else:
dc.DrawRectangle(max(padding - 1, 1), 1, 1, rect.height)
dc.DrawRectangle(round(max(padding - 1, 1)), 1, 1, round(rect.height))
def OnTimer(self, event):
old_value = self._old_percentage

View File

@@ -103,10 +103,9 @@ class BitmapLoader:
pyfalog.warning("Missing icon file: {0}/{1}".format(location, filename))
return None
bmp: wx.Bitmap = img.ConvertToBitmap()
if scale > 1:
bmp.SetSize((bmp.GetWidth() // scale, bmp.GetHeight() // scale))
return bmp
return img.Scale(img.GetWidth() // scale, img.GetHeight() // scale).ConvertToBitmap()
return img.ConvertToBitmap()
@classmethod
def loadScaledBitmap(cls, name, location, scale=0):

View File

@@ -253,8 +253,8 @@ class PFSearchBox(wx.Window):
else:
spad = 0
dc.DrawBitmap(self.searchBitmapShadow, self.searchButtonX + 1, self.searchButtonY + 1)
dc.DrawBitmap(self.searchBitmap, self.searchButtonX + spad, self.searchButtonY + spad)
dc.DrawBitmap(self.searchBitmapShadow, round(self.searchButtonX + 1), round(self.searchButtonY + 1))
dc.DrawBitmap(self.searchBitmap, round(self.searchButtonX + spad), round(self.searchButtonY + spad))
if self.isCancelButtonVisible:
if self.cancelBitmap:
@@ -262,8 +262,8 @@ class PFSearchBox(wx.Window):
cpad = 1
else:
cpad = 0
dc.DrawBitmap(self.cancelBitmapShadow, self.cancelButtonX + 1, self.cancelButtonY + 1)
dc.DrawBitmap(self.cancelBitmap, self.cancelButtonX + cpad, self.cancelButtonY + cpad)
dc.DrawBitmap(self.cancelBitmapShadow, round(self.cancelButtonX + 1), round(self.cancelButtonY + 1))
dc.DrawBitmap(self.cancelBitmap, round(self.cancelButtonX + cpad), round(self.cancelButtonY + cpad))
dc.SetPen(wx.Pen(sepColor, 1))
dc.DrawLine(0, rect.height - 1, rect.width, rect.height - 1)

View File

@@ -64,7 +64,7 @@ class PFGeneralPref(PreferenceView):
langBox.Add(hl.HyperLinkCtrl(panel, -1,
_t("Interested in helping with translations?"),
URL="https://github.com/pyfa-org/Pyfa/blob/master/locale/README.md"
), 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 15)
), 0, wx.LEFT, 15)
else:
self.stLangLabel = wx.StaticText(panel, wx.ID_ANY, _t("Pyfa language selection disabled. Please check if .mo files have been generated.\nRefer to locale/README.md for info."), wx.DefaultPosition, wx.DefaultSize, 0)
self.stLangLabel.Wrap(-1)
@@ -93,7 +93,7 @@ class PFGeneralPref(PreferenceView):
langBox.Add(wx.StaticText(panel, wx.ID_ANY,
_t("Auto will use the same language pyfa uses if available, otherwise English"),
wx.DefaultPosition,
wx.DefaultSize, 0), 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 15)
wx.DefaultSize, 0), 0, wx.LEFT, 15)
self.cbGlobalChar = wx.CheckBox(panel, wx.ID_ANY, _t("Use global character"), wx.DefaultPosition, wx.DefaultSize,
0)

View File

@@ -104,14 +104,14 @@ class CategoryItem(SFBrowserItem):
textColor = colorUtils.GetSuitable(windowColor, 1)
mdc.SetTextForeground(textColor)
mdc.DrawBitmap(self.dropShadowBitmap, self.shipBmpx + 1, self.shipBmpy + 1)
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
mdc.DrawBitmap(self.dropShadowBitmap, round(self.shipBmpx + 1), round(self.shipBmpy + 1))
mdc.DrawBitmap(self.shipBmp, round(self.shipBmpx), round(self.shipBmpy), 0)
mdc.SetFont(self.fontBig)
categoryName, fittings = self.fittingInfo
mdc.DrawText(categoryName, self.catx, self.caty)
mdc.DrawText(categoryName, round(self.catx), round(self.caty))
# =============================================================================

View File

@@ -416,9 +416,18 @@ class FitItem(SFItem.SFBrowserItem):
if self.dragging:
if not self.dragged:
if self.dragMotionTrigger < 0:
if not self.dragTLFBmp:
tdc = wx.MemoryDC()
bmpWidth = self.toolbarx if self.toolbarx < 200 else 200
self.dragTLFBmp = wx.Bitmap(bmpWidth, self.GetRect().height)
tdc.SelectObject(self.dragTLFBmp)
tdc.SetBrush(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)))
tdc.DrawRectangle(0, 0, bmpWidth, self.GetRect().height)
self.DrawItem(tdc)
tdc.SelectObject(wx.NullBitmap)
if not self.HasCapture():
self.CaptureMouse()
self.dragWindow = PFBitmapFrame(self, pos, self.dragTLFBmp)
self.dragWindow = PFBitmapFrame(self, pos, self.dragTLFBmp)
self.dragWindow.Show()
self.dragged = True
self.dragMotionTrigger = self.dragMotionTrail
@@ -493,9 +502,9 @@ class FitItem(SFItem.SFBrowserItem):
else:
shipEffBk = self.shipEffBk
mdc.DrawBitmap(shipEffBk, self.shipEffx, self.shipEffy, 0)
mdc.DrawBitmap(shipEffBk, round(self.shipEffx), round(self.shipEffy), 0)
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
mdc.DrawBitmap(self.shipBmp, round(self.shipBmpx), round(self.shipBmpy), 0)
mdc.SetFont(self.fontNormal)
@@ -504,26 +513,21 @@ class FitItem(SFItem.SFBrowserItem):
pfdate = drawUtils.GetPartialText(mdc, fitLocalDate,
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
mdc.DrawText(pfdate, self.textStartx, self.timestampy)
mdc.DrawText(pfdate, round(self.textStartx), round(self.timestampy))
mdc.SetFont(self.fontSmall)
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
mdc.DrawText(self.toolbar.hoverLabel, round(self.thoverx), round(self.thovery))
mdc.SetFont(self.fontBig)
psname = drawUtils.GetPartialText(mdc, self.fitName,
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
mdc.DrawText(psname, self.textStartx, self.fitNamey)
mdc.DrawText(psname, round(self.textStartx), round(self.fitNamey))
if self.tcFitName.IsShown():
self.AdjustControlSizePos(self.tcFitName, self.textStartx, self.toolbarx - self.editWidth - self.padding)
tdc = wx.MemoryDC()
self.dragTLFBmp = wx.Bitmap((self.toolbarx if self.toolbarx < 200 else 200), rect.height, 24)
tdc.SelectObject(self.dragTLFBmp)
tdc.Blit(0, 0, (self.toolbarx if self.toolbarx < 200 else 200), rect.height, mdc, 0, 0, wx.COPY)
tdc.SelectObject(wx.NullBitmap)
def AdjustControlSizePos(self, editCtl, start, end):
fnEditSize = editCtl.GetSize()

View File

@@ -231,7 +231,7 @@ class NavigationPanel(SFItem.SFBrowserItem):
self.toolbar.SetPosition((self.toolbarx, self.toolbary))
mdc.SetFont(self.fontSmall)
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
mdc.DrawText(self.toolbar.hoverLabel, round(self.thoverx), round(self.thovery))
mdc.SetPen(wx.Pen(sepColor, 1))
mdc.DrawLine(0, rect.height - 1, rect.width, rect.height - 1)

View File

@@ -63,4 +63,4 @@ class PFBitmapFrame(wx.Frame):
mdc.DrawBitmap(self.bitmap, 0, 0)
mdc.SetPen(wx.Pen("#000000", width=1))
mdc.SetBrush(wx.TRANSPARENT_BRUSH)
mdc.DrawRectangle(0, 0, rect.width, rect.height)
mdc.DrawRectangle(0, 0, round(rect.width), round(rect.height))

View File

@@ -57,7 +57,7 @@ class PFListPane(wx.ScrolledWindow):
posy = self.GetScrollPos(wx.VERTICAL)
posy -= self.itemsHeight
self.Scroll(0, posy)
self.Scroll(0, round(posy))
event.Skip()
@@ -65,7 +65,7 @@ class PFListPane(wx.ScrolledWindow):
posy = self.GetScrollPos(wx.VERTICAL)
posy += self.itemsHeight
self.Scroll(0, posy)
self.Scroll(0, round(posy))
event.Skip()
@@ -109,7 +109,7 @@ class PFListPane(wx.ScrolledWindow):
# if we need to adjust
if new_vs_x != -1 or new_vs_y != -1:
self.Scroll(new_vs_x, new_vs_y)
self.Scroll(round(new_vs_x), round(new_vs_y))
def AddWidget(self, widget):
widget.Reparent(self)

View File

@@ -194,25 +194,25 @@ class RaceSelector(wx.Window):
bmp = wx.Bitmap(img)
if self.layout == wx.VERTICAL:
mdc.DrawBitmap(dropShadow, rect.width - self.buttonsPadding - bmp.GetWidth() + 1, y + 1)
mdc.DrawBitmap(bmp, rect.width - self.buttonsPadding - bmp.GetWidth(), y)
mdc.DrawBitmap(dropShadow, round(rect.width - self.buttonsPadding - bmp.GetWidth() + 1), round(y + 1))
mdc.DrawBitmap(bmp, round(rect.width - self.buttonsPadding - bmp.GetWidth()), round(y))
y += raceBmp.GetHeight() + self.buttonsPadding
mdc.SetPen(wx.Pen(sepColor, 1))
mdc.DrawLine(rect.width - 1, 0, rect.width - 1, rect.height)
else:
mdc.DrawBitmap(dropShadow, x + 1, self.buttonsPadding + 1)
mdc.DrawBitmap(bmp, x, self.buttonsPadding)
mdc.DrawBitmap(dropShadow, round(x + 1), round(self.buttonsPadding + 1))
mdc.DrawBitmap(bmp, round(x), round(self.buttonsPadding))
x += raceBmp.GetWidth() + self.buttonsPadding
mdc.SetPen(wx.Pen(sepColor, 1))
mdc.DrawLine(0, 0, rect.width, 0)
if self.direction < 1:
if self.layout == wx.VERTICAL:
mdc.DrawBitmap(self.bmpArrow, -2, (rect.height - self.bmpArrow.GetHeight()) / 2)
mdc.DrawBitmap(self.bmpArrow, -2, round((rect.height - self.bmpArrow.GetHeight()) / 2))
else:
mdc.SetPen(wx.Pen(sepColor, 1))
mdc.DrawLine(0, 0, rect.width, 0)
mdc.DrawBitmap(self.bmpArrow, (rect.width - self.bmpArrow.GetWidth()) / 2, -2)
mdc.DrawBitmap(self.bmpArrow, round((rect.width - self.bmpArrow.GetWidth()) / 2), -2)
def OnTimer(self, event):
if event.GetId() == self.animTimerID:

View File

@@ -233,8 +233,8 @@ class PFToolbar:
bmpWidth = bmp.GetWidth()
pdc.DrawBitmap(dropShadowBmp, bx + self.padding / 2, self.toolbarY + self.padding / 2)
pdc.DrawBitmap(bmp, tbx, by)
pdc.DrawBitmap(dropShadowBmp, round(bx + self.padding / 2), round(self.toolbarY + self.padding / 2))
pdc.DrawBitmap(bmp, round(tbx), round(by))
bx += bmpWidth + self.padding

View File

@@ -247,12 +247,12 @@ class ShipItem(SFItem.SFBrowserItem):
else:
shipEffBk = self.shipEffBk
mdc.DrawBitmap(shipEffBk, self.shipEffx, self.shipEffy, 0)
mdc.DrawBitmap(shipEffBk, round(self.shipEffx), round(self.shipEffy), 0)
mdc.DrawBitmap(self.shipBmp, self.shipBmpx, self.shipBmpy, 0)
mdc.DrawBitmap(self.shipBmp, round(self.shipBmpx), round(self.shipBmpy), 0)
mdc.DrawBitmap(self.raceDropShadowBmp, self.raceBmpx + 1, self.raceBmpy + 1)
mdc.DrawBitmap(self.raceBmp, self.raceBmpx, self.raceBmpy)
mdc.DrawBitmap(self.raceDropShadowBmp, round(self.raceBmpx + 1), round(self.raceBmpy + 1))
mdc.DrawBitmap(self.raceBmp, round(self.raceBmpx), round(self.raceBmpy))
shipName, shipTrait, fittings = self.shipFittingInfo
@@ -264,17 +264,17 @@ class ShipItem(SFItem.SFBrowserItem):
fformat = "%d fits"
mdc.SetFont(self.fontNormal)
mdc.DrawText(fformat % fittings if fittings > 0 else fformat, self.textStartx, self.fittingsy)
mdc.DrawText(fformat % fittings if fittings > 0 else fformat, round(self.textStartx), round(self.fittingsy))
mdc.SetFont(self.fontSmall)
mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery)
mdc.DrawText(self.toolbar.hoverLabel, round(self.thoverx), round(self.thovery))
mdc.SetFont(self.fontBig)
psname = drawUtils.GetPartialText(mdc, shipName,
self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw)
mdc.DrawText(psname, self.textStartx, self.shipNamey)
mdc.DrawText(psname, round(self.textStartx), round(self.shipNamey))
if self.tcFitName.IsShown():
self.AdjustControlSizePos(self.tcFitName, self.textStartx, self.toolbarx - self.editWidth - self.padding)

View File

@@ -146,8 +146,8 @@ class ResistancesViewFull(StatsView):
lbl = PyGauge(contentPanel, font, 100)
lbl.SetMinSize((48, 16))
lbl.SetBackgroundColour(wx.Colour(bc[0], bc[1], bc[2]))
lbl.SetBarColour(wx.Colour(fc[0], fc[1], fc[2]))
lbl.SetBackgroundColour(wx.Colour(round(bc[0]), round(bc[1]), round(bc[2])))
lbl.SetBarColour(wx.Colour(round(fc[0]), round(fc[1]), round(fc[2])))
lbl.SetBarGradient()
lbl.SetFractionDigits(1)

View File

@@ -956,7 +956,7 @@ class FittingView(d.Display):
cx = padding
if slotMap[st.slot]:
mdc.DrawRectangle(cx, cy, maxWidth - cx, maxRowHeight)
mdc.DrawRectangle(round(cx), round(cy), round(maxWidth - cx), round(maxRowHeight))
for i, col in enumerate(self.activeColumns):
if i > maxColumns:

View File

@@ -533,7 +533,7 @@ class SkillTreeView(wx.Panel):
iconId = self.skillBookDirtyImageId
childId = tree.AppendItem(root, name, iconId, data=('skill', id))
tree.SetItemText(childId, 1, _t("Level {}d").format(int(level)) if isinstance(level, float) else level)
tree.SetItemText(childId, 1, _t("Level {}").format(int(level)) if isinstance(level, float) else level)
def populateSkillTree(self, event=None):
sChar = Character.getInstance()
@@ -591,7 +591,6 @@ class SkillTreeView(wx.Panel):
iconId = self.skillBookDirtyImageId
childId = tree.AppendItem(root, name, iconId, data=('skill', id))
tree.SetItemText(childId, 1, _t("Level {}").format(int(level)) if isinstance(level, float) else level)
def spawnMenu(self, event):

View File

@@ -530,11 +530,11 @@ class _TabRenderer:
mbmp = wx.Bitmap(mimg)
# draw middle bitmap, offset by left
mdc.DrawBitmap(mbmp, self.left_width, 0)
mdc.DrawBitmap(mbmp, round(self.left_width), 0)
# draw right bitmap offset by left + middle
mdc.DrawBitmap(self.ctab_right_bmp,
self.content_width + self.left_width, 0)
round(self.content_width + self.left_width), 0)
mdc.SelectObject(wx.NullBitmap)
@@ -555,7 +555,7 @@ class _TabRenderer:
+ self.left_width \
- self.ctab_close_bmp.GetWidth() / 2
y_offset = (self.tab_height - self.ctab_close_bmp.GetHeight()) / 2
self.close_region.Offset(x_offset, y_offset)
self.close_region.Offset(round(x_offset), round(y_offset))
def InitColors(self):
"""Determines colors used for tab, based on system settings"""
@@ -590,8 +590,8 @@ class _TabRenderer:
# Draw tab icon
mdc.DrawBitmap(
bmp,
self.left_width + self.padding - bmp.GetWidth() / 2,
(height - bmp.GetHeight()) / 2)
round(self.left_width + self.padding - bmp.GetWidth() / 2),
round((height - bmp.GetHeight()) / 2))
# draw close button
if self.closeable:
@@ -604,8 +604,8 @@ class _TabRenderer:
mdc.DrawBitmap(
cbmp,
self.content_width + self.left_width - cbmp.GetWidth() / 2,
(height - cbmp.GetHeight()) / 2)
round(self.content_width + self.left_width - cbmp.GetWidth() / 2),
round((height - cbmp.GetHeight()) / 2))
mdc.SelectObject(wx.NullBitmap)
@@ -640,7 +640,7 @@ class _TabRenderer:
# draw text (with no ellipses)
text = draw.GetPartialText(dc, self.text, maxsize, "")
tx, ty = dc.GetTextExtent(text)
dc.DrawText(text, text_start + self.padding, height / 2 - ty / 2)
dc.DrawText(text, round(text_start + self.padding), round(height / 2 - ty / 2))
def __repr__(self):
return "_TabRenderer(text={}, disabled={}) at {}".format(
@@ -1005,7 +1005,7 @@ class _TabsContainer(wx.Panel):
region = tab.GetCloseButtonRegion()
posx, posy = tab.GetPosition()
region.Offset(posx, posy)
region.Offset(round(posx), round(posy))
if region.Contains(x, y):
index = self.tabs.index(tab)
@@ -1036,7 +1036,7 @@ class _TabsContainer(wx.Panel):
region = self.add_button.GetRegion()
ax, ay = self.add_button.GetPosition()
region.Offset(ax, ay)
region.Offset(round(ax), round(ay))
if region.Contains(x, y):
ev = PageAdding()
@@ -1058,7 +1058,7 @@ class _TabsContainer(wx.Panel):
for tab in self.tabs:
region = tab.GetCloseButtonRegion()
posx, posy = tab.GetPosition()
region.Offset(posx, posy)
region.Offset(round(posx), round(posy))
if region.Contains(x, y):
if not tab.GetCloseButtonHoverStatus():
@@ -1093,7 +1093,7 @@ class _TabsContainer(wx.Panel):
tabRegion = tab.GetTabRegion()
tabPos = tab.GetPosition()
tabPosX, tabPosY = tabPos
tabRegion.Offset(tabPosX, tabPosY)
tabRegion.Offset(round(tabPosX), round(tabPosY))
if tabRegion.Contains(x, y):
return True
@@ -1166,7 +1166,7 @@ class _TabsContainer(wx.Panel):
region = self.add_button.GetRegion()
ax, ay = self.add_button.GetPosition()
region.Offset(ax, ay)
region.Offset(round(ax), round(ay))
if region.Contains(x, y):
if not self.add_button.IsHighlighted():
@@ -1198,7 +1198,7 @@ class _TabsContainer(wx.Panel):
if self.show_add_button:
ax, ay = self.add_button.GetPosition()
mdc.DrawBitmap(self.add_button.Render(), ax, ay, True)
mdc.DrawBitmap(self.add_button.Render(), round(ax), round(ay), True)
for i in range(len(self.tabs) - 1, -1, -1):
tab = self.tabs[i]
@@ -1206,12 +1206,12 @@ class _TabsContainer(wx.Panel):
if not tab.IsSelected():
# drop shadow first
mdc.DrawBitmap(self.fxBmps[tab], posx, posy, True)
mdc.DrawBitmap(self.fxBmps[tab], round(posx), (posy), True)
bmp = tab.Render()
img = bmp.ConvertToImage()
img = img.AdjustChannels(1, 1, 1, 0.85)
bmp = wx.Bitmap(img)
mdc.DrawBitmap(bmp, posx, posy, True)
mdc.DrawBitmap(bmp, round(posx), (posy), True)
mdc.SetDeviceOrigin(posx, posy)
tab.DrawText(mdc)
@@ -1224,7 +1224,7 @@ class _TabsContainer(wx.Panel):
if selected:
posx, posy = selected.GetPosition()
# drop shadow first
mdc.DrawBitmap(self.fxBmps[selected], posx, posy, True)
mdc.DrawBitmap(self.fxBmps[selected], round(posx), round(posy), True)
bmp = selected.Render()
@@ -1233,7 +1233,7 @@ class _TabsContainer(wx.Panel):
img = img.AdjustChannels(1.2, 1.2, 1.2, 0.7)
bmp = wx.Bitmap(img)
mdc.DrawBitmap(bmp, posx, posy, True)
mdc.DrawBitmap(bmp, round(posx), round(posy), True)
mdc.SetDeviceOrigin(posx, posy)
selected.DrawText(mdc)
@@ -1514,7 +1514,7 @@ class PFNotebookPagePreview(wx.Frame):
x, y = mdc.GetTextExtent(self.title)
mdc.SetBrush(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)))
mdc.DrawRectangle(0, 0, rect.width, 16)
mdc.DrawRectangle(0, 0, round(rect.width), 16)
mdc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
@@ -1523,4 +1523,4 @@ class PFNotebookPagePreview(wx.Frame):
mdc.SetPen(wx.Pen("#000000", width=1))
mdc.SetBrush(wx.TRANSPARENT_BRUSH)
mdc.DrawRectangle(0, 16, rect.width, rect.height - 16)
mdc.DrawRectangle(0, 16, round(rect.width), round(rect.height - 16))

View File

@@ -42,7 +42,7 @@ class DmgPatternNameValidator(BaseValidator):
return DmgPatternNameValidator()
def Validate(self, win):
entityEditor = win.parent
entityEditor = win.Parent.parent
textCtrl = self.GetWindow()
text = textCtrl.GetValue().strip()

View File

@@ -257,7 +257,7 @@ class PyGauge(wx.Window):
else:
w = rect.width * (float(value) / 100)
r = copy.copy(rect)
r.width = w
r.width = round(w)
dc.DrawRectangle(r)
else:
# if bar color is not set, then we use pre-defined transitions
@@ -269,7 +269,7 @@ class PyGauge(wx.Window):
else:
w = rect.width * (float(value) / 100)
r = copy.copy(rect)
r.width = w
r.width = round(w)
# determine transition range number and calculate xv (which is the
# progress between the two transition ranges)
@@ -317,7 +317,7 @@ class PyGauge(wx.Window):
gradient_color
)
if gradient_bitmap is not None:
dc.DrawBitmap(gradient_bitmap, r.left, r.top)
dc.DrawBitmap(gradient_bitmap, round(r.left), round(r.top))
# font stuff begins here
dc.SetFont(self.font)

View File

@@ -39,7 +39,7 @@ class ImplantTextValidor(BaseValidator):
return ImplantTextValidor()
def Validate(self, win):
entityEditor = win.parent
entityEditor = win.Parent.parent
textCtrl = self.GetWindow()
text = textCtrl.GetValue().strip()

View File

@@ -62,7 +62,7 @@ class TargetProfileNameValidator(BaseValidator):
return TargetProfileNameValidator()
def Validate(self, win):
entityEditor = win.parent
entityEditor = win.Parent.parent
textCtrl = self.GetWindow()
text = textCtrl.GetValue().strip()

View File

@@ -80,7 +80,7 @@ class LoadAnimation(wx.Window):
bh = rect.height
y = 0
dc.DrawRectangle(x, y, barWidth, bh)
dc.DrawRectangle(round(x), round(y), round(barWidth), round(bh))
x += barWidth
textColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)

View File

@@ -12,7 +12,7 @@ def Brighten(color, factor):
b += (255 - b) * factor
g += (255 - g) * factor
return wx.Colour(r, g, b, a)
return wx.Colour(round(r), round(g), round(b), round(a))
def Darken(color, factor):
@@ -30,7 +30,7 @@ def Darken(color, factor):
b = min(max(b, 0), 255)
g = min(max(g, 0), 255)
return wx.Colour(r, g, b, a)
return wx.Colour(round(r), round(g), round(b), round(a))
def _getBrightness(color):
@@ -70,4 +70,4 @@ def CalculateTransition(s_color, e_color, delta):
tG = sG + (eG - sG) * delta
tB = sB + (eB - sB) * delta
return wx.Colour(tR, tG, tB, (sA + eA) / 2)
return wx.Colour(round(tR), round(tG), round(tB), round((sA + eA) / 2))

View File

@@ -43,14 +43,14 @@ def DrawGradientBar(width, height, gStart, gEnd, gMid=None, fillRatio=4):
mdc.SelectObject(canvas)
r = wx.Rect(0, 0, width, height)
r.SetHeight(height / fillRatio)
r.SetHeight(round(height / fillRatio))
if gMid is None:
gMid = gStart
mdc.GradientFillLinear(r, gStart, gMid, wx.SOUTH)
r.SetTop(r.GetHeight())
r.SetHeight(height * (fillRatio - 1) / fillRatio + (1 if height % fillRatio != 0 else 0))
r.SetHeight(round(height * (fillRatio - 1) / fillRatio + (1 if height % fillRatio != 0 else 0)))
mdc.GradientFillLinear(r, gMid, gEnd, wx.SOUTH)

View File

@@ -92,7 +92,8 @@ exe = EXE(
upx=upx,
icon= icon,
# version='win-version-info.txt',
console=False
console=False,
contents_directory='app',
)
coll = COLLECT(

View File

@@ -1,15 +1,15 @@
wxPython == 4.0.6
logbook >= 1.0.0
numpy == 1.19.2
matplotlib == 3.2.2
wxPython
logbook
numpy
matplotlib
python-dateutil
requests == 2.28.1
sqlalchemy == 1.3.23
cryptography >= 2.3
markdown2 >= 2.3.5
packaging >= 16.8
roman >= 2.0.0
beautifulsoup4 >= 4.6.0
pyyaml >= 5.1
python-jose==3.0.1
requests-cache==0.8.1
requests
sqlalchemy==1.4.50
cryptography
markdown2
packaging
roman
beautifulsoup4
pyyaml
python-jose
requests-cache

View File

@@ -19,7 +19,7 @@ params = {
resp = requests.get('https://api.crowdin.com/api/project/pyfa/status', params=params)
data = resp.json()
if resp.status_code is not 200:
if resp.status_code != 200:
print("Error fetching Crowdin progress. Error: {}; {}".format(data['error']['message']))
sys.exit()
@@ -36,4 +36,4 @@ data = {x['canonical_name']: x for x in data}
with open("locale/progress.json", 'w') as file:
file.seek(0)
file.truncate()
json.dump(data, file)
json.dump(data, file)

View File

@@ -4,7 +4,7 @@ echo "${PYFA_VERSION}"
echo "Pyfa version (YAML):"
cat version.yml
echo "Building distributive..."
python3 -m PyInstaller -y --clean --windowed dist_assets/mac/pyfa.spec
python3 -m PyInstaller -y --clean dist_assets/mac/pyfa.spec
echo "Compressing distributive..."
cd dist
/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${PYFA_VERSION}" "pyfa.app/Contents/Info.plist" # Add missing

View File

@@ -3,9 +3,7 @@ echo "Python version:"
python3 --version
echo "Upgrading pip..."
python3 -m pip install --upgrade pip
echo "Installing pathlib2 (wxpython issue workaround)..."
python3 -m pip install pathlib2
echo "Installing app requirements..."
python3 -m pip install -r requirements.txt
echo "Installing packaging tools..."
python3 -m pip install PyInstaller==3.6
python3 -m pip install PyInstaller

View File

@@ -88,7 +88,7 @@ class Fit:
"enableGaugeAnimation": True,
"openFitInNew": False,
"priceSystem": "Jita",
"priceSource": "evemarketer",
"priceSource": "fuzzwork market",
"showShipBrowserTooltip": True,
"marketSearchDelay": 250,
"ammoChangeAll": False,

View File

@@ -1 +1 @@
__all__ = ['evemarketer', 'evemarketdata', 'fuzzwork', 'cevemarket']
__all__ = ['evetycoon', 'evemarketdata', 'fuzzwork', 'cevemarket']

View File

@@ -1,75 +0,0 @@
# =============================================================================
# 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/>.
# =============================================================================
from xml.dom import minidom
from logbook import Logger
from eos.saveddata.price import PriceStatus
from service.network import Network
from service.price import Price
pyfalog = Logger(__name__)
class EveMarketer:
name = 'evemarketer'
group = 'tranquility'
def __init__(self, priceMap, system, fetchTimeout):
# Try selected system first
self.fetchPrices(priceMap, max(2 * fetchTimeout / 3, 2), system)
# If price was not available - try globally
if priceMap:
self.fetchPrices(priceMap, max(fetchTimeout / 3, 2))
@staticmethod
def fetchPrices(priceMap, fetchTimeout, system=None):
params = {'typeid': {typeID for typeID in priceMap}}
if system is not None:
params['usesystem'] = system
baseurl = 'https://api.evemarketer.com/ec/marketstat'
network = Network.getInstance()
data = network.get(url=baseurl, type=network.PRICES, params=params, timeout=fetchTimeout)
xml = minidom.parseString(data.text)
types = xml.getElementsByTagName('marketstat').item(0).getElementsByTagName('type')
# Cycle through all types we've got from request
for type_ in types:
# Get data out of each typeID details tree
typeID = int(type_.getAttribute('id'))
sell = type_.getElementsByTagName('sell').item(0)
# If price data wasn't there, skip the item
try:
percprice = float(sell.getElementsByTagName('percentile').item(0).firstChild.data)
except (TypeError, ValueError):
pyfalog.warning('Failed to get price for: {0}', type_)
continue
# Price is 0 if evemarketer has info on this item, but it is not available
# for current scope limit. If we provided scope limit - make sure to skip
# such items to check globally, and do not skip if requested globally
if percprice == 0 and system is not None:
continue
priceMap[typeID].update(PriceStatus.fetchSuccess, percprice)
del priceMap[typeID]
Price.register(EveMarketer)

View File

@@ -0,0 +1,68 @@
# =============================================================================
# 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/>.
# =============================================================================
from xml.dom import minidom
from logbook import Logger
from eos.saveddata.price import PriceStatus
from service.network import Network
from service.price import Price
pyfalog = Logger(__name__)
locations = {
30000142: (10000002, 60003760), # Jita 4-4 CNAP
30002187: (10000043, 60008494), # Amarr VIII
30002659: (10000032, 60011866), # Dodixie
30002510: (10000030, 60004588), # Rens
30002053: (10000042, 60005686)} # Hek
class EveTycoon:
name = 'evetycoon'
group = 'tranquility'
def __init__(self, priceMap, system, fetchTimeout):
# Try selected system first
self.fetchPrices(priceMap, max(2 * fetchTimeout / 3, 2), system)
@staticmethod
def fetchPrices(priceMap, fetchTimeout, system=None):
# Default to jita when system is not found
regionID, stationID = locations.get(system, locations[30000142])
baseurl = 'https://evetycoon.com/api/v1/market/stats'
network = Network.getInstance()
# Cycle through all types we've got from request
for typeID in tuple(priceMap):
url = f'{baseurl}/{regionID}/{typeID}'
resp = network.get(url=url, params={'locationId': stationID}, type=network.PRICES, timeout=fetchTimeout)
if resp.status_code != 200:
continue
price = resp.json()['sellAvgFivePercent']
# Price is 0 - no data
if price == 0:
continue
priceMap[typeID].update(PriceStatus.fetchSuccess, price)
del priceMap[typeID]
Price.register(EveTycoon)

View File

@@ -276,4 +276,4 @@ class PriceWorkerThread(threading.Thread):
# Import market sources only to initialize price source modules, they register on their own
from service.marketSources import evemarketer, evemarketdata, fuzzwork, cevemarket # noqa: E402
from service.marketSources import evemarketdata, fuzzwork, cevemarket, evetycoon # noqa: E402

View File

@@ -1 +1 @@
version: v2.56.0
version: v2.57.0dev1