Compare commits
511 Commits
v1.22.2
...
preview_ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d8c76209d | ||
|
|
c2038a6cf2 | ||
|
|
082ac233ad | ||
|
|
5d46fe7e4d | ||
|
|
6049c9837c | ||
|
|
a76eef01de | ||
|
|
b3eb4f35cd | ||
|
|
6b6dacf94c | ||
|
|
f010f2fef2 | ||
|
|
a952f80ea4 | ||
|
|
6d34ae2960 | ||
|
|
d17ff000c7 | ||
|
|
6b3d3ecd93 | ||
|
|
32dc28f48d | ||
|
|
a210724312 | ||
|
|
1d69ed7584 | ||
|
|
43e864e47b | ||
|
|
fb538027f7 | ||
|
|
cbf7f7d320 | ||
|
|
4111d670a7 | ||
|
|
397084a9ff | ||
|
|
968d633d46 | ||
|
|
96c3363edc | ||
|
|
a853ed9960 | ||
|
|
323a7060ec | ||
|
|
d0fa2510e5 | ||
|
|
8d57f641f7 | ||
|
|
055957567f | ||
|
|
5aff3f007e | ||
|
|
c34d86ba80 | ||
|
|
2038f36254 | ||
|
|
b1fc07a4cf | ||
|
|
a366420d65 | ||
|
|
8095b4852b | ||
|
|
cc3274f245 | ||
|
|
fbde9ce7bf | ||
|
|
130fc189ad | ||
|
|
a50e4fcc46 | ||
|
|
ae96ff244e | ||
|
|
1b0cdeedce | ||
|
|
992820ac42 | ||
|
|
c0ecc6a329 | ||
|
|
85131e6166 | ||
|
|
330983d9dd | ||
|
|
1bb7c4e825 | ||
|
|
450e1427a1 | ||
|
|
5614cec19d | ||
|
|
3f24a4b2c5 | ||
|
|
4e9e5735dc | ||
|
|
b1a6189c55 | ||
|
|
836504ee01 | ||
|
|
269565e959 | ||
|
|
e45027a66c | ||
|
|
2d3310d8e0 | ||
|
|
77066f0389 | ||
|
|
5e0567ef4d | ||
|
|
b49de4b0fa | ||
|
|
372495a83a | ||
|
|
468a4644d6 | ||
|
|
29d0f102fd | ||
|
|
ebc7173c50 | ||
|
|
43f1ac78a6 | ||
|
|
d489fdd700 | ||
|
|
d6b1e4465e | ||
|
|
5cbffcf3ac | ||
|
|
c91723516e | ||
|
|
a68f45d15a | ||
|
|
152a708ee8 | ||
|
|
a0ec13d2ed | ||
|
|
3313b7421f | ||
|
|
a76ee6b2fc | ||
|
|
0056b704d4 | ||
|
|
c1ead5fe27 | ||
|
|
85a89339a7 | ||
|
|
55f82c48bc | ||
|
|
f4761e099b | ||
|
|
be3696deba | ||
|
|
cd41e9e9be | ||
|
|
d6db30b7fc | ||
|
|
fd066c2150 | ||
|
|
f9ba95b3de | ||
|
|
7ee4d1d588 | ||
|
|
cef5842344 | ||
|
|
a7b6647135 | ||
|
|
bef17e53c6 | ||
|
|
d4b6099d6e | ||
|
|
ff60538e21 | ||
|
|
50c6133046 | ||
|
|
b7d7b80544 | ||
|
|
2b9342692d | ||
|
|
a24e247f1b | ||
|
|
3396056dae | ||
|
|
366d6c8971 | ||
|
|
14bf7ddf7a | ||
|
|
30cce09063 | ||
|
|
9a50ebfc47 | ||
|
|
0f05b60c20 | ||
|
|
4f8493d1bb | ||
|
|
58dd629956 | ||
|
|
936b746954 | ||
|
|
ef14bfac58 | ||
|
|
291f73b661 | ||
|
|
3d9dae0d52 | ||
|
|
017c37c4af | ||
|
|
ee0c852ddb | ||
|
|
d63627a37b | ||
|
|
b1c9e70f95 | ||
|
|
3ac2fd870f | ||
|
|
af7272cd10 | ||
|
|
d7c71f5d47 | ||
|
|
c858fc2859 | ||
|
|
f76f44e9f3 | ||
|
|
4fb07cc1d0 | ||
|
|
658a87cbc0 | ||
|
|
956fa7a8b7 | ||
|
|
0ebb992354 | ||
|
|
37f8253836 | ||
|
|
200ff5a1a4 | ||
|
|
0d44cbf74a | ||
|
|
bb216aa6ed | ||
|
|
eccf405ba8 | ||
|
|
9df87f61cd | ||
|
|
4186e19c65 | ||
|
|
57edc32a4b | ||
|
|
9cfa0748ac | ||
|
|
df859a2132 | ||
|
|
52257d60ac | ||
|
|
96ddb0bbff | ||
|
|
b529a28715 | ||
|
|
ea3a374ced | ||
|
|
2eacadf08f | ||
|
|
1a127bb1a6 | ||
|
|
edfa130939 | ||
|
|
7fbd89392a | ||
|
|
9f4b31979c | ||
|
|
9ecfc475e3 | ||
|
|
84dc93ac54 | ||
|
|
7532bcda08 | ||
|
|
08b5abc7ad | ||
|
|
38bf143704 | ||
|
|
a440ed3b37 | ||
|
|
39b7d9fdeb | ||
|
|
dfa728a486 | ||
|
|
7bd8ca5a55 | ||
|
|
627977ab51 | ||
|
|
e3b592977a | ||
|
|
622a734405 | ||
|
|
28404cd8bb | ||
|
|
be53dedb18 | ||
|
|
8ab6e26def | ||
|
|
b2a5a20650 | ||
|
|
57f930c83e | ||
|
|
b4dd65cf3e | ||
|
|
4a9b1df9b4 | ||
|
|
874bfb3305 | ||
|
|
ab9c925c47 | ||
|
|
d3b6bc1c93 | ||
|
|
cd7d25e4e1 | ||
|
|
1e5e9122ae | ||
|
|
506c7d31ca | ||
|
|
54cc5abf21 | ||
|
|
18e913d9ba | ||
|
|
180de97893 | ||
|
|
f198ff1773 | ||
|
|
55c13d1ad0 | ||
|
|
16505b30bf | ||
|
|
95b3f0a21c | ||
|
|
6adcfc52cd | ||
|
|
0a28fb60df | ||
|
|
2bab1464ee | ||
|
|
7875c2acaa | ||
|
|
49bf40484d | ||
|
|
07148f1e7f | ||
|
|
8a6ef788b3 | ||
|
|
d3e360b7c0 | ||
|
|
b1bba74c5a | ||
|
|
a954759012 | ||
|
|
90c1033437 | ||
|
|
191a065de1 | ||
|
|
cf91ae7627 | ||
|
|
0ba88d081a | ||
|
|
b6420b9a4b | ||
|
|
4f77dff6dd | ||
|
|
2b3e646213 | ||
|
|
e0e7478857 | ||
|
|
828d722be8 | ||
|
|
1ae55b34ee | ||
|
|
c9bc2341d1 | ||
|
|
eba98fec33 | ||
|
|
70af2b0df7 | ||
|
|
753b5c5339 | ||
|
|
9bb86b4ee4 | ||
|
|
2702193337 | ||
|
|
907196018b | ||
|
|
5eb2fef89c | ||
|
|
9403a1fce9 | ||
|
|
fd224d6781 | ||
|
|
f5776a0cb2 | ||
|
|
5b62419520 | ||
|
|
b9e5a47924 | ||
|
|
545c48266c | ||
|
|
61d1878494 | ||
|
|
4a95156e35 | ||
|
|
ab5f3488e7 | ||
|
|
510492e5e9 | ||
|
|
b375d3cb6c | ||
|
|
6ef57e735e | ||
|
|
f160aede3e | ||
|
|
ea8a4c01cb | ||
|
|
d963327ed4 | ||
|
|
bb96b0af1a | ||
|
|
34e3aa20ba | ||
|
|
5a846c36ab | ||
|
|
7bd6344359 | ||
|
|
b76e8df1bf | ||
|
|
5a0165282f | ||
|
|
597d9f2612 | ||
|
|
4d9c2898bf | ||
|
|
1854a21a50 | ||
|
|
0e4e7525e1 | ||
|
|
5259df2828 | ||
|
|
a5b5da6d27 | ||
|
|
b2cf4b8aa5 | ||
|
|
0d874f9ad1 | ||
|
|
019b8e93b4 | ||
|
|
b29fa2467a | ||
|
|
8b17cbfbc8 | ||
|
|
a445509d75 | ||
|
|
5a8eac21a3 | ||
|
|
45480a0216 | ||
|
|
97f72f6df5 | ||
|
|
466b2ac706 | ||
|
|
0d4f24ade9 | ||
|
|
459d55c31a | ||
|
|
7e98d29de0 | ||
|
|
6bd51ff0d5 | ||
|
|
6500e6d467 | ||
|
|
abcce8879f | ||
|
|
e30040c9fd | ||
|
|
6bbfb8e837 | ||
|
|
2ec203a3a2 | ||
|
|
4df22d2063 | ||
|
|
bf16246825 | ||
|
|
0eed01811c | ||
|
|
96b3d5637a | ||
|
|
4a09cbcec9 | ||
|
|
964493d701 | ||
|
|
f1b9c788f3 | ||
|
|
a50f89db67 | ||
|
|
0d94ffe27a | ||
|
|
dc4c4c7353 | ||
|
|
8d4e0a259e | ||
|
|
91f87b02cc | ||
|
|
870e333605 | ||
|
|
7ea3103c25 | ||
|
|
3aa60ac669 | ||
|
|
81612cc32a | ||
|
|
d3caee328f | ||
|
|
d5af6127e5 | ||
|
|
5eb5fb3310 | ||
|
|
8605bab4d4 | ||
|
|
1540c9463a | ||
|
|
130105ca9f | ||
|
|
cb225eabb3 | ||
|
|
72245d8ebe | ||
|
|
96505e4421 | ||
|
|
fbb1750528 | ||
|
|
dad63b6d77 | ||
|
|
14e69b1e59 | ||
|
|
883917d5d6 | ||
|
|
deeccc85a3 | ||
|
|
cfa57a70dc | ||
|
|
e6dfb1e90a | ||
|
|
e03d3278a0 | ||
|
|
eae4bb75e5 | ||
|
|
e6dead2e27 | ||
|
|
59b854b00d | ||
|
|
675533a732 | ||
|
|
7751a2e072 | ||
|
|
b4bbc82ba1 | ||
|
|
a0a0ec9b1f | ||
|
|
26285cfc95 | ||
|
|
6799e71f1a | ||
|
|
8806c941a8 | ||
|
|
78cbed516a | ||
|
|
2281fae615 | ||
|
|
1192a0658a | ||
|
|
7f2ac25455 | ||
|
|
62a696cc4b | ||
|
|
11716f7f94 | ||
|
|
180166156a | ||
|
|
3c8bab92b5 | ||
|
|
cf361593a4 | ||
|
|
8ad639a122 | ||
|
|
a7cd445cef | ||
|
|
380d74b333 | ||
|
|
eade4f0ebd | ||
|
|
08be50caf2 | ||
|
|
6a5c86b84f | ||
|
|
1fb5bbc36e | ||
|
|
d6edb57a10 | ||
|
|
d3fdf9854d | ||
|
|
3217980ada | ||
|
|
29b5a7433d | ||
|
|
5bca2d723e | ||
|
|
d2a52e26b2 | ||
|
|
8a4fe1627e | ||
|
|
a9fb55fedd | ||
|
|
04c30e70af | ||
|
|
c0210895e9 | ||
|
|
fe9917e620 | ||
|
|
a3dfa3b5ba | ||
|
|
34243b7b71 | ||
|
|
9fd81e8acd | ||
|
|
bbc4ef8146 | ||
|
|
7fe7056c12 | ||
|
|
ab32a3afb0 | ||
|
|
ea3e5e273f | ||
|
|
6849478226 | ||
|
|
b6c5183d40 | ||
|
|
e5d65b97ce | ||
|
|
6cda47be9f | ||
|
|
a0ef1a3d9b | ||
|
|
ba47420577 | ||
|
|
806f17545f | ||
|
|
f0f5b4c04c | ||
|
|
ad76104033 | ||
|
|
c6e481efcf | ||
|
|
2ad0c00c17 | ||
|
|
26ab7d5e6f | ||
|
|
832e7e6637 | ||
|
|
8c7972ed78 | ||
|
|
05bbc14965 | ||
|
|
e7feee6878 | ||
|
|
791ddcb9a1 | ||
|
|
12d5a21982 | ||
|
|
7493b92d83 | ||
|
|
e7c79e58b4 | ||
|
|
0dbdbf7cfe | ||
|
|
f39ca66dbf | ||
|
|
8d80494b8d | ||
|
|
058768baab | ||
|
|
cfee6fdcd0 | ||
|
|
34c95bea5d | ||
|
|
50911c7fc8 | ||
|
|
4e1f0f9cc6 | ||
|
|
2b1abfc9b2 | ||
|
|
595c139ca8 | ||
|
|
6637feb3a6 | ||
|
|
928246a8ca | ||
|
|
fd3e0bbebf | ||
|
|
2a0a572b76 | ||
|
|
a314cd7cfd | ||
|
|
cd28375019 | ||
|
|
7cf4134a73 | ||
|
|
44c76f0b98 | ||
|
|
69a122a271 | ||
|
|
0c0eb327f7 | ||
|
|
74ce79ba8f | ||
|
|
1dc15936ed | ||
|
|
126fa7be29 | ||
|
|
d61251e9b3 | ||
|
|
f9f53a13c0 | ||
|
|
b4360d44f1 | ||
|
|
574d575cad | ||
|
|
5e10339c20 | ||
|
|
feb83cf737 | ||
|
|
0ff4aec400 | ||
|
|
e2944f6be7 | ||
|
|
3e842f30f1 | ||
|
|
481619101b | ||
|
|
2ac66d87af | ||
|
|
e818ce62c8 | ||
|
|
49851d1131 | ||
|
|
a8061c9276 | ||
|
|
4036ac8cd2 | ||
|
|
57bbbfcc3b | ||
|
|
68f769aac2 | ||
|
|
ef9bd3edc8 | ||
|
|
45f88a92dc | ||
|
|
02c8b46b74 | ||
|
|
32068e8d8e | ||
|
|
ccd8ee87f3 | ||
|
|
c73b446482 | ||
|
|
699276ca58 | ||
|
|
3187bab90a | ||
|
|
c1dfd676e1 | ||
|
|
c7554ec400 | ||
|
|
f1771a61d0 | ||
|
|
d3cb968c19 | ||
|
|
9c685263bb | ||
|
|
d43db40469 | ||
|
|
a50471c0a6 | ||
|
|
8d215f7d7f | ||
|
|
eb9b034d65 | ||
|
|
c52fecead3 | ||
|
|
5b09cf7c4d | ||
|
|
9be9a21b22 | ||
|
|
3e4b748952 | ||
|
|
9fe91472cf | ||
|
|
a06810c7c8 | ||
|
|
160de64135 | ||
|
|
2b5535c5d1 | ||
|
|
1e9f911385 | ||
|
|
2a9a4fbdff | ||
|
|
7331c158b6 | ||
|
|
ddcbbb7fcf | ||
|
|
e7ac1597bb | ||
|
|
11e8ea4fe8 | ||
|
|
1853500729 | ||
|
|
a349626923 | ||
|
|
f466f9cc49 | ||
|
|
13b452223d | ||
|
|
c166fa6bf5 | ||
|
|
3a7e343f1c | ||
|
|
02557701f0 | ||
|
|
30755fbb73 | ||
|
|
c1b3491933 | ||
|
|
5467a58b04 | ||
|
|
75f07afcb7 | ||
|
|
c64838f7f5 | ||
|
|
a0359b8bd9 | ||
|
|
e2434619b5 | ||
|
|
becb3d4bb6 | ||
|
|
44fb4a558c | ||
|
|
9a574cb31b | ||
|
|
4fa4640991 | ||
|
|
35b5002eca | ||
|
|
b5574ca535 | ||
|
|
8fec03bcbf | ||
|
|
7de90cc2d8 | ||
|
|
c700d9b661 | ||
|
|
48f264851d | ||
|
|
467d244bea | ||
|
|
840c041f8c | ||
|
|
c30190f63e | ||
|
|
6e54d6788c | ||
|
|
68f45706ab | ||
|
|
43ee031121 | ||
|
|
533c86de16 | ||
|
|
ba3c9b87b5 | ||
|
|
8338b6adb3 | ||
|
|
54c950f951 | ||
|
|
d1c18d9642 | ||
|
|
19090e7353 | ||
|
|
1d52382460 | ||
|
|
a074199219 | ||
|
|
c1179ddb40 | ||
|
|
ef06a1ccb1 | ||
|
|
e31f3cb46e | ||
|
|
9f9cd29a7f | ||
|
|
ed24ef2615 | ||
|
|
c5b78c20e5 | ||
|
|
f98f6a120b | ||
|
|
6192343add | ||
|
|
6728aba0a5 | ||
|
|
64b75303af | ||
|
|
0eef1ee480 | ||
|
|
fef087ae46 | ||
|
|
0e15adecf2 | ||
|
|
be6addf4d0 | ||
|
|
052e9b68b5 | ||
|
|
fd91f56e55 | ||
|
|
a0a35d60ec | ||
|
|
639f3d27b4 | ||
|
|
e3040854d8 | ||
|
|
4597fd27da | ||
|
|
88bceae6b0 | ||
|
|
9ace9815b6 | ||
|
|
bfda7014db | ||
|
|
5107d383e0 | ||
|
|
32ba3fa516 | ||
|
|
69723d1bd0 | ||
|
|
5a5ab846c2 | ||
|
|
394381c736 | ||
|
|
fea1a28760 | ||
|
|
f895e82c69 | ||
|
|
710d15a66c | ||
|
|
d81a51bd8c | ||
|
|
3ac733a30c | ||
|
|
7a715fc471 | ||
|
|
b9b72ebf40 | ||
|
|
071dfaf656 | ||
|
|
88384a2fd8 | ||
|
|
a2c0049488 | ||
|
|
60288204fc | ||
|
|
7d0f65c1f3 | ||
|
|
a35b9b5d3f | ||
|
|
2a2842100a | ||
|
|
faed0ce159 | ||
|
|
7b2a89d66b | ||
|
|
4d158d99fd | ||
|
|
c3983a26c5 | ||
|
|
016854a292 | ||
|
|
5d7252cbec | ||
|
|
0e0bcf51fc | ||
|
|
1c194b67f3 | ||
|
|
72e77d2264 | ||
|
|
10c79ac812 | ||
|
|
fe8c3a4957 | ||
|
|
3734be21d6 | ||
|
|
8ae6ad879e | ||
|
|
fb2e6e5c17 | ||
|
|
6e2878194c | ||
|
|
655d658a52 | ||
|
|
62fd545d24 | ||
|
|
4041ecddc4 | ||
|
|
10f51b41b7 | ||
|
|
7cf0a35a7a | ||
|
|
523f7793b5 | ||
|
|
9891aecf19 |
26
.codecov.yml
Normal file
26
.codecov.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
codecov:
|
||||
notify:
|
||||
require_ci_to_pass: yes
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
|
||||
status:
|
||||
project: yes
|
||||
patch: yes
|
||||
changes: no
|
||||
|
||||
parsers:
|
||||
gcov:
|
||||
branch_detection:
|
||||
conditional: yes
|
||||
loop: yes
|
||||
method: no
|
||||
macro: no
|
||||
|
||||
comment:
|
||||
layout: "header, diff"
|
||||
behavior: default
|
||||
require_changes: no
|
||||
40
.gitattributes
vendored
Normal file
40
.gitattributes
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
# *.c text
|
||||
# *.h text
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
# Source files
|
||||
# ============
|
||||
*.pxd text eol=crlf
|
||||
*.py text eol=crlf
|
||||
*.py3 text eol=crlf
|
||||
*.pyw text eol=crlf
|
||||
*.pyx text eol=crlf
|
||||
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
# Binary files
|
||||
# ============
|
||||
*.db binary
|
||||
*.p binary
|
||||
*.pkl binary
|
||||
*.pyc binary
|
||||
*.pyd binary
|
||||
*.pyo binary
|
||||
|
||||
# Note: .db, .p, and .pkl files are associated
|
||||
# with the python modules ``pickle``, ``dbm.*``,
|
||||
# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
|
||||
# (among others).
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
# Image files
|
||||
# ============
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.icns binary
|
||||
*.ico binary
|
||||
113
.gitignore
vendored
113
.gitignore
vendored
@@ -4,20 +4,117 @@
|
||||
#Kwrite/Gedit/Other crapapps making backups
|
||||
*~
|
||||
|
||||
#Eclipse
|
||||
.project
|
||||
.pydevproject
|
||||
.settings
|
||||
|
||||
#Patch files
|
||||
*.patch
|
||||
|
||||
#Personal
|
||||
/saveddata/
|
||||
|
||||
#PyCharm
|
||||
.idea/
|
||||
|
||||
#Pyfa file
|
||||
pyfaFits.html
|
||||
|
||||
#Temporary files
|
||||
*.py__jb_tmp__
|
||||
|
||||
# Based on https://github.com/github/gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
Pyfa.egg-info/
|
||||
|
||||
# PyInstaller
|
||||
# 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
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# IPython Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
# virtualenv
|
||||
.venv/
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# Eclipse project settings
|
||||
.project
|
||||
.pydevproject
|
||||
.settings
|
||||
|
||||
# Pycharm project settings
|
||||
.idea
|
||||
eos.iml
|
||||
|
||||
25
.travis.yml
Normal file
25
.travis.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
language: python
|
||||
python:
|
||||
- '2.7'
|
||||
env:
|
||||
- TOXENV=pep8
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# for wxPython:
|
||||
- python-wxgtk2.8
|
||||
- python-wxtools
|
||||
- wx2.8-doc
|
||||
- wx2.8-examples
|
||||
- wx2.8-headers
|
||||
- wx2.8-i18n
|
||||
before_install:
|
||||
- pip install -U tox
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r requirements_test.txt
|
||||
script:
|
||||
- tox
|
||||
- py.test --cov=./
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
@@ -1,6 +1,6 @@
|
||||
# pyfa
|
||||
|
||||
[](https://gitter.im/pyfa-org/Pyfa?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://pyfainvite.azurewebsites.net/)
|
||||
|
||||

|
||||
|
||||
@@ -22,7 +22,7 @@ There are two different distributives for OS X: `-mac` and `-mac-deprecated`.
|
||||
|
||||
There is also a [Homebrew](http://brew.sh) option for installing pyfa on OS X. Please note this is maintained by a third-party and is not tested by pyfa developers. Simply fire up in terminal:
|
||||
```
|
||||
$ brew cask install pyfa
|
||||
$ brew install Caskroom/cask/pyfa
|
||||
```
|
||||
|
||||
### Linux Distro-specific Packages
|
||||
@@ -38,7 +38,7 @@ If you wish to help with development or simply need to run pyfa through a Python
|
||||
|
||||
* Python 2.7
|
||||
* `wxPython` 2.8/3.0
|
||||
* `sqlalchemy` >= 0.6
|
||||
* `sqlalchemy` >= 1.0.5
|
||||
* `dateutil`
|
||||
* `matplotlib` (for some Linux distributions you may need to install separate wxPython bindings such as `python-matplotlib-wx`)
|
||||
* `requests`
|
||||
@@ -50,7 +50,7 @@ The preferred method of reporting bugs is through the project's [GitHub Issues i
|
||||
pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||
|
||||
## Resources
|
||||
* Development repository: [http://github.com/DarkFenX/Pyfa](http://github.com/DarkFenX/Pyfa)
|
||||
* 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 University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||
|
||||
112
config.py
112
config.py
@@ -18,10 +18,10 @@ debug = False
|
||||
saveInRoot = False
|
||||
|
||||
# Version data
|
||||
version = "1.22.2"
|
||||
tag = "Stable"
|
||||
expansionName = "YC 118.6"
|
||||
expansionVersion = "1.0"
|
||||
version = "1.26.1"
|
||||
tag = "git"
|
||||
expansionName = "YC118.10"
|
||||
expansionVersion = "1.2"
|
||||
evemonMinVersion = "4081"
|
||||
|
||||
pyfaPath = None
|
||||
@@ -31,18 +31,20 @@ 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 = ''
|
||||
"""
|
||||
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 write(self, buf):
|
||||
for line in buf.rstrip().splitlines():
|
||||
self.logger.log(self.log_level, line.rstrip())
|
||||
|
||||
def isFrozen():
|
||||
if hasattr(sys, 'frozen'):
|
||||
@@ -50,16 +52,12 @@ def isFrozen():
|
||||
else:
|
||||
return False
|
||||
|
||||
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 __createDirs(path):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
|
||||
def defPaths(customSavePath):
|
||||
global debug
|
||||
global pyfaPath
|
||||
@@ -77,32 +75,32 @@ def defPaths(customSavePath):
|
||||
# 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 = getPyfaRoot()
|
||||
pyfaPath = getPyfaPath()
|
||||
|
||||
# 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 = os.path.join(pyfaPath, "saveddata")
|
||||
savePath = getPyfaPath("saveddata")
|
||||
else:
|
||||
savePath = getattr(configforced, "savePath", None)
|
||||
if savePath is None:
|
||||
if customSavePath is None: # customSavePath is not overriden
|
||||
savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")),
|
||||
sys.getfilesystemencoding())
|
||||
if customSavePath is None: # customSavePath is not overriden
|
||||
savePath = os.path.expanduser(os.path.join("~", ".pyfa"))
|
||||
else:
|
||||
savePath = customSavePath
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
if isFrozen():
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
certName = "cacert.pem"
|
||||
os.environ["REQUESTS_CA_BUNDLE"] = getPyfaPath(certName).encode('utf8')
|
||||
os.environ["SSL_CERT_FILE"] = getPyfaPath(certName).encode('utf8')
|
||||
|
||||
format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
|
||||
logging.basicConfig(format=format, level=logLevel)
|
||||
handler = logging.handlers.RotatingFileHandler(os.path.join(savePath, "log.txt"), maxBytes=1000000, backupCount=3)
|
||||
formatter = logging.Formatter(format)
|
||||
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)
|
||||
|
||||
@@ -114,23 +112,61 @@ def defPaths(customSavePath):
|
||||
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
|
||||
# stderr_logger = logging.getLogger('STDERR')
|
||||
# sl = StreamToLogger(stderr_logger, logging.ERROR)
|
||||
# sys.stderr = sl
|
||||
|
||||
# The database where we store all the fits etc
|
||||
saveDB = os.path.join(savePath, "saveddata.db")
|
||||
saveDB = getSavePath("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 = os.path.join(pyfaPath, "eve.db")
|
||||
gameDB = getPyfaPath("eve.db")
|
||||
|
||||
## DON'T MODIFY ANYTHING BELOW ##
|
||||
# DON'T MODIFY ANYTHING BELOW!
|
||||
import eos.config
|
||||
|
||||
#Caching modifiers, disable all gamedata caching, its unneeded.
|
||||
# Caching modifiers, disable all gamedata caching, its unneeded.
|
||||
eos.config.gamedataCache = False
|
||||
# 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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
version = "0.2.3"
|
||||
tag = "git"
|
||||
|
||||
|
||||
def test():
|
||||
import tests.runTests
|
||||
import unittest
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import heapq
|
||||
from math import sqrt, exp
|
||||
import time
|
||||
|
||||
from math import sqrt, exp
|
||||
|
||||
DAY = 24 * 60 * 60 * 1000
|
||||
|
||||
def lcm(a,b):
|
||||
n = a*b
|
||||
|
||||
def lcm(a, b):
|
||||
n = a * b
|
||||
while b:
|
||||
a, b = b, a % b
|
||||
return n / a
|
||||
@@ -40,20 +40,19 @@ class CapSimulator(object):
|
||||
# relevant decimal digits of capacitor for LCM period optimization
|
||||
self.stability_precision = 1
|
||||
|
||||
|
||||
def scale_activation(self, duration, capNeed):
|
||||
for res in self.scale_resolutions:
|
||||
mod = duration % res
|
||||
if mod:
|
||||
if mod > res/2.0:
|
||||
mod = res-mod
|
||||
if mod > res / 2.0:
|
||||
mod = res - mod
|
||||
else:
|
||||
mod = -mod
|
||||
|
||||
if abs(mod) <= duration/100.0:
|
||||
if abs(mod) <= duration / 100.0:
|
||||
# only adjust if the adjustment is less than 1%
|
||||
duration += mod
|
||||
capNeed += float(mod)/duration * capNeed
|
||||
capNeed += float(mod) / duration * capNeed
|
||||
break
|
||||
|
||||
return duration, capNeed
|
||||
@@ -91,12 +90,12 @@ class CapSimulator(object):
|
||||
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
|
||||
if self.stagger and not disableStagger:
|
||||
if clipSize == 0:
|
||||
duration = int(duration/amount)
|
||||
duration = int(duration / amount)
|
||||
else:
|
||||
stagger_amount = (duration*clipSize+10000)/(amount*clipSize)
|
||||
stagger_amount = (duration * clipSize + 10000) / (amount * clipSize)
|
||||
for i in range(1, amount):
|
||||
heapq.heappush(self.state,
|
||||
[i*stagger_amount, duration,
|
||||
[i * stagger_amount, duration,
|
||||
capNeed, 0, clipSize])
|
||||
else:
|
||||
capNeed *= amount
|
||||
@@ -109,13 +108,11 @@ class CapSimulator(object):
|
||||
|
||||
heapq.heappush(self.state, [0, duration, capNeed, 0, clipSize])
|
||||
|
||||
|
||||
if disable_period:
|
||||
self.period = self.t_max
|
||||
else:
|
||||
self.period = period
|
||||
|
||||
|
||||
def run(self):
|
||||
"""Run the simulation"""
|
||||
|
||||
@@ -135,13 +132,13 @@ class CapSimulator(object):
|
||||
capCapacity = self.capacitorCapacity
|
||||
tau = self.capacitorRecharge / 5.0
|
||||
|
||||
cap_wrap = capCapacity # cap value at last period
|
||||
cap_lowest = capCapacity # lowest cap value encountered
|
||||
cap_lowest_pre = capCapacity # lowest cap value before activations
|
||||
cap = capCapacity # current cap value
|
||||
t_wrap = self.period # point in time of next period
|
||||
cap_wrap = capCapacity # cap value at last period
|
||||
cap_lowest = capCapacity # lowest cap value encountered
|
||||
cap_lowest_pre = capCapacity # lowest cap value before activations
|
||||
cap = capCapacity # current cap value
|
||||
t_wrap = self.period # point in time of next period
|
||||
|
||||
t_now = t_last = 0
|
||||
t_last = 0
|
||||
t_max = self.t_max
|
||||
|
||||
while 1:
|
||||
@@ -150,7 +147,7 @@ class CapSimulator(object):
|
||||
if t_now >= t_max:
|
||||
break
|
||||
|
||||
cap = ((1.0+(sqrt(cap/capCapacity)-1.0)*exp((t_last-t_now)/tau))**2)*capCapacity
|
||||
cap = ((1.0 + (sqrt(cap / capCapacity) - 1.0) * exp((t_last - t_now) / tau)) ** 2) * capCapacity
|
||||
|
||||
if t_now != t_last:
|
||||
if cap < cap_lowest_pre:
|
||||
@@ -182,7 +179,7 @@ class CapSimulator(object):
|
||||
if clipSize:
|
||||
if shot % clipSize == 0:
|
||||
shot = 0
|
||||
t_now += 10000 # include reload time
|
||||
t_now += 10000 # include reload time
|
||||
activation[0] = t_now
|
||||
activation[3] = shot
|
||||
|
||||
@@ -195,19 +192,17 @@ class CapSimulator(object):
|
||||
|
||||
# calculate EVE's stability value
|
||||
try:
|
||||
avgDrain = reduce(float.__add__, map(lambda x: x[2]/x[1], self.state), 0.0)
|
||||
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity)/capCapacity)) ** 2
|
||||
avgDrain = reduce(float.__add__, map(lambda x: x[2] / x[1], self.state), 0.0)
|
||||
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity) / capCapacity)) ** 2
|
||||
except ValueError:
|
||||
self.cap_stable_eve = 0.0
|
||||
|
||||
|
||||
if cap > 0.0:
|
||||
# capacitor low/high water marks
|
||||
self.cap_stable_low = cap_lowest
|
||||
self.cap_stable_high = cap_lowest_pre
|
||||
else:
|
||||
self.cap_stable_low =\
|
||||
self.cap_stable_high = 0.0
|
||||
self.cap_stable_low = \
|
||||
self.cap_stable_high = 0.0
|
||||
|
||||
|
||||
self.runtime = time.time()-start
|
||||
self.runtime = time.time() - start
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
from os.path import realpath, join, dirname, abspath
|
||||
import sys
|
||||
from os.path import realpath, join, dirname, abspath
|
||||
|
||||
debug = False
|
||||
gamedataCache = True
|
||||
saveddataCache = True
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
gamedata_version = ""
|
||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")),
|
||||
sys.getfilesystemencoding())
|
||||
saveddata_connectionstring = 'sqlite:///' + unicode(
|
||||
realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
||||
|
||||
#Autodetect path, only change if the autodetection bugs out.
|
||||
|
||||
# Autodetect path, only change if the autodetection bugs out.
|
||||
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
import threading
|
||||
|
||||
@@ -24,17 +24,20 @@ from sqlalchemy.orm import sessionmaker, scoped_session
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import pool
|
||||
|
||||
from eos import config
|
||||
|
||||
import migration
|
||||
from eos import config
|
||||
|
||||
|
||||
class ReadOnlyException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
gamedata_connectionstring = config.gamedata_connectionstring
|
||||
if callable(gamedata_connectionstring):
|
||||
gamedata_engine = create_engine("sqlite://", creator=gamedata_connectionstring, echo = config.debug)
|
||||
gamedata_engine = create_engine("sqlite://", creator=gamedata_connectionstring, echo=config.debug)
|
||||
else:
|
||||
gamedata_engine = create_engine(gamedata_connectionstring, echo = config.debug)
|
||||
gamedata_engine = create_engine(gamedata_connectionstring, echo=config.debug)
|
||||
|
||||
gamedata_meta = MetaData()
|
||||
gamedata_meta.bind = gamedata_engine
|
||||
@@ -44,8 +47,8 @@ gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on
|
||||
# game db because we haven't reached gamedata_meta.create_all()
|
||||
try:
|
||||
config.gamedata_version = gamedata_session.execute(
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||
).fetchone()[0]
|
||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||
).fetchone()[0]
|
||||
except:
|
||||
config.gamedata_version = None
|
||||
|
||||
@@ -63,19 +66,19 @@ if saveddata_connectionstring is not None:
|
||||
# Lock controlling any changes introduced to session
|
||||
sd_lock = threading.Lock()
|
||||
|
||||
#Import all the definitions for all our database stuff
|
||||
# Import all the definitions for all our database stuff
|
||||
from eos.db.gamedata import *
|
||||
from eos.db.saveddata import *
|
||||
|
||||
#Import queries
|
||||
# Import queries
|
||||
from eos.db.gamedata.queries import *
|
||||
from eos.db.saveddata.queries import *
|
||||
|
||||
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||
# If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||
if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||
saveddata_meta.create_all()
|
||||
|
||||
|
||||
def rollback():
|
||||
with sd_lock:
|
||||
saveddata_session.rollback()
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
__all__ = ["attribute", "category", "effect", "group", "metaData",
|
||||
"icon", "item", "marketGroup", "metaGroup", "unit"]
|
||||
"icon", "item", "marketGroup", "metaGroup", "unit", "alphaClones"]
|
||||
|
||||
46
eos/db/gamedata/alphaClones.py
Normal file
46
eos/db/gamedata/alphaClones.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Table, ForeignKey
|
||||
from sqlalchemy.orm import relation, mapper, synonym
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import AlphaClone, AlphaCloneSkill
|
||||
|
||||
alphaclones_table = Table("alphaClones", gamedata_meta,
|
||||
Column("alphaCloneID", Integer, primary_key=True),
|
||||
Column("alphaCloneName", String),
|
||||
)
|
||||
|
||||
alphacloneskskills_table = Table("alphaCloneSkills", gamedata_meta,
|
||||
Column("alphaCloneID", Integer, ForeignKey("alphaClones.alphaCloneID"), primary_key=True),
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("level", Integer),
|
||||
)
|
||||
|
||||
mapper(AlphaClone, alphaclones_table,
|
||||
properties={
|
||||
"ID": synonym("alphaCloneID"),
|
||||
"skills": relation(
|
||||
AlphaCloneSkill,
|
||||
cascade="all,delete-orphan",
|
||||
backref="clone")
|
||||
})
|
||||
|
||||
mapper(AlphaCloneSkill, alphacloneskskills_table)
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,20 +15,22 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, Unicode, ForeignKey, String, Boolean
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from eos.types import Attribute, Icon, AttributeInfo, Unit
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import Attribute, Icon, AttributeInfo, Unit
|
||||
|
||||
typeattributes_table = Table("dgmtypeattribs", gamedata_meta,
|
||||
Column("value", Float),
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True))
|
||||
Column("value", Float),
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True))
|
||||
|
||||
attributes_table = Table("dgmattribs", gamedata_meta,
|
||||
Column("attributeID", Integer, primary_key = True),
|
||||
Column("attributeID", Integer, primary_key=True),
|
||||
Column("attributeName", String),
|
||||
Column("defaultValue", Float),
|
||||
Column("maxAttributeID", Integer, ForeignKey("dgmattribs.attributeID")),
|
||||
@@ -40,14 +42,14 @@ attributes_table = Table("dgmattribs", gamedata_meta,
|
||||
Column("unitID", Integer, ForeignKey("dgmunits.unitID")))
|
||||
|
||||
mapper(Attribute, typeattributes_table,
|
||||
properties = {"info": relation(AttributeInfo, lazy=False)})
|
||||
properties={"info": relation(AttributeInfo, lazy=False)})
|
||||
|
||||
mapper(AttributeInfo, attributes_table,
|
||||
properties = {"icon" : relation(Icon),
|
||||
"unit": relation(Unit),
|
||||
"ID": synonym("attributeID"),
|
||||
"name": synonym("attributeName"),
|
||||
"description" : deferred(attributes_table.c.description)})
|
||||
properties={"icon": relation(Icon),
|
||||
"unit": relation(Unit),
|
||||
"ID": synonym("attributeID"),
|
||||
"name": synonym("attributeName"),
|
||||
"description": deferred(attributes_table.c.description)})
|
||||
|
||||
Attribute.ID = association_proxy("info", "attributeID")
|
||||
Attribute.name = association_proxy("info", "attributeName")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
@@ -24,14 +24,14 @@ from eos.db import gamedata_meta
|
||||
from eos.types import Category, Icon
|
||||
|
||||
categories_table = Table("invcategories", gamedata_meta,
|
||||
Column("categoryID", Integer, primary_key = True),
|
||||
Column("categoryID", Integer, primary_key=True),
|
||||
Column("categoryName", String),
|
||||
Column("description", String),
|
||||
Column("published", Boolean),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
|
||||
mapper(Category, categories_table,
|
||||
properties = {"icon" : relation(Icon),
|
||||
"ID" : synonym("categoryID"),
|
||||
"name" : synonym("categoryName"),
|
||||
"description" : deferred(categories_table.c.description)})
|
||||
properties={"icon": relation(Icon),
|
||||
"ID": synonym("categoryID"),
|
||||
"name": synonym("categoryName"),
|
||||
"description": deferred(categories_table.c.description)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,35 +15,35 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, Table, ForeignKey
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import mapper, synonym, relation, deferred
|
||||
from eos.types import Effect, EffectInfo
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import Effect, EffectInfo
|
||||
|
||||
typeeffects_table = Table("dgmtypeeffects", gamedata_meta,
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||
Column("effectID", Integer, ForeignKey("dgmeffects.effectID"), primary_key=True))
|
||||
|
||||
effects_table = Table("dgmeffects", gamedata_meta,
|
||||
Column("effectID", Integer, primary_key = True),
|
||||
Column("effectID", Integer, primary_key=True),
|
||||
Column("effectName", String),
|
||||
Column("description", String),
|
||||
Column("published", Boolean),
|
||||
Column("isAssistance", Boolean),
|
||||
Column("isOffensive", Boolean))
|
||||
|
||||
|
||||
mapper(EffectInfo, effects_table,
|
||||
properties = {"ID" : synonym("effectID"),
|
||||
"name" : synonym("effectName"),
|
||||
"description" : deferred(effects_table.c.description)})
|
||||
properties={"ID": synonym("effectID"),
|
||||
"name": synonym("effectName"),
|
||||
"description": deferred(effects_table.c.description)})
|
||||
|
||||
mapper(Effect, typeeffects_table,
|
||||
properties = {"ID": synonym("effectID"),
|
||||
"info": relation(EffectInfo, lazy=False)})
|
||||
properties={"ID": synonym("effectID"),
|
||||
"info": relation(EffectInfo, lazy=False)})
|
||||
|
||||
Effect.name = association_proxy("info", "name")
|
||||
Effect.description = association_proxy("info", "description")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
@@ -24,7 +24,7 @@ from eos.db import gamedata_meta
|
||||
from eos.types import Group, Icon, Category
|
||||
|
||||
groups_table = Table("invgroups", gamedata_meta,
|
||||
Column("groupID", Integer, primary_key = True),
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
Column("groupName", String),
|
||||
Column("description", String),
|
||||
Column("published", Boolean),
|
||||
@@ -32,8 +32,8 @@ groups_table = Table("invgroups", gamedata_meta,
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
|
||||
mapper(Group, groups_table,
|
||||
properties = {"category" : relation(Category, backref = "groups"),
|
||||
"icon" : relation(Icon),
|
||||
"ID" : synonym("groupID"),
|
||||
"name" : synonym("groupName"),
|
||||
"description" : deferred(groups_table.c.description)})
|
||||
properties={"category": relation(Category, backref="groups"),
|
||||
"icon": relation(Icon),
|
||||
"ID": synonym("groupID"),
|
||||
"name": synonym("groupName"),
|
||||
"description": deferred(groups_table.c.description)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Table
|
||||
from sqlalchemy.orm import mapper, synonym, deferred
|
||||
@@ -24,10 +24,10 @@ from eos.db import gamedata_meta
|
||||
from eos.types import Icon
|
||||
|
||||
icons_table = Table("icons", gamedata_meta,
|
||||
Column("iconID", Integer, primary_key = True),
|
||||
Column("iconID", Integer, primary_key=True),
|
||||
Column("description", String),
|
||||
Column("iconFile", String))
|
||||
|
||||
mapper(Icon, icons_table,
|
||||
properties = {"ID" : synonym("iconID"),
|
||||
"description" : deferred(icons_table.c.description)})
|
||||
properties={"ID": synonym("iconID"),
|
||||
"description": deferred(icons_table.c.description)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,18 +15,18 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import Icon, Attribute, Item, Effect, MetaType, Group, Traits
|
||||
|
||||
items_table = Table("invtypes", gamedata_meta,
|
||||
Column("typeID", Integer, primary_key = True),
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("typeName", String, index=True),
|
||||
Column("description", String),
|
||||
Column("raceID", Integer),
|
||||
@@ -39,23 +39,23 @@ items_table = Table("invtypes", gamedata_meta,
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")),
|
||||
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
|
||||
|
||||
from .metaGroup import metatypes_table
|
||||
from .traits import traits_table
|
||||
from .metaGroup import metatypes_table # noqa
|
||||
from .traits import traits_table # noqa
|
||||
|
||||
mapper(Item, items_table,
|
||||
properties = {"group" : relation(Group, backref = "items"),
|
||||
"icon" : relation(Icon),
|
||||
"_Item__attributes" : relation(Attribute, collection_class = attribute_mapped_collection('name')),
|
||||
"effects" : relation(Effect, collection_class = attribute_mapped_collection('name')),
|
||||
"metaGroup" : relation(MetaType,
|
||||
primaryjoin = metatypes_table.c.typeID == items_table.c.typeID,
|
||||
uselist = False),
|
||||
"ID" : synonym("typeID"),
|
||||
"name" : synonym("typeName"),
|
||||
"description" : deferred(items_table.c.description),
|
||||
"traits" : relation(Traits,
|
||||
primaryjoin = traits_table.c.typeID == items_table.c.typeID,
|
||||
uselist = False)
|
||||
})
|
||||
properties={"group": relation(Group, backref="items"),
|
||||
"icon": relation(Icon),
|
||||
"_Item__attributes": relation(Attribute, collection_class=attribute_mapped_collection('name')),
|
||||
"effects": relation(Effect, collection_class=attribute_mapped_collection('name')),
|
||||
"metaGroup": relation(MetaType,
|
||||
primaryjoin=metatypes_table.c.typeID == items_table.c.typeID,
|
||||
uselist=False),
|
||||
"ID": synonym("typeID"),
|
||||
"name": synonym("typeName"),
|
||||
"description": deferred(items_table.c.description),
|
||||
"traits": relation(Traits,
|
||||
primaryjoin=traits_table.c.typeID == items_table.c.typeID,
|
||||
uselist=False)
|
||||
})
|
||||
|
||||
Item.category = association_proxy("group", "category")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||
@@ -24,17 +24,19 @@ from eos.db import gamedata_meta
|
||||
from eos.types import Item, MarketGroup, Icon
|
||||
|
||||
marketgroups_table = Table("invmarketgroups", gamedata_meta,
|
||||
Column("marketGroupID", Integer, primary_key = True),
|
||||
Column("marketGroupID", Integer, primary_key=True),
|
||||
Column("marketGroupName", String),
|
||||
Column("description", String),
|
||||
Column("hasTypes", Boolean),
|
||||
Column("parentGroupID", Integer, ForeignKey("invmarketgroups.marketGroupID", initially="DEFERRED", deferrable=True)),
|
||||
Column("parentGroupID", Integer,
|
||||
ForeignKey("invmarketgroups.marketGroupID", initially="DEFERRED", deferrable=True)),
|
||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||
|
||||
mapper(MarketGroup, marketgroups_table,
|
||||
properties = {"items" : relation(Item, backref = "marketGroup"),
|
||||
"parent" : relation(MarketGroup, backref = "children", remote_side = [marketgroups_table.c.marketGroupID]),
|
||||
"icon" : relation(Icon),
|
||||
"ID" : synonym("marketGroupID"),
|
||||
"name" : synonym("marketGroupName"),
|
||||
"description" : deferred(marketgroups_table.c.description)})
|
||||
properties={"items": relation(Item, backref="marketGroup"),
|
||||
"parent": relation(MarketGroup, backref="children",
|
||||
remote_side=[marketgroups_table.c.marketGroupID]),
|
||||
"icon": relation(Icon),
|
||||
"ID": synonym("marketGroupID"),
|
||||
"name": synonym("marketGroupName"),
|
||||
"description": deferred(marketgroups_table.c.description)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,16 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, Table, String
|
||||
from sqlalchemy.orm import mapper
|
||||
from eos.types import MetaData
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import MetaData
|
||||
|
||||
metadata_table = Table("metadata", gamedata_meta,
|
||||
Column("field_name", String, primary_key=True),
|
||||
Column("field_value", String))
|
||||
Column("field_name", String, primary_key=True),
|
||||
Column("field_value", String))
|
||||
|
||||
mapper(MetaData, metadata_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,33 +15,33 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import relation, mapper, synonym
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.db.gamedata.item import items_table
|
||||
from eos.types import MetaGroup, Item, MetaType
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
|
||||
metagroups_table = Table("invmetagroups", gamedata_meta,
|
||||
Column("metaGroupID", Integer, primary_key = True),
|
||||
Column("metaGroupID", Integer, primary_key=True),
|
||||
Column("metaGroupName", String))
|
||||
|
||||
metatypes_table = Table("invmetatypes", gamedata_meta,
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key = True),
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True),
|
||||
Column("parentTypeID", Integer, ForeignKey("invtypes.typeID")),
|
||||
Column("metaGroupID", Integer, ForeignKey("invmetagroups.metaGroupID")))
|
||||
|
||||
mapper(MetaGroup, metagroups_table,
|
||||
properties = {"ID" : synonym("metaGroupID"),
|
||||
"name" : synonym("metaGroupName")})
|
||||
properties={"ID": synonym("metaGroupID"),
|
||||
"name": synonym("metaGroupName")})
|
||||
|
||||
mapper(MetaType, metatypes_table,
|
||||
properties = {"ID" : synonym("metaGroupID"),
|
||||
"parent" : relation(Item, primaryjoin = metatypes_table.c.parentTypeID == items_table.c.typeID),
|
||||
"items" : relation(Item, primaryjoin = metatypes_table.c.typeID == items_table.c.typeID),
|
||||
"info": relation(MetaGroup, lazy=False)})
|
||||
properties={"ID": synonym("metaGroupID"),
|
||||
"parent": relation(Item, primaryjoin=metatypes_table.c.parentTypeID == items_table.c.typeID),
|
||||
"items": relation(Item, primaryjoin=metatypes_table.c.typeID == items_table.c.typeID),
|
||||
"info": relation(MetaGroup, lazy=False)})
|
||||
|
||||
MetaType.name = association_proxy("info", "name")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,21 +15,26 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.orm import join, exc
|
||||
from sqlalchemy.sql import and_, or_, select
|
||||
|
||||
import eos.config
|
||||
# TODO: Unsure which item the code below needs :(
|
||||
# from eos.gamedata import Item
|
||||
from eos.gamedata import Attribute
|
||||
from eos.db import gamedata_session
|
||||
from eos.db.gamedata.metaGroup import metatypes_table, items_table
|
||||
from sqlalchemy.sql import and_, or_, select, func
|
||||
from sqlalchemy.orm import join, exc
|
||||
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup
|
||||
from eos.db.util import processEager, processWhere
|
||||
import eos.config
|
||||
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup, AlphaClone
|
||||
|
||||
configVal = getattr(eos.config, "gamedataCache", None)
|
||||
if configVal is True:
|
||||
def cachedQuery(amount, *keywords):
|
||||
def deco(function):
|
||||
cache = {}
|
||||
|
||||
def checkAndReturn(*args, **kwargs):
|
||||
useCache = kwargs.pop("useCache", True)
|
||||
cacheKey = []
|
||||
@@ -45,6 +50,7 @@ if configVal is True:
|
||||
return handler
|
||||
|
||||
return checkAndReturn
|
||||
|
||||
return deco
|
||||
|
||||
elif callable(configVal):
|
||||
@@ -56,8 +62,10 @@ else:
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return checkAndReturn
|
||||
|
||||
return deco
|
||||
|
||||
|
||||
def sqlizeString(line):
|
||||
# Escape backslashes first, as they will be as escape symbol in queries
|
||||
# Then escape percent and underscore signs
|
||||
@@ -65,7 +73,10 @@ def sqlizeString(line):
|
||||
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
||||
return line
|
||||
|
||||
|
||||
itemNameMap = {}
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getItem(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -88,7 +99,28 @@ def getItem(lookfor, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return item
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getAlphaClone(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
item = gamedata_session.query(AlphaClone).get(lookfor)
|
||||
else:
|
||||
item = gamedata_session.query(AlphaClone).options(*processEager(eager)).filter(AlphaClone.ID == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return item
|
||||
|
||||
|
||||
def getAlphaCloneList(eager=None):
|
||||
eager = processEager(eager)
|
||||
clones = gamedata_session.query(AlphaClone).options(*eager).all()
|
||||
return clones
|
||||
|
||||
|
||||
groupNameMap = {}
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getGroup(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -111,63 +143,78 @@ def getGroup(lookfor, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return group
|
||||
|
||||
|
||||
categoryNameMap = {}
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getCategory(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
category = gamedata_session.query(Category).get(lookfor)
|
||||
else:
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.ID == lookfor).first()
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
|
||||
Category.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
if lookfor in categoryNameMap:
|
||||
id = categoryNameMap[lookfor]
|
||||
if eager is None:
|
||||
category = gamedata_session.query(Category).get(id)
|
||||
else:
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.ID == id).first()
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
|
||||
Category.ID == id).first()
|
||||
else:
|
||||
# Category names are unique, so we can use first() instead of one()
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.name == lookfor).first()
|
||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
|
||||
Category.name == lookfor).first()
|
||||
categoryNameMap[lookfor] = category.ID
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return category
|
||||
|
||||
|
||||
metaGroupNameMap = {}
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getMetaGroup(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
metaGroup = gamedata_session.query(MetaGroup).get(lookfor)
|
||||
else:
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.ID == lookfor).first()
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
|
||||
MetaGroup.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
if lookfor in metaGroupNameMap:
|
||||
id = metaGroupNameMap[lookfor]
|
||||
if eager is None:
|
||||
metaGroup = gamedata_session.query(MetaGroup).get(id)
|
||||
else:
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.ID == id).first()
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
|
||||
MetaGroup.ID == id).first()
|
||||
else:
|
||||
# MetaGroup names are unique, so we can use first() instead of one()
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.name == lookfor).first()
|
||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
|
||||
MetaGroup.name == lookfor).first()
|
||||
metaGroupNameMap[lookfor] = metaGroup.ID
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return metaGroup
|
||||
|
||||
|
||||
@cachedQuery(1, "lookfor")
|
||||
def getMarketGroup(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
if eager is None:
|
||||
marketGroup = gamedata_session.query(MarketGroup).get(lookfor)
|
||||
else:
|
||||
marketGroup = gamedata_session.query(MarketGroup).options(*processEager(eager)).filter(MarketGroup.ID == lookfor).first()
|
||||
marketGroup = gamedata_session.query(MarketGroup).options(*processEager(eager)).filter(
|
||||
MarketGroup.ID == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return marketGroup
|
||||
|
||||
|
||||
@cachedQuery(2, "where", "filter")
|
||||
def getItemsByCategory(filter, where=None, eager=None):
|
||||
if isinstance(filter, int):
|
||||
@@ -178,7 +225,9 @@ def getItemsByCategory(filter, where=None, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
|
||||
filter = processWhere(filter, where)
|
||||
return gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category).filter(filter).all()
|
||||
return gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category).filter(
|
||||
filter).all()
|
||||
|
||||
|
||||
@cachedQuery(3, "where", "nameLike", "join")
|
||||
def searchItems(nameLike, where=None, join=None, eager=None):
|
||||
@@ -194,10 +243,14 @@ def searchItems(nameLike, where=None, join=None, eager=None):
|
||||
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
|
||||
for token in nameLike.split(' '):
|
||||
token_safe = u"%{0}%".format(sqlizeString(token))
|
||||
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
|
||||
if where is not None:
|
||||
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), where))
|
||||
else:
|
||||
items = items.filter(Item.name.like(token_safe, escape="\\"))
|
||||
items = items.limit(100).all()
|
||||
return items
|
||||
|
||||
|
||||
@cachedQuery(2, "where", "itemids")
|
||||
def getVariations(itemids, where=None, eager=None):
|
||||
for itemid in itemids:
|
||||
@@ -210,9 +263,11 @@ def getVariations(itemids, where=None, eager=None):
|
||||
itemfilter = or_(*(metatypes_table.c.parentTypeID == itemid for itemid in itemids))
|
||||
filter = processWhere(itemfilter, where)
|
||||
joinon = items_table.c.typeID == metatypes_table.c.typeID
|
||||
vars = gamedata_session.query(Item).options(*processEager(eager)).join((metatypes_table, joinon)).filter(filter).all()
|
||||
vars = gamedata_session.query(Item).options(*processEager(eager)).join((metatypes_table, joinon)).filter(
|
||||
filter).all()
|
||||
return vars
|
||||
|
||||
|
||||
@cachedQuery(1, "attr")
|
||||
def getAttributeInfo(attr, eager=None):
|
||||
if isinstance(attr, basestring):
|
||||
@@ -227,6 +282,7 @@ def getAttributeInfo(attr, eager=None):
|
||||
result = None
|
||||
return result
|
||||
|
||||
|
||||
@cachedQuery(1, "field")
|
||||
def getMetaData(field):
|
||||
if isinstance(field, basestring):
|
||||
@@ -235,6 +291,7 @@ def getMetaData(field):
|
||||
raise TypeError("Need string as argument")
|
||||
return data
|
||||
|
||||
|
||||
@cachedQuery(2, "itemIDs", "attributeID")
|
||||
def directAttributeRequest(itemIDs, attrIDs):
|
||||
for itemID in itemIDs:
|
||||
@@ -244,9 +301,9 @@ def directAttributeRequest(itemIDs, attrIDs):
|
||||
if not isinstance(itemID, int):
|
||||
raise TypeError("All itemIDs must be integer")
|
||||
|
||||
q = select((eos.types.Item.typeID, eos.types.Attribute.attributeID, eos.types.Attribute.value),
|
||||
and_(eos.types.Attribute.attributeID.in_(attrIDs), eos.types.Item.typeID.in_(itemIDs)),
|
||||
from_obj=[join(eos.types.Attribute, eos.types.Item)])
|
||||
q = select((Item.typeID, Attribute.attributeID, Attribute.value),
|
||||
and_(Attribute.attributeID.in_(attrIDs), Item.typeID.in_(itemIDs)),
|
||||
from_obj=[join(Attribute, Item)])
|
||||
|
||||
result = gamedata_session.execute(q).fetchall()
|
||||
return result
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
from sqlalchemy import Column, Table, Integer, String, ForeignKey
|
||||
from sqlalchemy.orm import mapper
|
||||
from eos.types import Traits
|
||||
|
||||
from eos.db import gamedata_meta
|
||||
from eos.types import Traits
|
||||
|
||||
traits_table = Table("invtraits", gamedata_meta,
|
||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True),
|
||||
Column("traitText", String))
|
||||
|
||||
mapper(Traits, traits_table);
|
||||
mapper(Traits, traits_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, Table, Integer, String
|
||||
from sqlalchemy.orm import mapper, synonym
|
||||
@@ -24,10 +24,10 @@ from eos.db import gamedata_meta
|
||||
from eos.types import Unit
|
||||
|
||||
groups_table = Table("dgmunits", gamedata_meta,
|
||||
Column("unitID", Integer, primary_key = True),
|
||||
Column("unitID", Integer, primary_key=True),
|
||||
Column("unitName", String),
|
||||
Column("displayName", String))
|
||||
|
||||
mapper(Unit, groups_table,
|
||||
properties = {"ID" : synonym("unitID"),
|
||||
"name" : synonym("unitName")})
|
||||
properties={"ID": synonym("unitID"),
|
||||
"name": synonym("unitName")})
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import config
|
||||
import logging
|
||||
import shutil
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
|
||||
import config
|
||||
import migrations
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getVersion(db):
|
||||
cursor = db.execute('PRAGMA user_version')
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
|
||||
def getAppVersion():
|
||||
return migrations.appVersion
|
||||
|
||||
|
||||
def update(saveddata_engine):
|
||||
dbVersion = getVersion(saveddata_engine)
|
||||
appVersion = getAppVersion()
|
||||
@@ -24,7 +26,7 @@ def update(saveddata_engine):
|
||||
|
||||
if dbVersion < appVersion:
|
||||
# Automatically backup database
|
||||
toFile = "%s/saveddata_migration_%d-%d_%s.db"%(
|
||||
toFile = "%s/saveddata_migration_%d-%d_%s.db" % (
|
||||
config.savePath,
|
||||
dbVersion,
|
||||
appVersion,
|
||||
@@ -33,9 +35,9 @@ def update(saveddata_engine):
|
||||
shutil.copyfile(config.saveDB, toFile)
|
||||
|
||||
for version in xrange(dbVersion, appVersion):
|
||||
func = migrations.updates[version+1]
|
||||
func = migrations.updates[version + 1]
|
||||
if func:
|
||||
logger.info("Applying database update: %d", version+1)
|
||||
logger.info("Applying database update: %d", version + 1)
|
||||
func(saveddata_engine)
|
||||
|
||||
# when all is said and done, set version to current
|
||||
|
||||
@@ -11,7 +11,6 @@ upgrade files 1-5)
|
||||
import pkgutil
|
||||
import re
|
||||
|
||||
|
||||
updates = {}
|
||||
appVersion = 0
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ CONVERSIONS = {
|
||||
8746, # Quantum Co-Processor
|
||||
8745, # Photonic CPU Enhancer
|
||||
15425, # Naiyon's Modified Co-Processor (never existed but convert
|
||||
# anyway as some fits may include it)
|
||||
# anyway as some fits may include it)
|
||||
],
|
||||
8748: [ # Upgraded Co-Processor
|
||||
8747, # Nanomechanical CPU Enhancer I
|
||||
@@ -70,7 +70,7 @@ CONVERSIONS = {
|
||||
16543, # Micro 'Vigor' Core Augmentation
|
||||
],
|
||||
8089: [ # Compact Light Missile Launcher
|
||||
8093, # Prototype 'Arbalest' Light Missile Launcher
|
||||
8093, # Prototype 'Arbalest' Light Missile Launcher
|
||||
],
|
||||
8091: [ # Ample Light Missile Launcher
|
||||
7993, # Experimental TE-2100 Light Missile Launcher
|
||||
@@ -82,6 +82,7 @@ CONVERSIONS = {
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update fits schema to include target resists attribute
|
||||
try:
|
||||
@@ -92,6 +93,7 @@ def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -6,6 +6,7 @@ Migration 10
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update projectedFits schema to include active attribute
|
||||
try:
|
||||
|
||||
@@ -7,7 +7,6 @@ Migration 11
|
||||
modules with their new replacements
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
16467: ( # Medium Gremlin Compact Energy Neutralizer
|
||||
16471, # Medium Unstable Power Fluctuator I
|
||||
@@ -106,11 +105,12 @@ CONVERSIONS = {
|
||||
),
|
||||
}
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -7,7 +7,6 @@ Migration 12
|
||||
modules with their new replacements
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
16457: ( # Crosslink Compact Ballistic Control System
|
||||
16459, # Muon Coil Bolt Array I
|
||||
@@ -330,11 +329,12 @@ CONVERSIONS = {
|
||||
),
|
||||
}
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -6,10 +6,11 @@ Migration 13
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update fits schema to include implant location attribute
|
||||
try:
|
||||
saveddata_engine.execute("SELECT implantLocation FROM fits LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN implantLocation INTEGER;")
|
||||
saveddata_engine.execute("UPDATE fits SET implantLocation = 0")
|
||||
saveddata_engine.execute("UPDATE fits SET implantLocation = 0")
|
||||
|
||||
@@ -6,8 +6,10 @@ Migration 14
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
if saveddata_engine.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='fighters'").scalar() == 'fighters':
|
||||
if saveddata_engine.execute(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='fighters'").scalar() == 'fighters':
|
||||
# Fighters table exists
|
||||
try:
|
||||
saveddata_engine.execute("SELECT active FROM fighters LIMIT 1")
|
||||
@@ -16,4 +18,4 @@ def upgrade(saveddata_engine):
|
||||
# (they will be recreated)
|
||||
|
||||
saveddata_engine.execute("DROP TABLE fighters")
|
||||
saveddata_engine.execute("DROP TABLE fightersAbilities")
|
||||
saveddata_engine.execute("DROP TABLE fightersAbilities")
|
||||
|
||||
21
eos/db/migrations/upgrade15.py
Normal file
21
eos/db/migrations/upgrade15.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
Migration 15
|
||||
|
||||
- Delete projected modules on citadels
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
sql = """
|
||||
DELETE FROM modules WHERE ID IN
|
||||
(
|
||||
SELECT m.ID FROM modules AS m
|
||||
JOIN fits AS f ON m.fitID = f.ID
|
||||
WHERE f.shipID IN ("35832", "35833", "35834", "40340")
|
||||
AND m.projected = 1
|
||||
)
|
||||
"""
|
||||
|
||||
saveddata_engine.execute(sql)
|
||||
15
eos/db/migrations/upgrade16.py
Normal file
15
eos/db/migrations/upgrade16.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Migration 16
|
||||
|
||||
- Alters fits table to introduce notes attribute
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update fits schema to include notes attribute
|
||||
try:
|
||||
saveddata_engine.execute("SELECT notes FROM fits LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN notes VARCHAR;")
|
||||
40
eos/db/migrations/upgrade17.py
Normal file
40
eos/db/migrations/upgrade17.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""
|
||||
Migration 17
|
||||
|
||||
- Moves all fleet boosters to the new schema
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
from eos.db import saveddata_session
|
||||
from eos.db.saveddata.fit import commandFits_table
|
||||
|
||||
sql = """
|
||||
SELECT sm.memberID as boostedFit, s.leaderID AS squadBoost, w.leaderID AS wingBoost, g.leaderID AS gangBoost
|
||||
FROM squadmembers sm
|
||||
JOIN squads s ON s.ID = sm.squadID
|
||||
JOIN wings w on w.ID = s.wingID
|
||||
JOIN gangs g on g.ID = w.gangID
|
||||
"""
|
||||
|
||||
results = saveddata_session.execute(sql)
|
||||
|
||||
inserts = []
|
||||
|
||||
for row in results:
|
||||
boosted = row["boostedFit"]
|
||||
types = ("squad", "wing", "gang")
|
||||
for x in types:
|
||||
value = row["{}Boost".format(x)]
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
inserts.append({"boosterID": value, "boostedID": boosted, "active": 1})
|
||||
try:
|
||||
saveddata_session.execute(commandFits_table.insert(),
|
||||
{"boosterID": value, "boostedID": boosted, "active": 1})
|
||||
except Exception:
|
||||
pass
|
||||
saveddata_session.commit()
|
||||
68
eos/db/migrations/upgrade18.py
Normal file
68
eos/db/migrations/upgrade18.py
Normal file
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Migration 8
|
||||
|
||||
- Converts modules from old Warfare Links to Command Modules
|
||||
"""
|
||||
|
||||
CONVERSIONS = {
|
||||
42526: ( # Armor Command Burst I
|
||||
20069, # Armored Warfare Link - Damage Control I
|
||||
20409, # Armored Warfare Link - Passive Defense I
|
||||
22227, # Armored Warfare Link - Rapid Repair I
|
||||
),
|
||||
43552: ( # Armor Command Burst II
|
||||
4264, # Armored Warfare Link - Damage Control II
|
||||
4266, # Armored Warfare Link - Passive Defense II
|
||||
4266, # Armored Warfare Link - Rapid Repair II
|
||||
),
|
||||
42527: ( # Information Command Burst I
|
||||
11052, # Information Warfare Link - Sensor Integrity I
|
||||
20405, # Information Warfare Link - Recon Operation I
|
||||
20406, # Information Warfare Link - Electronic Superiority I
|
||||
),
|
||||
43554: ( # Information Command Burst II
|
||||
4268, # Information Warfare Link - Electronic Superiority II
|
||||
4270, # Information Warfare Link - Recon Operation II
|
||||
4272, # Information Warfare Link - Sensor Integrity II
|
||||
),
|
||||
42529: ( # Shield Command Burst I
|
||||
20124, # Siege Warfare Link - Active Shielding I
|
||||
20514, # Siege Warfare Link - Shield Harmonizing I
|
||||
22228, # Siege Warfare Link - Shield Efficiency I
|
||||
),
|
||||
43555: ( # Shield Command Burst II
|
||||
4280, # Siege Warfare Link - Active Shielding II
|
||||
4282, # Siege Warfare Link - Shield Efficiency II
|
||||
4284 # Siege Warfare Link - Shield Harmonizing II
|
||||
),
|
||||
42530: ( # Skirmish Command Burst I
|
||||
11017, # Skirmish Warfare Link - Interdiction Maneuvers I
|
||||
20070, # Skirmish Warfare Link - Evasive Maneuvers I
|
||||
20408, # Skirmish Warfare Link - Rapid Deployment I
|
||||
),
|
||||
43556: ( # Skirmish Command Burst II
|
||||
4286, # Skirmish Warfare Link - Evasive Maneuvers II
|
||||
4288, # Skirmish Warfare Link - Interdiction Maneuvers II
|
||||
4290 # Skirmish Warfare Link - Rapid Deployment II
|
||||
),
|
||||
42528: ( # Mining Foreman Burst I
|
||||
22553, # Mining Foreman Link - Harvester Capacitor Efficiency I
|
||||
22555, # Mining Foreman Link - Mining Laser Field Enhancement I
|
||||
22557, # Mining Foreman Link - Laser Optimization I
|
||||
),
|
||||
43551: ( # Mining Foreman Burst II
|
||||
4274, # Mining Foreman Link - Harvester Capacitor Efficiency II
|
||||
4276, # Mining Foreman Link - Laser Optimization II
|
||||
4278 # Mining Foreman Link - Mining Laser Field Enhancement II
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
20
eos/db/migrations/upgrade19.py
Normal file
20
eos/db/migrations/upgrade19.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""
|
||||
Migration 19
|
||||
|
||||
- Deletes broken references to fits from the commandFits table (see GH issue #844)
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
from eos.db import saveddata_session
|
||||
|
||||
sql = """
|
||||
DELETE FROM commandFits
|
||||
WHERE boosterID NOT IN (select ID from fits)
|
||||
OR boostedID NOT IN (select ID from fits)
|
||||
"""
|
||||
|
||||
saveddata_session.execute(sql)
|
||||
saveddata_session.commit()
|
||||
@@ -6,6 +6,7 @@ Migration 2
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update characters schema to include default chars
|
||||
try:
|
||||
|
||||
15
eos/db/migrations/upgrade20.py
Normal file
15
eos/db/migrations/upgrade20.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Migration 20
|
||||
|
||||
- Adds support for alpha clones to the characters table
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Update characters schema to include alphaCloneID
|
||||
try:
|
||||
saveddata_engine.execute("SELECT alphaCloneID FROM characters LIMIT 1")
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
saveddata_engine.execute("ALTER TABLE characters ADD COLUMN alphaCloneID INTEGER;")
|
||||
@@ -6,6 +6,7 @@ Migration 3
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
try:
|
||||
saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1")
|
||||
|
||||
@@ -10,7 +10,6 @@ Migration 4
|
||||
and output of itemDiff.py
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
506: ( # 'Basic' Capacitor Power Relay
|
||||
8205, # Alpha Reactor Control: Capacitor Power Relay
|
||||
@@ -131,11 +130,12 @@ CONVERSIONS = {
|
||||
),
|
||||
}
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -4,5 +4,6 @@ Migration 5
|
||||
Simply deletes damage profiles with a blank name. See GH issue #256
|
||||
"""
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ?', ("",))
|
||||
|
||||
@@ -4,6 +4,8 @@ Migration 6
|
||||
Overwrites damage profile 0 to reset bad uniform values (bad values set with bug)
|
||||
"""
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ? OR ID LIKE ?', ("Uniform", "1"))
|
||||
saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)', (1, "Uniform", 25, 25, 25, 25, None))
|
||||
saveddata_engine.execute('INSERT INTO damagePatterns VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
(1, "Uniform", 25, 25, 25, 25, None))
|
||||
|
||||
@@ -8,17 +8,16 @@ Migration 7
|
||||
Pyfa.
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
640: ( # Scorpion
|
||||
4005, # Scorpion Ishukone Watch
|
||||
)
|
||||
}
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert ships
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "fits" SET "shipID" = ? WHERE "shipID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -7,7 +7,6 @@ Migration 8
|
||||
modules with their new replacements
|
||||
"""
|
||||
|
||||
|
||||
CONVERSIONS = {
|
||||
8529: ( # Large F-S9 Regolith Compact Shield Extender
|
||||
8409, # Large Subordinate Screen Stabilizer I
|
||||
@@ -71,15 +70,16 @@ CONVERSIONS = {
|
||||
11321, # 800mm Reinforced Nanofiber Plates I
|
||||
),
|
||||
11317: ( # 800mm Rolled Tungsten Compact Plates
|
||||
11315, # 800mm Reinforced Titanium Plates I
|
||||
11315, # 800mm Reinforced Titanium Plates I
|
||||
),
|
||||
}
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
# Convert modules
|
||||
for replacement_item, list in CONVERSIONS.iteritems():
|
||||
for retired_item in list:
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
||||
|
||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||
(replacement_item, retired_item))
|
||||
|
||||
@@ -16,8 +16,10 @@ CREATE TABLE boostersTemp (
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def upgrade(saveddata_engine):
|
||||
saveddata_engine.execute(tmpTable)
|
||||
saveddata_engine.execute("INSERT INTO boostersTemp (ID, itemID, fitID, active) SELECT ID, itemID, fitID, active FROM boosters")
|
||||
saveddata_engine.execute(
|
||||
"INSERT INTO boostersTemp (ID, itemID, fitID, active) SELECT ID, itemID, fitID, active FROM boosters")
|
||||
saveddata_engine.execute("DROP TABLE boosters")
|
||||
saveddata_engine.execute("ALTER TABLE boostersTemp RENAME TO boosters")
|
||||
|
||||
@@ -8,7 +8,6 @@ __all__ = [
|
||||
"booster",
|
||||
"drone",
|
||||
"implant",
|
||||
"fleet",
|
||||
"damagePattern",
|
||||
"miscData",
|
||||
"targetResists",
|
||||
@@ -17,4 +16,3 @@ __all__ = [
|
||||
"implantSet",
|
||||
"loadDefaultDatabaseValues"
|
||||
]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,25 +15,27 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, ForeignKey, Integer, UniqueConstraint, Boolean
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
from sqlalchemy import Table, Column, ForeignKey, Integer, Boolean
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Booster
|
||||
|
||||
boosters_table = Table("boosters", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("itemID", Integer),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False),
|
||||
Column("active", Boolean),
|
||||
)
|
||||
|
||||
# Legacy booster side effect code, should disable but a mapper relies on it.
|
||||
activeSideEffects_table = Table("boostersActiveSideEffects", saveddata_meta,
|
||||
Column("boosterID", ForeignKey("boosters.ID"), primary_key = True),
|
||||
Column("effectID", Integer, primary_key = True))
|
||||
Column("boosterID", ForeignKey("boosters.ID"), primary_key=True),
|
||||
Column("effectID", Integer, primary_key=True))
|
||||
|
||||
|
||||
class ActiveSideEffectsDummy(object):
|
||||
def __init__(self, effectID):
|
||||
@@ -42,6 +44,6 @@ class ActiveSideEffectsDummy(object):
|
||||
|
||||
mapper(ActiveSideEffectsDummy, activeSideEffects_table)
|
||||
mapper(Booster, boosters_table,
|
||||
properties = {"_Booster__activeSideEffectDummies" : relation(ActiveSideEffectsDummy)})
|
||||
properties={"_Booster__activeSideEffectDummies": relation(ActiveSideEffectsDummy)})
|
||||
|
||||
Booster._Booster__activeSideEffectIDs = association_proxy("_Booster__activeSideEffectDummies", "effectID")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,18 +15,18 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Cargo
|
||||
|
||||
cargo_table = Table("cargo", saveddata_meta,
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
||||
Column("itemID", Integer, nullable = False),
|
||||
Column("amount", Integer, nullable = False))
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=False),
|
||||
Column("amount", Integer, nullable=False))
|
||||
|
||||
mapper(Cargo, cargo_table)
|
||||
mapper(Cargo, cargo_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,44 +15,46 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.implant import charImplants_table
|
||||
from eos.types import Character, User, Skill, Implant
|
||||
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
||||
from eos.types import Character, User, Skill, Implant
|
||||
|
||||
characters_table = Table("characters", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String, nullable = False),
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String, nullable=False),
|
||||
Column("apiID", Integer),
|
||||
Column("apiKey", String),
|
||||
Column("defaultChar", Integer),
|
||||
Column("chars", String, nullable = True),
|
||||
Column("chars", String, nullable=True),
|
||||
Column("defaultLevel", Integer, nullable=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable = True))
|
||||
Column("alphaCloneID", Integer, nullable=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
||||
|
||||
mapper(Character, characters_table,
|
||||
properties = {
|
||||
"savedName": characters_table.c.name,
|
||||
"_Character__owner": relation(
|
||||
User,
|
||||
backref = "characters"),
|
||||
"_Character__skills": relation(
|
||||
Skill,
|
||||
backref="character",
|
||||
cascade = "all,delete-orphan"),
|
||||
"_Character__implants": relation(
|
||||
Implant,
|
||||
collection_class = HandledImplantBoosterList,
|
||||
cascade='all,delete-orphan',
|
||||
backref='character',
|
||||
single_parent=True,
|
||||
primaryjoin = charImplants_table.c.charID == characters_table.c.ID,
|
||||
secondaryjoin = charImplants_table.c.implantID == Implant.ID,
|
||||
secondary = charImplants_table),
|
||||
}
|
||||
)
|
||||
properties={
|
||||
"_Character__alphaCloneID": characters_table.c.alphaCloneID,
|
||||
"savedName": characters_table.c.name,
|
||||
"_Character__owner": relation(
|
||||
User,
|
||||
backref="characters"),
|
||||
"_Character__skills": relation(
|
||||
Skill,
|
||||
backref="character",
|
||||
cascade="all,delete-orphan"),
|
||||
"_Character__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all,delete-orphan',
|
||||
backref='character',
|
||||
single_parent=True,
|
||||
primaryjoin=charImplants_table.c.charID == characters_table.c.ID,
|
||||
secondaryjoin=charImplants_table.c.implantID == Implant.ID,
|
||||
secondary=charImplants_table),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,17 +15,17 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, Boolean
|
||||
from sqlalchemy import Table, Column, Integer, String
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import CrestChar
|
||||
|
||||
crest_table = Table("crest", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String, nullable = False, unique = True),
|
||||
Column("refresh_token", String, nullable = False))
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String, nullable=False, unique=True),
|
||||
Column("refresh_token", String, nullable=False))
|
||||
|
||||
mapper(CrestChar, crest_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,7 +24,7 @@ from eos.db import saveddata_meta
|
||||
from eos.types import DamagePattern
|
||||
|
||||
damagePatterns_table = Table("damagePatterns", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String),
|
||||
Column("emAmount", Integer),
|
||||
Column("thermalAmount", Integer),
|
||||
|
||||
162
eos/db/saveddata/databaseRepair.py
Normal file
162
eos/db/saveddata/databaseRepair.py
Normal file
@@ -0,0 +1,162 @@
|
||||
# ===============================================================================
|
||||
# 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 sqlalchemy
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DatabaseCleanup:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def ExecuteSQLQuery(saveddata_engine, query):
|
||||
try:
|
||||
results = saveddata_engine.execute(query)
|
||||
return results
|
||||
except sqlalchemy.exc.DatabaseError:
|
||||
logger.error("Failed to connect to database or error executing query:\n%s",query)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def OrphanedCharacterSkills(saveddata_engine):
|
||||
# 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.")
|
||||
query = "SELECT COUNT(*) AS num FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
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)
|
||||
|
||||
@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.")
|
||||
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)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num']:
|
||||
# Get Uniform damage pattern ID
|
||||
uniform_query = "SELECT ID FROM damagePatterns WHERE name = 'Uniform'"
|
||||
uniform_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, uniform_query)
|
||||
|
||||
if uniform_results is None:
|
||||
return
|
||||
|
||||
rows = uniform_results.fetchall()
|
||||
|
||||
if len(rows) == 0:
|
||||
logger.error("Missing uniform damage pattern.")
|
||||
elif len(rows) > 1:
|
||||
logger.error("More than one uniform damage pattern found.")
|
||||
else:
|
||||
uniform_damage_pattern_id = rows[0]['ID']
|
||||
update_query = "UPDATE 'fits' SET 'damagePatternID' = " + str(uniform_damage_pattern_id) + \
|
||||
" WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
|
||||
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||
logger.error("Database corruption found. Cleaning up %d 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.")
|
||||
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)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
if row and row['num']:
|
||||
# Get All 5 character ID
|
||||
all5_query = "SELECT ID FROM characters WHERE name = 'All 5'"
|
||||
all5_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, all5_query)
|
||||
|
||||
if all5_results is None:
|
||||
return
|
||||
|
||||
rows = all5_results.fetchall()
|
||||
|
||||
if len(rows) == 0:
|
||||
logger.error("Missing 'All 5' character.")
|
||||
elif len(rows) > 1:
|
||||
logger.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)
|
||||
|
||||
@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.")
|
||||
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name IS NULL OR name = ''"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
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)
|
||||
|
||||
@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.")
|
||||
query = "SELECT COUNT(*) AS num FROM targetResists WHERE name IS NULL OR name = ''"
|
||||
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||
|
||||
if results is None:
|
||||
return
|
||||
|
||||
row = results.first()
|
||||
|
||||
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)
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,19 +15,20 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Drone
|
||||
|
||||
drones_table = Table("drones", saveddata_meta,
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
||||
Column("itemID", Integer, nullable = False),
|
||||
Column("amount", Integer, nullable = False),
|
||||
Column("amountActive", Integer, nullable = False),
|
||||
Column("projected", Boolean, default = False))
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=False),
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("amountActive", Integer, nullable=False),
|
||||
Column("projected", Boolean, default=False))
|
||||
|
||||
mapper(Drone, drones_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,38 +15,36 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Fighter, Fit
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.sql import and_
|
||||
from eos.effectHandlerHelpers import *
|
||||
from eos.types import FighterAbility
|
||||
|
||||
|
||||
fighters_table = Table("fighters", saveddata_meta,
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
||||
Column("itemID", Integer, nullable = False),
|
||||
Column("active", Boolean, nullable=True),
|
||||
Column("amount", Integer, nullable = False),
|
||||
Column("projected", Boolean, default = False))
|
||||
Column("groupID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=False),
|
||||
Column("active", Boolean, nullable=True),
|
||||
Column("amount", Integer, nullable=False),
|
||||
Column("projected", Boolean, default=False))
|
||||
|
||||
fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
|
||||
Column("groupID", Integer, ForeignKey("fighters.groupID"), primary_key=True, index = True),
|
||||
Column("effectID", Integer, nullable = False, primary_key=True),
|
||||
Column("active", Boolean, default = False))
|
||||
Column("groupID", Integer, ForeignKey("fighters.groupID"), primary_key=True,
|
||||
index=True),
|
||||
Column("effectID", Integer, nullable=False, primary_key=True),
|
||||
Column("active", Boolean, default=False))
|
||||
|
||||
mapper(Fighter, fighters_table,
|
||||
properties = {
|
||||
"owner": relation(Fit),
|
||||
"_Fighter__abilities": relation(
|
||||
FighterAbility,
|
||||
backref="fighter",
|
||||
cascade='all, delete, delete-orphan'),
|
||||
properties={
|
||||
"owner": relation(Fit),
|
||||
"_Fighter__abilities": relation(
|
||||
FighterAbility,
|
||||
backref="fighter",
|
||||
cascade='all, delete, delete-orphan'),
|
||||
})
|
||||
|
||||
mapper(FighterAbility, fighter_abilities_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,43 +15,54 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
from sqlalchemy.sql import and_
|
||||
from sqlalchemy.orm import relation, reconstructor, mapper, relationship
|
||||
from sqlalchemy import ForeignKey, Column, Integer, String, Table, Boolean
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.db import saveddata_session
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.drone import drones_table
|
||||
from eos.db.saveddata.fighter import fighters_table
|
||||
from eos.db.saveddata.cargo import cargo_table
|
||||
from eos.db.saveddata.implant import fitImplants_table
|
||||
from eos.types import Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, TargetResists, ImplantLocation
|
||||
from eos.effectHandlerHelpers import *
|
||||
from eos.db.saveddata.module import modules_table
|
||||
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
|
||||
HandledDroneCargoList, HandledProjectedDroneList
|
||||
from eos.types import Fit as es_Fit, Module, User, Booster, Drone, Fighter, Cargo, Implant, Character, DamagePattern, \
|
||||
TargetResists, ImplantLocation
|
||||
|
||||
fits_table = Table("fits", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
|
||||
Column("shipID", Integer, nullable = False, index = True),
|
||||
Column("name", String, nullable = False),
|
||||
Column("timestamp", Integer, nullable = False),
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable = True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable = False, index = True, default = 0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
)
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True, index=True),
|
||||
Column("shipID", Integer, nullable=False, index=True),
|
||||
Column("name", String, nullable=False),
|
||||
Column("timestamp", Integer, nullable=False),
|
||||
Column("characterID", ForeignKey("characters.ID"), nullable=True),
|
||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||
Column("booster", Boolean, nullable=False, index=True, default=0),
|
||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||
Column("modeID", Integer, nullable=True),
|
||||
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||
Column("notes", String, nullable=True),
|
||||
)
|
||||
|
||||
projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("victimID", ForeignKey("fits.ID"), primary_key = True),
|
||||
Column("amount", Integer, nullable = False, default = 1),
|
||||
Column("active", Boolean, nullable = False, default = 1),
|
||||
)
|
||||
Column("sourceID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("victimID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("amount", Integer, nullable=False, default=1),
|
||||
Column("active", Boolean, nullable=False, default=1),
|
||||
)
|
||||
|
||||
commandFits_table = Table("commandFits", saveddata_meta,
|
||||
Column("boosterID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("boostedID", ForeignKey("fits.ID"), primary_key=True),
|
||||
Column("active", Boolean, nullable=False, default=1)
|
||||
)
|
||||
|
||||
|
||||
class ProjectedFit(object):
|
||||
def __init__(self, sourceID, source_fit, amount=1, active=True):
|
||||
@@ -64,9 +75,9 @@ class ProjectedFit(object):
|
||||
def init(self):
|
||||
if self.source_fit.isInvalid:
|
||||
# Very rare for this to happen, but be prepared for it
|
||||
eos.db.saveddata_session.delete(self.source_fit)
|
||||
eos.db.saveddata_session.flush()
|
||||
eos.db.saveddata_session.refresh(self.victim_fit)
|
||||
saveddata_session.delete(self.source_fit)
|
||||
saveddata_session.flush()
|
||||
saveddata_session.refresh(self.victim_fit)
|
||||
|
||||
# We have a series of setters and getters here just in case someone
|
||||
# downgrades and screws up the table with NULL values
|
||||
@@ -83,97 +94,137 @@ class ProjectedFit(object):
|
||||
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
|
||||
)
|
||||
|
||||
Fit._Fit__projectedFits = association_proxy(
|
||||
|
||||
class CommandFit(object):
|
||||
def __init__(self, boosterID, booster_fit, active=True):
|
||||
self.boosterID = boosterID
|
||||
self.booster_fit = booster_fit
|
||||
self.active = active
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
if self.booster_fit.isInvalid:
|
||||
# Very rare for this to happen, but be prepared for it
|
||||
saveddata_session.delete(self.booster_fit)
|
||||
saveddata_session.flush()
|
||||
saveddata_session.refresh(self.boosted_fit)
|
||||
|
||||
def __repr__(self):
|
||||
return "CommandFit(boosterID={}, boostedID={}, active={}) at {}".format(
|
||||
self.boosterID, self.boostedID, self.active, hex(id(self))
|
||||
)
|
||||
|
||||
|
||||
es_Fit._Fit__projectedFits = association_proxy(
|
||||
"victimOf", # look at the victimOf association...
|
||||
"source_fit", # .. and return the source fits
|
||||
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
|
||||
)
|
||||
|
||||
mapper(Fit, fits_table,
|
||||
properties = {
|
||||
"_Fit__modules": relation(
|
||||
Module,
|
||||
collection_class=HandledModuleList,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False),
|
||||
order_by=modules_table.c.position,
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"_Fit__projectedModules": relation(
|
||||
Module,
|
||||
collection_class=HandledProjectedModList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)),
|
||||
"owner": relation(
|
||||
User,
|
||||
backref="fits"),
|
||||
"itemID": fits_table.c.shipID,
|
||||
"shipID": fits_table.c.shipID,
|
||||
"_Fit__boosters": relation(
|
||||
Booster,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True),
|
||||
"_Fit__drones": relation(
|
||||
Drone,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
|
||||
"_Fit__fighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledDroneCargoList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)),
|
||||
"_Fit__cargo": relation(
|
||||
Cargo,
|
||||
collection_class=HandledDroneCargoList,
|
||||
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,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)),
|
||||
"_Fit__projectedFighters": relation(
|
||||
Fighter,
|
||||
collection_class=HandledProjectedDroneList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True,
|
||||
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)),
|
||||
"_Fit__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='fit',
|
||||
single_parent=True,
|
||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
||||
secondary=fitImplants_table),
|
||||
"_Fit__character": relation(
|
||||
Character,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"projectedOnto": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
}
|
||||
es_Fit._Fit__commandFits = association_proxy(
|
||||
"boostedOf", # look at the boostedOf association...
|
||||
"booster_fit", # .. and return the booster fit
|
||||
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||
)
|
||||
mapper(es_Fit, fits_table,
|
||||
properties={
|
||||
"_Fit__modules": relation(
|
||||
Module,
|
||||
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,
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"_Fit__projectedModules": relation(
|
||||
Module,
|
||||
collection_class=HandledProjectedModList,
|
||||
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,
|
||||
backref="fits"),
|
||||
"itemID": fits_table.c.shipID,
|
||||
"shipID": fits_table.c.shipID,
|
||||
"_Fit__boosters": relation(
|
||||
Booster,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
single_parent=True),
|
||||
"_Fit__drones": relation(
|
||||
Drone,
|
||||
collection_class=HandledDroneCargoList,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='fit',
|
||||
single_parent=True,
|
||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
||||
secondary=fitImplants_table),
|
||||
"_Fit__character": relation(
|
||||
Character,
|
||||
backref="fits"),
|
||||
"_Fit__damagePattern": relation(DamagePattern),
|
||||
"_Fit__targetResists": relation(TargetResists),
|
||||
"projectedOnto": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||
backref='source_fit',
|
||||
collection_class=attribute_mapped_collection('victimID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"victimOf": relationship(
|
||||
ProjectedFit,
|
||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
||||
backref='victim_fit',
|
||||
collection_class=attribute_mapped_collection('sourceID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOnto": relationship(
|
||||
CommandFit,
|
||||
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
|
||||
backref='booster_fit',
|
||||
collection_class=attribute_mapped_collection('boostedID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
"boostedOf": relationship(
|
||||
CommandFit,
|
||||
primaryjoin=fits_table.c.ID == commandFits_table.c.boostedID,
|
||||
backref='boosted_fit',
|
||||
collection_class=attribute_mapped_collection('boosterID'),
|
||||
cascade='all, delete, delete-orphan'),
|
||||
}
|
||||
)
|
||||
|
||||
mapper(ProjectedFit, projectedFits_table,
|
||||
properties = {
|
||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
||||
properties={
|
||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
mapper(CommandFit, commandFits_table)
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
#===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Fleet, Wing, Squad, Fit
|
||||
from eos.db.saveddata.fit import fits_table
|
||||
|
||||
gangs_table = Table("gangs", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("leaderID", ForeignKey("fits.ID")),
|
||||
Column("boosterID", ForeignKey("fits.ID")),
|
||||
Column("name", String))
|
||||
|
||||
wings_table = Table("wings", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("gangID", ForeignKey("gangs.ID")),
|
||||
Column("boosterID", ForeignKey("fits.ID")),
|
||||
Column("leaderID", ForeignKey("fits.ID")))
|
||||
|
||||
squads_table = Table("squads", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("wingID", ForeignKey("wings.ID")),
|
||||
Column("leaderID", ForeignKey("fits.ID")),
|
||||
Column("boosterID", ForeignKey("fits.ID")))
|
||||
|
||||
squadmembers_table = Table("squadmembers", saveddata_meta,
|
||||
Column("squadID", ForeignKey("squads.ID"), primary_key = True),
|
||||
Column("memberID", ForeignKey("fits.ID"), primary_key = True))
|
||||
|
||||
mapper(Fleet, gangs_table,
|
||||
properties = {"wings" : relation(Wing, backref="gang"),
|
||||
"leader" : relation(Fit, primaryjoin = gangs_table.c.leaderID == fits_table.c.ID),
|
||||
"booster": relation(Fit, primaryjoin = gangs_table.c.boosterID == fits_table.c.ID)})
|
||||
|
||||
mapper(Wing, wings_table,
|
||||
properties = {"squads" : relation(Squad, backref="wing"),
|
||||
"leader" : relation(Fit, primaryjoin = wings_table.c.leaderID == fits_table.c.ID),
|
||||
"booster": relation(Fit, primaryjoin = wings_table.c.boosterID == fits_table.c.ID)})
|
||||
|
||||
mapper(Squad, squads_table,
|
||||
properties = {"leader" : relation(Fit, primaryjoin = squads_table.c.leaderID == fits_table.c.ID),
|
||||
"booster" : relation(Fit, primaryjoin = squads_table.c.boosterID == fits_table.c.ID),
|
||||
"members" : relation(Fit,
|
||||
primaryjoin = squads_table.c.ID == squadmembers_table.c.squadID,
|
||||
secondaryjoin = squadmembers_table.c.memberID == fits_table.c.ID,
|
||||
secondary = squadmembers_table)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,20 +24,20 @@ from eos.db import saveddata_meta
|
||||
from eos.types import Implant
|
||||
|
||||
implants_table = Table("implants", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("itemID", Integer),
|
||||
Column("active", Boolean))
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("itemID", Integer),
|
||||
Column("active", Boolean))
|
||||
|
||||
fitImplants_table = Table("fitImplants", saveddata_meta,
|
||||
Column("fitID", ForeignKey("fits.ID"), index = True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
|
||||
Column("fitID", ForeignKey("fits.ID"), index=True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key=True))
|
||||
|
||||
charImplants_table = Table("charImplants", saveddata_meta,
|
||||
Column("charID", ForeignKey("characters.ID"), index = True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
|
||||
Column("charID", ForeignKey("characters.ID"), index=True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key=True))
|
||||
|
||||
implantsSetMap_table = Table("implantSetMap", saveddata_meta,
|
||||
Column("setID", ForeignKey("implantSets.ID"), index = True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
|
||||
Column("setID", ForeignKey("implantSets.ID"), index=True),
|
||||
Column("implantID", ForeignKey("implants.ID"), primary_key=True))
|
||||
|
||||
mapper(Implant, implants_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2016 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,31 +15,31 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, String
|
||||
from sqlalchemy import Table, Column, Integer, String
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.db.saveddata.implant import implantsSetMap_table
|
||||
from eos.types import Implant, ImplantSet
|
||||
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
||||
from eos.types import Implant, ImplantSet
|
||||
|
||||
implant_set_table = Table("implantSets", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String, nullable = False),
|
||||
)
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String, nullable=False),
|
||||
)
|
||||
|
||||
mapper(ImplantSet, implant_set_table,
|
||||
properties = {
|
||||
"_ImplantSet__implants": relation(
|
||||
Implant,
|
||||
collection_class = HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='set',
|
||||
single_parent=True,
|
||||
primaryjoin = implantsSetMap_table.c.setID == implant_set_table.c.ID,
|
||||
secondaryjoin = implantsSetMap_table.c.implantID == Implant.ID,
|
||||
secondary = implantsSetMap_table),
|
||||
}
|
||||
)
|
||||
properties={
|
||||
"_ImplantSet__implants": relation(
|
||||
Implant,
|
||||
collection_class=HandledImplantBoosterList,
|
||||
cascade='all, delete, delete-orphan',
|
||||
backref='set',
|
||||
single_parent=True,
|
||||
primaryjoin=implantsSetMap_table.c.setID == implant_set_table.c.ID,
|
||||
secondaryjoin=implantsSetMap_table.c.implantID == Implant.ID,
|
||||
secondary=implantsSetMap_table),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of pyfa.
|
||||
@@ -15,176 +15,184 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
import eos.db
|
||||
import eos.types
|
||||
from eos.saveddata.damagePattern import DamagePattern as es_DamagePattern
|
||||
from eos.saveddata.targetResists import TargetResists as es_TargetResists
|
||||
|
||||
|
||||
class ImportError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class DefaultDatabaseValues():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
instance = None
|
||||
|
||||
@classmethod
|
||||
def importDamageProfileDefaults(self):
|
||||
damageProfileList = []
|
||||
damageProfileList.append(["Uniform", "25", "25", "25", "25"])
|
||||
damageProfileList.append(["[Generic]EM", "100", "0", "0", "0"])
|
||||
damageProfileList.append(["[Generic]Thermal", "0", "100", "0", "0"])
|
||||
damageProfileList.append(["[Generic]Kinetic", "0", "0", "100", "0"])
|
||||
damageProfileList.append(["[Generic]Explosive", "0", "0", "0", "100"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Blood Raiders", "5067", "4214", "0", "0"])
|
||||
damageProfileList.append(["[Bombs]Concussion Bomb", "0", "0", "6400", "0"])
|
||||
damageProfileList.append(["[Bombs]Electron Bomb", "6400", "0", "0", "0"])
|
||||
damageProfileList.append(["[Bombs]Scorch Bomb", "0", "6400", "0", "0"])
|
||||
damageProfileList.append(["[Bombs]Shrapnel Bomb", "0", "0", "0", "6400"])
|
||||
damageProfileList.append(["[Frequency Crystals][T2] Gleam", "56", "56", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals][T2] Aurora", "40", "24", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals][T2] Scorch", "72", "16", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals][T2] Conflagration", "61.6", "61.6", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Gamma", "61.6", "35.2", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Infrared", "44", "17.6", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Microwave", "35.2", "17.6", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Multifrequency", "61.6", "44", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Radio", "44", "0", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Standard", "44", "26.4", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Ultraviolet", "52.8", "26.4", "0", "0"])
|
||||
damageProfileList.append(["[Frequency Crystals]Xray", "52.8", "35.2", "0", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges][T2] Void", "0", "61.6", "61.6", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges][T2] Null", "0", "48", "40", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges][T2] Javelin", "0", "64", "48", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges][T2] Spike", "0", "32", "32", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Antimatter", "0", "48", "67.2", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Iridium", "0", "28.8", "38.4", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Iron", "0", "19.2", "28.8", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Lead", "0", "28.8", "48", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Plutonium", "0", "48", "57.6", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Thorium", "0", "38.4", "48", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Tungsten", "0", "19.2", "38.4", "0"])
|
||||
damageProfileList.append(["[Hybrid Charges]Uranium", "0", "38.4", "57.6", "0"])
|
||||
damageProfileList.append(["[Missiles]Mjolnir", "100", "0", "0", "0"])
|
||||
damageProfileList.append(["[Missiles]Inferno", "0", "100", "0", "0"])
|
||||
damageProfileList.append(["[Missiles]Scourge", "0", "0", "100", "0"])
|
||||
damageProfileList.append(["[Missiles]Nova", "0", "0", "0", "100"])
|
||||
damageProfileList.append(["[Missiles][Structure) Standup Missile", "100", "100", "100", "100"])
|
||||
damageProfileList.append(["[Projectile Ammo][T2] Tremor", "0", "0", "24", "40"])
|
||||
damageProfileList.append(["[Projectile Ammo][T2] Quake", "0", "0", "40", "72"])
|
||||
damageProfileList.append(["[Projectile Ammo][T2] Hail", "0", "0", "26.4", "96.8"])
|
||||
damageProfileList.append(["[Projectile Ammo][T2] Barrage", "0", "0", "40", "48"])
|
||||
damageProfileList.append(["[Projectile Ammo]Carbonized Lead", "0", "0", "35.2", "8.8"])
|
||||
damageProfileList.append(["[Projectile Ammo]Depleted Uranium", "0", "26.4", "17.6", "26.4"])
|
||||
damageProfileList.append(["[Projectile Ammo]EMP", "79.2", "0", "8.8", "17.6"])
|
||||
damageProfileList.append(["[Projectile Ammo]Fusion", "0", "0", "17.6", "88"])
|
||||
damageProfileList.append(["[Projectile Ammo]Nuclear", "0", "0", "8.8", "35.2"])
|
||||
damageProfileList.append(["[Projectile Ammo]Phased Plasma", "0", "88", "17.6", "0"])
|
||||
damageProfileList.append(["[Projectile Ammo]Proton", "26.4", "0", "17.6", "0"])
|
||||
damageProfileList.append(["[Projectile Ammo]Titanium Sabot", "0", "0", "52.8", "176"])
|
||||
damageProfileList.append(["[NPC][Burner] Cruor (Blood Raiders)", "90", "90", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Dramiel (Angel)", "55", "0", "20", "96"])
|
||||
damageProfileList.append(["[NPC][Burner] Daredevil (Serpentis)", "0", "110", "154", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Succubus (Sanshas Nation)", "135", "30", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Worm (Guristas)", "0", "0", "228", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Enyo", "0", "147", "147", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Hawk", "0", "0", "247", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Jaguar", "36", "0", "50", "182"])
|
||||
damageProfileList.append(["[NPC][Burner] Vengeance", "232", "0", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Ashimmu (Blood Raiders)", "260", "100", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Talos", "0", "413", "413", "0"])
|
||||
damageProfileList.append(["[NPC][Burner] Sentinel", "0", "75", "0", "90"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Angel Cartel", "1838", "562", "2215", "3838"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Angel Cartel", "369", "533", "1395", "3302"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Blood Raiders", "6040", "5052", "10", "15"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Guristas", "0", "1828", "7413", "0"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Guristas", "0", "1531", "9680", "0"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Rogue Drone", "394", "666", "1090", "1687"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Rogue Drone", "276", "1071", "1069", "871"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Sanshas Nation", "5586", "4112", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Sanshas Nation", "3009", "2237", "0", "0"])
|
||||
damageProfileList.append(["[NPC][Asteroid] Serpentis", "0", "5373", "4813", "0"])
|
||||
damageProfileList.append(["[NPC][Deadspace] Serpentis", "0", "3110", "1929", "0"])
|
||||
damageProfileList.append(["[NPC][Mission] Amarr Empire", "4464", "3546", "97", "0"])
|
||||
damageProfileList.append(["[NPC][Mission] Caldari State", "0", "2139", "4867", "0"])
|
||||
damageProfileList.append(["[NPC][Mission] CONCORD", "336", "134", "212", "412"])
|
||||
damageProfileList.append(["[NPC][Mission] Gallente Federation", "9", "3712", "2758", "0"])
|
||||
damageProfileList.append(["[NPC][Mission] Khanid", "612", "483", "43", "6"])
|
||||
damageProfileList.append(["[NPC][Mission] Minmatar Republic", "1024", "388", "1655", "4285"])
|
||||
damageProfileList.append(["[NPC][Mission] Mordus Legion", "25", "262", "625", "0"])
|
||||
damageProfileList.append(["[NPC][Mission] Thukker", "0", "52", "10", "79"])
|
||||
damageProfileList.append(["[NPC][Other] Sleepers", "1472", "1472", "1384", "1384"])
|
||||
damageProfileList.append(["[NPC][Other] Sansha Incursion", "1682", "1347", "3678", "3678"])
|
||||
def importDamageProfileDefaults(cls):
|
||||
damageProfileList = [["Uniform", "25", "25", "25", "25"], ["[Generic]EM", "100", "0", "0", "0"],
|
||||
["[Generic]Thermal", "0", "100", "0", "0"], ["[Generic]Kinetic", "0", "0", "100", "0"],
|
||||
["[Generic]Explosive", "0", "0", "0", "100"],
|
||||
["[NPC][Asteroid] Blood Raiders", "5067", "4214", "0", "0"],
|
||||
["[Bombs]Concussion Bomb", "0", "0", "6400", "0"],
|
||||
["[Bombs]Electron Bomb", "6400", "0", "0", "0"],
|
||||
["[Bombs]Scorch Bomb", "0", "6400", "0", "0"],
|
||||
["[Bombs]Shrapnel Bomb", "0", "0", "0", "6400"],
|
||||
["[Frequency Crystals][T2] Gleam", "56", "56", "0", "0"],
|
||||
["[Frequency Crystals][T2] Aurora", "40", "24", "0", "0"],
|
||||
["[Frequency Crystals][T2] Scorch", "72", "16", "0", "0"],
|
||||
["[Frequency Crystals][T2] Conflagration", "61.6", "61.6", "0", "0"],
|
||||
["[Frequency Crystals]Gamma", "61.6", "35.2", "0", "0"],
|
||||
["[Frequency Crystals]Infrared", "44", "17.6", "0", "0"],
|
||||
["[Frequency Crystals]Microwave", "35.2", "17.6", "0", "0"],
|
||||
["[Frequency Crystals]Multifrequency", "61.6", "44", "0", "0"],
|
||||
["[Frequency Crystals]Radio", "44", "0", "0", "0"],
|
||||
["[Frequency Crystals]Standard", "44", "26.4", "0", "0"],
|
||||
["[Frequency Crystals]Ultraviolet", "52.8", "26.4", "0", "0"],
|
||||
["[Frequency Crystals]Xray", "52.8", "35.2", "0", "0"],
|
||||
["[Hybrid Charges][T2] Void", "0", "61.6", "61.6", "0"],
|
||||
["[Hybrid Charges][T2] Null", "0", "48", "40", "0"],
|
||||
["[Hybrid Charges][T2] Javelin", "0", "64", "48", "0"],
|
||||
["[Hybrid Charges][T2] Spike", "0", "32", "32", "0"],
|
||||
["[Hybrid Charges]Antimatter", "0", "48", "67.2", "0"],
|
||||
["[Hybrid Charges]Iridium", "0", "28.8", "38.4", "0"],
|
||||
["[Hybrid Charges]Iron", "0", "19.2", "28.8", "0"],
|
||||
["[Hybrid Charges]Lead", "0", "28.8", "48", "0"],
|
||||
["[Hybrid Charges]Plutonium", "0", "48", "57.6", "0"],
|
||||
["[Hybrid Charges]Thorium", "0", "38.4", "48", "0"],
|
||||
["[Hybrid Charges]Tungsten", "0", "19.2", "38.4", "0"],
|
||||
["[Hybrid Charges]Uranium", "0", "38.4", "57.6", "0"],
|
||||
["[Missiles]Mjolnir", "100", "0", "0", "0"], ["[Missiles]Inferno", "0", "100", "0", "0"],
|
||||
["[Missiles]Scourge", "0", "0", "100", "0"], ["[Missiles]Nova", "0", "0", "0", "100"],
|
||||
["[Missiles][Structure) Standup Missile", "100", "100", "100", "100"],
|
||||
["[Projectile Ammo][T2] Tremor", "0", "0", "24", "40"],
|
||||
["[Projectile Ammo][T2] Quake", "0", "0", "40", "72"],
|
||||
["[Projectile Ammo][T2] Hail", "0", "0", "26.4", "96.8"],
|
||||
["[Projectile Ammo][T2] Barrage", "0", "0", "40", "48"],
|
||||
["[Projectile Ammo]Carbonized Lead", "0", "0", "35.2", "8.8"],
|
||||
["[Projectile Ammo]Depleted Uranium", "0", "26.4", "17.6", "26.4"],
|
||||
["[Projectile Ammo]EMP", "79.2", "0", "8.8", "17.6"],
|
||||
["[Projectile Ammo]Fusion", "0", "0", "17.6", "88"],
|
||||
["[Projectile Ammo]Nuclear", "0", "0", "8.8", "35.2"],
|
||||
["[Projectile Ammo]Phased Plasma", "0", "88", "17.6", "0"],
|
||||
["[Projectile Ammo]Proton", "26.4", "0", "17.6", "0"],
|
||||
["[Projectile Ammo]Titanium Sabot", "0", "0", "52.8", "176"],
|
||||
["[NPC][Burner] Cruor (Blood Raiders)", "90", "90", "0", "0"],
|
||||
["[NPC][Burner] Dramiel (Angel)", "55", "0", "20", "96"],
|
||||
["[NPC][Burner] Daredevil (Serpentis)", "0", "110", "154", "0"],
|
||||
["[NPC][Burner] Succubus (Sanshas Nation)", "135", "30", "0", "0"],
|
||||
["[NPC][Burner] Worm (Guristas)", "0", "0", "228", "0"],
|
||||
["[NPC][Burner] Enyo", "0", "147", "147", "0"],
|
||||
["[NPC][Burner] Hawk", "0", "0", "247", "0"],
|
||||
["[NPC][Burner] Jaguar", "36", "0", "50", "182"],
|
||||
["[NPC][Burner] Vengeance", "232", "0", "0", "0"],
|
||||
["[NPC][Burner] Ashimmu (Blood Raiders)", "260", "100", "0", "0"],
|
||||
["[NPC][Burner] Talos", "0", "413", "413", "0"],
|
||||
["[NPC][Burner] Sentinel", "0", "75", "0", "90"],
|
||||
["[NPC][Asteroid] Angel Cartel", "1838", "562", "2215", "3838"],
|
||||
["[NPC][Deadspace] Angel Cartel", "369", "533", "1395", "3302"],
|
||||
["[NPC][Deadspace] Blood Raiders", "6040", "5052", "10", "15"],
|
||||
["[NPC][Asteroid] Guristas", "0", "1828", "7413", "0"],
|
||||
["[NPC][Deadspace] Guristas", "0", "1531", "9680", "0"],
|
||||
["[NPC][Asteroid] Rogue Drone", "394", "666", "1090", "1687"],
|
||||
["[NPC][Deadspace] Rogue Drone", "276", "1071", "1069", "871"],
|
||||
["[NPC][Asteroid] Sanshas Nation", "5586", "4112", "0", "0"],
|
||||
["[NPC][Deadspace] Sanshas Nation", "3009", "2237", "0", "0"],
|
||||
["[NPC][Asteroid] Serpentis", "0", "5373", "4813", "0"],
|
||||
["[NPC][Deadspace] Serpentis", "0", "3110", "1929", "0"],
|
||||
["[NPC][Mission] Amarr Empire", "4464", "3546", "97", "0"],
|
||||
["[NPC][Mission] Caldari State", "0", "2139", "4867", "0"],
|
||||
["[NPC][Mission] CONCORD", "336", "134", "212", "412"],
|
||||
["[NPC][Mission] Gallente Federation", "9", "3712", "2758", "0"],
|
||||
["[NPC][Mission] Khanid", "612", "483", "43", "6"],
|
||||
["[NPC][Mission] Minmatar Republic", "1024", "388", "1655", "4285"],
|
||||
["[NPC][Mission] Mordus Legion", "25", "262", "625", "0"],
|
||||
["[NPC][Mission] Thukker", "0", "52", "10", "79"],
|
||||
["[NPC][Other] Sleepers", "1472", "1472", "1384", "1384"],
|
||||
["[NPC][Other] Sansha Incursion", "1682", "1347", "3678", "3678"]]
|
||||
|
||||
for damageProfileRow in damageProfileList:
|
||||
name, em, therm, kin, exp = damageProfileRow
|
||||
damageProfile = eos.db.getDamagePattern(name)
|
||||
if damageProfile is None:
|
||||
damageProfile = eos.types.DamagePattern(em, therm, kin, exp)
|
||||
damageProfile = es_DamagePattern(em, therm, kin, exp)
|
||||
damageProfile.name = name
|
||||
eos.db.save(damageProfile)
|
||||
|
||||
@classmethod
|
||||
def importResistProfileDefaults(self):
|
||||
targetResistProfileList = []
|
||||
targetResistProfileList.append(["Uniform (25%)", "0.25", "0.25", "0.25", "0.25"])
|
||||
targetResistProfileList.append(["Uniform (50%)", "0.50", "0.50", "0.50", "0.50"])
|
||||
targetResistProfileList.append(["Uniform (75%)", "0.75", "0.75", "0.75", "0.75"])
|
||||
targetResistProfileList.append(["[T1 Resist]Shield", "0.0", "0.20", "0.40", "0.50"])
|
||||
targetResistProfileList.append(["[T1 Resist]Armor", "0.50", "0.45", "0.25", "0.10"])
|
||||
targetResistProfileList.append(["[T1 Resist]Hull", "0.33", "0.33", "0.33", "0.33"])
|
||||
targetResistProfileList.append(["[T1 Resist]Shield (+T2 DCU)", "0.125", "0.30", "0.475", "0.562"])
|
||||
targetResistProfileList.append(["[T1 Resist]Armor (+T2 DCU)", "0.575", "0.532", "0.363", "0.235"])
|
||||
targetResistProfileList.append(["[T1 Resist]Hull (+T2 DCU)", "0.598", "0.598", "0.598", "0.598"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Angel Cartel", "0.54", "0.42", "0.37", "0.32"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Blood Raiders", "0.34", "0.39", "0.45", "0.52"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Guristas", "0.55", "0.35", "0.3", "0.48"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Rogue Drones", "0.35", "0.38", "0.44", "0.49"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Sanshas Nation", "0.35", "0.4", "0.47", "0.53"])
|
||||
targetResistProfileList.append(["[NPC][Asteroid] Serpentis", "0.49", "0.38", "0.29", "0.51"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Angel Cartel", "0.59", "0.48", "0.4", "0.32"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Blood Raiders", "0.31", "0.39", "0.47", "0.56"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Guristas", "0.57", "0.39", "0.31", "0.5"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Rogue Drones", "0.42", "0.42", "0.47", "0.49"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Sanshas Nation", "0.31", "0.39", "0.47", "0.56"])
|
||||
targetResistProfileList.append(["[NPC][Deadspace] Serpentis", "0.49", "0.38", "0.29", "0.56"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Amarr Empire", "0.34", "0.38", "0.42", "0.46"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Caldari State", "0.51", "0.38", "0.3", "0.51"])
|
||||
targetResistProfileList.append(["[NPC][Mission] CONCORD", "0.47", "0.46", "0.47", "0.47"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Gallente Federation", "0.51", "0.38", "0.31", "0.52"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Khanid", "0.51", "0.42", "0.36", "0.4"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Minmatar Republic", "0.51", "0.46", "0.41", "0.35"])
|
||||
targetResistProfileList.append(["[NPC][Mission] Mordus Legion", "0.32", "0.48", "0.4", "0.62"])
|
||||
targetResistProfileList.append(["[NPC][Other] Sleeper", "0.61", "0.61", "0.61", "0.61"])
|
||||
targetResistProfileList.append(["[NPC][Other] Sansha Incursion", "0.65", "0.63", "0.64", "0.65"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Cruor (Blood Raiders)", "0.8", "0.73", "0.69", "0.67"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Dramiel (Angel)", "0.35", "0.48", "0.61", "0.68"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Daredevil (Serpentis)", "0.69", "0.59", "0.59", "0.43"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Succubus (Sanshas Nation)", "0.35", "0.48", "0.61", "0.68"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Worm (Guristas)", "0.48", "0.58", "0.69", "0.74"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Enyo", "0.58", "0.72", "0.86", "0.24"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Hawk", "0.3", "0.86", "0.79", "0.65"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Jaguar", "0.78", "0.65", "0.48", "0.56"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Vengeance", "0.66", "0.56", "0.75", "0.86"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Ashimmu (Blood Raiders)", "0.8", "0.76", "0.68", "0.7"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Talos", "0.68", "0.59", "0.59", "0.43"])
|
||||
targetResistProfileList.append(["[NPC][Burner] Sentinel", "0.58", "0.45", "0.52", "0.66"])
|
||||
def importResistProfileDefaults(cls):
|
||||
targetResistProfileList = [["Uniform (25%)", "0.25", "0.25", "0.25", "0.25"],
|
||||
["Uniform (50%)", "0.50", "0.50", "0.50", "0.50"],
|
||||
["Uniform (75%)", "0.75", "0.75", "0.75", "0.75"],
|
||||
["Uniform (90%)", "0.90", "0.90", "0.90", "0.90"],
|
||||
["[T1 Resist]Shield", "0.0", "0.20", "0.40", "0.50"],
|
||||
["[T1 Resist]Armor", "0.50", "0.45", "0.25", "0.10"],
|
||||
["[T1 Resist]Hull", "0.33", "0.33", "0.33", "0.33"],
|
||||
["[T1 Resist]Shield (+T2 DCU)", "0.125", "0.30", "0.475", "0.562"],
|
||||
["[T1 Resist]Armor (+T2 DCU)", "0.575", "0.532", "0.363", "0.235"],
|
||||
["[T1 Resist]Hull (+T2 DCU)", "0.598", "0.598", "0.598", "0.598"],
|
||||
["[T2 Resist]Amarr (Shield)", "0.0", "0.20", "0.70", "0.875"],
|
||||
["[T2 Resist]Amarr (Armor)", "0.50", "0.35", "0.625", "0.80"],
|
||||
["[T2 Resist]Caldari (Shield)", "0.20", "0.84", "0.76", "0.60"],
|
||||
["[T2 Resist]Caldari (Armor)", "0.50", "0.8625", "0.625", "0.10"],
|
||||
["[T2 Resist]Gallente (Shield)", "0.0", "0.60", "0.85", "0.50"],
|
||||
["[T2 Resist]Gallente (Armor)", "0.50", "0.675", "0.8375", "0.10"],
|
||||
["[T2 Resist]Minmatar (Shield)", "0.75", "0.60", "0.40", "0.50"],
|
||||
["[T2 Resist]Minmatar (Armor)", "0.90", "0.675", "0.25", "0.10"],
|
||||
["[NPC][Asteroid] Angel Cartel", "0.54", "0.42", "0.37", "0.32"],
|
||||
["[NPC][Asteroid] Blood Raiders", "0.34", "0.39", "0.45", "0.52"],
|
||||
["[NPC][Asteroid] Guristas", "0.55", "0.35", "0.3", "0.48"],
|
||||
["[NPC][Asteroid] Rogue Drones", "0.35", "0.38", "0.44", "0.49"],
|
||||
["[NPC][Asteroid] Sanshas Nation", "0.35", "0.4", "0.47", "0.53"],
|
||||
["[NPC][Asteroid] Serpentis", "0.49", "0.38", "0.29", "0.51"],
|
||||
["[NPC][Deadspace] Angel Cartel", "0.59", "0.48", "0.4", "0.32"],
|
||||
["[NPC][Deadspace] Blood Raiders", "0.31", "0.39", "0.47", "0.56"],
|
||||
["[NPC][Deadspace] Guristas", "0.57", "0.39", "0.31", "0.5"],
|
||||
["[NPC][Deadspace] Rogue Drones", "0.42", "0.42", "0.47", "0.49"],
|
||||
["[NPC][Deadspace] Sanshas Nation", "0.31", "0.39", "0.47", "0.56"],
|
||||
["[NPC][Deadspace] Serpentis", "0.49", "0.38", "0.29", "0.56"],
|
||||
["[NPC][Mission] Amarr Empire", "0.34", "0.38", "0.42", "0.46"],
|
||||
["[NPC][Mission] Caldari State", "0.51", "0.38", "0.3", "0.51"],
|
||||
["[NPC][Mission] CONCORD", "0.47", "0.46", "0.47", "0.47"],
|
||||
["[NPC][Mission] Gallente Federation", "0.51", "0.38", "0.31", "0.52"],
|
||||
["[NPC][Mission] Khanid", "0.51", "0.42", "0.36", "0.4"],
|
||||
["[NPC][Mission] Minmatar Republic", "0.51", "0.46", "0.41", "0.35"],
|
||||
["[NPC][Mission] Mordus Legion", "0.32", "0.48", "0.4", "0.62"],
|
||||
["[NPC][Other] Sleeper", "0.61", "0.61", "0.61", "0.61"],
|
||||
["[NPC][Other] Sansha Incursion", "0.65", "0.63", "0.64", "0.65"],
|
||||
["[NPC][Burner] Cruor (Blood Raiders)", "0.8", "0.73", "0.69", "0.67"],
|
||||
["[NPC][Burner] Dramiel (Angel)", "0.35", "0.48", "0.61", "0.68"],
|
||||
["[NPC][Burner] Daredevil (Serpentis)", "0.69", "0.59", "0.59", "0.43"],
|
||||
["[NPC][Burner] Succubus (Sanshas Nation)", "0.35", "0.48", "0.61", "0.68"],
|
||||
["[NPC][Burner] Worm (Guristas)", "0.48", "0.58", "0.69", "0.74"],
|
||||
["[NPC][Burner] Enyo", "0.58", "0.72", "0.86", "0.24"],
|
||||
["[NPC][Burner] Hawk", "0.3", "0.86", "0.79", "0.65"],
|
||||
["[NPC][Burner] Jaguar", "0.78", "0.65", "0.48", "0.56"],
|
||||
["[NPC][Burner] Vengeance", "0.66", "0.56", "0.75", "0.86"],
|
||||
["[NPC][Burner] Ashimmu (Blood Raiders)", "0.8", "0.76", "0.68", "0.7"],
|
||||
["[NPC][Burner] Talos", "0.68", "0.59", "0.59", "0.43"],
|
||||
["[NPC][Burner] Sentinel", "0.58", "0.45", "0.52", "0.66"]]
|
||||
|
||||
for targetResistProfileRow in targetResistProfileList:
|
||||
name, em, therm, kin, exp = targetResistProfileRow
|
||||
resistsProfile = eos.db.eos.db.getTargetResists(name)
|
||||
if resistsProfile is None:
|
||||
resistsProfile = eos.types.TargetResists(em, therm, kin, exp)
|
||||
resistsProfile = es_TargetResists(em, therm, kin, exp)
|
||||
resistsProfile.name = name
|
||||
eos.db.save(resistsProfile)
|
||||
|
||||
@classmethod
|
||||
def importRequiredDefaults(self):
|
||||
damageProfileList = []
|
||||
damageProfileList.append(["Uniform", "25", "25", "25", "25"])
|
||||
def importRequiredDefaults(cls):
|
||||
damageProfileList = [["Uniform", "25", "25", "25", "25"]]
|
||||
|
||||
for damageProfileRow in damageProfileList:
|
||||
name, em, therm, kin, exp = damageProfileRow
|
||||
damageProfile = eos.db.getDamagePattern(name)
|
||||
if damageProfile is None:
|
||||
damageProfile = eos.types.DamagePattern(em, therm, kin, exp)
|
||||
damageProfile = es_DamagePattern(em, therm, kin, exp)
|
||||
damageProfile.name = name
|
||||
eos.db.save(damageProfile)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2011 Anton Vorobyov
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,16 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Column, Table, String
|
||||
from sqlalchemy.orm import mapper
|
||||
from eos.types import MiscData
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import MiscData
|
||||
|
||||
miscdata_table = Table("miscdata", saveddata_meta,
|
||||
Column("fieldName", String, primary_key=True),
|
||||
Column("fieldValue", String))
|
||||
Column("fieldName", String, primary_key=True),
|
||||
Column("fieldValue", String))
|
||||
|
||||
mapper(MiscData, miscdata_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean
|
||||
from sqlalchemy.orm import relation, mapper
|
||||
@@ -24,16 +24,15 @@ from eos.db import saveddata_meta
|
||||
from eos.types import Module, Fit
|
||||
|
||||
modules_table = Table("modules", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
||||
Column("itemID", Integer, nullable = True),
|
||||
Column("dummySlot", Integer, nullable = True, default = None),
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||
Column("itemID", Integer, nullable=True),
|
||||
Column("dummySlot", Integer, nullable=True, default=None),
|
||||
Column("chargeID", Integer),
|
||||
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),
|
||||
Column("projected", Boolean, default = False, nullable = False),
|
||||
Column("projected", Boolean, default=False, nullable=False),
|
||||
Column("position", Integer),
|
||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||
|
||||
mapper(Module, modules_table,
|
||||
properties = {"owner" : relation(Fit)})
|
||||
|
||||
properties={"owner": relation(Fit)})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,8 +24,8 @@ from eos.db import saveddata_meta
|
||||
from eos.types import Override
|
||||
|
||||
overrides_table = Table("overrides", saveddata_meta,
|
||||
Column("itemID", Integer, primary_key=True, index = True),
|
||||
Column("attrID", Integer, primary_key=True, index = True),
|
||||
Column("value", Float, nullable = False))
|
||||
Column("itemID", Integer, primary_key=True, index=True),
|
||||
Column("attrID", Integer, primary_key=True, index=True),
|
||||
Column("value", Float, nullable=False))
|
||||
|
||||
mapper(Override, overrides_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,17 +15,18 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Float, Integer
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.types import Price
|
||||
|
||||
prices_table = Table("prices", saveddata_meta,
|
||||
Column("typeID", Integer, primary_key=True),
|
||||
Column("price", Float),
|
||||
Column("time", Integer, nullable = False),
|
||||
Column("time", Integer, nullable=False),
|
||||
Column("failed", Integer))
|
||||
|
||||
mapper(Price, prices_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,13 +15,16 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.sql import and_
|
||||
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
from eos.db.util import processEager, processWhere
|
||||
from eos.db import saveddata_session, sd_lock
|
||||
|
||||
from eos.types import *
|
||||
from eos.db.saveddata.fleet import squadmembers_table
|
||||
from eos.db.saveddata.fit import projectedFits_table
|
||||
from sqlalchemy.sql import and_
|
||||
import eos.config
|
||||
@@ -29,13 +32,17 @@ import eos.config
|
||||
configVal = getattr(eos.config, "saveddataCache", None)
|
||||
if configVal is True:
|
||||
import weakref
|
||||
|
||||
itemCache = {}
|
||||
queryCache = {}
|
||||
|
||||
def cachedQuery(type, amount, *keywords):
|
||||
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
|
||||
queryCache[type] = typeQueryCache = {}
|
||||
|
||||
def deco(function):
|
||||
localQueryCache = typeQueryCache[function] = {}
|
||||
|
||||
def setCache(cacheKey, args, kwargs):
|
||||
items = function(*args, **kwargs)
|
||||
IDs = set()
|
||||
@@ -44,7 +51,7 @@ if configVal is True:
|
||||
for item in stuff:
|
||||
ID = getattr(item, "ID", None)
|
||||
if ID is None:
|
||||
#Some uncachable data, don't cache this query
|
||||
# Some uncachable data, don't cache this query
|
||||
del localQueryCache[cacheKey]
|
||||
break
|
||||
localItemCache[ID] = item
|
||||
@@ -70,7 +77,7 @@ if configVal is True:
|
||||
for ID in IDs:
|
||||
data = localItemCache.get(ID)
|
||||
if data is None:
|
||||
#Fuck, some of our stuff isn't cached it seems.
|
||||
# Fuck, some of our stuff isn't cached it seems.
|
||||
items = setCache(cacheKey, args, kwargs)
|
||||
break
|
||||
items.append(data)
|
||||
@@ -82,11 +89,13 @@ if configVal is True:
|
||||
break
|
||||
|
||||
return items
|
||||
|
||||
return checkAndReturn
|
||||
|
||||
return deco
|
||||
|
||||
def removeCachedEntry(type, ID):
|
||||
if not type in queryCache:
|
||||
if type not in queryCache:
|
||||
return
|
||||
functionCache = queryCache[type]
|
||||
for _, localCache in functionCache.iteritems():
|
||||
@@ -111,11 +120,13 @@ else:
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return checkAndReturn
|
||||
|
||||
return deco
|
||||
|
||||
def removeCachedEntry(*args, **kwargs):
|
||||
return
|
||||
|
||||
|
||||
def sqlizeString(line):
|
||||
# Escape backslashes first, as they will be as escape symbol in queries
|
||||
# Then escape percent and underscore signs
|
||||
@@ -123,6 +134,7 @@ def sqlizeString(line):
|
||||
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
||||
return line
|
||||
|
||||
|
||||
@cachedQuery(User, 1, "lookfor")
|
||||
def getUser(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -141,6 +153,7 @@ def getUser(lookfor, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return user
|
||||
|
||||
|
||||
@cachedQuery(Character, 1, "lookfor")
|
||||
def getCharacter(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -154,17 +167,20 @@ def getCharacter(lookfor, eager=None):
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
character = saveddata_session.query(Character).options(*eager).filter(Character.savedName == lookfor).first()
|
||||
character = saveddata_session.query(Character).options(*eager).filter(
|
||||
Character.savedName == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return character
|
||||
|
||||
|
||||
def getCharacterList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
characters = saveddata_session.query(Character).options(*eager).all()
|
||||
return characters
|
||||
|
||||
|
||||
def getCharactersForUser(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
eager = processEager(eager)
|
||||
@@ -174,6 +190,7 @@ def getCharactersForUser(lookfor, eager=None):
|
||||
raise TypeError("Need integer as argument")
|
||||
return characters
|
||||
|
||||
|
||||
@cachedQuery(Fit, 1, "lookfor")
|
||||
def getFit(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -194,47 +211,6 @@ def getFit(lookfor, eager=None):
|
||||
|
||||
return fit
|
||||
|
||||
@cachedQuery(Fleet, 1, "fleetID")
|
||||
def getFleet(fleetID, eager=None):
|
||||
if isinstance(fleetID, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
fleet = saveddata_session.query(Fleet).get(fleetID)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return fleet
|
||||
|
||||
@cachedQuery(Wing, 1, "wingID")
|
||||
def getWing(wingID, eager=None):
|
||||
if isinstance(wingID, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
wing = saveddata_session.query(Wing).get(wingID)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return wing
|
||||
|
||||
@cachedQuery(Squad, 1, "squadID")
|
||||
def getSquad(squadID, eager=None):
|
||||
if isinstance(squadID, int):
|
||||
if eager is None:
|
||||
with sd_lock:
|
||||
squad = saveddata_session.query(Squad).get(squadID)
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
return squad
|
||||
|
||||
def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||
"""
|
||||
@@ -257,6 +233,7 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||
|
||||
return fits
|
||||
|
||||
|
||||
def getBoosterFits(ownerID=None, where=None, eager=None):
|
||||
"""
|
||||
Get all the fits that are flagged as a boosting ship
|
||||
@@ -276,31 +253,41 @@ def getBoosterFits(ownerID=None, where=None, eager=None):
|
||||
|
||||
return fits
|
||||
|
||||
|
||||
def countAllFits():
|
||||
with sd_lock:
|
||||
count = saveddata_session.query(Fit).count()
|
||||
return count
|
||||
|
||||
def countFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||
|
||||
def countFitsWithShip(lookfor, ownerID=None, where=None, eager=None):
|
||||
"""
|
||||
Get all the fits using a certain ship.
|
||||
If no user is passed, do this for all users.
|
||||
"""
|
||||
if isinstance(shipID, int):
|
||||
if ownerID is not None and not isinstance(ownerID, int):
|
||||
raise TypeError("OwnerID must be integer")
|
||||
filter = Fit.shipID == shipID
|
||||
if ownerID is not None:
|
||||
filter = and_(filter, Fit.ownerID == ownerID)
|
||||
if ownerID is not None and not isinstance(ownerID, int):
|
||||
raise TypeError("OwnerID must be integer")
|
||||
|
||||
filter = processWhere(filter, where)
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
|
||||
if isinstance(lookfor, int):
|
||||
filter = Fit.shipID == lookfor
|
||||
elif isinstance(lookfor, list):
|
||||
if len(lookfor) == 0:
|
||||
return 0
|
||||
filter = Fit.shipID.in_(lookfor)
|
||||
else:
|
||||
raise TypeError("ShipID must be integer")
|
||||
raise TypeError("You must supply either an integer or ShipID must be integer")
|
||||
|
||||
if ownerID is not None:
|
||||
filter = and_(filter, Fit.ownerID == ownerID)
|
||||
|
||||
filter = processWhere(filter, where)
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def getFitList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
@@ -308,11 +295,6 @@ def getFitList(eager=None):
|
||||
|
||||
return fits
|
||||
|
||||
def getFleetList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
fleets = saveddata_session.query(Fleet).options(*eager).all()
|
||||
return fleets
|
||||
|
||||
@cachedQuery(Price, 1, "typeID")
|
||||
def getPrice(typeID):
|
||||
@@ -323,12 +305,14 @@ def getPrice(typeID):
|
||||
raise TypeError("Need integer as argument")
|
||||
return price
|
||||
|
||||
|
||||
def clearPrices():
|
||||
with sd_lock:
|
||||
deleted_rows = saveddata_session.query(Price).delete()
|
||||
commit()
|
||||
return deleted_rows
|
||||
|
||||
|
||||
def getMiscData(field):
|
||||
if isinstance(field, basestring):
|
||||
with sd_lock:
|
||||
@@ -337,24 +321,28 @@ def getMiscData(field):
|
||||
raise TypeError("Need string as argument")
|
||||
return data
|
||||
|
||||
|
||||
def getDamagePatternList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
patterns = saveddata_session.query(DamagePattern).options(*eager).all()
|
||||
return patterns
|
||||
|
||||
|
||||
def getTargetResistsList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
patterns = saveddata_session.query(TargetResists).options(*eager).all()
|
||||
return patterns
|
||||
|
||||
|
||||
def getImplantSetList(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
sets = saveddata_session.query(ImplantSet).options(*eager).all()
|
||||
return sets
|
||||
|
||||
|
||||
@cachedQuery(DamagePattern, 1, "lookfor")
|
||||
def getDamagePattern(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -364,15 +352,18 @@ def getDamagePattern(lookfor, eager=None):
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.ID == lookfor).first()
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
|
||||
DamagePattern.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.name == lookfor).first()
|
||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
|
||||
DamagePattern.name == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return pattern
|
||||
|
||||
|
||||
@cachedQuery(TargetResists, 1, "lookfor")
|
||||
def getTargetResists(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -382,15 +373,18 @@ def getTargetResists(lookfor, eager=None):
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.ID == lookfor).first()
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
|
||||
TargetResists.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.name == lookfor).first()
|
||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
|
||||
TargetResists.name == lookfor).first()
|
||||
else:
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return pattern
|
||||
|
||||
|
||||
@cachedQuery(ImplantSet, 1, "lookfor")
|
||||
def getImplantSet(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -400,7 +394,8 @@ def getImplantSet(lookfor, eager=None):
|
||||
else:
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.ID == lookfor).first()
|
||||
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(
|
||||
TargetResists.ID == lookfor).first()
|
||||
elif isinstance(lookfor, basestring):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
@@ -409,13 +404,14 @@ def getImplantSet(lookfor, eager=None):
|
||||
raise TypeError("Improper argument")
|
||||
return pattern
|
||||
|
||||
|
||||
def searchFits(nameLike, where=None, eager=None):
|
||||
if not isinstance(nameLike, basestring):
|
||||
raise TypeError("Need string as argument")
|
||||
# Prepare our string for request
|
||||
nameLike = u"%{0}%".format(sqlizeString(nameLike))
|
||||
|
||||
#Add any extra components to the search to our where clause
|
||||
# Add any extra components to the search to our where clause
|
||||
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
@@ -423,14 +419,6 @@ def searchFits(nameLike, where=None, eager=None):
|
||||
|
||||
return fits
|
||||
|
||||
def getSquadsIDsWithFitID(fitID):
|
||||
if isinstance(fitID, int):
|
||||
with sd_lock:
|
||||
squads = saveddata_session.query(squadmembers_table.c.squadID).filter(squadmembers_table.c.memberID == fitID).all()
|
||||
squads = tuple(entry[0] for entry in squads)
|
||||
return squads
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
def getProjectedFits(fitID):
|
||||
if isinstance(fitID, int):
|
||||
@@ -441,12 +429,14 @@ def getProjectedFits(fitID):
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
|
||||
def getCrestCharacters(eager=None):
|
||||
eager = processEager(eager)
|
||||
with sd_lock:
|
||||
characters = saveddata_session.query(CrestChar).options(*eager).all()
|
||||
return characters
|
||||
|
||||
|
||||
@cachedQuery(CrestChar, 1, "lookfor")
|
||||
def getCrestCharacter(lookfor, eager=None):
|
||||
if isinstance(lookfor, int):
|
||||
@@ -465,21 +455,25 @@ def getCrestCharacter(lookfor, eager=None):
|
||||
raise TypeError("Need integer or string as argument")
|
||||
return character
|
||||
|
||||
|
||||
def getOverrides(itemID, eager=None):
|
||||
if isinstance(itemID, int):
|
||||
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
|
||||
else:
|
||||
raise TypeError("Need integer as argument")
|
||||
|
||||
|
||||
def clearOverrides():
|
||||
with sd_lock:
|
||||
deleted_rows = saveddata_session.query(Override).delete()
|
||||
commit()
|
||||
return deleted_rows
|
||||
|
||||
|
||||
def getAllOverrides(eager=None):
|
||||
return saveddata_session.query(Override).all()
|
||||
|
||||
|
||||
def removeInvalid(fits):
|
||||
invalids = [f for f in fits if f.isInvalid]
|
||||
|
||||
@@ -490,14 +484,17 @@ def removeInvalid(fits):
|
||||
|
||||
return fits
|
||||
|
||||
|
||||
def add(stuff):
|
||||
with sd_lock:
|
||||
saveddata_session.add(stuff)
|
||||
|
||||
|
||||
def save(stuff):
|
||||
add(stuff)
|
||||
commit()
|
||||
|
||||
|
||||
def remove(stuff):
|
||||
removeCachedEntry(type(stuff), stuff.ID)
|
||||
with sd_lock:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,8 +24,8 @@ from eos.db import saveddata_meta
|
||||
from eos.types import Skill
|
||||
|
||||
skills_table = Table("characterSkills", saveddata_meta,
|
||||
Column("characterID", ForeignKey("characters.ID"), primary_key = True, index = True),
|
||||
Column("itemID", Integer, primary_key = True),
|
||||
Column("_Skill__level", Integer, nullable = True))
|
||||
Column("characterID", ForeignKey("characters.ID"), primary_key=True, index=True),
|
||||
Column("itemID", Integer, primary_key=True),
|
||||
Column("_Skill__level", Integer, nullable=True))
|
||||
|
||||
mapper(Skill, skills_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,12 +24,12 @@ from eos.db import saveddata_meta
|
||||
from eos.types import TargetResists
|
||||
|
||||
targetResists_table = Table("targetResists", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("name", String),
|
||||
Column("emAmount", Float),
|
||||
Column("thermalAmount", Float),
|
||||
Column("kineticAmount", Float),
|
||||
Column("explosiveAmount", Float),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("name", String),
|
||||
Column("emAmount", Float),
|
||||
Column("thermalAmount", Float),
|
||||
Column("kineticAmount", Float),
|
||||
Column("explosiveAmount", Float),
|
||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
||||
|
||||
mapper(TargetResists, targetResists_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy import Table, Column, Integer, String, Boolean
|
||||
from sqlalchemy.orm import mapper
|
||||
@@ -24,9 +24,9 @@ from eos.db import saveddata_meta
|
||||
from eos.types import User
|
||||
|
||||
users_table = Table("users", saveddata_meta,
|
||||
Column("ID", Integer, primary_key = True),
|
||||
Column("username", String, nullable = False, unique = True),
|
||||
Column("password", String, nullable = False),
|
||||
Column("admin", Boolean, nullable = False))
|
||||
Column("ID", Integer, primary_key=True),
|
||||
Column("username", String, nullable=False, unique=True),
|
||||
Column("password", String, nullable=False),
|
||||
Column("admin", Boolean, nullable=False))
|
||||
|
||||
mapper(User, users_table)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,10 +15,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
from sqlalchemy.orm import eagerload
|
||||
from sqlalchemy.sql import and_, or_
|
||||
from sqlalchemy.sql import and_
|
||||
|
||||
replace = {"attributes": "_Item__attributes",
|
||||
"modules": "_Fit__modules",
|
||||
@@ -31,8 +31,9 @@ replace = {"attributes": "_Item__attributes",
|
||||
"damagePattern": "_Fit__damagePattern",
|
||||
"projectedFits": "_Fit__projectedFits"}
|
||||
|
||||
|
||||
def processEager(eager):
|
||||
if eager == None:
|
||||
if eager is None:
|
||||
return tuple()
|
||||
else:
|
||||
l = []
|
||||
@@ -44,6 +45,7 @@ def processEager(eager):
|
||||
|
||||
return l
|
||||
|
||||
|
||||
def _replacements(eagerString):
|
||||
splitEager = eagerString.split(".")
|
||||
for i in xrange(len(splitEager)):
|
||||
@@ -54,6 +56,7 @@ def _replacements(eagerString):
|
||||
|
||||
return ".".join(splitEager)
|
||||
|
||||
|
||||
def processWhere(clause, where):
|
||||
if where is not None:
|
||||
if not hasattr(where, "__iter__"):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,16 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
#from sqlalchemy.orm.attributes import flag_modified
|
||||
import eos.db
|
||||
import eos.types
|
||||
# from sqlalchemy.orm.attributes import flag_modified
|
||||
import logging
|
||||
|
||||
import eos.db
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HandledList(list):
|
||||
def filteredItemPreAssign(self, filter, *args, **kwargs):
|
||||
for element in self:
|
||||
@@ -108,11 +109,12 @@ class HandledList(list):
|
||||
def remove(self, thing):
|
||||
# We must flag it as modified, otherwise it not be removed from the database
|
||||
# @todo: flag_modified isn't in os x skel. need to rebuild to include
|
||||
#flag_modified(thing, "itemID")
|
||||
# flag_modified(thing, "itemID")
|
||||
if thing.isInvalid: # see GH issue #324
|
||||
thing.itemID = 0
|
||||
list.remove(self, thing)
|
||||
|
||||
|
||||
class HandledModuleList(HandledList):
|
||||
def append(self, mod):
|
||||
emptyPosition = float("Inf")
|
||||
@@ -169,10 +171,12 @@ class HandledModuleList(HandledList):
|
||||
self[index] = mod
|
||||
|
||||
def freeSlot(self, slot):
|
||||
for i in range(len(self) -1, -1, -1):
|
||||
for i in range(len(self)):
|
||||
mod = self[i]
|
||||
if mod.getModifiedItemAttr("subSystemSlot") == slot:
|
||||
del self[i]
|
||||
self.toDummy(i)
|
||||
break
|
||||
|
||||
|
||||
class HandledDroneCargoList(HandledList):
|
||||
def find(self, item):
|
||||
@@ -190,6 +194,7 @@ class HandledDroneCargoList(HandledList):
|
||||
if thing.isInvalid:
|
||||
self.remove(thing)
|
||||
|
||||
|
||||
class HandledImplantBoosterList(HandledList):
|
||||
def append(self, thing):
|
||||
if thing.isInvalid:
|
||||
@@ -206,6 +211,7 @@ class HandledImplantBoosterList(HandledList):
|
||||
|
||||
HandledList.append(self, thing)
|
||||
|
||||
|
||||
class HandledProjectedModList(HandledList):
|
||||
def append(self, proj):
|
||||
if proj.isInvalid:
|
||||
@@ -232,6 +238,7 @@ class HandledProjectedModList(HandledList):
|
||||
if not proj.item.isType("projected") and not isSystemEffect:
|
||||
self.remove(proj)
|
||||
|
||||
|
||||
class HandledProjectedDroneList(HandledDroneCargoList):
|
||||
def append(self, proj):
|
||||
proj.projected = True
|
||||
@@ -241,6 +248,7 @@ class HandledProjectedDroneList(HandledDroneCargoList):
|
||||
if proj.isInvalid or not proj.item.isType("projected"):
|
||||
self.remove(proj)
|
||||
|
||||
|
||||
class HandledItem(object):
|
||||
def preAssignItemAttr(self, *args, **kwargs):
|
||||
self.itemModifiedAttributes.preAssign(*args, **kwargs)
|
||||
@@ -257,6 +265,7 @@ class HandledItem(object):
|
||||
def forceItemAttr(self, *args, **kwargs):
|
||||
self.itemModifiedAttributes.force(*args, **kwargs)
|
||||
|
||||
|
||||
class HandledCharge(object):
|
||||
def preAssignChargeAttr(self, *args, **kwargs):
|
||||
self.chargeModifiedAttributes.preAssign(*args, **kwargs)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
# 2010 Anton Vorobyov
|
||||
#
|
||||
@@ -16,4 +16,4 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Used by:
|
||||
# Modules named like: Dynamic Fuel Valve (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||
"capacitorNeed", container.getModifiedItemAttr("capNeedBonus"))
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# Implant: Zor's Custom Navigation Hyper-Link
|
||||
# Skill: Acceleration Control
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Used by:
|
||||
# Implants named like: Eifyr and Co. 'Rogue' Acceleration Control AC (6 of 6)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, implant, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||
"speedFactor", implant.getModifiedItemAttr("speedFBonus"))
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
# Implant: Poteque 'Prospector' Archaeology AC-905
|
||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
fit.modules.filteredItemIncrease(lambda module: module.item.requiresSkill("Archaeology"),
|
||||
"accessDifficultyBonus",
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||
# Implant: Poteque 'Prospector' Hacking HC-905
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
fit.modules.filteredItemIncrease(lambda c: c.item.requiresSkill("Hacking"),
|
||||
"accessDifficultyBonus",
|
||||
container.getModifiedItemAttr("accessDifficultyBonusModifier"), position="post")
|
||||
"accessDifficultyBonus",
|
||||
container.getModifiedItemAttr("accessDifficultyBonusModifier"), position="post")
|
||||
|
||||
@@ -2,17 +2,120 @@
|
||||
#
|
||||
# Used by:
|
||||
# Module: Reactive Armor Hardener
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
runTime = "late"
|
||||
type = "active"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
for type in ("kinetic", "thermal", "explosive", "em"):
|
||||
attr = "armor%sDamageResonance" % type.capitalize()
|
||||
damagePattern = fit.damagePattern
|
||||
|
||||
#Adjust RAH to match the current damage pattern
|
||||
damagePattern = fit.damagePattern
|
||||
attrDamagePattern = "%sAmount" % type
|
||||
damagePatternModifier = getattr(damagePattern,attrDamagePattern)/float(sum((damagePattern.emAmount,damagePattern.thermalAmount,damagePattern.kineticAmount,damagePattern.explosiveAmount)))
|
||||
modifiedResistModifier = (1-(((1-module.getModifiedItemAttr(attr))*4)*(damagePatternModifier)))
|
||||
module.forceItemAttr(attr, modifiedResistModifier)
|
||||
# Skip if there is no damage pattern. Example: projected ships or fleet boosters
|
||||
if damagePattern:
|
||||
# logger.debug("Damage Pattern: %f/%f/%f/%f", damagePattern.emAmount, damagePattern.thermalAmount, damagePattern.kineticAmount, damagePattern.explosiveAmount)
|
||||
# logger.debug("Original Armor Resists: %f/%f/%f/%f", fit.ship.getModifiedItemAttr('armorEmDamageResonance'), fit.ship.getModifiedItemAttr('armorThermalDamageResonance'), fit.ship.getModifiedItemAttr('armorKineticDamageResonance'), fit.ship.getModifiedItemAttr('armorExplosiveDamageResonance'))
|
||||
|
||||
fit.ship.multiplyItemAttr(attr, module.getModifiedItemAttr(attr),
|
||||
stackingPenalties=True, penaltyGroup="preMul")
|
||||
# Populate a tuple with the damage profile modified by current armor resists.
|
||||
baseDamageTaken = (
|
||||
damagePattern.emAmount * fit.ship.getModifiedItemAttr('armorEmDamageResonance'),
|
||||
damagePattern.thermalAmount * fit.ship.getModifiedItemAttr('armorThermalDamageResonance'),
|
||||
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])
|
||||
|
||||
resistanceShiftAmount = module.getModifiedItemAttr(
|
||||
'resistanceShiftAmount') / 100 # The attribute is in percent and we want a fraction
|
||||
RAHResistance = [
|
||||
module.getModifiedItemAttr('armorEmDamageResonance'),
|
||||
module.getModifiedItemAttr('armorThermalDamageResonance'),
|
||||
module.getModifiedItemAttr('armorKineticDamageResonance'),
|
||||
module.getModifiedItemAttr('armorExplosiveDamageResonance'),
|
||||
]
|
||||
|
||||
# Simulate RAH cycles until the RAH either stops changing or enters a loop.
|
||||
# The number of iterations is limited to prevent an infinite loop if something goes wrong.
|
||||
cycleList = []
|
||||
loopStart = -20
|
||||
for num in range(50):
|
||||
# logger.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 = [
|
||||
(0, baseDamageTaken[0] * RAHResistance[0], RAHResistance[0]),
|
||||
(3, baseDamageTaken[3] * RAHResistance[3], RAHResistance[3]),
|
||||
(2, baseDamageTaken[2] * RAHResistance[2], RAHResistance[2]),
|
||||
(1, baseDamageTaken[1] * RAHResistance[1], RAHResistance[1]),
|
||||
]
|
||||
# logger.debug("Damage taken this cycle: %f/%f/%f/%f", damagePattern_tuples[0][1], damagePattern_tuples[3][1], damagePattern_tuples[2][1], damagePattern_tuples[1][1])
|
||||
|
||||
# Sort the tuple to drop the highest damage value to the bottom
|
||||
sortedDamagePattern_tuples = sorted(damagePattern_tuples, key=lambda damagePattern: damagePattern[1])
|
||||
|
||||
if sortedDamagePattern_tuples[2][1] == 0:
|
||||
# One damage type: the top damage type takes from the other three
|
||||
# Since the resistances not taking damage will end up going to the type taking damage we just do the whole thing at once.
|
||||
change0 = 1 - sortedDamagePattern_tuples[0][2]
|
||||
change1 = 1 - sortedDamagePattern_tuples[1][2]
|
||||
change2 = 1 - sortedDamagePattern_tuples[2][2]
|
||||
change3 = -(change0 + change1 + change2)
|
||||
elif sortedDamagePattern_tuples[1][1] == 0:
|
||||
# Two damage types: the top two damage types take from the other two
|
||||
# Since the resistances not taking damage will end up going equally to the types taking damage we just do the whole thing at once.
|
||||
change0 = 1 - sortedDamagePattern_tuples[0][2]
|
||||
change1 = 1 - sortedDamagePattern_tuples[1][2]
|
||||
change2 = -(change0 + change1) / 2
|
||||
change3 = -(change0 + change1) / 2
|
||||
else:
|
||||
# Three or four damage types: the top two damage types take from the other two
|
||||
change0 = min(resistanceShiftAmount, 1 - sortedDamagePattern_tuples[0][2])
|
||||
change1 = min(resistanceShiftAmount, 1 - sortedDamagePattern_tuples[1][2])
|
||||
change2 = -(change0 + change1) / 2
|
||||
change3 = -(change0 + change1) / 2
|
||||
|
||||
RAHResistance[sortedDamagePattern_tuples[0][0]] = sortedDamagePattern_tuples[0][2] + change0
|
||||
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])
|
||||
|
||||
# See if the current RAH profile has been encountered before, indicating a loop.
|
||||
for i, val in enumerate(cycleList):
|
||||
tolerance = 1e-06
|
||||
if abs(RAHResistance[0] - val[0]) <= tolerance and \
|
||||
abs(RAHResistance[1] - val[1]) <= tolerance and \
|
||||
abs(RAHResistance[2] - val[2]) <= tolerance and \
|
||||
abs(RAHResistance[3] - val[3]) <= tolerance:
|
||||
loopStart = i
|
||||
# logger.debug("Loop found: %d-%d", loopStart, num)
|
||||
break
|
||||
if loopStart >= 0:
|
||||
break
|
||||
|
||||
cycleList.append(list(RAHResistance))
|
||||
|
||||
if loopStart < 0:
|
||||
logger.error("Reactive Armor Hardener failed to find equilibrium. Damage profile after armor: %f/%f/%f/%f",
|
||||
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.
|
||||
loopCycles = cycleList[loopStart:]
|
||||
numCycles = len(loopCycles)
|
||||
average = [0, 0, 0, 0]
|
||||
for cycle in loopCycles:
|
||||
for i in range(4):
|
||||
average[i] += cycle[i]
|
||||
|
||||
for i in range(4):
|
||||
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])
|
||||
for i, attr in enumerate((
|
||||
'armorEmDamageResonance', 'armorThermalDamageResonance', 'armorKineticDamageResonance',
|
||||
'armorExplosiveDamageResonance')):
|
||||
module.increaseItemAttr(attr, average[i] - module.getModifiedItemAttr(attr))
|
||||
fit.ship.multiplyItemAttr(attr, average[i], stackingPenalties=True, penaltyGroup="preMul")
|
||||
|
||||
@@ -4,5 +4,7 @@
|
||||
# Modules from group: Missile Launcher Bomb (2 of 2)
|
||||
# Modules from group: Shield Extender (33 of 33)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.increaseItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusAdd"))
|
||||
fit.ship.increaseItemAttr("signatureRadius", module.getModifiedItemAttr("signatureRadiusAdd"))
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# advancedDroneInterfacingMaxGroupDCUSkillLevel
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Advanced Drone Interfacing
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.group.name == "Fighter Support Unit",
|
||||
"maxGroupActive", skill.level)
|
||||
@@ -5,7 +5,9 @@
|
||||
# Implant: Zor's Custom Navigation Link
|
||||
# Skill: Afterburner
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Afterburner"),
|
||||
"duration", container.getModifiedItemAttr("durationBonus") * level)
|
||||
"duration", container.getModifiedItemAttr("durationBonus") * level)
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
# Modules from group: Nanofiber Internal Structure (7 of 7)
|
||||
# Modules from group: Reinforced Bulkhead (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("agility",
|
||||
module.getModifiedItemAttr("agilityMultiplier"),
|
||||
stackingPenalties = True)
|
||||
stackingPenalties=True)
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
# Used by:
|
||||
# Modules named like: Polycarbon Engine Housing (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityMultiplier"), stackingPenalties = True)
|
||||
fit.ship.boostItemAttr("agility", module.getModifiedItemAttr("agilityMultiplier"), stackingPenalties=True)
|
||||
|
||||
@@ -8,5 +8,7 @@
|
||||
# Charges from group: Advanced Pulse Laser Crystal (8 of 8)
|
||||
# Charges from group: Advanced Railgun Charge (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.multiplyItemAttr("falloff", module.getModifiedChargeAttr("fallofMultiplier") or 1)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# ammoInfluenceCapNeed
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (465 of 884)
|
||||
# Items from category: Charge (465 of 899)
|
||||
# Charges from group: Frequency Crystal (185 of 185)
|
||||
# Charges from group: Hybrid Charge (209 of 209)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
# Dirty hack to work around cap charges setting cap booster
|
||||
# injection amount to zero
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# ammoInfluenceRange
|
||||
#
|
||||
# Used by:
|
||||
# Items from category: Charge (571 of 884)
|
||||
# Items from category: Charge (571 of 899)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.multiplyItemAttr("maxRange", module.getModifiedChargeAttr("weaponRangeMultiplier"))
|
||||
module.multiplyItemAttr("maxRange", module.getModifiedChargeAttr("weaponRangeMultiplier"))
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# ammoSpeedMultiplier
|
||||
#
|
||||
# Used by:
|
||||
# Charges from group: Festival Charges (8 of 8)
|
||||
# Charges from group: Festival Charges (9 of 9)
|
||||
# Charges from group: Interdiction Probe (2 of 2)
|
||||
# Charges from group: Survey Probe (3 of 3)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.multiplyItemAttr("speed", module.getModifiedChargeAttr("speedMultiplier") or 1)
|
||||
|
||||
@@ -9,5 +9,7 @@
|
||||
# Charges from group: Advanced Railgun Charge (8 of 8)
|
||||
# Charges from group: Projectile Ammo (129 of 129)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
module.multiplyItemAttr("trackingSpeed", module.getModifiedChargeAttr("trackingSpeedMultiplier"))
|
||||
module.multiplyItemAttr("trackingSpeed", module.getModifiedChargeAttr("trackingSpeedMultiplier"))
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
# Implants named like: grade Halo (18 of 18)
|
||||
runTime = "early"
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, implant, context):
|
||||
fit.appliedImplants.filteredItemMultiply(
|
||||
lambda implant: "signatureRadiusBonus" in implant.itemModifiedAttributes and "implantSetAngel" in implant.itemModifiedAttributes,
|
||||
lambda implant: "signatureRadiusBonus" in implant.itemModifiedAttributes and
|
||||
"implantSetAngel" in implant.itemModifiedAttributes,
|
||||
"signatureRadiusBonus",
|
||||
implant.getModifiedItemAttr("implantSetAngel"))
|
||||
implant.getModifiedItemAttr("implantSetAngel"))
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Warp Core Stabilizer (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.increaseItemAttr("warmScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
|
||||
fit.ship.increaseItemAttr("warmScrambleStatus", module.getModifiedItemAttr("warpScrambleStrength"))
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||
# Skill: Archaeology
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, container, context):
|
||||
level = container.level if "skill" in context else 1
|
||||
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Archaeology"),
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
# Implants named like: Exile Booster (4 of 4)
|
||||
# Implant: Antipharmakon Kosybo
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, booster, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Repair Systems") or mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", booster.getModifiedItemAttr("armorDamageAmountBonus"))
|
||||
fit.modules.filteredItemBoost(
|
||||
lambda mod: mod.item.requiresSkill("Repair Systems") or mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", booster.getModifiedItemAttr("armorDamageAmountBonus"))
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Used by:
|
||||
# Modules named like: Auxiliary Nano Pump (8 of 8)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, implant, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
|
||||
"armorDamageAmount", implant.getModifiedItemAttr("repairBonus"),
|
||||
|
||||
11
eos/effects/armoredcommanddurationbonus.py
Normal file
11
eos/effects/armoredcommanddurationbonus.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# armoredCommandDurationBonus
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Armored Command
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
lvl = src.level
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
|
||||
src.getModifiedItemAttr("durationBonus") * lvl)
|
||||
20
eos/effects/armoredcommandmindlink.py
Normal file
20
eos/effects/armoredcommandmindlink.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# armoredCommandMindlink
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Armored Command Mindlink
|
||||
# Implant: Federation Navy Command Mindlink
|
||||
# Implant: Imperial Navy Command Mindlink
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier",
|
||||
src.getModifiedItemAttr("mindlinkBonus"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier",
|
||||
src.getModifiedItemAttr("mindlinkBonus"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier",
|
||||
src.getModifiedItemAttr("mindlinkBonus"))
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier",
|
||||
src.getModifiedItemAttr("mindlinkBonus"))
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "buffDuration",
|
||||
src.getModifiedItemAttr("mindlinkBonus"))
|
||||
17
eos/effects/armoredcommandstrengthbonus.py
Normal file
17
eos/effects/armoredcommandstrengthbonus.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# armoredCommandStrengthBonus
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Armored Command Specialist
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, src, context):
|
||||
lvl = src.level
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff1Multiplier",
|
||||
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff2Multiplier",
|
||||
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff4Multiplier",
|
||||
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
|
||||
fit.modules.filteredChargeBoost(lambda mod: mod.item.requiresSkill("Armored Command"), "warfareBuff3Multiplier",
|
||||
src.getModifiedItemAttr("commandStrengthBonus") * lvl)
|
||||
@@ -1,9 +0,0 @@
|
||||
# armoredSquadronCommand
|
||||
#
|
||||
# Used by:
|
||||
# Skill: Armored Warfare Specialist
|
||||
runTime = "early"
|
||||
type = "passive"
|
||||
def handler(fit, skill, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Warfare Specialist"),
|
||||
"commandBonus", skill.getModifiedItemAttr("squadronCommandBonus") * skill.level)
|
||||
@@ -1,10 +0,0 @@
|
||||
# armoredWarfareMindlink
|
||||
#
|
||||
# Used by:
|
||||
# Implant: Armored Warfare Mindlink
|
||||
# Implant: Federation Navy Warfare Mindlink
|
||||
# Implant: Imperial Navy Warfare Mindlink
|
||||
type = "passive"
|
||||
def handler(fit, implant, context):
|
||||
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Armored Warfare Specialist"),
|
||||
"commandBonus", implant.getModifiedItemAttr("mindlinkBonus"))
|
||||
@@ -3,5 +3,7 @@
|
||||
# Used by:
|
||||
# Modules from group: Armor Reinforcer (48 of 48)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.increaseItemAttr("armorHP", module.getModifiedItemAttr("armorHPBonusAdd"))
|
||||
fit.ship.increaseItemAttr("armorHP", module.getModifiedItemAttr("armorHPBonusAdd"))
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
# Used by:
|
||||
# Subsystems from group: Defensive Systems (16 of 16)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.increaseItemAttr("armorHP", module.getModifiedItemAttr("armorHPBonusAdd"))
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
# Modules from group: Armor Plating Energized (187 of 187)
|
||||
# Modules named like: QA Multiship Module Players (4 of 4)
|
||||
type = "passive"
|
||||
|
||||
|
||||
def handler(fit, module, context):
|
||||
fit.ship.multiplyItemAttr("armorHP", module.getModifiedItemAttr("armorHPMultiplier"))
|
||||
fit.ship.multiplyItemAttr("armorHP", module.getModifiedItemAttr("armorHPMultiplier"))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user