Compare commits
1953 Commits
singularit
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1e239b9b3 | ||
|
|
26aaeabd7f | ||
|
|
0e0bc9dfd2 | ||
|
|
8990cbfd6a | ||
|
|
8f34c03289 | ||
|
|
c1322a3566 | ||
|
|
5101e2851a | ||
|
|
7b7f67ad2e | ||
|
|
dbdc566ae4 | ||
|
|
f4fd991907 | ||
|
|
42ad74158b | ||
|
|
c99afa79e1 | ||
|
|
789c3b869a | ||
|
|
7d8d87662b | ||
|
|
645a5ced14 | ||
|
|
5ed98e8fed | ||
|
|
f12370389c | ||
|
|
fc35d7bb26 | ||
|
|
95c1f7bde0 | ||
|
|
d52c249921 | ||
|
|
0b9a50cd8d | ||
|
|
25bbfec318 | ||
|
|
1192c26b8f | ||
|
|
4a3201ffd4 | ||
|
|
406a22100d | ||
|
|
2547cf70c2 | ||
|
|
e83fa4d40b | ||
|
|
c552cb5e40 | ||
|
|
363904411d | ||
|
|
49bc9f50bc | ||
|
|
30501feb99 | ||
|
|
efc07e1553 | ||
|
|
9bbeec523e | ||
|
|
943ee517f4 | ||
|
|
18bb3bf246 | ||
|
|
117d51caab | ||
|
|
a3e411f225 | ||
|
|
083af3ebc7 | ||
|
|
3fd4d106d9 | ||
|
|
7c376c93a2 | ||
|
|
4ef7b645a8 | ||
|
|
cccc7ff2d0 | ||
|
|
b7c45f4c6e | ||
|
|
3964658d9a | ||
|
|
03212be54a | ||
|
|
46098f2127 | ||
|
|
2005d0b0b9 | ||
|
|
3293380515 | ||
|
|
68e5b22fe2 | ||
|
|
0f7dd7cc0c | ||
|
|
0713251685 | ||
|
|
3fda62e320 | ||
|
|
5f1c2d6676 | ||
|
|
c0ba559ca6 | ||
|
|
164720db3d | ||
|
|
bd90ec4bf0 | ||
|
|
d7e24dfa8f | ||
|
|
2f1ad21392 | ||
|
|
687d539534 | ||
|
|
bd6793bc19 | ||
|
|
6dd6452c11 | ||
|
|
e59a1cd27b | ||
|
|
24d14d5e19 | ||
|
|
e0584367c5 | ||
|
|
a2f48e8944 | ||
|
|
95ba18f8a9 | ||
|
|
122d8ef367 | ||
|
|
281d2ed1f4 | ||
|
|
48924774f9 | ||
|
|
ee00914a2b | ||
|
|
48d90c1eca | ||
|
|
415b3db809 | ||
|
|
53451dfaf6 | ||
|
|
49181dce2b | ||
|
|
199763bcca | ||
|
|
033647da61 | ||
|
|
00e8e9d84a | ||
|
|
96b701687b | ||
|
|
e1e90cc23e | ||
|
|
f41ecae8c8 | ||
|
|
65ec8cf4ee | ||
|
|
4fc93f7089 | ||
|
|
3ec01a20c2 | ||
|
|
8a10f0a766 | ||
|
|
0db125177f | ||
|
|
a3f532f62f | ||
|
|
234f36c8c0 | ||
|
|
2c3957b2db | ||
|
|
79deca41c1 | ||
|
|
570df7f645 | ||
|
|
8153b80d05 | ||
|
|
b74654a5b3 | ||
|
|
4c6f68b07e | ||
|
|
9839efc2dc | ||
|
|
9d379d966c | ||
|
|
61086989dc | ||
|
|
023ea43611 | ||
|
|
044e032ab3 | ||
|
|
da7b95041d | ||
|
|
f52f39984f | ||
|
|
1513b07071 | ||
|
|
be19b7414a | ||
|
|
75f9a0252a | ||
|
|
5169c35d5c | ||
|
|
bbdf1ee6cc | ||
|
|
6c6e8a9972 | ||
|
|
97742b08c8 | ||
|
|
8ef4c61fc3 | ||
|
|
ff607e4b03 | ||
|
|
30c1ab125c | ||
|
|
8276746dad | ||
|
|
5560ef4d34 | ||
|
|
fac31f7254 | ||
|
|
1efcc8d3ef | ||
|
|
03c2088e6b | ||
|
|
5c20ee7ade | ||
|
|
04c62aabea | ||
|
|
0994158abd | ||
|
|
77a66a66ea | ||
|
|
0b615b578a | ||
|
|
53f07db5fe | ||
|
|
4d4815d6af | ||
|
|
b296e0709c | ||
|
|
373e0a390b | ||
|
|
222037ff40 | ||
|
|
4fac10ccb7 | ||
|
|
7956ca0409 | ||
|
|
5b27d0559f | ||
|
|
85157fdf85 | ||
|
|
caf8e7f2d6 | ||
|
|
124bb027ab | ||
|
|
d5ca14ca52 | ||
|
|
99982aa547 | ||
|
|
3f4493c0ea | ||
|
|
cdb604b29f | ||
|
|
d3b8cebc8a | ||
|
|
7d245660bc | ||
|
|
b1e40427a3 | ||
|
|
73925df24b | ||
|
|
04fbd3b548 | ||
|
|
d9dd94d6c3 | ||
|
|
963353a1dc | ||
|
|
3411dcfd91 | ||
|
|
ae6434affb | ||
|
|
f773e0a935 | ||
|
|
7ab3ad9e08 | ||
|
|
3f3a82ca6c | ||
|
|
e902cc5780 | ||
|
|
fcb6952119 | ||
|
|
3eecd57979 | ||
|
|
6e73b9fefd | ||
|
|
f0b0285f77 | ||
|
|
e706a015b3 | ||
|
|
a804f9a1ad | ||
|
|
9e1b7dbb87 | ||
|
|
551ffe9ed3 | ||
|
|
cbe1ce5bcd | ||
|
|
917afd5067 | ||
|
|
c3fb9231a4 | ||
|
|
2ed2f8e262 | ||
|
|
390d90ac47 | ||
|
|
4c877e7a5a | ||
|
|
972fe433f7 | ||
|
|
ecaf6f96a9 | ||
|
|
8541e2a869 | ||
|
|
48a2963472 | ||
|
|
f245a02372 | ||
|
|
1c16343b46 | ||
|
|
d0f66f2d16 | ||
|
|
df0c6ed269 | ||
|
|
9a4e26a5be | ||
|
|
2b87f91279 | ||
|
|
9b48b61b9b | ||
|
|
57e67b3699 | ||
|
|
15e60c3d24 | ||
|
|
ebf07db6c6 | ||
|
|
1559767201 | ||
|
|
6e5e52df37 | ||
|
|
e9289c102b | ||
|
|
81d61d7e29 | ||
|
|
9ab4ec2d4f | ||
|
|
565332dfcd | ||
|
|
f94fbd740a | ||
|
|
a2719ec2f7 | ||
|
|
1da12cb18e | ||
|
|
e0cddcd061 | ||
|
|
78f632a4f6 | ||
|
|
52754535a0 | ||
|
|
a9db667c9c | ||
|
|
f442632fbc | ||
|
|
362086cc83 | ||
|
|
73d59569ff | ||
|
|
cb4fadf84c | ||
|
|
e85d144928 | ||
|
|
07099f4057 | ||
|
|
96c13c344a | ||
|
|
8f42822d9e | ||
|
|
c5ba79cfbb | ||
|
|
f69f76856a | ||
|
|
3a23d820cc | ||
|
|
c917d22db5 | ||
|
|
c3f8b102fa | ||
|
|
5e566db47d | ||
|
|
5b2c5907ed | ||
|
|
dd78a41171 | ||
|
|
201fb4e241 | ||
|
|
8abd25fe40 | ||
|
|
d59c897921 | ||
|
|
cb89d13d9f | ||
|
|
a1aa78adc0 | ||
|
|
4bbbd33917 | ||
|
|
42ccc53166 | ||
|
|
35ad21da38 | ||
|
|
72efef818f | ||
|
|
5571bae8b2 | ||
|
|
8b2cfe44f2 | ||
|
|
5ea7215ec0 | ||
|
|
e2ac90a040 | ||
|
|
6ab84240a2 | ||
|
|
12a526fa9e | ||
|
|
82e3db1ffb | ||
|
|
e779bb84e2 | ||
|
|
bd0fcbef3a | ||
|
|
0456cb2f96 | ||
|
|
cafd92f169 | ||
|
|
05f08970c9 | ||
|
|
f66485c48a | ||
|
|
2153c05183 | ||
|
|
f66c36e42b | ||
|
|
8771de9c1f | ||
|
|
fa3cf90421 | ||
|
|
636ee1de23 | ||
|
|
b36bf8fb21 | ||
|
|
55ad52919e | ||
|
|
0648feaa7b | ||
|
|
e16ae88ed9 | ||
|
|
c5c673e360 | ||
|
|
5cd21da7b1 | ||
|
|
da0f89ef91 | ||
|
|
efc3f1ba7d | ||
|
|
8d7f0b56f1 | ||
|
|
89b6e8f8c3 | ||
|
|
c6e715aa5c | ||
|
|
0e93136157 | ||
|
|
89c84aac96 | ||
|
|
649ba9f3e4 | ||
|
|
2d38fd4773 | ||
|
|
23f0f48c80 | ||
|
|
6254fa3e23 | ||
|
|
8686c02b1f | ||
|
|
fe1c4cc4d4 | ||
|
|
ed649dd4c7 | ||
|
|
33618f12f7 | ||
|
|
33eccaa374 | ||
|
|
5f0ce58c29 | ||
|
|
c329f5eeb8 | ||
|
|
320a0230f4 | ||
|
|
d94d49f0a9 | ||
|
|
9bfc5b35b6 | ||
|
|
0f30ea554d | ||
|
|
50dd74dbe8 | ||
|
|
9c355d8f96 | ||
|
|
7b0f672f04 | ||
|
|
33bf5234d0 | ||
|
|
cb392e7e5f | ||
|
|
dfba033190 | ||
|
|
5fbe623ae6 | ||
|
|
e025bff99b | ||
|
|
e77dddc15b | ||
|
|
eea8019593 | ||
|
|
c7360c8cc3 | ||
|
|
f81179db4b | ||
|
|
2d7eed4aac | ||
|
|
96828a5611 | ||
|
|
8a0f8ae609 | ||
|
|
ac8f805fcb | ||
|
|
9f3c2ca7a8 | ||
|
|
2376148380 | ||
|
|
2e8d7d3610 | ||
|
|
3179016aed | ||
|
|
514db91d7a | ||
|
|
269d3f326d | ||
|
|
b04fcb0d15 | ||
|
|
a29b3da8a6 | ||
|
|
18a5e35e80 | ||
|
|
3072dbb3ff | ||
|
|
b103f0df7e | ||
|
|
9e8166c13d | ||
|
|
9f7e4e0dc0 | ||
|
|
29d175c7b3 | ||
|
|
0c971a127c | ||
|
|
40ce7b7c0b | ||
|
|
a8060a5e15 | ||
|
|
cc063d1934 | ||
|
|
531721ef5e | ||
|
|
2936b88c3d | ||
|
|
2365112292 | ||
|
|
1daef5354d | ||
|
|
6f19d45c6d | ||
|
|
ac7908c62c | ||
|
|
c000b19986 | ||
|
|
1da127c898 | ||
|
|
fcdf55632f | ||
|
|
dd3bc66896 | ||
|
|
da67cdba9b | ||
|
|
8850da6cdb | ||
|
|
7d46d7e22d | ||
|
|
b3157303cd | ||
|
|
65e17119af | ||
|
|
f7b509f9a9 | ||
|
|
dea775058d | ||
|
|
3c405f51d8 | ||
|
|
337f0a9c8a | ||
|
|
53936a3e66 | ||
|
|
30a6e29b39 | ||
|
|
f3dc3bc654 | ||
|
|
0a935cf149 | ||
|
|
5697da7ec2 | ||
|
|
a7086b78cb | ||
|
|
e032c9c5b1 | ||
|
|
46b0aded03 | ||
|
|
d23398ce29 | ||
|
|
5e0a5da6d5 | ||
|
|
6e112b9ed5 | ||
|
|
b30b3fcbf1 | ||
|
|
455fea75c0 | ||
|
|
bd181559ed | ||
|
|
967128cb69 | ||
|
|
5fa43138b3 | ||
|
|
f0baba10df | ||
|
|
7058018aed | ||
|
|
d45d7204d2 | ||
|
|
b596447095 | ||
|
|
25df05a15d | ||
|
|
4a33365195 | ||
|
|
5d5646df79 | ||
|
|
405a965046 | ||
|
|
4138088d4a | ||
|
|
de44e6f932 | ||
|
|
d4df989427 | ||
|
|
6c8b143936 | ||
|
|
0f94557699 | ||
|
|
a52b9e58e9 | ||
|
|
0d8904d59f | ||
|
|
d956cb7861 | ||
|
|
e848cec815 | ||
|
|
ce8f1d385d | ||
|
|
90e338b969 | ||
|
|
1978f5cb92 | ||
|
|
979bc494f0 | ||
|
|
cc9b6ea04b | ||
|
|
8cbb327659 | ||
|
|
2f6e306f8e | ||
|
|
065747f425 | ||
|
|
c4f41fb5fa | ||
|
|
e4f3ed05cc | ||
|
|
0e84d6c557 | ||
|
|
c384848870 | ||
|
|
1fc9b2941d | ||
|
|
e9be07f281 | ||
|
|
df7dc30e7e | ||
|
|
d0235f6d93 | ||
|
|
de646cf252 | ||
|
|
21838f2d9a | ||
|
|
266398b1de | ||
|
|
0cc646bab9 | ||
|
|
cebca64e5e | ||
|
|
bd0de82a8e | ||
|
|
0f5ae8d9b6 | ||
|
|
5ae7805bb1 | ||
|
|
6a382c4445 | ||
|
|
3b0c8b6117 | ||
|
|
0e1e4cad6d | ||
|
|
e0b92198b0 | ||
|
|
ce3b94696a | ||
|
|
cacf286176 | ||
|
|
a02bbe3964 | ||
|
|
866d410695 | ||
|
|
ea6f31c021 | ||
|
|
d522fff511 | ||
|
|
ca27cd3250 | ||
|
|
20a1618e41 | ||
|
|
2830729cb4 | ||
|
|
c0e15f61c6 | ||
|
|
4355f35eef | ||
|
|
029e61edaf | ||
|
|
b18f82505b | ||
|
|
f8a65de47f | ||
|
|
e5a0ef1877 | ||
|
|
8647fe460c | ||
|
|
a4950e9015 | ||
|
|
82d50cfa0d | ||
|
|
efea46006a | ||
|
|
d9800dcf19 | ||
|
|
266b3ce985 | ||
|
|
3b61a07c55 | ||
|
|
5dc092ace5 | ||
|
|
7b32fe08ac | ||
|
|
fd6e318ae3 | ||
|
|
504c395ea2 | ||
|
|
9ed210d5b5 | ||
|
|
c7f0f6215a | ||
|
|
34c692c972 | ||
|
|
56f34873a6 | ||
|
|
b4dfcf53fb | ||
|
|
3c26676b66 | ||
|
|
3fb7411b9d | ||
|
|
cac8e528a3 | ||
|
|
2afc8b1abe | ||
|
|
06e82a04b4 | ||
|
|
782df18501 | ||
|
|
a87d659e5d | ||
|
|
cd35c9319c | ||
|
|
dfe3d5c82a | ||
|
|
ccd8cdd099 | ||
|
|
72062e6213 | ||
|
|
10836acab2 | ||
|
|
08ab8fbc5b | ||
|
|
da5aaf2f78 | ||
|
|
4484b68a3a | ||
|
|
81fce93186 | ||
|
|
d58987e427 | ||
|
|
05a5ebff00 | ||
|
|
2f28afc7ae | ||
|
|
0134c3b9a1 | ||
|
|
9f433fd072 | ||
|
|
7729bd9210 | ||
|
|
ce5803dd9c | ||
|
|
821ede8579 | ||
|
|
592f9a2298 | ||
|
|
c30c07b91c | ||
|
|
73d9dd60e6 | ||
|
|
dbdbe155f3 | ||
|
|
7d41260863 | ||
|
|
d53ff0f502 | ||
|
|
f37f4573bf | ||
|
|
ee392e07c4 | ||
|
|
59b09a255a | ||
|
|
3e73c2eb34 | ||
|
|
3625b4395a | ||
|
|
1444a24e70 | ||
|
|
73dfa25ef0 | ||
|
|
a01284ff1c | ||
|
|
8cc81cebdd | ||
|
|
c33aeb7275 | ||
|
|
c0237905b6 | ||
|
|
eda6d738a4 | ||
|
|
eef3b420a9 | ||
|
|
caef752a74 | ||
|
|
e13bd7af52 | ||
|
|
c263575788 | ||
|
|
5bd80d3d06 | ||
|
|
47cbc71e8a | ||
|
|
fdba8d147f | ||
|
|
4720b611b0 | ||
|
|
1f43410780 | ||
|
|
ead595e666 | ||
|
|
89cf40423b | ||
|
|
95d6944298 | ||
|
|
a3c19d1d1c | ||
|
|
88185cb886 | ||
|
|
7962aa7b1b | ||
|
|
220ce23e8f | ||
|
|
66752b2cbf | ||
|
|
f59a65f314 | ||
|
|
725034ebc5 | ||
|
|
0210020658 | ||
|
|
22dc6512c0 | ||
|
|
709b4524e6 | ||
|
|
bc462ede3e | ||
|
|
277bd14453 | ||
|
|
59fed2c516 | ||
|
|
d19486ce15 | ||
|
|
b55fcfaf04 | ||
|
|
60e5085724 | ||
|
|
5adde95807 | ||
|
|
3da0b8bc29 | ||
|
|
0104e8954a | ||
|
|
78e065feff | ||
|
|
30fe7930a9 | ||
|
|
453054f6c7 | ||
|
|
231f9a91c2 | ||
|
|
c553790eaf | ||
|
|
f2e8506ea7 | ||
|
|
76b22dfe17 | ||
|
|
1202c335d9 | ||
|
|
f70d671f1d | ||
|
|
1305a1f2b6 | ||
|
|
f5108c34db | ||
|
|
d553c60b65 | ||
|
|
be84cf1db7 | ||
|
|
854d7cb09c | ||
|
|
b70f401a91 | ||
|
|
496b28226d | ||
|
|
fec7c8fd0b | ||
|
|
f8e5e15051 | ||
|
|
78b273455d | ||
|
|
de35692666 | ||
|
|
49b2e42d8c | ||
|
|
307ccd10e8 | ||
|
|
1225f2074a | ||
|
|
afee4469f0 | ||
|
|
3b716e6e5e | ||
|
|
961b389b40 | ||
|
|
e9c691575f | ||
|
|
27236feec3 | ||
|
|
2e598a7ef7 | ||
|
|
0527a506ac | ||
|
|
1082d8a173 | ||
|
|
7ae41b71b2 | ||
|
|
de5a734919 | ||
|
|
987c55ed8f | ||
|
|
57783fe80f | ||
|
|
f24c2ddd22 | ||
|
|
58a242f753 | ||
|
|
5c2cf6dd15 | ||
|
|
287f3bc510 | ||
|
|
caaa6bcd0c | ||
|
|
b01c961251 | ||
|
|
826c73c903 | ||
|
|
b6a28ae15f | ||
|
|
ad0d55faed | ||
|
|
910ae6315d | ||
|
|
25b4d3a45b | ||
|
|
f355cb3a72 | ||
|
|
ff58648f94 | ||
|
|
f16e14e0b4 | ||
|
|
729c46ab00 | ||
|
|
3b546de070 | ||
|
|
ba64f75f88 | ||
|
|
4b8f2ce9e7 | ||
|
|
8c5c7fba29 | ||
|
|
bec26d5d05 | ||
|
|
8f369daf1e | ||
|
|
43cbdc1e57 | ||
|
|
cf4d0706ae | ||
|
|
2857eff884 | ||
|
|
050f1b4add | ||
|
|
2bbcd96ce3 | ||
|
|
1cbd8ee901 | ||
|
|
7e86cb0f84 | ||
|
|
0e7dccccfe | ||
|
|
9d75dea31a | ||
|
|
610f501608 | ||
|
|
361f7fc5bb | ||
|
|
951b35a345 | ||
|
|
6c317d56ee | ||
|
|
2acb3e759e | ||
|
|
9712ec4fbf | ||
|
|
ae0da59ed2 | ||
|
|
8e4db5a8c3 | ||
|
|
7f392006d1 | ||
|
|
828b18d0fd | ||
|
|
ad535ccc78 | ||
|
|
9dee761f6d | ||
|
|
f5531b458b | ||
|
|
a7c89f7b40 | ||
|
|
048ae0205c | ||
|
|
e6a0784466 | ||
|
|
53d15425f3 | ||
|
|
a79257271e | ||
|
|
94256876e4 | ||
|
|
d319b74d7a | ||
|
|
acb7c0878e | ||
|
|
47fcbefe8b | ||
|
|
c2cb5d763f | ||
|
|
208148b670 | ||
|
|
cf02c74272 | ||
|
|
f77cd0b834 | ||
|
|
461f5219e5 | ||
|
|
373ead8da6 | ||
|
|
3371086d54 | ||
|
|
45c3533501 | ||
|
|
4286f2ea5a | ||
|
|
344546a583 | ||
|
|
46f61ecfa3 | ||
|
|
2ec9c5addb | ||
|
|
d09f21fe15 | ||
|
|
33410f0618 | ||
|
|
2c98baade8 | ||
|
|
380f90d065 | ||
|
|
1781c6dcf0 | ||
|
|
cff3d0ee95 | ||
|
|
d1fc2dd6ec | ||
|
|
218712835e | ||
|
|
5a60cff9a1 | ||
|
|
18554e3186 | ||
|
|
2e2303c9aa | ||
|
|
fbf455c9fe | ||
|
|
00dcda6fad | ||
|
|
3be7538daa | ||
|
|
9e0638c54c | ||
|
|
a5ff46fbd1 | ||
|
|
6900938208 | ||
|
|
4887817142 | ||
|
|
0d721b55a7 | ||
|
|
65f71b6f6b | ||
|
|
89b508d0f6 | ||
|
|
6344f7a975 | ||
|
|
11eea37aa7 | ||
|
|
bff44c46f8 | ||
|
|
7a0ea759ef | ||
|
|
f9419977c0 | ||
|
|
da33a372cb | ||
|
|
0db141d0a6 | ||
|
|
79445225de | ||
|
|
a0f5e4cbb3 | ||
|
|
3b23c9eacd | ||
|
|
d4ce1ef3db | ||
|
|
b4f063b07a | ||
|
|
ffe840e245 | ||
|
|
2e3c3e92f1 | ||
|
|
5e20d6973f | ||
|
|
c68739d78c | ||
|
|
5392aaa27e | ||
|
|
fee82d294b | ||
|
|
9f5e14fe2d | ||
|
|
b39ec4f9b3 | ||
|
|
25bfb4ddb8 | ||
|
|
de9b167242 | ||
|
|
18d44979e4 | ||
|
|
1eddad859a | ||
|
|
e2de1565bf | ||
|
|
fc9408d062 | ||
|
|
cb98618e5e | ||
|
|
892ee13542 | ||
|
|
2595c59c73 | ||
|
|
93c26aa02f | ||
|
|
a6a153b703 | ||
|
|
38e6e7d5ed | ||
|
|
4d8c9e0522 | ||
|
|
e75e2b7605 | ||
|
|
0e81c985a3 | ||
|
|
21a071ea40 | ||
|
|
4f1e7697ed | ||
|
|
ccfd414cb3 | ||
|
|
3de63c5ca5 | ||
|
|
42e64a6223 | ||
|
|
53f589284b | ||
|
|
aecbf8f86e | ||
|
|
dd09b3d951 | ||
|
|
f022c2474c | ||
|
|
249956689a | ||
|
|
6b22bd189a | ||
|
|
524bb43113 | ||
|
|
83a7a854bb | ||
|
|
0507a55731 | ||
|
|
f1eb3f68d1 | ||
|
|
1604ea1f2c | ||
|
|
4a9662c0f7 | ||
|
|
47a683c44c | ||
|
|
d888982657 | ||
|
|
184c46dbce | ||
|
|
b2ae6913d7 | ||
|
|
703d6dbc85 | ||
|
|
2e6066e848 | ||
|
|
f751eff1cf | ||
|
|
d342e66db4 | ||
|
|
1222567a4f | ||
|
|
1f7858f853 | ||
|
|
283cb1e50c | ||
|
|
c2880c0175 | ||
|
|
3d0a4b84d4 | ||
|
|
622efb624d | ||
|
|
50965244c0 | ||
|
|
9e6aca2496 | ||
|
|
1cf844d415 | ||
|
|
f57e7cf1ec | ||
|
|
bedd6efff2 | ||
|
|
9bffc6afd6 | ||
|
|
77b5e8afdc | ||
|
|
f9b7376cc7 | ||
|
|
34723d7bb1 | ||
|
|
32f417ce5a | ||
|
|
5657438e3c | ||
|
|
f7349316b4 | ||
|
|
c0f74cd0a3 | ||
|
|
bb73065b43 | ||
|
|
ae99a179d9 | ||
|
|
b4930d15b7 | ||
|
|
86e6250a63 | ||
|
|
c9a04e886a | ||
|
|
b21c850598 | ||
|
|
58abdcfa22 | ||
|
|
d0a4fa1c9d | ||
|
|
e94b4a1c18 | ||
|
|
2a679efc14 | ||
|
|
4652b91e98 | ||
|
|
0079f76f67 | ||
|
|
711537dcf4 | ||
|
|
e971b7927e | ||
|
|
3afa829173 | ||
|
|
cd30d74393 | ||
|
|
25a945f9e6 | ||
|
|
504d582b59 | ||
|
|
3d8a80aeaa | ||
|
|
9ac609528b | ||
|
|
988861af1f | ||
|
|
66a8669c64 | ||
|
|
99b0322289 | ||
|
|
b0e7c02a6a | ||
|
|
f0fc5643e9 | ||
|
|
8c83ac120f | ||
|
|
53cab4b1ab | ||
|
|
6d176c0010 | ||
|
|
1aaa93c1fd | ||
|
|
9d1c77f5b7 | ||
|
|
3b351603a3 | ||
|
|
f563b2666d | ||
|
|
cede46d4a4 | ||
|
|
90d854fd24 | ||
|
|
9c406a0a44 | ||
|
|
81160e9e72 | ||
|
|
7bfd19dca4 | ||
|
|
8ff244d509 | ||
|
|
e2061a25c2 | ||
|
|
272201c0fc | ||
|
|
54930d7d50 | ||
|
|
5ddac97719 | ||
|
|
973432b997 | ||
|
|
1ee679903c | ||
|
|
89614f7948 | ||
|
|
dec5970bd6 | ||
|
|
a374fb4a12 | ||
|
|
5d066f1401 | ||
|
|
e8749d379a | ||
|
|
b02506d6cd | ||
|
|
cca61b8ac1 | ||
|
|
962c45b807 | ||
|
|
9646cee324 | ||
|
|
04242ef52c | ||
|
|
da9816d1bd | ||
|
|
283aba4f85 | ||
|
|
080590a292 | ||
|
|
a7ec10525e | ||
|
|
e28bf545e9 | ||
|
|
5aeb3a38c8 | ||
|
|
c00372900f | ||
|
|
7f50503aec | ||
|
|
87a600349c | ||
|
|
114246bf1e | ||
|
|
ebda1349cf | ||
|
|
45a8aaf387 | ||
|
|
514933e0e4 | ||
|
|
6f914386ec | ||
|
|
efaede0929 | ||
|
|
73821cbe49 | ||
|
|
e245891cb4 | ||
|
|
50e604f412 | ||
|
|
4e74555b5d | ||
|
|
894c86ebc3 | ||
|
|
47ea12f4ba | ||
|
|
ce01c66b3e | ||
|
|
1260900668 | ||
|
|
a86ff19c98 | ||
|
|
c07bcf6a29 | ||
|
|
82f6d26a88 | ||
|
|
d1e8f5cf5c | ||
|
|
82edaf05d3 | ||
|
|
fadc514592 | ||
|
|
fc7ca56f8b | ||
|
|
d629061506 | ||
|
|
4a964ab6be | ||
|
|
53957c24df | ||
|
|
addff1118c | ||
|
|
6a1d106fea | ||
|
|
07f88cc4d1 | ||
|
|
5f35553438 | ||
|
|
802e2afcc0 | ||
|
|
ee09b41e08 | ||
|
|
994bd72409 | ||
|
|
01eaba6697 | ||
|
|
d4d69522f5 | ||
|
|
dd88d64d67 | ||
|
|
0ecaa4d36c | ||
|
|
e9e8ef964c | ||
|
|
c2360528ee | ||
|
|
3221fba02c | ||
|
|
c1b74f481a | ||
|
|
e2c0dc7e92 | ||
|
|
df510c40f4 | ||
|
|
48db3c8ce4 | ||
|
|
9d029b46b1 | ||
|
|
d2af4f7d9c | ||
|
|
3dd539b4f0 | ||
|
|
1daafd15e6 | ||
|
|
8fd424814a | ||
|
|
4d8c3eadbc | ||
|
|
92722d491f | ||
|
|
c560d17bdd | ||
|
|
55dff65142 | ||
|
|
cdec6fad99 | ||
|
|
216dac068d | ||
|
|
f9ec79c8eb | ||
|
|
112ab91e34 | ||
|
|
59b0ac127f | ||
|
|
e03b3227d4 | ||
|
|
f08a66924c | ||
|
|
535b75225b | ||
|
|
b99c44667e | ||
|
|
c6d50b7d6e | ||
|
|
03f12bfca1 | ||
|
|
78a8c105f4 | ||
|
|
878d9d7148 | ||
|
|
cb77987129 | ||
|
|
37ec3d41d9 | ||
|
|
6ececbb81a | ||
|
|
a67c28a4c9 | ||
|
|
c3a0176c88 | ||
|
|
e7de57fc7a | ||
|
|
d928df9c69 | ||
|
|
b18bb200a9 | ||
|
|
225011f2c1 | ||
|
|
024edc500f | ||
|
|
42d59d21a6 | ||
|
|
4795571629 | ||
|
|
df587892a3 | ||
|
|
57a1f71fdd | ||
|
|
1ffcdc92f2 | ||
|
|
bd043c2358 | ||
|
|
fbd0a6ddda | ||
|
|
e7aceb6a8b | ||
|
|
fd745c5f62 | ||
|
|
41628ca17f | ||
|
|
21fbbf154d | ||
|
|
66c4aefc1e | ||
|
|
5d5c95fb2c | ||
|
|
13305d9ee1 | ||
|
|
4a9638767d | ||
|
|
55cd0d5000 | ||
|
|
1da15cfde3 | ||
|
|
9df0ee9a1c | ||
|
|
8baeafbdc2 | ||
|
|
aacddb251d | ||
|
|
1240e0f768 | ||
|
|
cdbd2979d2 | ||
|
|
da493d07c0 | ||
|
|
bccb1d2805 | ||
|
|
d84787b041 | ||
|
|
f1d6252d8b | ||
|
|
38a7a50d1c | ||
|
|
3ca181fce4 | ||
|
|
9eeb01b746 | ||
|
|
9ef9a0f1fb | ||
|
|
599b5318fc | ||
|
|
75df133071 | ||
|
|
403b39659c | ||
|
|
8d357ee282 | ||
|
|
96ad687944 | ||
|
|
79040adf1a | ||
|
|
cbcc81d42e | ||
|
|
732386b83a | ||
|
|
4065022866 | ||
|
|
6c1d949cef | ||
|
|
c4293bba6b | ||
|
|
0a1008f64f | ||
|
|
a5cb2a9f00 | ||
|
|
4a6c0db4fa | ||
|
|
f31ec9a154 | ||
|
|
b4ad4becd3 | ||
|
|
554807968a | ||
|
|
5cecb24654 | ||
|
|
5911538e29 | ||
|
|
0ccd812398 | ||
|
|
9c693cd7ed | ||
|
|
fbcd8396db | ||
|
|
b1be2eee06 | ||
|
|
bca26721ff | ||
|
|
301e874cd4 | ||
|
|
2ff66970ad | ||
|
|
58142664cc | ||
|
|
73f6a68b9d | ||
|
|
b88f4bc77f | ||
|
|
e3c2220a1c | ||
|
|
26238e731d | ||
|
|
717db2f906 | ||
|
|
1c59a27902 | ||
|
|
6ce52a1da9 | ||
|
|
f2a0e42810 | ||
|
|
63f2f85c25 | ||
|
|
80375d1f5b | ||
|
|
20ac2ad847 | ||
|
|
3b5fc7e13c | ||
|
|
73a12aedeb | ||
|
|
2ce6592048 | ||
|
|
a588aec978 | ||
|
|
8b124f3194 | ||
|
|
588ac62b6f | ||
|
|
63001d83b9 | ||
|
|
1112415f93 | ||
|
|
4633a1c136 | ||
|
|
8991e1dbad | ||
|
|
d5f6f7b37c | ||
|
|
4ffec21cd3 | ||
|
|
9d34c2a2e6 | ||
|
|
4f12caa05f | ||
|
|
649ba71c0f | ||
|
|
af5a9b31bc | ||
|
|
b72304203c | ||
|
|
f70d250995 | ||
|
|
a4d07a4611 | ||
|
|
91b1b1dfc2 | ||
|
|
53937d1723 | ||
|
|
46626e9a63 | ||
|
|
b5626c13b1 | ||
|
|
84de420002 | ||
|
|
99f939026f | ||
|
|
ad973dd51a | ||
|
|
9da485da55 | ||
|
|
da922601cd | ||
|
|
8322307ae0 | ||
|
|
58977810f9 | ||
|
|
05facc6961 | ||
|
|
f8db54136e | ||
|
|
ce972ceddd | ||
|
|
9ad61c1e23 | ||
|
|
1c4128b9a1 | ||
|
|
2c4a2f7dd9 | ||
|
|
9befaf7c91 | ||
|
|
ab34b31219 | ||
|
|
b9b56f5e73 | ||
|
|
d28312f13b | ||
|
|
9134464a39 | ||
|
|
ff5d40dcd3 | ||
|
|
9a284bc740 | ||
|
|
d67573f83a | ||
|
|
c97a388fc4 | ||
|
|
370b58d500 | ||
|
|
dbffdedc92 | ||
|
|
712b1811b3 | ||
|
|
f2fa598ed7 | ||
|
|
5283c50f84 | ||
|
|
ee7dbd5208 | ||
|
|
821298b6d0 | ||
|
|
dc6cde86c9 | ||
|
|
1826122381 | ||
|
|
fbf35edae2 | ||
|
|
70934e05e1 | ||
|
|
b235dddbe0 | ||
|
|
fc45cef834 | ||
|
|
a43de00153 | ||
|
|
949144ab25 | ||
|
|
68e75025be | ||
|
|
77e5bebf13 | ||
|
|
2a72d10bfc | ||
|
|
5aa5732606 | ||
|
|
3209459e6d | ||
|
|
0bc0cb7f82 | ||
|
|
4e9d2a5e18 | ||
|
|
915df1c731 | ||
|
|
7eb193cbbb | ||
|
|
b63c5fa1ff | ||
|
|
e4d0f2dc6f | ||
|
|
767cb46d40 | ||
|
|
c430a2d798 | ||
|
|
1c273210e9 | ||
|
|
db4e5e05a4 | ||
|
|
c6483c4b98 | ||
|
|
94c098cce3 | ||
|
|
6eddfd2694 | ||
|
|
cb15a3a1d6 | ||
|
|
cd516f80bb | ||
|
|
1d9b85c043 | ||
|
|
1ae5f64696 | ||
|
|
bf24e5f518 | ||
|
|
7115cd178c | ||
|
|
6da806c9c5 | ||
|
|
4895d76bea | ||
|
|
f527f9533e | ||
|
|
5adfcbf343 | ||
|
|
c0e0612e02 | ||
|
|
4ba4a753cb | ||
|
|
3cbd154c8a | ||
|
|
6ab936ef09 | ||
|
|
3383153b66 | ||
|
|
04b412dd5b | ||
|
|
ac20030612 | ||
|
|
083c5d1722 | ||
|
|
baec24ef14 | ||
|
|
df7f0b20f5 | ||
|
|
e5e3133869 | ||
|
|
ca6ef546e5 | ||
|
|
c24798ad2f | ||
|
|
3411eca1e7 | ||
|
|
43073069c7 | ||
|
|
db330ad035 | ||
|
|
b3c7273681 | ||
|
|
3892ac5996 | ||
|
|
249841c0db | ||
|
|
8900674b72 | ||
|
|
5ca882d3ea | ||
|
|
516ff6f8e6 | ||
|
|
dc9c481b80 | ||
|
|
5c55290944 | ||
|
|
86a145f01c | ||
|
|
78597a8554 | ||
|
|
0288ba6012 | ||
|
|
bada45ec69 | ||
|
|
ee407913c3 | ||
|
|
6e643d7579 | ||
|
|
b8c771f747 | ||
|
|
a07e1d8f3a | ||
|
|
565a78610e | ||
|
|
cdbf4cf5ec | ||
|
|
ec5c7e5d0e | ||
|
|
b583589849 | ||
|
|
c3144088ca | ||
|
|
7df3fe266e | ||
|
|
b351befa97 | ||
|
|
3925386109 | ||
|
|
cdf392e3e5 | ||
|
|
e51ca85e26 | ||
|
|
4ba11d832a | ||
|
|
66d78fed2c | ||
|
|
e8101f9410 | ||
|
|
56f1e9ed3a | ||
|
|
fff67906d6 | ||
|
|
343331c667 | ||
|
|
201d596c80 | ||
|
|
6f733394f7 | ||
|
|
b164b86eda | ||
|
|
eb97a1c11c | ||
|
|
13996d7770 | ||
|
|
6e04707457 | ||
|
|
25b17a221c | ||
|
|
de50bbb16f | ||
|
|
e835cb7f8c | ||
|
|
7fea0c9431 | ||
|
|
bcd045ae4e | ||
|
|
3f46db55b6 | ||
|
|
93e7b4f5cf | ||
|
|
a865028420 | ||
|
|
489637ec67 | ||
|
|
71ca7d153e | ||
|
|
0a37834fd8 | ||
|
|
0cc279b351 | ||
|
|
06baa10cdc | ||
|
|
c406102995 | ||
|
|
0dc3eda99f | ||
|
|
2dca9fc3f3 | ||
|
|
97cdd751b8 | ||
|
|
159472f82c | ||
|
|
be9eaa0859 | ||
|
|
35e330f574 | ||
|
|
e7a5cb4b1d | ||
|
|
c9c29da803 | ||
|
|
2527fe2e1e | ||
|
|
a4de0f2b5b | ||
|
|
401d0d58d5 | ||
|
|
441b3f1646 | ||
|
|
3b185e1bcb | ||
|
|
beed414429 | ||
|
|
99b2fdefcc | ||
|
|
9ec6a829c2 | ||
|
|
913f70b24d | ||
|
|
5a4d68684e | ||
|
|
096842de44 | ||
|
|
81e5b33bc9 | ||
|
|
5c91f29efb | ||
|
|
bfcb73f344 | ||
|
|
a2ca5eb8a4 | ||
|
|
f34e564ccd | ||
|
|
0cba428c81 | ||
|
|
423a433e16 | ||
|
|
bdee8f662c | ||
|
|
62bb550afd | ||
|
|
3562577521 | ||
|
|
8c7682c6d4 | ||
|
|
2b45a16872 | ||
|
|
73cc17ce72 | ||
|
|
07a2020303 | ||
|
|
0fc45ead6e | ||
|
|
6b37e2c973 | ||
|
|
cdabd83afe | ||
|
|
f610f525ba | ||
|
|
514f927a56 | ||
|
|
3c641606da | ||
|
|
af44d878d1 | ||
|
|
72ebafe925 | ||
|
|
134365c764 | ||
|
|
b6871c72ca | ||
|
|
aaece725aa | ||
|
|
ef6da6a96b | ||
|
|
df9daf9b4b | ||
|
|
228425fdb9 | ||
|
|
9775d1064e | ||
|
|
1a9591d411 | ||
|
|
64070a0798 | ||
|
|
bfa772609a | ||
|
|
d15acf89ba | ||
|
|
d25673b8fe | ||
|
|
dd9924a7a7 | ||
|
|
0f00b7237a | ||
|
|
579a13da44 | ||
|
|
7865219164 | ||
|
|
f2c84692a9 | ||
|
|
f61aeb8285 | ||
|
|
11d7f9d029 | ||
|
|
72633825cf | ||
|
|
9a137bb158 | ||
|
|
32944f4c9c | ||
|
|
23c6f2add5 | ||
|
|
e535f050c1 | ||
|
|
7a2feb9152 | ||
|
|
3b91ec8c06 | ||
|
|
636474610b | ||
|
|
6e524de320 | ||
|
|
3e916e42f2 | ||
|
|
de87c992d7 | ||
|
|
e5fb90f017 | ||
|
|
a3501b925d | ||
|
|
e47b0f3c44 | ||
|
|
518f7c9e03 | ||
|
|
91d57ded8a | ||
|
|
86fd1be8b2 | ||
|
|
e18deb5eeb | ||
|
|
a8fd7cf2e9 | ||
|
|
25182de365 | ||
|
|
c90efb8d0a | ||
|
|
7a521c655f | ||
|
|
8a9d2a032e | ||
|
|
b1b3ff2637 | ||
|
|
752f9e77f5 | ||
|
|
e52db0b2f5 | ||
|
|
ce9069af4a | ||
|
|
31d74730c5 | ||
|
|
84867c6e67 | ||
|
|
f7d7b3fe5e | ||
|
|
356c0c8be1 | ||
|
|
f957c42e26 | ||
|
|
ca311e5dec | ||
|
|
3ccd4ad2ca | ||
|
|
867fb30286 | ||
|
|
a8ab876053 | ||
|
|
dfc5627031 | ||
|
|
542542f48d | ||
|
|
5fda29e651 | ||
|
|
c25a07c95b | ||
|
|
aafc850dbd | ||
|
|
41ae8de99b | ||
|
|
808f070df4 | ||
|
|
e4cd66be5c | ||
|
|
a638e991af | ||
|
|
d67dbaa0ae | ||
|
|
be66ff1eec | ||
|
|
603a8acdfc | ||
|
|
86393d728f | ||
|
|
e564e051a3 | ||
|
|
2ade7dc632 | ||
|
|
a938845aa2 | ||
|
|
ba2205867e | ||
|
|
d7ec04f995 | ||
|
|
91baabd1b3 | ||
|
|
c3fdabd3a2 | ||
|
|
3d8c76209d | ||
|
|
c2038a6cf2 | ||
|
|
082ac233ad | ||
|
|
5d46fe7e4d | ||
|
|
32611e07c8 | ||
|
|
dd3316a1c2 | ||
|
|
1ebd54b282 | ||
|
|
e524197a4d | ||
|
|
f111c49cc6 | ||
|
|
c567ee2c08 | ||
|
|
1a0ac7bb35 | ||
|
|
34c69cf10f | ||
|
|
88125634d2 | ||
|
|
6049c9837c | ||
|
|
a76eef01de | ||
|
|
b3eb4f35cd | ||
|
|
6b6dacf94c | ||
|
|
f010f2fef2 | ||
|
|
a952f80ea4 | ||
|
|
6d34ae2960 | ||
|
|
d17ff000c7 | ||
|
|
6b3d3ecd93 | ||
|
|
32dc28f48d | ||
|
|
a210724312 | ||
|
|
1d69ed7584 | ||
|
|
43e864e47b | ||
|
|
fb538027f7 | ||
|
|
cbf7f7d320 | ||
|
|
200023234c | ||
|
|
fc99d6f0a6 | ||
|
|
e6b4ecdaf7 | ||
|
|
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 | ||
|
|
ade47bed8b | ||
|
|
ea12ec9cd1 | ||
|
|
3774e3bca0 | ||
|
|
77066f0389 | ||
|
|
5e0567ef4d | ||
|
|
b49de4b0fa | ||
|
|
372495a83a | ||
|
|
468a4644d6 | ||
|
|
3c31391ec9 | ||
|
|
29d0f102fd | ||
|
|
ebc7173c50 | ||
|
|
43f1ac78a6 | ||
|
|
9df54238d9 | ||
|
|
fcd934319d | ||
|
|
48ccc7ff06 | ||
|
|
edc48f0017 | ||
|
|
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 | ||
|
|
2f2800c360 | ||
|
|
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 | ||
|
|
7eb3ad98fa | ||
|
|
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 | ||
|
|
23a6849fe3 | ||
|
|
91c6e91023 | ||
|
|
8f64c91677 | ||
|
|
842ee3d426 | ||
|
|
45d338ba3d | ||
|
|
f141fac3a2 | ||
|
|
7b2a89d66b | ||
|
|
4d158d99fd | ||
|
|
c3983a26c5 | ||
|
|
016854a292 | ||
|
|
5d7252cbec | ||
|
|
0e0bcf51fc | ||
|
|
f396077cd6 | ||
|
|
1c194b67f3 | ||
|
|
72e77d2264 | ||
|
|
10c79ac812 | ||
|
|
fe8c3a4957 | ||
|
|
3734be21d6 | ||
|
|
8ae6ad879e | ||
|
|
92b2a35888 | ||
|
|
fb2e6e5c17 | ||
|
|
2212311a44 | ||
|
|
ef3791f845 | ||
|
|
6e2878194c | ||
|
|
e7780485f1 | ||
|
|
7831999563 | ||
|
|
7020f4bda9 | ||
|
|
dcd21bd165 | ||
|
|
4a70028762 | ||
|
|
9255a9e638 | ||
|
|
02736ac92d | ||
|
|
2df01c7157 | ||
|
|
01a0745b9b | ||
|
|
c7573ad4c3 | ||
|
|
06f402bb9d | ||
|
|
b9f0812b38 | ||
|
|
cdca8fe236 | ||
|
|
c8175d1191 | ||
|
|
7a7a0f1eff | ||
|
|
5176fe0366 | ||
|
|
b4bd6e7acd | ||
|
|
bd4dbf45af | ||
|
|
d9fc3d436b | ||
|
|
67143cbc0e | ||
|
|
ed3b2eb1bf | ||
|
|
7a5e4291a5 | ||
|
|
d1c6810e1e | ||
|
|
faa9c0a2b9 | ||
|
|
0456973093 | ||
|
|
4a79a4e4d9 | ||
|
|
ac46d33a60 | ||
|
|
0f958bef81 | ||
|
|
b79009517e | ||
|
|
12ccc96f46 | ||
|
|
47828c38d2 | ||
|
|
afdae6a3d6 | ||
|
|
03d1d8f5a4 | ||
|
|
cc4e4c0f13 | ||
|
|
2f6f14fef2 | ||
|
|
fb590ddfdd | ||
|
|
a5e674cdc4 | ||
|
|
e28883dd47 | ||
|
|
b4694dcf03 | ||
|
|
4c05d9a687 | ||
|
|
53da2f9bb2 | ||
|
|
ea106b6064 | ||
|
|
32f671b4f2 | ||
|
|
25e298ff69 | ||
|
|
45006fe043 | ||
|
|
3e1c561752 | ||
|
|
be4b78ee1c | ||
|
|
5a2989cae4 | ||
|
|
15519fd783 | ||
|
|
a357a5b845 | ||
|
|
806b8f135b | ||
|
|
f2b636bd44 | ||
|
|
0d25eca6e5 | ||
|
|
e5dcac43dc | ||
|
|
8629710223 | ||
|
|
111e2cc0de | ||
|
|
8eb0b942c8 | ||
|
|
4c55827aa4 | ||
|
|
0a1be7d966 | ||
|
|
8f3370307a | ||
|
|
dd1545c7e1 | ||
|
|
8ea9bee810 | ||
|
|
6141356754 | ||
|
|
e70ea67fec | ||
|
|
62be4c5bce | ||
|
|
394a9540b0 | ||
|
|
62d22f0e74 | ||
|
|
1cd7b9a250 | ||
|
|
7044534765 | ||
|
|
9c3b50d622 | ||
|
|
fd62c254a4 | ||
|
|
90e54c6334 | ||
|
|
f423c67979 | ||
|
|
4607dd788c | ||
|
|
f9c595473f | ||
|
|
de6c843e1c | ||
|
|
b45924aa52 | ||
|
|
d04ea5b061 | ||
|
|
7406210c4a | ||
|
|
c24986fba3 | ||
|
|
30c1c00b9b | ||
|
|
655d658a52 | ||
|
|
a089c4cbc2 | ||
|
|
62fd545d24 | ||
|
|
4041ecddc4 | ||
|
|
10f51b41b7 | ||
|
|
7cf0a35a7a | ||
|
|
523f7793b5 | ||
|
|
9891aecf19 | ||
|
|
fd700f73e5 | ||
|
|
d71b05095d | ||
|
|
d061a13b58 | ||
|
|
5176cc3b06 | ||
|
|
1e364913cd | ||
|
|
1adc7c77ac | ||
|
|
51fbcce803 | ||
|
|
80dab63119 | ||
|
|
8c769f152b | ||
|
|
3673391f5a | ||
|
|
f96a2e72f7 | ||
|
|
19929ef3ba | ||
|
|
e3a3d287bf | ||
|
|
b2b92b00f3 | ||
|
|
6bd2c19b21 | ||
|
|
eb8e5c5135 | ||
|
|
5a07be40f1 | ||
|
|
13a15a38c5 | ||
|
|
caa10614d9 | ||
|
|
0943b4b097 | ||
|
|
8823baaef4 | ||
|
|
5a5e77414a | ||
|
|
f524591327 | ||
|
|
55ae7c39a4 | ||
|
|
d4e5f8d165 | ||
|
|
b9dad60b61 | ||
|
|
57b9b916ed | ||
|
|
854476db76 | ||
|
|
941c57b4a8 | ||
|
|
fb1c5a760f | ||
|
|
e5367127ea | ||
|
|
ffebd3f311 | ||
|
|
d8fcbd4032 | ||
|
|
583f416373 | ||
|
|
f605b37a1e | ||
|
|
a1d64acff4 | ||
|
|
1fe42f6a79 | ||
|
|
3ce5f69225 | ||
|
|
985107c601 | ||
|
|
d416124081 | ||
|
|
3a62a6c40d | ||
|
|
8f6f55b001 | ||
|
|
6d1ae39bc6 | ||
|
|
850197faa1 | ||
|
|
1aa206bc82 | ||
|
|
5a9cdb67f9 | ||
|
|
c9810cd019 | ||
|
|
8bf75e38ad | ||
|
|
fe9139ae93 | ||
|
|
87a354a314 | ||
|
|
270ac99a1e | ||
|
|
dc5d6a4ef8 | ||
|
|
4cdb36de09 | ||
|
|
7fce1d00d7 | ||
|
|
26c27153f0 | ||
|
|
b5420e9c6a | ||
|
|
cfd82a6ad4 | ||
|
|
7a352b49a0 | ||
|
|
8a4f3b7642 | ||
|
|
a09d4139d5 | ||
|
|
a257ac87f7 | ||
|
|
1669a5434c | ||
|
|
2fc83aa61c | ||
|
|
ed6f00a893 | ||
|
|
b15f9766c1 | ||
|
|
0ad4f07591 | ||
|
|
4704c5a1b0 | ||
|
|
034a9bc3c3 | ||
|
|
e7dc9db75a | ||
|
|
4a2d1b7997 | ||
|
|
a5e2a32fb8 | ||
|
|
43f69bb184 | ||
|
|
71482c2359 | ||
|
|
84a27a60a5 | ||
|
|
87f865ce1f | ||
|
|
12c78b41af | ||
|
|
c3db808b7c | ||
|
|
af9a9c5698 | ||
|
|
a7e6d3e969 | ||
|
|
708425c67a | ||
|
|
021de1af80 | ||
|
|
b66e98f697 | ||
|
|
28ad32aad5 | ||
|
|
94dc3117bc | ||
|
|
803ada4b27 | ||
|
|
e7118f637c | ||
|
|
e11e368c4b | ||
|
|
27a9051822 | ||
|
|
54caece5b3 | ||
|
|
b1fade5d3b | ||
|
|
8ed485df0e | ||
|
|
9c33947a45 | ||
|
|
33dc06055c | ||
|
|
8ff4a99cf3 | ||
|
|
d38abec819 | ||
|
|
0ba48aa230 | ||
|
|
acf47ad7a6 | ||
|
|
c948c62cac | ||
|
|
eee4dbf66c | ||
|
|
653b995774 | ||
|
|
a78151c5aa | ||
|
|
3177713447 | ||
|
|
0769df1e55 | ||
|
|
0cfa7cb28f | ||
|
|
1e621ee133 | ||
|
|
a203799bd2 | ||
|
|
8fc9724204 | ||
|
|
0d41cb96ab | ||
|
|
39b2f87194 | ||
|
|
1161037092 | ||
|
|
a3d9d5cca8 | ||
|
|
4b67411ca6 | ||
|
|
126b807dc7 | ||
|
|
ca81d2d602 | ||
|
|
015c195c9f | ||
|
|
5fd170d480 | ||
|
|
4b167ba9de | ||
|
|
38ac41bccb | ||
|
|
3315d27d45 | ||
|
|
c3dcdb0686 | ||
|
|
ca91f6bd92 | ||
|
|
65483309ab | ||
|
|
71d33f3429 | ||
|
|
9b1c543eb7 | ||
|
|
24bb0ff39a | ||
|
|
3ae312db37 | ||
|
|
94f73241ea | ||
|
|
d4632b9059 | ||
|
|
dd15d52130 | ||
|
|
145f252ca6 | ||
|
|
731b54a1f7 | ||
|
|
f8d7b68289 | ||
|
|
80e47d5157 | ||
|
|
c1653c5f2e | ||
|
|
36ad31ab25 | ||
|
|
6f1872fb94 | ||
|
|
ff56e70b81 | ||
|
|
201263237f | ||
|
|
1ddd37f381 | ||
|
|
f9d2a78c5e | ||
|
|
443c917c6b | ||
|
|
7c787cd13b | ||
|
|
dc8aff6b6c | ||
|
|
397040549f | ||
|
|
0b858d6e94 | ||
|
|
6c8efcda12 | ||
|
|
3fa0aa9242 | ||
|
|
18775286c0 | ||
|
|
57433efe80 | ||
|
|
c42748a5dd | ||
|
|
b5cf835959 | ||
|
|
48b45b5f51 | ||
|
|
7d658c3f3d | ||
|
|
91980c9f2c | ||
|
|
db1c80c7e3 | ||
|
|
e53bd70c2c | ||
|
|
fe64e2e24c | ||
|
|
a020ca9a71 | ||
|
|
7a9fde822c | ||
|
|
152af02336 | ||
|
|
be7d3a921a | ||
|
|
78acb205d3 | ||
|
|
627dac692c | ||
|
|
68a6a828d8 | ||
|
|
e8604788df | ||
|
|
cf60bbc904 | ||
|
|
02d4ac81dd | ||
|
|
f0775af439 | ||
|
|
96048b5133 | ||
|
|
ca34d7cced | ||
|
|
938e2a871d | ||
|
|
dc55dbdf36 | ||
|
|
d0ec17feba | ||
|
|
5b5fdd97d6 |
186
.appveyor.yml
Normal file
186
.appveyor.yml
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
environment:
|
||||||
|
|
||||||
|
global:
|
||||||
|
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
|
||||||
|
# /E:ON and /V:ON options are not enabled in the batch script intepreter
|
||||||
|
# See: http://stackoverflow.com/a/13751649/163740
|
||||||
|
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
|
||||||
|
# Python 2.7.10 is the latest version and is not pre-installed.
|
||||||
|
|
||||||
|
- PYTHON: "C:\\Python27.10"
|
||||||
|
PYTHON_VERSION: "2.7.10"
|
||||||
|
PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python27.10-x64"
|
||||||
|
# PYTHON_VERSION: "2.7.10"
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
# Pre-installed Python versions, which Appveyor may upgrade to
|
||||||
|
# a later point release.
|
||||||
|
# See: http://www.appveyor.com/docs/installed-software#python
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python27"
|
||||||
|
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python27-x64"
|
||||||
|
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python33"
|
||||||
|
# PYTHON_VERSION: "3.3.x" # currently 3.3.5
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python33-x64"
|
||||||
|
# PYTHON_VERSION: "3.3.x" # currently 3.3.5
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python34"
|
||||||
|
# PYTHON_VERSION: "3.4.x" # currently 3.4.3
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python34-x64"
|
||||||
|
# PYTHON_VERSION: "3.4.x" # currently 3.4.3
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
# Python versions not pre-installed
|
||||||
|
|
||||||
|
# Python 2.6.6 is the latest Python 2.6 with a Windows installer
|
||||||
|
# See: https://github.com/ogrisel/python-appveyor-demo/issues/10
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python266"
|
||||||
|
# PYTHON_VERSION: "2.6.6"
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python266-x64"
|
||||||
|
# PYTHON_VERSION: "2.6.6"
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python35"
|
||||||
|
# PYTHON_VERSION: "3.5.0"
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python35-x64"
|
||||||
|
# PYTHON_VERSION: "3.5.0"
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
# Major and minor releases (i.e x.0.0 and x.y.0) prior to 3.3.0 use
|
||||||
|
# a different naming scheme.
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python270"
|
||||||
|
# PYTHON_VERSION: "2.7.0"
|
||||||
|
# PYTHON_ARCH: "32"
|
||||||
|
|
||||||
|
#- PYTHON: "C:\\Python270-x64"
|
||||||
|
# PYTHON_VERSION: "2.7.0"
|
||||||
|
# PYTHON_ARCH: "64"
|
||||||
|
|
||||||
|
install:
|
||||||
|
# If there is a newer build queued for the same PR, cancel this one.
|
||||||
|
# The AppVeyor 'rollout builds' option is supposed to serve the same
|
||||||
|
# purpose but it is problematic because it tends to cancel builds pushed
|
||||||
|
# directly to master instead of just PR builds (or the converse).
|
||||||
|
# credits: JuliaLang developers.
|
||||||
|
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
|
||||||
|
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
|
||||||
|
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
|
||||||
|
throw "There are newer queued builds for this pull request, failing early." }
|
||||||
|
|
||||||
|
# Install wxPython
|
||||||
|
- 'ECHO Downloading wxPython.'
|
||||||
|
- "appveyor DownloadFile https://goo.gl/yvO8PB -FileName C:\\wxpython.exe"
|
||||||
|
#- "appveyor DownloadFile https://goo.gl/Uj0jV3 -FileName C:\\wxpython64.exe"
|
||||||
|
|
||||||
|
- 'ECHO Install wxPython'
|
||||||
|
- "C:\\wxpython.exe /SP- /VERYSILENT /NORESTART"
|
||||||
|
#- "C:\\wxpython64.exe /SP- /VERYSILENT /NORESTART"
|
||||||
|
|
||||||
|
- ECHO "Filesystem root:"
|
||||||
|
- ps: "ls \"C:/\""
|
||||||
|
|
||||||
|
- ECHO "Filesystem pyfa root:"
|
||||||
|
- ps: "ls \"C:\\projects\\pyfa\\\""
|
||||||
|
|
||||||
|
- ECHO "Installed SDKs:"
|
||||||
|
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
|
||||||
|
|
||||||
|
# Install Python (from the official .msi of http://python.org) and pip when
|
||||||
|
# not already installed.
|
||||||
|
# - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
|
||||||
|
|
||||||
|
# Prepend newly installed Python to the PATH of this build (this cannot be
|
||||||
|
# done from inside the powershell script as it would require to restart
|
||||||
|
# the parent CMD process).
|
||||||
|
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||||
|
|
||||||
|
# Check that we have the expected version and architecture for Python
|
||||||
|
- "python --version"
|
||||||
|
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
|
||||||
|
|
||||||
|
# Upgrade to the latest version of pip to avoid it displaying warnings
|
||||||
|
# about it being out of date.
|
||||||
|
- "pip install --disable-pip-version-check --user --upgrade pip"
|
||||||
|
|
||||||
|
# Install the build dependencies of the project. If some dependencies contain
|
||||||
|
# compiled extensions and are not provided as pre-built wheel packages,
|
||||||
|
# pip will build them from source using the MSVC compiler matching the
|
||||||
|
# target Python version and architecture
|
||||||
|
# C:\\projects\\eve-gnosis\\
|
||||||
|
- ECHO "Install pip requirements:"
|
||||||
|
- "pip install -r requirements.txt"
|
||||||
|
- "pip install -r requirements_test.txt"
|
||||||
|
- "pip install -r requirements_build_windows.txt"
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
# Build the compiled extension
|
||||||
|
# - "python setup.py build"
|
||||||
|
- ECHO "Build pyfa:"
|
||||||
|
#- copy C:\projects\pyfa\dist_assets\win\pyfa.spec C:\projects\pyfa\pyfa.spec
|
||||||
|
- "python C:\\projects\\pyfa\\setup.py build"
|
||||||
|
|
||||||
|
#- ECHO "Build pyfa (Debug):"
|
||||||
|
#- copy C:\projects\pyfa\dist_assets\win\pyfa_debug.spec C:\projects\pyfa\pyfa_debug.spec
|
||||||
|
#- "pyinstaller.exe --clean --noconfirm --windowed --upx-dir=C:\\projects\\pyfa\\scripts\\upx.exe C:\\projects\\pyfa\\pyfa_debug.spec"
|
||||||
|
|
||||||
|
build: on
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- ps: "ls \"./\""
|
||||||
|
#- ps: "ls \"C:\\projects\\pyfa\\build\\pyfa\\\""
|
||||||
|
- ps: "ls \"C:\\projects\\pyfa\\build\\\""
|
||||||
|
- ps: "ls \"C:\\projects\\pyfa\\build\\exe.win32-2.7\\\""
|
||||||
|
# Zip
|
||||||
|
# APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER
|
||||||
|
#- 7z a build.zip -r C:\projects\pyfa\build\pyfa\*.*
|
||||||
|
- 7z a pyfa.zip -r C:\projects\pyfa\build\exe.win32-2.7\*.*
|
||||||
|
#- 7z a pyfa_debug.zip -r C:\projects\pyfa\dist\pyfa_debug\*.*
|
||||||
|
|
||||||
|
on_success:
|
||||||
|
# Do nothing right now
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
#- tox
|
||||||
|
#- "py.test --cov=./"
|
||||||
|
# Run the project tests
|
||||||
|
# - "%CMD_IN_ENV% python C:/projects/eve-gnosis/setup.py nosetests"
|
||||||
|
|
||||||
|
after_test:
|
||||||
|
# If tests are successful, create binary packages for the project.
|
||||||
|
# - "%CMD_IN_ENV% python setup.py bdist_wheel"
|
||||||
|
# - "%CMD_IN_ENV% python setup.py bdist_wininst"
|
||||||
|
# - "%CMD_IN_ENV% python setup.py bdist_msi"
|
||||||
|
# - ps: "ls dist"
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
# Archive the generated packages in the ci.appveyor.com build report.
|
||||||
|
- path: pyfa.zip
|
||||||
|
name: 'pyfa.zip'
|
||||||
|
#- path: pyfa_debug.zip
|
||||||
|
# name: Pyfa_debug
|
||||||
|
|
||||||
|
#on_success:
|
||||||
|
# - TODO: upload the content of dist/*.whl to a public wheelhouse
|
||||||
|
#
|
||||||
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
|
||||||
|
pyfa.py text eol=lf
|
||||||
|
|
||||||
|
# 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
|
||||||
117
.gitignore
vendored
117
.gitignore
vendored
@@ -4,20 +4,121 @@
|
|||||||
#Kwrite/Gedit/Other crapapps making backups
|
#Kwrite/Gedit/Other crapapps making backups
|
||||||
*~
|
*~
|
||||||
|
|
||||||
#Eclipse
|
|
||||||
.project
|
|
||||||
.pydevproject
|
|
||||||
.settings
|
|
||||||
|
|
||||||
#Patch files
|
#Patch files
|
||||||
*.patch
|
*.patch
|
||||||
|
|
||||||
#Personal
|
#Personal
|
||||||
/saveddata/
|
/saveddata/
|
||||||
|
|
||||||
#PyCharm
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
#Pyfa file
|
#Pyfa file
|
||||||
pyfaFits.html
|
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/
|
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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
gitversion
|
||||||
|
.version
|
||||||
|
/.version
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
|||||||
14
.mailmap
Normal file
14
.mailmap
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
cncfanatics <diego.duclos@gmail.com> cncfanatics <cncfanatics@titanium.(none)>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com> blitzmann <ryan.xgamer99@gmail.com>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com> blitzman <ryan.xgamer99@gmail.com>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com> Ryan Holmes <ryan.holmes.90@gmail.com>
|
||||||
|
blitzmann <holmes.ryan.90@gmail.com>
|
||||||
|
Corollax <corollax@gmail.com> Corollax <corollax@corollax-laptop.(none)>
|
||||||
|
Corollax <corollax@gmail.com> Corollax <corollax@corollax-N76VM.(none)>
|
||||||
|
Mr. Nukealizer <mr.nukealizer@gmail.com> Mr. Nukealizer <MrNukealizer@users.noreply.github.com>
|
||||||
|
DarkPhoenix <phoenix@mail.ru>
|
||||||
|
Sakari Orisi <sakari@evefit.org>
|
||||||
|
Will Wykeham <will@wykeham.net> Will Wykeham <will.wykeham@paconsulting.com>
|
||||||
|
OISumeko <camerongrout@gmail.com> OISumeko <cameron@sporadic.co.nz>
|
||||||
39
.travis.yml
Normal file
39
.travis.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
language: python
|
||||||
|
cache: pip
|
||||||
|
python:
|
||||||
|
- '2.7'
|
||||||
|
env:
|
||||||
|
- TOXENV=pep8
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get update && sudo apt-get --reinstall install -qq language-pack-en language-pack-ru language-pack-he language-pack-zh-hans
|
||||||
|
- pip install tox
|
||||||
|
# We're not actually installing Tox, but have to run it before we install wxPython via Conda. This is fugly but vOv
|
||||||
|
- tox
|
||||||
|
# get Conda
|
||||||
|
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||||
|
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||||
|
else
|
||||||
|
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||||
|
fi
|
||||||
|
- bash miniconda.sh -b -p $HOME/miniconda
|
||||||
|
- export PATH="$HOME/miniconda/bin:$PATH"
|
||||||
|
- hash -r
|
||||||
|
- conda config --set always_yes yes --set changeps1 no
|
||||||
|
- conda update -q conda
|
||||||
|
# Useful for debugging any issues with conda
|
||||||
|
- conda info -a
|
||||||
|
install:
|
||||||
|
# install wxPython 3.0.0.0
|
||||||
|
- conda install -c https://conda.anaconda.org/travis wxpython
|
||||||
|
before_script:
|
||||||
|
- pip install -r requirements.txt
|
||||||
|
- pip install -r requirements_test.txt
|
||||||
|
script:
|
||||||
|
- py.test --cov=./
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
before_deploy:
|
||||||
|
- pip install -r requirements_build_linux.txt
|
||||||
34
ISSUE_TEMPLATE.md
Normal file
34
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Submit a bug report bug report or feature request
|
||||||
|
|
||||||
|
Here you can inform pyfa developers of potential bugs or suggest features / improvements to the project. Please check
|
||||||
|
to make sure that the bug hasn't been reported or feature requested before submitting. If you have general questions
|
||||||
|
about the project and want to reach out to the developers personally, please check out out our [Slack]
|
||||||
|
(https://pyfainvite.azurewebsites.net/).
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Bug Report
|
||||||
|
|
||||||
|
|
||||||
|
### Expected behavior:
|
||||||
|
|
||||||
|
|
||||||
|
### Actual behavior:
|
||||||
|
|
||||||
|
|
||||||
|
### Detailed steps to reproduce:
|
||||||
|
|
||||||
|
|
||||||
|
### Fits involved in EFT format (Edit > To Clipboard > EFT):
|
||||||
|
|
||||||
|
|
||||||
|
### Release or development git branch? Please note the release version or commit hash:
|
||||||
|
|
||||||
|
|
||||||
|
### Operating system and version (eg: Windows 10, OS X 10.9, OS X 10.11, Ubuntu 16.10):
|
||||||
|
|
||||||
|
|
||||||
|
### Other relevant information:
|
||||||
|
|
||||||
44
README.md
44
README.md
@@ -1,6 +1,6 @@
|
|||||||
# pyfa
|
# pyfa
|
||||||
|
|
||||||
[](https://gitter.im/pyfa-org/Pyfa?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://pyfainvite.azurewebsites.net/) [](https://travis-ci.org/pyfa-org/Pyfa)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -9,50 +9,50 @@
|
|||||||
pyfa, short for **py**thon **f**itting **a**ssistant, allows you to create, experiment with, and save ship fittings without being in game. Open source and written in Python, it is available on any platform where Python 2.x and wxWidgets are available, including Windows, Mac OS X, and Linux.
|
pyfa, short for **py**thon **f**itting **a**ssistant, allows you to create, experiment with, and save ship fittings without being in game. Open source and written in Python, it is available on any platform where Python 2.x and wxWidgets are available, including Windows, Mac OS X, and Linux.
|
||||||
|
|
||||||
## Latest Version and Changelogs
|
## Latest Version and Changelogs
|
||||||
The latest version along with release notes can always be found on the projects [Releases](https://github.com/DarkFenX/Pyfa/releases) page. pyfa will notify you if you are running an outdated version.
|
The latest version along with release notes can always be found on the project's [Releases](https://github.com/DarkFenX/Pyfa/releases) page. pyfa will notify you if you are running an outdated version.
|
||||||
|
|
||||||
## Installing
|
## Installation
|
||||||
Windows and OS X users are supplied self-contained builds of pyfa that can be run without additional software. An `.exe` installer is also available for the Windows builds. There is no self-contained package for Linux users, which are expected to run pyfa through their distributions Python interpreter. However, there are a number of third-party packages available that handle the dependencies and updates for pyfa (for example, [pyfa for Arch Linux](https://aur.archlinux.org/packages/pyfa/)). Please check your distributions repositories.
|
Windows and OS X users are supplied self-contained builds of pyfa on the [latest releases](https://github.com/pyfa-org/Pyfa/releases/latest) page. An `.exe` installer is also available for Windows builds. Linux users can run pyfa using their distribution's Python interpreter. There is no official self-contained package for Linux, however, there are a number of third-party packages available through distribution-specific repositories.
|
||||||
|
|
||||||
### Requirements
|
#### OS X
|
||||||
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
|
||||||
|
|
||||||
* Python 2.7
|
Apart from the official release, 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:
|
||||||
* `wxPython` 2.8/3.0
|
```
|
||||||
* `sqlalchemy` >= 0.6
|
$ brew install Caskroom/cask/pyfa
|
||||||
* `dateutil`
|
```
|
||||||
* `matplotlib` (for some Linux distributions, you may need to install separate wxPython bindings, such as `python-matplotlib-wx`)
|
|
||||||
* `requests`
|
|
||||||
|
|
||||||
### Linux Distro-specific Packages
|
### Linux Distro-specific Packages
|
||||||
The following is a list of pyfa packages available for certain distros. Please note that these packages are maintained by third-parties and are not evaluated by the pyfa developers.
|
The following is a list of pyfa packages available for certain distributions. Please note that these packages are maintained by third-parties and are not evaluated by the pyfa developers.
|
||||||
|
|
||||||
* Debian/Ubuntu/derivitives: https://github.com/AdamMajer/Pyfa/releases
|
* Debian/Ubuntu/derivitives: https://github.com/AdamMajer/Pyfa/releases
|
||||||
* Arch: https://aur.archlinux.org/packages/pyfa/
|
* Arch: https://aur.archlinux.org/packages/pyfa/
|
||||||
* openSUSE: https://build.opensuse.org/package/show/home:rmk2/pyfa
|
* openSUSE: https://build.opensuse.org/package/show/home:rmk2/pyfa
|
||||||
* FreeBSD: http://www.freshports.org/games/pyfa/ (see #484 for instructions)
|
* FreeBSD: http://www.freshports.org/games/pyfa/ (see [#484](https://github.com/pyfa-org/Pyfa/issues/484) for instructions)
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
If you wish to help with development or simply need to run pyfa through a Python interpreter, the following software is required:
|
||||||
|
|
||||||
|
* Python 3.6
|
||||||
|
* Requirements as listed in `requirements.txt`
|
||||||
|
|
||||||
## Bug Reporting
|
## Bug Reporting
|
||||||
The preferred method of reporting bugs is through the projects GitHub Issues interface. Alternatively, posting a report in the pyfa thread on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
The preferred method of reporting bugs is through the project's [GitHub Issues interface](https://github.com/pyfa-org/Pyfa/issues). Alternatively, posting a report in the [pyfa thread](http://forums.eveonline.com/default.aspx?g=posts&t=247609) on the official EVE Online forums is acceptable. Guidelines for bug reporting can be found on [this wiki page](https://github.com/DarkFenX/Pyfa/wiki/Bug-Reporting).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
pyfa is licensed under the GNU GPL v3.0, see LICENSE
|
||||||
|
|
||||||
## Resources
|
## 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](https://forums.eveonline.com/t/27156)
|
||||||
* [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)
|
* [EVE University guide using pyfa](http://wiki.eveuniversity.org/Guide_to_using_PYFA)
|
||||||
* [EVE Online website](http://www.eveonline.com/)
|
* [EVE Online website](http://www.eveonline.com/)
|
||||||
|
|
||||||
## Contacts:
|
## Contacts:
|
||||||
* Kadesh Priestess
|
|
||||||
* GitHub: @DarkFenX
|
|
||||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @kadesh
|
|
||||||
* Sable Blitzmann
|
* Sable Blitzmann
|
||||||
* GitHub: @blitzmann
|
* GitHub: @blitzmann
|
||||||
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @blitzmann
|
* [TweetFleet Slack](https://www.fuzzwork.co.uk/tweetfleet-slack-invites/): @blitzmann
|
||||||
|
* [Gitter chat](https://gitter.im/pyfa-org/Pyfa): @ blitzmann
|
||||||
* Email: sable.blitzmann@gmail.com
|
* Email: sable.blitzmann@gmail.com
|
||||||
|
|
||||||
## CCP Copyright Notice
|
## CCP Copyright Notice
|
||||||
EVE Online, the EVE logo, EVE and all associated logos and designs are the intellectual property of CCP hf. All artwork, screenshots, characters, vehicles, storylines, world facts or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of CCP hf. EVE Online and the EVE logo are the registered trademarks of CCP hf. All rights are reserved worldwide. All other trademarks are the property of their respective owners. CCP hf. has granted permission to Osmium to use EVE Online and all associated logos and designs for promotional and information purposes on its website but does not endorse, and is not in any way affiliated with, Osmium. CCP is in no way responsible for the content on or functioning of this website, nor can it be liable for any damage arising from the use of this website.
|
EVE Online, the EVE logo, EVE and all associated logos and designs are the intellectual property of CCP hf. All artwork, screenshots, characters, vehicles, storylines, world facts or other recognizable features of the intellectual property relating to these trademarks are likewise the intellectual property of CCP hf. EVE Online and the EVE logo are the registered trademarks of CCP hf. All rights are reserved worldwide. All other trademarks are the property of their respective owners. CCP hf. has granted permission to pyfa to use EVE Online and all associated logos and designs for promotional and information purposes on its website but does not endorse, and is not in any way affiliated with, pyfa. CCP is in no way responsible for the content on or functioning of this program, nor can it be liable for any damage arising from the use of this program.
|
||||||
|
|||||||
13
_development/Pyfa_CodeStyle.xml
Normal file
13
_development/Pyfa_CodeStyle.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<code_scheme name="Pyfa">
|
||||||
|
<option name="LINE_SEPARATOR" value="
" />
|
||||||
|
<option name="RIGHT_MARGIN" value="165" />
|
||||||
|
<Python>
|
||||||
|
<option name="NEW_LINE_AFTER_COLON" value="true" />
|
||||||
|
<option name="DICT_ALIGNMENT" value="2" />
|
||||||
|
<option name="DICT_NEW_LINE_AFTER_LEFT_BRACE" value="true" />
|
||||||
|
<option name="DICT_NEW_LINE_BEFORE_RIGHT_BRACE" value="true" />
|
||||||
|
<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true" />
|
||||||
|
<option name="OPTIMIZE_IMPORTS_SORT_NAMES_IN_FROM_IMPORTS" value="true" />
|
||||||
|
<option name="OPTIMIZE_IMPORTS_JOIN_FROM_IMPORTS_WITH_SAME_SOURCE" value="true" />
|
||||||
|
</Python>
|
||||||
|
</code_scheme>
|
||||||
54
_development/Pyfa_Inspections.xml
Normal file
54
_development/Pyfa_Inspections.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Pyfa" />
|
||||||
|
<inspection_tool class="IgnoreUnusedEntry" enabled="false" level="UNUSED ENTRY" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="ProblematicWhitespace" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyBehaveInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyClassicStyleClassInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ourVersions">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="2.7" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMissingTypeHintsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="wxPython" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPep8Inspection" enabled="true" level="TYPO" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="E203" />
|
||||||
|
<option value="E127" />
|
||||||
|
<option value="E128" />
|
||||||
|
<option value="E126" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="TYPO" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N802" />
|
||||||
|
<option value="N806" />
|
||||||
|
<option value="N803" />
|
||||||
|
<option value="N814" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyShadowingBuiltinsInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyShadowingNamesInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
0
_development/__init__.py
Normal file
0
_development/__init__.py
Normal file
145
_development/helpers.py
Normal file
145
_development/helpers.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# noinspection PyPackageRequirements
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from sqlalchemy import MetaData, create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
# Add root folder to python paths
|
||||||
|
sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..')))
|
||||||
|
sys._called_from_test = True
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences,PyUnusedLocal
|
||||||
|
@pytest.fixture
|
||||||
|
def DBInMemory_test():
|
||||||
|
def rollback():
|
||||||
|
with sd_lock:
|
||||||
|
saveddata_session.rollback()
|
||||||
|
|
||||||
|
|
||||||
|
print("Creating database in memory")
|
||||||
|
from os.path import realpath, join, dirname, abspath
|
||||||
|
|
||||||
|
debug = False
|
||||||
|
gamedataCache = True
|
||||||
|
saveddataCache = True
|
||||||
|
gamedata_version = ""
|
||||||
|
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(str(__file__))), "..", "eve.db"))
|
||||||
|
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||||
|
|
||||||
|
class ReadOnlyException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if callable(gamedata_connectionstring):
|
||||||
|
gamedata_engine = create_engine("sqlite://", creator=gamedata_connectionstring, echo=debug)
|
||||||
|
else:
|
||||||
|
gamedata_engine = create_engine(gamedata_connectionstring, echo=debug)
|
||||||
|
|
||||||
|
gamedata_meta = MetaData()
|
||||||
|
gamedata_meta.bind = gamedata_engine
|
||||||
|
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
|
||||||
|
|
||||||
|
# This should be moved elsewhere, maybe as an actual query. Current, without try-except, it breaks when making a new
|
||||||
|
# game db because we haven't reached gamedata_meta.create_all()
|
||||||
|
try:
|
||||||
|
gamedata_version = gamedata_session.execute(
|
||||||
|
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||||
|
).fetchone()[0]
|
||||||
|
except Exception as e:
|
||||||
|
print("Missing gamedata version.")
|
||||||
|
gamedata_version = None
|
||||||
|
|
||||||
|
if saveddata_connectionstring is not None:
|
||||||
|
if callable(saveddata_connectionstring):
|
||||||
|
saveddata_engine = create_engine(creator=saveddata_connectionstring, echo=debug)
|
||||||
|
else:
|
||||||
|
saveddata_engine = create_engine(saveddata_connectionstring, echo=debug)
|
||||||
|
|
||||||
|
saveddata_meta = MetaData()
|
||||||
|
saveddata_meta.bind = saveddata_engine
|
||||||
|
saveddata_session = sessionmaker(bind=saveddata_engine, autoflush=False, expire_on_commit=False)()
|
||||||
|
else:
|
||||||
|
saveddata_meta = None
|
||||||
|
|
||||||
|
# Lock controlling any changes introduced to session
|
||||||
|
sd_lock = threading.Lock()
|
||||||
|
|
||||||
|
# Import all the definitions for all our database stuff
|
||||||
|
# noinspection PyPep8
|
||||||
|
#from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
||||||
|
# noinspection PyPep8
|
||||||
|
#from eos.db.saveddata import booster, cargo, character, crest, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, miscData, module, override, price, queries, skill, targetResists, user
|
||||||
|
|
||||||
|
# If using in memory saveddata, you'll want to reflect it so the data structure is good.
|
||||||
|
if saveddata_connectionstring == "sqlite:///:memory:":
|
||||||
|
saveddata_meta.create_all()
|
||||||
|
|
||||||
|
# Output debug info to help us troubleshoot Travis
|
||||||
|
print(saveddata_engine)
|
||||||
|
print(gamedata_engine)
|
||||||
|
|
||||||
|
helper = {
|
||||||
|
#'config': eos.config,
|
||||||
|
'gamedata_session' : gamedata_session,
|
||||||
|
'saveddata_session' : saveddata_session,
|
||||||
|
}
|
||||||
|
return helper
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences,PyUnusedLocal
|
||||||
|
@pytest.fixture
|
||||||
|
def DBInMemory():
|
||||||
|
print("Creating database in memory")
|
||||||
|
|
||||||
|
import eos.config
|
||||||
|
|
||||||
|
import eos
|
||||||
|
import eos.db
|
||||||
|
|
||||||
|
# Output debug info to help us troubleshoot Travis
|
||||||
|
print((eos.db.saveddata_engine))
|
||||||
|
print((eos.db.gamedata_engine))
|
||||||
|
|
||||||
|
helper = {
|
||||||
|
'config': eos.config,
|
||||||
|
'db' : eos.db,
|
||||||
|
'gamedata_session' : eos.db.gamedata_session,
|
||||||
|
'saveddata_session' : eos.db.saveddata_session,
|
||||||
|
}
|
||||||
|
return helper
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def Gamedata():
|
||||||
|
print("Building Gamedata")
|
||||||
|
from eos.gamedata import Item
|
||||||
|
|
||||||
|
helper = {
|
||||||
|
'Item': Item,
|
||||||
|
}
|
||||||
|
return helper
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def Saveddata():
|
||||||
|
print("Building Saveddata")
|
||||||
|
from eos.saveddata.ship import Ship
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
from eos.saveddata.character import Character
|
||||||
|
from eos.saveddata.module import Module, State
|
||||||
|
from eos.saveddata.citadel import Citadel
|
||||||
|
from eos.saveddata.booster import Booster
|
||||||
|
|
||||||
|
helper = {
|
||||||
|
'Structure': Citadel,
|
||||||
|
'Ship' : Ship,
|
||||||
|
'Fit' : Fit,
|
||||||
|
'Character': Character,
|
||||||
|
'Module' : Module,
|
||||||
|
'State' : State,
|
||||||
|
'Booster' : Booster,
|
||||||
|
}
|
||||||
|
return helper
|
||||||
66
_development/helpers_fits.py
Normal file
66
_development/helpers_fits.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
# noinspection PyPackageRequirements
|
||||||
|
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingNames
|
||||||
|
@pytest.fixture
|
||||||
|
def RifterFit(DB, Gamedata, Saveddata):
|
||||||
|
print("Creating Rifter")
|
||||||
|
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Rifter").first()
|
||||||
|
ship = Saveddata['Ship'](item)
|
||||||
|
# setup fit
|
||||||
|
fit = Saveddata['Fit'](ship, "My Rifter Fit")
|
||||||
|
|
||||||
|
return fit
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingNames
|
||||||
|
@pytest.fixture
|
||||||
|
def KeepstarFit(DB, Gamedata, Saveddata):
|
||||||
|
print("Creating Keepstar")
|
||||||
|
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Keepstar").first()
|
||||||
|
ship = Saveddata['Structure'](item)
|
||||||
|
# setup fit
|
||||||
|
fit = Saveddata['Fit'](ship, "Keepstar Fit")
|
||||||
|
|
||||||
|
return fit
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingNames
|
||||||
|
@pytest.fixture
|
||||||
|
def CurseFit(DB, Gamedata, Saveddata):
|
||||||
|
print("Creating Curse - With Neuts")
|
||||||
|
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Curse").first()
|
||||||
|
ship = Saveddata['Ship'](item)
|
||||||
|
# setup fit
|
||||||
|
fit = Saveddata['Fit'](ship, "Curse - With Neuts")
|
||||||
|
|
||||||
|
mod = Saveddata['Module'](DB['db'].getItem("Medium Energy Neutralizer II"))
|
||||||
|
mod.state = Saveddata['State'].ONLINE
|
||||||
|
|
||||||
|
# Add 5 neuts
|
||||||
|
for _ in range(5):
|
||||||
|
fit.modules.append(mod)
|
||||||
|
|
||||||
|
return fit
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingNames
|
||||||
|
@pytest.fixture
|
||||||
|
def HeronFit(DB, Gamedata, Saveddata):
|
||||||
|
print("Creating Heron - RemoteSebo")
|
||||||
|
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Heron").first()
|
||||||
|
ship = Saveddata['Ship'](item)
|
||||||
|
# setup fit
|
||||||
|
fit = Saveddata['Fit'](ship, "Heron - RemoteSebo")
|
||||||
|
|
||||||
|
mod = Saveddata['Module'](DB['db'].getItem("Remote Sensor Booster II"))
|
||||||
|
mod.state = Saveddata['State'].ONLINE
|
||||||
|
|
||||||
|
# Add 5 neuts
|
||||||
|
for _ in range(4):
|
||||||
|
fit.modules.append(mod)
|
||||||
|
|
||||||
|
return fit
|
||||||
12
_development/helpers_items.py
Normal file
12
_development/helpers_items.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
# noinspection PyPackageRequirements
|
||||||
|
from _development.helpers import DBInMemory as DB, Gamedata, Saveddata
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingNames
|
||||||
|
@pytest.fixture
|
||||||
|
def StrongBluePillBooster (DB, Gamedata, Saveddata):
|
||||||
|
print("Creating Strong Blue Pill Booster")
|
||||||
|
item = DB['gamedata_session'].query(Gamedata['Item']).filter(Gamedata['Item'].name == "Strong Blue Pill Booster").first()
|
||||||
|
return Saveddata['Booster'](item)
|
||||||
101
_development/helpers_locale.py
Normal file
101
_development/helpers_locale.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
|
||||||
|
windows_codecs = {
|
||||||
|
'cp1252', # Standard Windows
|
||||||
|
'cp1251', # Russian
|
||||||
|
'cp037',
|
||||||
|
'cp424',
|
||||||
|
'cp437',
|
||||||
|
'cp500',
|
||||||
|
'cp720',
|
||||||
|
'cp737',
|
||||||
|
'cp775',
|
||||||
|
'cp850',
|
||||||
|
'cp852',
|
||||||
|
'cp855',
|
||||||
|
'cp856',
|
||||||
|
'cp857',
|
||||||
|
'cp858',
|
||||||
|
'cp860',
|
||||||
|
'cp861',
|
||||||
|
'cp862',
|
||||||
|
'cp863',
|
||||||
|
'cp864',
|
||||||
|
'cp865',
|
||||||
|
'cp866',
|
||||||
|
'cp869',
|
||||||
|
'cp874',
|
||||||
|
'cp875',
|
||||||
|
'cp932',
|
||||||
|
'cp949',
|
||||||
|
'cp950',
|
||||||
|
'cp1006',
|
||||||
|
'cp1026',
|
||||||
|
'cp1140',
|
||||||
|
'cp1250',
|
||||||
|
'cp1253',
|
||||||
|
'cp1254',
|
||||||
|
'cp1255',
|
||||||
|
'cp1256',
|
||||||
|
'cp1257',
|
||||||
|
'cp1258',
|
||||||
|
}
|
||||||
|
|
||||||
|
linux_codecs = {
|
||||||
|
'utf_8', # Generic Linux/Mac
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_codecs = [
|
||||||
|
'utf_8', # Generic Linux/Mac
|
||||||
|
'mac_cyrillic',
|
||||||
|
'mac_greek',
|
||||||
|
'mac_iceland',
|
||||||
|
'mac_latin2',
|
||||||
|
'mac_roman',
|
||||||
|
'mac_turkish',
|
||||||
|
]
|
||||||
|
|
||||||
|
universal_codecs = [
|
||||||
|
'utf_16', 'utf_32', 'utf_32_be', 'utf_32_le', 'utf_16_be', 'utf_16_le', 'utf_7', 'utf_8_sig',
|
||||||
|
]
|
||||||
|
|
||||||
|
other_codecs = [
|
||||||
|
'scii', 'big5', 'big5hkscs', 'euc_jp', 'euc_jis_2004', 'euc_jisx0213', 'euc_kr', 'gb2312', 'gbk', 'gb18030', 'hz', 'iso2022_jp', 'iso2022_jp_1',
|
||||||
|
'iso2022_jp_2', 'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr', 'latin_1', 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5',
|
||||||
|
'iso8859_6', 'iso8859_7', 'iso8859_8', 'iso8859_9', 'iso8859_10', 'iso8859_11', 'iso8859_13', 'iso8859_14', 'iso8859_15', 'iso8859_16', 'johab', 'koi8_r',
|
||||||
|
'koi8_u', 'ptcp154', 'shift_jis', 'shift_jis_2004', 'shift_jisx0213'
|
||||||
|
]
|
||||||
|
|
||||||
|
system_names = {
|
||||||
|
'Windows': windows_codecs,
|
||||||
|
'Linux': linux_codecs,
|
||||||
|
'Darwin': mac_codecs,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def GetPath(root, file=None, codec=None):
|
||||||
|
# Replace this with the function we actually use for this
|
||||||
|
path = os.path.realpath(os.path.abspath(root))
|
||||||
|
|
||||||
|
if file:
|
||||||
|
path = os.path.join(path, file)
|
||||||
|
|
||||||
|
if codec:
|
||||||
|
path = path.decode(codec)
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
|
def GetUnicodePath(root, file=None, codec=None):
|
||||||
|
# Replace this with the function we actually use for this
|
||||||
|
path = os.path.realpath(os.path.abspath(root))
|
||||||
|
|
||||||
|
if file:
|
||||||
|
path = os.path.join(path, file)
|
||||||
|
|
||||||
|
if codec:
|
||||||
|
path = str(path, codec)
|
||||||
|
else:
|
||||||
|
path = str(path)
|
||||||
|
|
||||||
|
return path
|
||||||
242
config.py
242
config.py
@@ -1,48 +1,62 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# TODO: move all logging back to pyfa.py main loop
|
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
|
||||||
# We moved it here just to avoid rebuilding windows skeleton for now (any change to pyfa.py needs it)
|
StreamHandler, TimedRotatingFileHandler, WARNING
|
||||||
import logging
|
import hashlib
|
||||||
import logging.handlers
|
|
||||||
|
from cryptography.fernet import Fernet
|
||||||
|
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
|
||||||
# Load variable overrides specific to distribution type
|
# Load variable overrides specific to distribution type
|
||||||
try:
|
try:
|
||||||
import configforced
|
import configforced
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
pyfalog.warning("Failed to import: configforced")
|
||||||
configforced = None
|
configforced = None
|
||||||
|
|
||||||
|
|
||||||
# Turns on debug mode
|
# Turns on debug mode
|
||||||
debug = False
|
debug = False
|
||||||
# Defines if our saveddata will be in pyfa root or not
|
# Defines if our saveddata will be in pyfa root or not
|
||||||
saveInRoot = False
|
saveInRoot = False
|
||||||
|
|
||||||
# Version data
|
# Version data
|
||||||
version = "1.19.2"
|
|
||||||
tag = "git"
|
version = "2.0.0"
|
||||||
expansionName = "Singularity"
|
tag = "Stable"
|
||||||
expansionVersion = "1015913"
|
expansionName = "YC120.3"
|
||||||
|
expansionVersion = "1.8"
|
||||||
evemonMinVersion = "4081"
|
evemonMinVersion = "4081"
|
||||||
|
|
||||||
|
minItemSearchLength = 3
|
||||||
|
|
||||||
pyfaPath = None
|
pyfaPath = None
|
||||||
savePath = None
|
savePath = None
|
||||||
saveDB = None
|
saveDB = None
|
||||||
gameDB = None
|
gameDB = None
|
||||||
|
logPath = None
|
||||||
|
loggingLevel = None
|
||||||
|
logging_setup = None
|
||||||
|
cipher = None
|
||||||
|
clientHash = None
|
||||||
|
|
||||||
|
ESI_AUTH_PROXY = "https://www.pyfa.io" # "http://localhost:5015"
|
||||||
|
ESI_CACHE = 'esi_cache'
|
||||||
|
|
||||||
|
LOGLEVEL_MAP = {
|
||||||
|
"critical": CRITICAL,
|
||||||
|
"error": ERROR,
|
||||||
|
"warning": WARNING,
|
||||||
|
"info": INFO,
|
||||||
|
"debug": DEBUG,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class StreamToLogger(object):
|
def getClientSecret():
|
||||||
"""
|
return clientHash
|
||||||
Fake file-like stream object that redirects writes to a logger instance.
|
|
||||||
From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/
|
|
||||||
"""
|
|
||||||
def __init__(self, logger, log_level=logging.INFO):
|
|
||||||
self.logger = logger
|
|
||||||
self.log_level = log_level
|
|
||||||
self.linebuf = ''
|
|
||||||
|
|
||||||
def write(self, buf):
|
|
||||||
for line in buf.rstrip().splitlines():
|
|
||||||
self.logger.log(self.log_level, line.rstrip())
|
|
||||||
|
|
||||||
def isFrozen():
|
def isFrozen():
|
||||||
if hasattr(sys, 'frozen'):
|
if hasattr(sys, 'frozen'):
|
||||||
@@ -50,28 +64,46 @@ def isFrozen():
|
|||||||
else:
|
else:
|
||||||
return False
|
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):
|
def __createDirs(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
def defPaths():
|
|
||||||
|
def getPyfaRoot():
|
||||||
|
if hasattr(sys, '_MEIPASS'):
|
||||||
|
return sys._MEIPASS
|
||||||
|
base = getattr(sys.modules['__main__'], "__file__", sys.executable) if isFrozen() else __file__
|
||||||
|
root = os.path.dirname(os.path.realpath(os.path.abspath(base)))
|
||||||
|
root = root
|
||||||
|
return root
|
||||||
|
|
||||||
|
|
||||||
|
def getVersion():
|
||||||
|
if os.path.isfile(os.path.join(pyfaPath, '.version')):
|
||||||
|
with open(os.path.join(pyfaPath, '.version')) as f:
|
||||||
|
gitVersion = f.readline()
|
||||||
|
return gitVersion
|
||||||
|
# if no version file exists, then user is running from source or not an official build
|
||||||
|
return version + " (git)"
|
||||||
|
|
||||||
|
|
||||||
|
def getDefaultSave():
|
||||||
|
return os.path.expanduser(os.path.join("~", ".pyfa"))
|
||||||
|
|
||||||
|
|
||||||
|
def defPaths(customSavePath=None):
|
||||||
global debug
|
global debug
|
||||||
global pyfaPath
|
global pyfaPath
|
||||||
global savePath
|
global savePath
|
||||||
global saveDB
|
global saveDB
|
||||||
global gameDB
|
global gameDB
|
||||||
global saveInRoot
|
global saveInRoot
|
||||||
|
global logPath
|
||||||
|
global cipher
|
||||||
|
global clientHash
|
||||||
|
|
||||||
if debug:
|
pyfalog.debug("Configuring Pyfa")
|
||||||
logLevel = logging.DEBUG
|
|
||||||
else:
|
|
||||||
logLevel = logging.WARN
|
|
||||||
|
|
||||||
# The main pyfa directory which contains run.py
|
# The main pyfa directory which contains run.py
|
||||||
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
# Python 2.X uses ANSI by default, so we need to convert the character encoding
|
||||||
@@ -87,33 +119,26 @@ def defPaths():
|
|||||||
else:
|
else:
|
||||||
savePath = getattr(configforced, "savePath", None)
|
savePath = getattr(configforced, "savePath", None)
|
||||||
if savePath is None:
|
if savePath is None:
|
||||||
savePath = unicode(os.path.expanduser(os.path.join("~", ".pyfa")),
|
if customSavePath is None: # customSavePath is not overriden
|
||||||
sys.getfilesystemencoding())
|
savePath = getDefaultSave()
|
||||||
|
else:
|
||||||
|
savePath = customSavePath
|
||||||
|
|
||||||
__createDirs(savePath)
|
__createDirs(savePath)
|
||||||
|
|
||||||
if isFrozen():
|
secret_file = os.path.join(savePath, ".secret")
|
||||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
if not os.path.exists(secret_file):
|
||||||
os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
|
with open(secret_file, "wb") as _file:
|
||||||
|
_file.write(Fernet.generate_key())
|
||||||
|
|
||||||
format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s'
|
with open(secret_file, 'rb') as fp:
|
||||||
logging.basicConfig(format=format, level=logLevel)
|
key = fp.read()
|
||||||
handler = logging.handlers.RotatingFileHandler(os.path.join(savePath, "log.txt"), maxBytes=1000000, backupCount=3)
|
clientHash = hashlib.sha3_256(key).hexdigest()
|
||||||
formatter = logging.Formatter(format)
|
cipher = Fernet(key)
|
||||||
handler.setFormatter(formatter)
|
|
||||||
logging.getLogger('').addHandler(handler)
|
|
||||||
|
|
||||||
logging.info("Starting pyfa")
|
# if isFrozen():
|
||||||
|
# os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||||
if hasattr(sys, 'frozen'):
|
# os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||||
stdout_logger = logging.getLogger('STDOUT')
|
|
||||||
sl = StreamToLogger(stdout_logger, logging.INFO)
|
|
||||||
sys.stdout = sl
|
|
||||||
|
|
||||||
# This interferes with cx_Freeze's own handling of exceptions. Find a way to fix this.
|
|
||||||
#stderr_logger = logging.getLogger('STDERR')
|
|
||||||
#sl = StreamToLogger(stderr_logger, logging.ERROR)
|
|
||||||
#sys.stderr = sl
|
|
||||||
|
|
||||||
# The database where we store all the fits etc
|
# The database where we store all the fits etc
|
||||||
saveDB = os.path.join(savePath, "saveddata.db")
|
saveDB = os.path.join(savePath, "saveddata.db")
|
||||||
@@ -121,13 +146,120 @@ def defPaths():
|
|||||||
# The database where the static EVE data from the datadump is kept.
|
# 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
|
# This is not the standard sqlite datadump but a modified version created by eos
|
||||||
# maintenance script
|
# maintenance script
|
||||||
gameDB = os.path.join(pyfaPath, "eve.db")
|
gameDB = getattr(configforced, "gameDB", gameDB)
|
||||||
|
if not gameDB:
|
||||||
|
gameDB = os.path.join(pyfaPath, "eve.db")
|
||||||
|
|
||||||
## DON'T MODIFY ANYTHING BELOW ##
|
if debug:
|
||||||
|
logFile = "pyfa_debug.log"
|
||||||
|
else:
|
||||||
|
logFile = "pyfa.log"
|
||||||
|
|
||||||
|
logPath = os.path.join(savePath, logFile)
|
||||||
|
|
||||||
|
# DON'T MODIFY ANYTHING BELOW
|
||||||
import eos.config
|
import eos.config
|
||||||
|
|
||||||
#Caching modifiers, disable all gamedata caching, its unneeded.
|
# Caching modifiers, disable all gamedata caching, its unneeded.
|
||||||
eos.config.gamedataCache = False
|
eos.config.gamedataCache = False
|
||||||
# saveddata db location modifier, shouldn't ever need to touch this
|
# saveddata db location modifier, shouldn't ever need to touch this
|
||||||
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
eos.config.saveddata_connectionstring = "sqlite:///" + saveDB + "?check_same_thread=False"
|
||||||
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
eos.config.gamedata_connectionstring = "sqlite:///" + gameDB + "?check_same_thread=False"
|
||||||
|
|
||||||
|
print(eos.config.saveddata_connectionstring)
|
||||||
|
print(eos.config.gamedata_connectionstring)
|
||||||
|
|
||||||
|
# initialize the settings
|
||||||
|
from service.settings import EOSSettings
|
||||||
|
eos.config.settings = EOSSettings.getInstance().EOSSettings # this is kind of confusing, but whatever
|
||||||
|
|
||||||
|
|
||||||
|
def defLogging():
|
||||||
|
global debug
|
||||||
|
global logPath
|
||||||
|
global loggingLevel
|
||||||
|
global logging_setup
|
||||||
|
|
||||||
|
try:
|
||||||
|
if debug:
|
||||||
|
logging_setup = NestedSetup([
|
||||||
|
# make sure we never bubble up to the stderr handler
|
||||||
|
# if we run out of setup handling
|
||||||
|
NullHandler(),
|
||||||
|
StreamHandler(
|
||||||
|
sys.stdout,
|
||||||
|
bubble=False,
|
||||||
|
level=loggingLevel
|
||||||
|
),
|
||||||
|
TimedRotatingFileHandler(
|
||||||
|
logPath,
|
||||||
|
level=0,
|
||||||
|
backup_count=3,
|
||||||
|
bubble=True,
|
||||||
|
date_format='%Y-%m-%d',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
logging_setup = NestedSetup([
|
||||||
|
# make sure we never bubble up to the stderr handler
|
||||||
|
# if we run out of setup handling
|
||||||
|
NullHandler(),
|
||||||
|
FingersCrossedHandler(
|
||||||
|
TimedRotatingFileHandler(
|
||||||
|
logPath,
|
||||||
|
level=0,
|
||||||
|
backup_count=3,
|
||||||
|
bubble=False,
|
||||||
|
date_format='%Y-%m-%d',
|
||||||
|
),
|
||||||
|
action_level=ERROR,
|
||||||
|
buffer_size=1000,
|
||||||
|
# pull_information=True,
|
||||||
|
# reset=False,
|
||||||
|
)
|
||||||
|
])
|
||||||
|
except:
|
||||||
|
print("Critical error attempting to setup logging. Falling back to console only.")
|
||||||
|
logging_setup = NestedSetup([
|
||||||
|
# make sure we never bubble up to the stderr handler
|
||||||
|
# if we run out of setup handling
|
||||||
|
NullHandler(),
|
||||||
|
StreamHandler(
|
||||||
|
sys.stdout,
|
||||||
|
bubble=False
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
with logging_setup.threadbound():
|
||||||
|
|
||||||
|
# Output all stdout (print) messages as warnings
|
||||||
|
try:
|
||||||
|
sys.stdout = LoggerWriter(pyfalog.warning)
|
||||||
|
except:
|
||||||
|
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")
|
||||||
|
|
||||||
|
# Output all stderr (stacktrace) messages as critical
|
||||||
|
try:
|
||||||
|
sys.stderr = LoggerWriter(pyfalog.critical)
|
||||||
|
except:
|
||||||
|
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")
|
||||||
|
|
||||||
|
|
||||||
|
class LoggerWriter(object):
|
||||||
|
def __init__(self, level):
|
||||||
|
# self.level is really like using log.debug(message)
|
||||||
|
# at least in my case
|
||||||
|
self.level = level
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
# if statement reduces the amount of newlines that are
|
||||||
|
# printed to the logger
|
||||||
|
if message.strip() != '':
|
||||||
|
self.level(message.replace("\n", ""))
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
# create a flush method so things can be flushed when
|
||||||
|
# the system wants to. Not sure if simply 'printing'
|
||||||
|
# sys.stderr is the correct way to do it, but it seemed
|
||||||
|
# to work properly for me.
|
||||||
|
self.level(sys.stderr)
|
||||||
|
|||||||
5666
dist_assets/cacert.pem
Normal file
5666
dist_assets/cacert.pem
Normal file
File diff suppressed because it is too large
Load Diff
70
dist_assets/linux/pyfa-linux.spec
Normal file
70
dist_assets/linux/pyfa-linux.spec
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
from itertools import chain
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
label = subprocess.check_output([
|
||||||
|
"git", "describe", "--tags"]).strip()
|
||||||
|
|
||||||
|
with open('gitversion', 'w+') as f:
|
||||||
|
f.write(label.decode())
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
|
||||||
|
added_files = [
|
||||||
|
( 'imgs/gui/*.png', 'imgs/gui' ),
|
||||||
|
( 'imgs/gui/*.gif', 'imgs/gui' ),
|
||||||
|
( 'imgs/icons/*.png', 'imgs/icons' ),
|
||||||
|
( 'imgs/renders/*.png', 'imgs/renders' ),
|
||||||
|
( 'dist_assets/win/pyfa.ico', '.' ),
|
||||||
|
( 'dist_assets/cacert.pem', '.' ),
|
||||||
|
( 'eve.db', '.' ),
|
||||||
|
( 'README.md', '.' ),
|
||||||
|
( 'LICENSE', '.' ),
|
||||||
|
( 'gitversion', '.' ),
|
||||||
|
]
|
||||||
|
|
||||||
|
import_these = []
|
||||||
|
|
||||||
|
# Walk directories that do dynamic importing
|
||||||
|
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||||
|
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||||
|
for file_ in files:
|
||||||
|
if file_.endswith(".py") and not file_.startswith("_"):
|
||||||
|
mod_name = "{}.{}".format(
|
||||||
|
root.replace("/", "."),
|
||||||
|
file_.split(".py")[0],
|
||||||
|
)
|
||||||
|
import_these.append(mod_name)
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(['pyfa.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=added_files,
|
||||||
|
hiddenimports=import_these,
|
||||||
|
hookspath=[],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
exclude_binaries=True,
|
||||||
|
name='pyfa',
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
console=True )
|
||||||
|
coll = COLLECT(exe,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
name='pyfa')
|
||||||
74
dist_assets/mac/pyfa.spec
Normal file
74
dist_assets/mac/pyfa.spec
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
from itertools import chain
|
||||||
|
import subprocess
|
||||||
|
import requests.certs
|
||||||
|
|
||||||
|
label = subprocess.check_output([
|
||||||
|
"git", "describe", "--tags"]).strip()
|
||||||
|
|
||||||
|
with open('.version', 'w+') as f:
|
||||||
|
f.write(label.decode())
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
added_files = [
|
||||||
|
('../../imgs/gui/*.png', 'imgs/gui'),
|
||||||
|
('../../imgs/gui/*.gif', 'imgs/gui'),
|
||||||
|
('../../imgs/icons/*.png', 'imgs/icons'),
|
||||||
|
('../../imgs/renders/*.png', 'imgs/renders'),
|
||||||
|
('../../dist_assets/win/pyfa.ico', '.'),
|
||||||
|
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||||
|
(requests.certs.where(), '.'), # is this needed anymore?
|
||||||
|
('../../eve.db', '.'),
|
||||||
|
('../../README.md', '.'),
|
||||||
|
('../../LICENSE', '.'),
|
||||||
|
('../../.version', '.'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
import_these = []
|
||||||
|
|
||||||
|
# Walk directories that do dynamic importing
|
||||||
|
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||||
|
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||||
|
for file_ in files:
|
||||||
|
if file_.endswith(".py") and not file_.startswith("_"):
|
||||||
|
mod_name = "{}.{}".format(
|
||||||
|
root.replace("/", "."),
|
||||||
|
file_.split(".py")[0],
|
||||||
|
)
|
||||||
|
import_these.append(mod_name)
|
||||||
|
|
||||||
|
a = Analysis([r'../../pyfa.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=added_files,
|
||||||
|
hiddenimports=import_these,
|
||||||
|
hookspath=['dist_assets/pyinstaller_hooks'],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
name='pyfa',
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False ,
|
||||||
|
icon='dist_assets/mac/pyfa.icns',
|
||||||
|
)
|
||||||
|
|
||||||
|
app = BUNDLE(exe,
|
||||||
|
name='pyfa.app',
|
||||||
|
icon=None,
|
||||||
|
bundle_identifier=None)
|
||||||
78
dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py
Normal file
78
dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# This apes hook-matplotlib.backends.py, but REMOVES backends, all but
|
||||||
|
# the ones in the list below.
|
||||||
|
# Courtesy of https://github.com/bpteague/cytoflow/blob/70f9291/packaging/hook-matplotlib.backends.py
|
||||||
|
|
||||||
|
KEEP = ["WXAgg", "WX", "agg"]
|
||||||
|
|
||||||
|
from PyInstaller.compat import is_darwin
|
||||||
|
from PyInstaller.utils.hooks import (
|
||||||
|
eval_statement, exec_statement, logger)
|
||||||
|
|
||||||
|
|
||||||
|
def get_matplotlib_backend_module_names():
|
||||||
|
"""
|
||||||
|
List the names of all matplotlib backend modules importable under the
|
||||||
|
current Python installation.
|
||||||
|
Returns
|
||||||
|
----------
|
||||||
|
list
|
||||||
|
List of the fully-qualified names of all such modules.
|
||||||
|
"""
|
||||||
|
# Statement safely importing a single backend module.
|
||||||
|
import_statement = """
|
||||||
|
import os, sys
|
||||||
|
# Preserve stdout.
|
||||||
|
sys_stdout = sys.stdout
|
||||||
|
try:
|
||||||
|
# Redirect output printed by this importation to "/dev/null", preventing
|
||||||
|
# such output from being erroneously interpreted as an error.
|
||||||
|
with open(os.devnull, 'w') as dev_null:
|
||||||
|
sys.stdout = dev_null
|
||||||
|
__import__('%s')
|
||||||
|
# If this is an ImportError, print this exception's message without a traceback.
|
||||||
|
# ImportError messages are human-readable and require no additional context.
|
||||||
|
except ImportError as exc:
|
||||||
|
sys.stdout = sys_stdout
|
||||||
|
print(exc)
|
||||||
|
# Else, print this exception preceded by a traceback. traceback.print_exc()
|
||||||
|
# prints to stderr rather than stdout and must not be called here!
|
||||||
|
except Exception:
|
||||||
|
sys.stdout = sys_stdout
|
||||||
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
|
"""
|
||||||
|
|
||||||
|
# List of the human-readable names of all available backends.
|
||||||
|
backend_names = eval_statement(
|
||||||
|
'import matplotlib; print(matplotlib.rcsetup.all_backends)')
|
||||||
|
|
||||||
|
# List of the fully-qualified names of all importable backend modules.
|
||||||
|
module_names = []
|
||||||
|
|
||||||
|
# If the current system is not OS X and the "CocoaAgg" backend is available,
|
||||||
|
# remove this backend from consideration. Attempting to import this backend
|
||||||
|
# on non-OS X systems halts the current subprocess without printing output
|
||||||
|
# or raising exceptions, preventing its reliable detection.
|
||||||
|
if not is_darwin and 'CocoaAgg' in backend_names:
|
||||||
|
backend_names.remove('CocoaAgg')
|
||||||
|
|
||||||
|
# For safety, attempt to import each backend in a unique subprocess.
|
||||||
|
for backend_name in backend_names:
|
||||||
|
if backend_name in KEEP:
|
||||||
|
continue
|
||||||
|
|
||||||
|
module_name = 'matplotlib.backends.backend_%s' % backend_name.lower()
|
||||||
|
stdout = exec_statement(import_statement % module_name)
|
||||||
|
|
||||||
|
# If no output was printed, this backend is importable.
|
||||||
|
if not stdout:
|
||||||
|
module_names.append(module_name)
|
||||||
|
logger.info(' Matplotlib backend "%s": removed' % backend_name)
|
||||||
|
|
||||||
|
return module_names
|
||||||
|
|
||||||
|
# Freeze all importable backends, as PyInstaller is unable to determine exactly
|
||||||
|
# which backends are required by the current program.
|
||||||
|
e=get_matplotlib_backend_module_names()
|
||||||
|
print(e)
|
||||||
|
excludedimports = e
|
||||||
82
dist_assets/win/pyfa.spec
Normal file
82
dist_assets/win/pyfa.spec
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
from itertools import chain
|
||||||
|
import subprocess
|
||||||
|
import requests.certs
|
||||||
|
|
||||||
|
label = subprocess.check_output([
|
||||||
|
"git", "describe", "--tags"]).strip()
|
||||||
|
|
||||||
|
with open('.version', 'w+') as f:
|
||||||
|
f.write(label.decode())
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
added_files = [
|
||||||
|
('../../imgs/gui/*.png', 'imgs/gui'),
|
||||||
|
('../../imgs/gui/*.gif', 'imgs/gui'),
|
||||||
|
('../../imgs/icons/*.png', 'imgs/icons'),
|
||||||
|
('../../imgs/renders/*.png', 'imgs/renders'),
|
||||||
|
('../../service/jargon/*.yaml', 'service/jargon'),
|
||||||
|
('../../dist_assets/win/pyfa.ico', '.'),
|
||||||
|
(requests.certs.where(), '.'), # is this needed anymore?
|
||||||
|
('../../eve.db', '.'),
|
||||||
|
('../../README.md', '.'),
|
||||||
|
('../../LICENSE', '.'),
|
||||||
|
('../../.version', '.'),
|
||||||
|
]
|
||||||
|
|
||||||
|
import_these = []
|
||||||
|
|
||||||
|
# Walk directories that do dynamic importing
|
||||||
|
paths = ('eos/effects', 'eos/db/migrations', 'service/conversions')
|
||||||
|
for root, folders, files in chain.from_iterable(os.walk(path) for path in paths):
|
||||||
|
for file_ in files:
|
||||||
|
if file_.endswith(".py") and not file_.startswith("_"):
|
||||||
|
mod_name = "{}.{}".format(
|
||||||
|
root.replace("/", "."),
|
||||||
|
file_.split(".py")[0],
|
||||||
|
)
|
||||||
|
import_these.append(mod_name)
|
||||||
|
|
||||||
|
a = Analysis(['../../pyfa.py'],
|
||||||
|
pathex=[
|
||||||
|
# Need this, see https://github.com/pyinstaller/pyinstaller/issues/1566
|
||||||
|
# To get this, download and install windows 10 SDK
|
||||||
|
# If not building on Windows 10, this might be optional
|
||||||
|
r'C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86'],
|
||||||
|
binaries=[],
|
||||||
|
datas=added_files,
|
||||||
|
hiddenimports=import_these,
|
||||||
|
hookspath=['dist_assets/pyinstaller_hooks'],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=['Tkinter'],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
exclude_binaries=True,
|
||||||
|
debug=False,
|
||||||
|
console=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
name='pyfa',
|
||||||
|
icon='dist_assets/win/pyfa.ico',
|
||||||
|
)
|
||||||
|
|
||||||
|
coll = COLLECT(
|
||||||
|
exe,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
name='pyfa',
|
||||||
|
icon='dist_assets/win/pyfa.ico',
|
||||||
|
)
|
||||||
83
dist_assets/win/pyfa_debug.spec
Normal file
83
dist_assets/win/pyfa_debug.spec
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
# Note: This script is provided AS-IS for those that may be interested.
|
||||||
|
# pyfa does not currently support pyInstaller (or any other build process) 100% at the moment
|
||||||
|
|
||||||
|
# Command line to build:
|
||||||
|
# (Run from directory where pyfa.py and pyfa.spec lives.)
|
||||||
|
# c:\Python27\scripts\pyinstaller.exe --clean --noconfirm --windowed --upx-dir=.\scripts\upx.exe pyfa.spec
|
||||||
|
|
||||||
|
# Don't forget to change the path to where your pyfa.py and pyfa.spec lives
|
||||||
|
# pathex=['C:\\Users\\Ebag333\\Documents\\GitHub\\Ebag333\\Pyfa'],
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
added_files = [
|
||||||
|
( 'imgs/gui/*.png', 'imgs/gui' ),
|
||||||
|
( 'imgs/gui/*.gif', 'imgs/gui' ),
|
||||||
|
( 'imgs/icons/*.png', 'imgs/icons' ),
|
||||||
|
( 'imgs/renders/*.png', 'imgs/renders' ),
|
||||||
|
( 'dist_assets/win/pyfa.ico', '.' ),
|
||||||
|
( 'dist_assets/cacert.pem', '.' ),
|
||||||
|
( 'eve.db', '.' ),
|
||||||
|
( 'README.md', '.' ),
|
||||||
|
( 'LICENSE', '.' ),
|
||||||
|
]
|
||||||
|
|
||||||
|
import_these = []
|
||||||
|
|
||||||
|
# Walk eos.effects and add all effects so we can import them properly
|
||||||
|
for root, folders, files in os.walk("eos/effects"):
|
||||||
|
for file_ in files:
|
||||||
|
if file_.endswith(".py") and not file_.startswith("_"):
|
||||||
|
mod_name = "{}.{}".format(
|
||||||
|
root.replace("/", "."),
|
||||||
|
file_.split(".py")[0],
|
||||||
|
)
|
||||||
|
import_these.append(mod_name)
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['pyfa.py'],
|
||||||
|
pathex=['C:\\projects\\pyfa\\'],
|
||||||
|
binaries=[],
|
||||||
|
datas=added_files,
|
||||||
|
hiddenimports=import_these,
|
||||||
|
hookspath=[],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
)
|
||||||
|
|
||||||
|
pyz = PYZ(
|
||||||
|
a.pure,
|
||||||
|
a.zipped_data,
|
||||||
|
cipher=block_cipher,
|
||||||
|
)
|
||||||
|
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
exclude_binaries=True,
|
||||||
|
debug=True,
|
||||||
|
console=True,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
name='pyfa_debug',
|
||||||
|
icon='dist_assets/win/pyfa.ico',
|
||||||
|
onefile=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
coll = COLLECT(
|
||||||
|
exe,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
onefile=False,
|
||||||
|
name='pyfa_debug',
|
||||||
|
icon='dist_assets/win/pyfa.ico',
|
||||||
|
)
|
||||||
45
dist_assets/win/version_resource.py
Normal file
45
dist_assets/win/version_resource.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# UTF-8
|
||||||
|
#
|
||||||
|
# For more details about fixed file info 'ffi' see:
|
||||||
|
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
|
||||||
|
VSVersionInfo(
|
||||||
|
ffi=FixedFileInfo(
|
||||||
|
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||||
|
# Set not needed items to zero 0.
|
||||||
|
filevers=(1, 15, 1, 0),
|
||||||
|
prodvers=(1, 15, 1, 0),
|
||||||
|
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||||
|
mask=0x3f,
|
||||||
|
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||||
|
flags=0x0,
|
||||||
|
# The operating system for which this file was designed.
|
||||||
|
# 0x4 - NT and there is no need to change it.
|
||||||
|
OS=0x40004,
|
||||||
|
# The general type of file.
|
||||||
|
# 0x1 - the file is an application.
|
||||||
|
fileType=0x1,
|
||||||
|
# The function of the file.
|
||||||
|
# 0x0 - the function is not defined for this fileType
|
||||||
|
subtype=0x0,
|
||||||
|
# Creation date and time stamp.
|
||||||
|
date=(0, 0)
|
||||||
|
),
|
||||||
|
kids=[
|
||||||
|
StringFileInfo(
|
||||||
|
[
|
||||||
|
StringTable(
|
||||||
|
u'040904E4',
|
||||||
|
[StringStruct(u'LegalCopyright', u''),
|
||||||
|
StringStruct(u'InternalName', u'pyfa.exe'),
|
||||||
|
StringStruct(u'FileVersion', u'1.15.1.0'),
|
||||||
|
StringStruct(u'CompanyName', u''),
|
||||||
|
StringStruct(u'OriginalFilename', u'pyfa.exe'),
|
||||||
|
StringStruct(u'ProductVersion', u'1.15.1.0'),
|
||||||
|
StringStruct(u'FileDescription', u'Python fitting assistant'),
|
||||||
|
StringStruct(u'LegalTrademarks', u''),
|
||||||
|
StringStruct(u'Comments', u''),
|
||||||
|
StringStruct(u'ProductName', u'pyfa')])
|
||||||
|
]),
|
||||||
|
VarFileInfo([VarStruct(u'Translation', [1033, 1252])])
|
||||||
|
]
|
||||||
|
)
|
||||||
@@ -1,7 +1,2 @@
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
tag = "git"
|
tag = "git"
|
||||||
|
|
||||||
def test():
|
|
||||||
import tests.runTests
|
|
||||||
import unittest
|
|
||||||
unittest.main(defaultTest="discover", testLoader=tests.runTests.loader)
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import heapq
|
import heapq
|
||||||
from math import sqrt, exp
|
|
||||||
import time
|
import time
|
||||||
|
from math import sqrt, exp
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
DAY = 24 * 60 * 60 * 1000
|
DAY = 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
def lcm(a,b):
|
|
||||||
n = a*b
|
def lcm(a, b):
|
||||||
|
n = a * b
|
||||||
while b:
|
while b:
|
||||||
a, b = b, a % b
|
a, b = b, a % b
|
||||||
return n / a
|
return n / a
|
||||||
@@ -40,20 +41,19 @@ class CapSimulator(object):
|
|||||||
# relevant decimal digits of capacitor for LCM period optimization
|
# relevant decimal digits of capacitor for LCM period optimization
|
||||||
self.stability_precision = 1
|
self.stability_precision = 1
|
||||||
|
|
||||||
|
|
||||||
def scale_activation(self, duration, capNeed):
|
def scale_activation(self, duration, capNeed):
|
||||||
for res in self.scale_resolutions:
|
for res in self.scale_resolutions:
|
||||||
mod = duration % res
|
mod = duration % res
|
||||||
if mod:
|
if mod:
|
||||||
if mod > res/2.0:
|
if mod > res / 2.0:
|
||||||
mod = res-mod
|
mod = res - mod
|
||||||
else:
|
else:
|
||||||
mod = -mod
|
mod = -mod
|
||||||
|
|
||||||
if abs(mod) <= duration/100.0:
|
if abs(mod) <= duration / 100.0:
|
||||||
# only adjust if the adjustment is less than 1%
|
# only adjust if the adjustment is less than 1%
|
||||||
duration += mod
|
duration += mod
|
||||||
capNeed += float(mod)/duration * capNeed
|
capNeed += float(mod) / duration * capNeed
|
||||||
break
|
break
|
||||||
|
|
||||||
return duration, capNeed
|
return duration, capNeed
|
||||||
@@ -72,7 +72,7 @@ class CapSimulator(object):
|
|||||||
disable_period = False
|
disable_period = False
|
||||||
|
|
||||||
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
|
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
|
||||||
for (duration, capNeed, clipSize, disableStagger) in self.modules:
|
for (duration, capNeed, clipSize, disableStagger, reloadTime) in self.modules:
|
||||||
if self.scale:
|
if self.scale:
|
||||||
duration, capNeed = self.scale_activation(duration, capNeed)
|
duration, capNeed = self.scale_activation(duration, capNeed)
|
||||||
|
|
||||||
@@ -80,24 +80,25 @@ class CapSimulator(object):
|
|||||||
# a cap booster module.
|
# a cap booster module.
|
||||||
if not self.reload and capNeed > 0:
|
if not self.reload and capNeed > 0:
|
||||||
clipSize = 0
|
clipSize = 0
|
||||||
|
reloadTime = 0
|
||||||
|
|
||||||
# Group modules based on their properties
|
# Group modules based on their properties
|
||||||
if (duration, capNeed, clipSize, disableStagger) in mods:
|
if (duration, capNeed, clipSize, disableStagger, reloadTime) in mods:
|
||||||
mods[(duration, capNeed, clipSize, disableStagger)] += 1
|
mods[(duration, capNeed, clipSize, disableStagger, reloadTime)] += 1
|
||||||
else:
|
else:
|
||||||
mods[(duration, capNeed, clipSize, disableStagger)] = 1
|
mods[(duration, capNeed, clipSize, disableStagger, reloadTime)] = 1
|
||||||
|
|
||||||
# Loop over grouped modules, configure staggering and push to the simulation state
|
# Loop over grouped modules, configure staggering and push to the simulation state
|
||||||
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
|
for (duration, capNeed, clipSize, disableStagger, reloadTime), amount in mods.items():
|
||||||
if self.stagger and not disableStagger:
|
if self.stagger and not disableStagger:
|
||||||
if clipSize == 0:
|
if clipSize == 0:
|
||||||
duration = int(duration/amount)
|
duration = int(duration / amount)
|
||||||
else:
|
else:
|
||||||
stagger_amount = (duration*clipSize+10000)/(amount*clipSize)
|
stagger_amount = (duration * clipSize + reloadTime) / (amount * clipSize)
|
||||||
for i in range(1, amount):
|
for i in range(1, amount):
|
||||||
heapq.heappush(self.state,
|
heapq.heappush(self.state,
|
||||||
[i*stagger_amount, duration,
|
[i * stagger_amount, duration,
|
||||||
capNeed, 0, clipSize])
|
capNeed, 0, clipSize, reloadTime])
|
||||||
else:
|
else:
|
||||||
capNeed *= amount
|
capNeed *= amount
|
||||||
|
|
||||||
@@ -107,15 +108,13 @@ class CapSimulator(object):
|
|||||||
if clipSize:
|
if clipSize:
|
||||||
disable_period = True
|
disable_period = True
|
||||||
|
|
||||||
heapq.heappush(self.state, [0, duration, capNeed, 0, clipSize])
|
heapq.heappush(self.state, [0, duration, capNeed, 0, clipSize, reloadTime])
|
||||||
|
|
||||||
|
|
||||||
if disable_period:
|
if disable_period:
|
||||||
self.period = self.t_max
|
self.period = self.t_max
|
||||||
else:
|
else:
|
||||||
self.period = period
|
self.period = period
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run the simulation"""
|
"""Run the simulation"""
|
||||||
|
|
||||||
@@ -135,22 +134,22 @@ class CapSimulator(object):
|
|||||||
capCapacity = self.capacitorCapacity
|
capCapacity = self.capacitorCapacity
|
||||||
tau = self.capacitorRecharge / 5.0
|
tau = self.capacitorRecharge / 5.0
|
||||||
|
|
||||||
cap_wrap = capCapacity # cap value at last period
|
cap_wrap = capCapacity # cap value at last period
|
||||||
cap_lowest = capCapacity # lowest cap value encountered
|
cap_lowest = capCapacity # lowest cap value encountered
|
||||||
cap_lowest_pre = capCapacity # lowest cap value before activations
|
cap_lowest_pre = capCapacity # lowest cap value before activations
|
||||||
cap = capCapacity # current cap value
|
cap = capCapacity # current cap value
|
||||||
t_wrap = self.period # point in time of next period
|
t_wrap = self.period # point in time of next period
|
||||||
|
|
||||||
t_now = t_last = 0
|
t_last = 0
|
||||||
t_max = self.t_max
|
t_max = self.t_max
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
activation = pop(state)
|
activation = pop(state)
|
||||||
t_now, duration, capNeed, shot, clipSize = activation
|
t_now, duration, capNeed, shot, clipSize, reloadTime = activation
|
||||||
if t_now >= t_max:
|
if t_now >= t_max:
|
||||||
break
|
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 t_now != t_last:
|
||||||
if cap < cap_lowest_pre:
|
if cap < cap_lowest_pre:
|
||||||
@@ -182,7 +181,7 @@ class CapSimulator(object):
|
|||||||
if clipSize:
|
if clipSize:
|
||||||
if shot % clipSize == 0:
|
if shot % clipSize == 0:
|
||||||
shot = 0
|
shot = 0
|
||||||
t_now += 10000 # include reload time
|
t_now += reloadTime # include reload time
|
||||||
activation[0] = t_now
|
activation[0] = t_now
|
||||||
activation[3] = shot
|
activation[3] = shot
|
||||||
|
|
||||||
@@ -195,19 +194,17 @@ class CapSimulator(object):
|
|||||||
|
|
||||||
# calculate EVE's stability value
|
# calculate EVE's stability value
|
||||||
try:
|
try:
|
||||||
avgDrain = reduce(float.__add__, map(lambda x: x[2]/x[1], self.state), 0.0)
|
avgDrain = reduce(float.__add__, [x[2] / x[1] for x in self.state], 0.0)
|
||||||
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity)/capCapacity)) ** 2
|
self.cap_stable_eve = 0.25 * (1.0 + sqrt(-(2.0 * avgDrain * tau - capCapacity) / capCapacity)) ** 2
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.cap_stable_eve = 0.0
|
self.cap_stable_eve = 0.0
|
||||||
|
|
||||||
|
|
||||||
if cap > 0.0:
|
if cap > 0.0:
|
||||||
# capacitor low/high water marks
|
# capacitor low/high water marks
|
||||||
self.cap_stable_low = cap_lowest
|
self.cap_stable_low = cap_lowest
|
||||||
self.cap_stable_high = cap_lowest_pre
|
self.cap_stable_high = cap_lowest_pre
|
||||||
else:
|
else:
|
||||||
self.cap_stable_low =\
|
self.cap_stable_low = \
|
||||||
self.cap_stable_high = 0.0
|
self.cap_stable_high = 0.0
|
||||||
|
|
||||||
|
self.runtime = time.time() - start
|
||||||
self.runtime = time.time()-start
|
|
||||||
|
|||||||
@@ -1,11 +1,31 @@
|
|||||||
from os.path import realpath, join, dirname, abspath
|
|
||||||
import sys
|
import sys
|
||||||
|
from os.path import realpath, join, dirname, abspath
|
||||||
|
|
||||||
|
from logbook import Logger
|
||||||
|
import os
|
||||||
|
|
||||||
|
istravis = os.environ.get('TRAVIS') == 'true'
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
|
||||||
debug = False
|
debug = False
|
||||||
gamedataCache = True
|
gamedataCache = True
|
||||||
saveddataCache = True
|
saveddataCache = True
|
||||||
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
|
gamedata_version = ""
|
||||||
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
|
gamedata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "eve.db"))
|
||||||
|
pyfalog.debug("Gamedata connection string: {0}", gamedata_connectionstring)
|
||||||
|
|
||||||
#Autodetect path, only change if the autodetection bugs out.
|
if istravis is True or hasattr(sys, '_called_from_test'):
|
||||||
path = dirname(unicode(__file__, sys.getfilesystemencoding()))
|
# Running in Travis. Run saveddata database in memory.
|
||||||
|
saveddata_connectionstring = 'sqlite:///:memory:'
|
||||||
|
else:
|
||||||
|
saveddata_connectionstring = 'sqlite:///' + realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata-py3-db.db"))
|
||||||
|
|
||||||
|
pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring)
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"useStaticAdaptiveArmorHardener": False,
|
||||||
|
"strictSkillLevels": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autodetect path, only change if the autodetection bugs out.
|
||||||
|
path = dirname(__file__)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,26 +15,31 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from sqlalchemy import MetaData, create_engine
|
from sqlalchemy import MetaData, create_engine
|
||||||
from sqlalchemy.orm import sessionmaker, scoped_session
|
from sqlalchemy.orm import sessionmaker
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
|
||||||
from sqlalchemy import pool
|
|
||||||
|
|
||||||
|
from . import migration
|
||||||
from eos import config
|
from eos import config
|
||||||
import migration
|
from logbook import Logger
|
||||||
|
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
pyfalog.info("Initializing database")
|
||||||
|
pyfalog.info("Gamedata connection: {0}", config.gamedata_connectionstring)
|
||||||
|
pyfalog.info("Saveddata connection: {0}", config.saveddata_connectionstring)
|
||||||
|
|
||||||
class ReadOnlyException(Exception):
|
class ReadOnlyException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
gamedata_connectionstring = config.gamedata_connectionstring
|
gamedata_connectionstring = config.gamedata_connectionstring
|
||||||
if callable(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:
|
else:
|
||||||
gamedata_engine = create_engine(gamedata_connectionstring, echo = config.debug)
|
gamedata_engine = create_engine(gamedata_connectionstring, echo=config.debug)
|
||||||
|
|
||||||
gamedata_meta = MetaData()
|
gamedata_meta = MetaData()
|
||||||
gamedata_meta.bind = gamedata_engine
|
gamedata_meta.bind = gamedata_engine
|
||||||
@@ -45,8 +50,10 @@ gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on
|
|||||||
try:
|
try:
|
||||||
config.gamedata_version = gamedata_session.execute(
|
config.gamedata_version = gamedata_session.execute(
|
||||||
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
"SELECT `field_value` FROM `metadata` WHERE `field_name` LIKE 'client_build'"
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
except:
|
except Exception as e:
|
||||||
|
pyfalog.warning("Missing gamedata version.")
|
||||||
|
pyfalog.critical(e)
|
||||||
config.gamedata_version = None
|
config.gamedata_version = None
|
||||||
|
|
||||||
saveddata_connectionstring = config.saveddata_connectionstring
|
saveddata_connectionstring = config.saveddata_connectionstring
|
||||||
@@ -59,23 +66,32 @@ if saveddata_connectionstring is not None:
|
|||||||
saveddata_meta = MetaData()
|
saveddata_meta = MetaData()
|
||||||
saveddata_meta.bind = saveddata_engine
|
saveddata_meta.bind = saveddata_engine
|
||||||
saveddata_session = sessionmaker(bind=saveddata_engine, autoflush=False, expire_on_commit=False)()
|
saveddata_session = sessionmaker(bind=saveddata_engine, autoflush=False, expire_on_commit=False)()
|
||||||
|
else:
|
||||||
|
saveddata_meta = None
|
||||||
|
|
||||||
# Lock controlling any changes introduced to session
|
# Lock controlling any changes introduced to session
|
||||||
sd_lock = threading.Lock()
|
sd_lock = threading.RLock()
|
||||||
|
|
||||||
#Import all the definitions for all our database stuff
|
# Import all the definitions for all our database stuff
|
||||||
from eos.db.gamedata import *
|
# noinspection PyPep8
|
||||||
from eos.db.saveddata import *
|
from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
||||||
|
# noinspection PyPep8
|
||||||
|
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
||||||
|
miscData, module, override, price, queries, skill, targetResists, user
|
||||||
|
|
||||||
#Import queries
|
# Import queries
|
||||||
|
# noinspection PyPep8
|
||||||
from eos.db.gamedata.queries import *
|
from eos.db.gamedata.queries import *
|
||||||
|
# noinspection PyPep8
|
||||||
from eos.db.saveddata.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:":
|
if config.saveddata_connectionstring == "sqlite:///:memory:":
|
||||||
saveddata_meta.create_all()
|
saveddata_meta.create_all()
|
||||||
|
pyfalog.info("Running database out of memory.")
|
||||||
|
|
||||||
|
|
||||||
def rollback():
|
def rollback():
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
|
pyfalog.warning("Session rollback triggered.")
|
||||||
saveddata_session.rollback()
|
saveddata_session.rollback()
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
__all__ = ["attribute", "category", "effect", "group", "metaData",
|
__all__ = ["attribute", "category", "effect", "group", "metaData",
|
||||||
"icon", "item", "marketGroup", "metaGroup", "unit"]
|
"icon", "item", "marketGroup", "metaGroup", "unit", "alphaClones"]
|
||||||
|
|||||||
50
eos/db/gamedata/alphaClones.py
Normal file
50
eos/db/gamedata/alphaClones.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# 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.gamedata 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
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,20 +15,22 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, Float, Unicode, ForeignKey, String, Boolean
|
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 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.db import gamedata_meta
|
||||||
|
from eos.gamedata import Attribute, AttributeInfo, Unit, Icon
|
||||||
|
|
||||||
typeattributes_table = Table("dgmtypeattribs", gamedata_meta,
|
typeattributes_table = Table("dgmtypeattribs", gamedata_meta,
|
||||||
Column("value", Float),
|
Column("value", Float),
|
||||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||||
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True))
|
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True))
|
||||||
|
|
||||||
attributes_table = Table("dgmattribs", gamedata_meta,
|
attributes_table = Table("dgmattribs", gamedata_meta,
|
||||||
Column("attributeID", Integer, primary_key = True),
|
Column("attributeID", Integer, primary_key=True),
|
||||||
Column("attributeName", String),
|
Column("attributeName", String),
|
||||||
Column("defaultValue", Float),
|
Column("defaultValue", Float),
|
||||||
Column("maxAttributeID", Integer, ForeignKey("dgmattribs.attributeID")),
|
Column("maxAttributeID", Integer, ForeignKey("dgmattribs.attributeID")),
|
||||||
@@ -40,14 +42,16 @@ attributes_table = Table("dgmattribs", gamedata_meta,
|
|||||||
Column("unitID", Integer, ForeignKey("dgmunits.unitID")))
|
Column("unitID", Integer, ForeignKey("dgmunits.unitID")))
|
||||||
|
|
||||||
mapper(Attribute, typeattributes_table,
|
mapper(Attribute, typeattributes_table,
|
||||||
properties = {"info": relation(AttributeInfo, lazy=False)})
|
properties={"info": relation(AttributeInfo, lazy=False)})
|
||||||
|
|
||||||
mapper(AttributeInfo, attributes_table,
|
mapper(AttributeInfo, attributes_table,
|
||||||
properties = {"icon" : relation(Icon),
|
properties={
|
||||||
"unit": relation(Unit),
|
"icon" : relation(Icon),
|
||||||
"ID": synonym("attributeID"),
|
"unit" : relation(Unit),
|
||||||
"name": synonym("attributeName"),
|
"ID" : synonym("attributeID"),
|
||||||
"description" : deferred(attributes_table.c.description)})
|
"name" : synonym("attributeName"),
|
||||||
|
"description": deferred(attributes_table.c.description)
|
||||||
|
})
|
||||||
|
|
||||||
Attribute.ID = association_proxy("info", "attributeID")
|
Attribute.ID = association_proxy("info", "attributeID")
|
||||||
Attribute.name = association_proxy("info", "attributeName")
|
Attribute.name = association_proxy("info", "attributeName")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,23 +15,25 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
|
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
|
||||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Category, Icon
|
from eos.gamedata import Category, Icon
|
||||||
|
|
||||||
categories_table = Table("invcategories", gamedata_meta,
|
categories_table = Table("invcategories", gamedata_meta,
|
||||||
Column("categoryID", Integer, primary_key = True),
|
Column("categoryID", Integer, primary_key=True),
|
||||||
Column("categoryName", String),
|
Column("categoryName", String),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("published", Boolean),
|
Column("published", Boolean),
|
||||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||||
|
|
||||||
mapper(Category, categories_table,
|
mapper(Category, categories_table,
|
||||||
properties = {"icon" : relation(Icon),
|
properties={
|
||||||
"ID" : synonym("categoryID"),
|
"icon" : relation(Icon),
|
||||||
"name" : synonym("categoryName"),
|
"ID" : synonym("categoryID"),
|
||||||
"description" : deferred(categories_table.c.description)})
|
"name" : synonym("categoryName"),
|
||||||
|
"description": deferred(categories_table.c.description)
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,36 +15,32 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Boolean, Table, ForeignKey
|
from sqlalchemy import Column, String, Integer, Boolean, Table, ForeignKey
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
from sqlalchemy.orm import mapper, synonym, deferred
|
||||||
from sqlalchemy.orm import mapper, synonym, relation, deferred
|
|
||||||
from eos.types import Effect, EffectInfo
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
|
from eos.gamedata import Effect, ItemEffect
|
||||||
|
|
||||||
typeeffects_table = Table("dgmtypeeffects", gamedata_meta,
|
typeeffects_table = Table("dgmtypeeffects", gamedata_meta,
|
||||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
|
||||||
Column("effectID", Integer, ForeignKey("dgmeffects.effectID"), primary_key=True))
|
Column("effectID", Integer, ForeignKey("dgmeffects.effectID"), primary_key=True))
|
||||||
|
|
||||||
effects_table = Table("dgmeffects", gamedata_meta,
|
effects_table = Table("dgmeffects", gamedata_meta,
|
||||||
Column("effectID", Integer, primary_key = True),
|
Column("effectID", Integer, primary_key=True),
|
||||||
Column("effectName", String),
|
Column("effectName", String),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("published", Boolean),
|
Column("published", Boolean),
|
||||||
Column("isAssistance", Boolean),
|
Column("isAssistance", Boolean),
|
||||||
Column("isOffensive", Boolean))
|
Column("isOffensive", Boolean),
|
||||||
|
Column("resistanceID", Integer))
|
||||||
|
|
||||||
|
mapper(Effect, effects_table,
|
||||||
|
properties={
|
||||||
|
"ID" : synonym("effectID"),
|
||||||
|
"name" : synonym("effectName"),
|
||||||
|
"description": deferred(effects_table.c.description)
|
||||||
|
})
|
||||||
|
|
||||||
mapper(EffectInfo, effects_table,
|
mapper(ItemEffect, typeeffects_table)
|
||||||
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)})
|
|
||||||
|
|
||||||
Effect.name = association_proxy("info", "name")
|
|
||||||
Effect.description = association_proxy("info", "description")
|
|
||||||
Effect.published = association_proxy("info", "published")
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,16 +15,16 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Group, Icon, Category
|
from eos.gamedata import Category, Group, Icon
|
||||||
|
|
||||||
groups_table = Table("invgroups", gamedata_meta,
|
groups_table = Table("invgroups", gamedata_meta,
|
||||||
Column("groupID", Integer, primary_key = True),
|
Column("groupID", Integer, primary_key=True),
|
||||||
Column("groupName", String),
|
Column("groupName", String),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("published", Boolean),
|
Column("published", Boolean),
|
||||||
@@ -32,8 +32,10 @@ groups_table = Table("invgroups", gamedata_meta,
|
|||||||
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||||
|
|
||||||
mapper(Group, groups_table,
|
mapper(Group, groups_table,
|
||||||
properties = {"category" : relation(Category, backref = "groups"),
|
properties={
|
||||||
"icon" : relation(Icon),
|
"category" : relation(Category, backref="groups"),
|
||||||
"ID" : synonym("groupID"),
|
"icon" : relation(Icon),
|
||||||
"name" : synonym("groupName"),
|
"ID" : synonym("groupID"),
|
||||||
"description" : deferred(groups_table.c.description)})
|
"name" : synonym("groupName"),
|
||||||
|
"description": deferred(groups_table.c.description)
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,19 +15,21 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Table
|
from sqlalchemy import Column, String, Integer, Table
|
||||||
from sqlalchemy.orm import mapper, synonym, deferred
|
from sqlalchemy.orm import mapper, synonym, deferred
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Icon
|
from eos.gamedata import Icon
|
||||||
|
|
||||||
icons_table = Table("icons", gamedata_meta,
|
icons_table = Table("icons", gamedata_meta,
|
||||||
Column("iconID", Integer, primary_key = True),
|
Column("iconID", Integer, primary_key=True),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("iconFile", String))
|
Column("iconFile", String))
|
||||||
|
|
||||||
mapper(Icon, icons_table,
|
mapper(Icon, icons_table,
|
||||||
properties = {"ID" : synonym("iconID"),
|
properties={
|
||||||
"description" : deferred(icons_table.c.description)})
|
"ID" : synonym("iconID"),
|
||||||
|
"description": deferred(icons_table.c.description)
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,18 +15,19 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
|
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.ext.associationproxy import association_proxy
|
||||||
|
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||||
|
from eos.db.gamedata.effect import typeeffects_table
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Icon, Attribute, Item, Effect, MetaType, Group, Traits
|
from eos.gamedata import Attribute, Effect, Group, Icon, Item, MetaType, Traits
|
||||||
|
|
||||||
items_table = Table("invtypes", gamedata_meta,
|
items_table = Table("invtypes", gamedata_meta,
|
||||||
Column("typeID", Integer, primary_key = True),
|
Column("typeID", Integer, primary_key=True),
|
||||||
Column("typeName", String, index=True),
|
Column("typeName", String, index=True),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("raceID", Integer),
|
Column("raceID", Integer),
|
||||||
@@ -39,23 +40,24 @@ items_table = Table("invtypes", gamedata_meta,
|
|||||||
Column("iconID", Integer, ForeignKey("icons.iconID")),
|
Column("iconID", Integer, ForeignKey("icons.iconID")),
|
||||||
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
|
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
|
||||||
|
|
||||||
from .metaGroup import metatypes_table
|
from .metaGroup import metatypes_table # noqa
|
||||||
from .traits import traits_table
|
from .traits import traits_table # noqa
|
||||||
|
|
||||||
mapper(Item, items_table,
|
mapper(Item, items_table,
|
||||||
properties = {"group" : relation(Group, backref = "items"),
|
properties={
|
||||||
"icon" : relation(Icon),
|
"group" : relation(Group, backref="items"),
|
||||||
"_Item__attributes" : relation(Attribute, collection_class = attribute_mapped_collection('name')),
|
"icon" : relation(Icon),
|
||||||
"effects" : relation(Effect, collection_class = attribute_mapped_collection('name')),
|
"_Item__attributes": relation(Attribute, cascade='all, delete, delete-orphan', collection_class=attribute_mapped_collection('name')),
|
||||||
"metaGroup" : relation(MetaType,
|
"effects": relation(Effect, secondary=typeeffects_table, collection_class=attribute_mapped_collection('name')),
|
||||||
primaryjoin = metatypes_table.c.typeID == items_table.c.typeID,
|
"metaGroup" : relation(MetaType,
|
||||||
uselist = False),
|
primaryjoin=metatypes_table.c.typeID == items_table.c.typeID,
|
||||||
"ID" : synonym("typeID"),
|
uselist=False),
|
||||||
"name" : synonym("typeName"),
|
"ID" : synonym("typeID"),
|
||||||
"description" : deferred(items_table.c.description),
|
"name" : synonym("typeName"),
|
||||||
"traits" : relation(Traits,
|
"description" : deferred(items_table.c.description),
|
||||||
primaryjoin = traits_table.c.typeID == items_table.c.typeID,
|
"traits" : relation(Traits,
|
||||||
uselist = False)
|
primaryjoin=traits_table.c.typeID == items_table.c.typeID,
|
||||||
})
|
uselist=False)
|
||||||
|
})
|
||||||
|
|
||||||
Item.category = association_proxy("group", "category")
|
Item.category = association_proxy("group", "category")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,26 +15,30 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
|
||||||
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
from sqlalchemy.orm import relation, mapper, synonym, deferred
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Item, MarketGroup, Icon
|
from eos.gamedata import Icon, Item, MarketGroup
|
||||||
|
|
||||||
marketgroups_table = Table("invmarketgroups", gamedata_meta,
|
marketgroups_table = Table("invmarketgroups", gamedata_meta,
|
||||||
Column("marketGroupID", Integer, primary_key = True),
|
Column("marketGroupID", Integer, primary_key=True),
|
||||||
Column("marketGroupName", String),
|
Column("marketGroupName", String),
|
||||||
Column("description", String),
|
Column("description", String),
|
||||||
Column("hasTypes", Boolean),
|
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")))
|
Column("iconID", Integer, ForeignKey("icons.iconID")))
|
||||||
|
|
||||||
mapper(MarketGroup, marketgroups_table,
|
mapper(MarketGroup, marketgroups_table,
|
||||||
properties = {"items" : relation(Item, backref = "marketGroup"),
|
properties={
|
||||||
"parent" : relation(MarketGroup, backref = "children", remote_side = [marketgroups_table.c.marketGroupID]),
|
"items" : relation(Item, backref="marketGroup"),
|
||||||
"icon" : relation(Icon),
|
"parent" : relation(MarketGroup, backref="children",
|
||||||
"ID" : synonym("marketGroupID"),
|
remote_side=[marketgroups_table.c.marketGroupID]),
|
||||||
"name" : synonym("marketGroupName"),
|
"icon" : relation(Icon),
|
||||||
"description" : deferred(marketgroups_table.c.description)})
|
"ID" : synonym("marketGroupID"),
|
||||||
|
"name" : synonym("marketGroupName"),
|
||||||
|
"description": deferred(marketgroups_table.c.description)
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,29 +1,30 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
#
|
#
|
||||||
# eos is free software: you can redistribute it and/or modify
|
# 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
|
# 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
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# eos is distributed in the hope that it will be useful,
|
# eos is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU Lesser General Public License for more details.
|
# GNU Lesser General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, String
|
from sqlalchemy import Column, Table, String
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
from eos.types import MetaData
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
|
from eos.gamedata import MetaData
|
||||||
metadata_table = Table("metadata", gamedata_meta,
|
|
||||||
Column("field_name", String, primary_key=True),
|
metadata_table = Table("metadata", gamedata_meta,
|
||||||
Column("field_value", String))
|
Column("field_name", String, primary_key=True),
|
||||||
|
Column("field_value", String))
|
||||||
mapper(MetaData, metadata_table)
|
|
||||||
|
mapper(MetaData, metadata_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,33 +15,37 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, ForeignKey, String
|
||||||
|
from sqlalchemy.ext.associationproxy import association_proxy
|
||||||
from sqlalchemy.orm import relation, mapper, synonym
|
from sqlalchemy.orm import relation, mapper, synonym
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.db.gamedata.item import items_table
|
from eos.db.gamedata.item import items_table
|
||||||
from eos.types import MetaGroup, Item, MetaType
|
from eos.gamedata import Item, MetaGroup, MetaType
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
|
||||||
|
|
||||||
metagroups_table = Table("invmetagroups", gamedata_meta,
|
metagroups_table = Table("invmetagroups", gamedata_meta,
|
||||||
Column("metaGroupID", Integer, primary_key = True),
|
Column("metaGroupID", Integer, primary_key=True),
|
||||||
Column("metaGroupName", String))
|
Column("metaGroupName", String))
|
||||||
|
|
||||||
metatypes_table = Table("invmetatypes", gamedata_meta,
|
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("parentTypeID", Integer, ForeignKey("invtypes.typeID")),
|
||||||
Column("metaGroupID", Integer, ForeignKey("invmetagroups.metaGroupID")))
|
Column("metaGroupID", Integer, ForeignKey("invmetagroups.metaGroupID")))
|
||||||
|
|
||||||
mapper(MetaGroup, metagroups_table,
|
mapper(MetaGroup, metagroups_table,
|
||||||
properties = {"ID" : synonym("metaGroupID"),
|
properties={
|
||||||
"name" : synonym("metaGroupName")})
|
"ID" : synonym("metaGroupID"),
|
||||||
|
"name": synonym("metaGroupName")
|
||||||
|
})
|
||||||
|
|
||||||
mapper(MetaType, metatypes_table,
|
mapper(MetaType, metatypes_table,
|
||||||
properties = {"ID" : synonym("metaGroupID"),
|
properties={
|
||||||
"parent" : relation(Item, primaryjoin = metatypes_table.c.parentTypeID == items_table.c.typeID),
|
"ID" : synonym("metaGroupID"),
|
||||||
"items" : relation(Item, primaryjoin = metatypes_table.c.typeID == items_table.c.typeID),
|
"parent": relation(Item, primaryjoin=metatypes_table.c.parentTypeID == items_table.c.typeID),
|
||||||
"info": relation(MetaGroup, lazy=False)})
|
"items" : relation(Item, primaryjoin=metatypes_table.c.typeID == items_table.c.typeID),
|
||||||
|
"info" : relation(MetaGroup, lazy=False)
|
||||||
|
})
|
||||||
|
|
||||||
MetaType.name = association_proxy("info", "name")
|
MetaType.name = association_proxy("info", "name")
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,21 +15,23 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
|
from sqlalchemy.orm import join, exc, aliased
|
||||||
|
from sqlalchemy.sql import and_, or_, select
|
||||||
|
|
||||||
|
import eos.config
|
||||||
from eos.db import gamedata_session
|
from eos.db import gamedata_session
|
||||||
from eos.db.gamedata.metaGroup import metatypes_table, items_table
|
from eos.db.gamedata.metaGroup import metatypes_table, items_table
|
||||||
from sqlalchemy.sql import and_, or_, select, func
|
from eos.db.gamedata.group import groups_table
|
||||||
from sqlalchemy.orm import join, exc
|
|
||||||
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup
|
|
||||||
from eos.db.util import processEager, processWhere
|
from eos.db.util import processEager, processWhere
|
||||||
import eos.config
|
from eos.gamedata import AlphaClone, Attribute, Category, Group, Item, MarketGroup, MetaGroup, AttributeInfo, MetaData
|
||||||
|
|
||||||
|
cache = {}
|
||||||
configVal = getattr(eos.config, "gamedataCache", None)
|
configVal = getattr(eos.config, "gamedataCache", None)
|
||||||
if configVal is True:
|
if configVal is True:
|
||||||
def cachedQuery(amount, *keywords):
|
def cachedQuery(amount, *keywords):
|
||||||
def deco(function):
|
def deco(function):
|
||||||
cache = {}
|
|
||||||
def checkAndReturn(*args, **kwargs):
|
def checkAndReturn(*args, **kwargs):
|
||||||
useCache = kwargs.pop("useCache", True)
|
useCache = kwargs.pop("useCache", True)
|
||||||
cacheKey = []
|
cacheKey = []
|
||||||
@@ -45,6 +47,7 @@ if configVal is True:
|
|||||||
return handler
|
return handler
|
||||||
|
|
||||||
return checkAndReturn
|
return checkAndReturn
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
||||||
elif callable(configVal):
|
elif callable(configVal):
|
||||||
@@ -56,8 +59,10 @@ else:
|
|||||||
return function(*args, **kwargs)
|
return function(*args, **kwargs)
|
||||||
|
|
||||||
return checkAndReturn
|
return checkAndReturn
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
||||||
|
|
||||||
def sqlizeString(line):
|
def sqlizeString(line):
|
||||||
# Escape backslashes first, as they will be as escape symbol in queries
|
# Escape backslashes first, as they will be as escape symbol in queries
|
||||||
# Then escape percent and underscore signs
|
# Then escape percent and underscore signs
|
||||||
@@ -65,7 +70,10 @@ def sqlizeString(line):
|
|||||||
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
itemNameMap = {}
|
itemNameMap = {}
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "lookfor")
|
@cachedQuery(1, "lookfor")
|
||||||
def getItem(lookfor, eager=None):
|
def getItem(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -73,7 +81,7 @@ def getItem(lookfor, eager=None):
|
|||||||
item = gamedata_session.query(Item).get(lookfor)
|
item = gamedata_session.query(Item).get(lookfor)
|
||||||
else:
|
else:
|
||||||
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
|
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
|
||||||
elif isinstance(lookfor, basestring):
|
elif isinstance(lookfor, str):
|
||||||
if lookfor in itemNameMap:
|
if lookfor in itemNameMap:
|
||||||
id = itemNameMap[lookfor]
|
id = itemNameMap[lookfor]
|
||||||
if eager is None:
|
if eager is None:
|
||||||
@@ -88,7 +96,57 @@ def getItem(lookfor, eager=None):
|
|||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
|
||||||
|
@cachedQuery(1, "lookfor")
|
||||||
|
def getItems(lookfor, eager=None):
|
||||||
|
"""
|
||||||
|
Gets a list of items. Does a bit of cache hackery to get working properly -- cache
|
||||||
|
is usually based on function calls with the parameters, needed to extract data directly.
|
||||||
|
Works well enough. Not currently used, but it's here for possible future inclusion
|
||||||
|
"""
|
||||||
|
|
||||||
|
toGet = []
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for id in lookfor:
|
||||||
|
if (id, None) in cache:
|
||||||
|
results.append(cache.get((id, None)))
|
||||||
|
else:
|
||||||
|
toGet.append(id)
|
||||||
|
|
||||||
|
if len(toGet) > 0:
|
||||||
|
# Get items that aren't currently cached, and store them in the cache
|
||||||
|
items = gamedata_session.query(Item).filter(Item.ID.in_(toGet)).all()
|
||||||
|
for item in items:
|
||||||
|
cache[(item.ID, None)] = item
|
||||||
|
results += items
|
||||||
|
|
||||||
|
# sort the results based on the original indexing
|
||||||
|
results.sort(key=lambda x: lookfor.index(x.ID))
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
@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 = {}
|
groupNameMap = {}
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "lookfor")
|
@cachedQuery(1, "lookfor")
|
||||||
def getGroup(lookfor, eager=None):
|
def getGroup(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -96,7 +154,7 @@ def getGroup(lookfor, eager=None):
|
|||||||
group = gamedata_session.query(Group).get(lookfor)
|
group = gamedata_session.query(Group).get(lookfor)
|
||||||
else:
|
else:
|
||||||
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
|
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
|
||||||
elif isinstance(lookfor, basestring):
|
elif isinstance(lookfor, str):
|
||||||
if lookfor in groupNameMap:
|
if lookfor in groupNameMap:
|
||||||
id = groupNameMap[lookfor]
|
id = groupNameMap[lookfor]
|
||||||
if eager is None:
|
if eager is None:
|
||||||
@@ -111,78 +169,95 @@ def getGroup(lookfor, eager=None):
|
|||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
|
||||||
categoryNameMap = {}
|
categoryNameMap = {}
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "lookfor")
|
@cachedQuery(1, "lookfor")
|
||||||
def getCategory(lookfor, eager=None):
|
def getCategory(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
if eager is None:
|
if eager is None:
|
||||||
category = gamedata_session.query(Category).get(lookfor)
|
category = gamedata_session.query(Category).get(lookfor)
|
||||||
else:
|
else:
|
||||||
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.ID == lookfor).first()
|
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
|
||||||
elif isinstance(lookfor, basestring):
|
Category.ID == lookfor).first()
|
||||||
|
elif isinstance(lookfor, str):
|
||||||
if lookfor in categoryNameMap:
|
if lookfor in categoryNameMap:
|
||||||
id = categoryNameMap[lookfor]
|
id = categoryNameMap[lookfor]
|
||||||
if eager is None:
|
if eager is None:
|
||||||
category = gamedata_session.query(Category).get(id)
|
category = gamedata_session.query(Category).get(id)
|
||||||
else:
|
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:
|
else:
|
||||||
# Category names are unique, so we can use first() instead of one()
|
# 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
|
categoryNameMap[lookfor] = category.ID
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return category
|
return category
|
||||||
|
|
||||||
|
|
||||||
metaGroupNameMap = {}
|
metaGroupNameMap = {}
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "lookfor")
|
@cachedQuery(1, "lookfor")
|
||||||
def getMetaGroup(lookfor, eager=None):
|
def getMetaGroup(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
if eager is None:
|
if eager is None:
|
||||||
metaGroup = gamedata_session.query(MetaGroup).get(lookfor)
|
metaGroup = gamedata_session.query(MetaGroup).get(lookfor)
|
||||||
else:
|
else:
|
||||||
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.ID == lookfor).first()
|
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
|
||||||
elif isinstance(lookfor, basestring):
|
MetaGroup.ID == lookfor).first()
|
||||||
|
elif isinstance(lookfor, str):
|
||||||
if lookfor in metaGroupNameMap:
|
if lookfor in metaGroupNameMap:
|
||||||
id = metaGroupNameMap[lookfor]
|
id = metaGroupNameMap[lookfor]
|
||||||
if eager is None:
|
if eager is None:
|
||||||
metaGroup = gamedata_session.query(MetaGroup).get(id)
|
metaGroup = gamedata_session.query(MetaGroup).get(id)
|
||||||
else:
|
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:
|
else:
|
||||||
# MetaGroup names are unique, so we can use first() instead of one()
|
# 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
|
metaGroupNameMap[lookfor] = metaGroup.ID
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return metaGroup
|
return metaGroup
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "lookfor")
|
@cachedQuery(1, "lookfor")
|
||||||
def getMarketGroup(lookfor, eager=None):
|
def getMarketGroup(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
if eager is None:
|
if eager is None:
|
||||||
marketGroup = gamedata_session.query(MarketGroup).get(lookfor)
|
marketGroup = gamedata_session.query(MarketGroup).get(lookfor)
|
||||||
else:
|
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:
|
else:
|
||||||
raise TypeError("Need integer as argument")
|
raise TypeError("Need integer as argument")
|
||||||
return marketGroup
|
return marketGroup
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(2, "where", "filter")
|
@cachedQuery(2, "where", "filter")
|
||||||
def getItemsByCategory(filter, where=None, eager=None):
|
def getItemsByCategory(filter, where=None, eager=None):
|
||||||
if isinstance(filter, int):
|
if isinstance(filter, int):
|
||||||
filter = Category.ID == filter
|
filter = Category.ID == filter
|
||||||
elif isinstance(filter, basestring):
|
elif isinstance(filter, str):
|
||||||
filter = Category.name == filter
|
filter = Category.name == filter
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
|
|
||||||
filter = processWhere(filter, where)
|
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")
|
@cachedQuery(3, "where", "nameLike", "join")
|
||||||
def searchItems(nameLike, where=None, join=None, eager=None):
|
def searchItems(nameLike, where=None, join=None, eager=None):
|
||||||
if not isinstance(nameLike, basestring):
|
if not isinstance(nameLike, str):
|
||||||
raise TypeError("Need string as argument")
|
raise TypeError("Need string as argument")
|
||||||
|
|
||||||
if join is None:
|
if join is None:
|
||||||
@@ -193,13 +268,33 @@ def searchItems(nameLike, where=None, join=None, eager=None):
|
|||||||
|
|
||||||
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
|
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
|
||||||
for token in nameLike.split(' '):
|
for token in nameLike.split(' '):
|
||||||
token_safe = u"%{0}%".format(sqlizeString(token))
|
token_safe = "%{0}%".format(sqlizeString(token))
|
||||||
items = items.filter(processWhere(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()
|
items = items.limit(100).all()
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
@cachedQuery(3, "where", "nameLike", "join")
|
||||||
|
def searchSkills(nameLike, where=None, eager=None):
|
||||||
|
if not isinstance(nameLike, str):
|
||||||
|
raise TypeError("Need string as argument")
|
||||||
|
|
||||||
|
items = gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category)
|
||||||
|
for token in nameLike.split(' '):
|
||||||
|
token_safe = "%{0}%".format(sqlizeString(token))
|
||||||
|
if where is not None:
|
||||||
|
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16, where))
|
||||||
|
else:
|
||||||
|
items = items.filter(and_(Item.name.like(token_safe, escape="\\"), Category.ID == 16))
|
||||||
|
items = items.limit(100).all()
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(2, "where", "itemids")
|
@cachedQuery(2, "where", "itemids")
|
||||||
def getVariations(itemids, where=None, eager=None):
|
def getVariations(itemids, groupIDs=None, where=None, eager=None):
|
||||||
for itemid in itemids:
|
for itemid in itemids:
|
||||||
if not isinstance(itemid, int):
|
if not isinstance(itemid, int):
|
||||||
raise TypeError("All passed item IDs must be integers")
|
raise TypeError("All passed item IDs must be integers")
|
||||||
@@ -210,12 +305,24 @@ def getVariations(itemids, where=None, eager=None):
|
|||||||
itemfilter = or_(*(metatypes_table.c.parentTypeID == itemid for itemid in itemids))
|
itemfilter = or_(*(metatypes_table.c.parentTypeID == itemid for itemid in itemids))
|
||||||
filter = processWhere(itemfilter, where)
|
filter = processWhere(itemfilter, where)
|
||||||
joinon = items_table.c.typeID == metatypes_table.c.typeID
|
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()
|
||||||
|
|
||||||
|
if vars:
|
||||||
|
return vars
|
||||||
|
elif groupIDs:
|
||||||
|
itemfilter = or_(*(groups_table.c.groupID == groupID for groupID in groupIDs))
|
||||||
|
filter = processWhere(itemfilter, where)
|
||||||
|
joinon = items_table.c.groupID == groups_table.c.groupID
|
||||||
|
vars = gamedata_session.query(Item).options(*processEager(eager)).join((groups_table, joinon)).filter(
|
||||||
|
filter).all()
|
||||||
|
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "attr")
|
@cachedQuery(1, "attr")
|
||||||
def getAttributeInfo(attr, eager=None):
|
def getAttributeInfo(attr, eager=None):
|
||||||
if isinstance(attr, basestring):
|
if isinstance(attr, str):
|
||||||
filter = AttributeInfo.name == attr
|
filter = AttributeInfo.name == attr
|
||||||
elif isinstance(attr, int):
|
elif isinstance(attr, int):
|
||||||
filter = AttributeInfo.ID == attr
|
filter = AttributeInfo.ID == attr
|
||||||
@@ -227,14 +334,16 @@ def getAttributeInfo(attr, eager=None):
|
|||||||
result = None
|
result = None
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(1, "field")
|
@cachedQuery(1, "field")
|
||||||
def getMetaData(field):
|
def getMetaData(field):
|
||||||
if isinstance(field, basestring):
|
if isinstance(field, str):
|
||||||
data = gamedata_session.query(MetaData).get(field)
|
data = gamedata_session.query(MetaData).get(field)
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need string as argument")
|
raise TypeError("Need string as argument")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(2, "itemIDs", "attributeID")
|
@cachedQuery(2, "itemIDs", "attributeID")
|
||||||
def directAttributeRequest(itemIDs, attrIDs):
|
def directAttributeRequest(itemIDs, attrIDs):
|
||||||
for itemID in itemIDs:
|
for itemID in itemIDs:
|
||||||
@@ -244,9 +353,31 @@ def directAttributeRequest(itemIDs, attrIDs):
|
|||||||
if not isinstance(itemID, int):
|
if not isinstance(itemID, int):
|
||||||
raise TypeError("All itemIDs must be integer")
|
raise TypeError("All itemIDs must be integer")
|
||||||
|
|
||||||
q = select((eos.types.Item.typeID, eos.types.Attribute.attributeID, eos.types.Attribute.value),
|
q = select((Item.typeID, Attribute.attributeID, Attribute.value),
|
||||||
and_(eos.types.Attribute.attributeID.in_(attrIDs), eos.types.Item.typeID.in_(itemIDs)),
|
and_(Attribute.attributeID.in_(attrIDs), Item.typeID.in_(itemIDs)),
|
||||||
from_obj=[join(eos.types.Attribute, eos.types.Item)])
|
from_obj=[join(Attribute, Item)])
|
||||||
|
|
||||||
result = gamedata_session.execute(q).fetchall()
|
result = gamedata_session.execute(q).fetchall()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def getRequiredFor(itemID, attrMapping):
|
||||||
|
Attribute1 = aliased(Attribute)
|
||||||
|
Attribute2 = aliased(Attribute)
|
||||||
|
|
||||||
|
skillToLevelClauses = []
|
||||||
|
|
||||||
|
for attrSkill, attrLevel in attrMapping.items():
|
||||||
|
skillToLevelClauses.append(and_(Attribute1.attributeID == attrSkill, Attribute2.attributeID == attrLevel))
|
||||||
|
|
||||||
|
queryOr = or_(*skillToLevelClauses)
|
||||||
|
|
||||||
|
q = select((Attribute2.typeID, Attribute2.value),
|
||||||
|
and_(Attribute1.value == itemID, queryOr),
|
||||||
|
from_obj=[
|
||||||
|
join(Attribute1, Attribute2, Attribute1.typeID == Attribute2.typeID)
|
||||||
|
])
|
||||||
|
|
||||||
|
result = gamedata_session.execute(q).fetchall()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
from sqlalchemy import Column, Table, Integer, String, ForeignKey
|
from sqlalchemy import Column, Table, Integer, String, ForeignKey
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
from eos.types import Traits
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
|
from eos.gamedata import Traits
|
||||||
|
|
||||||
traits_table = Table("invtraits", gamedata_meta,
|
traits_table = Table("invtraits", gamedata_meta,
|
||||||
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True),
|
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True),
|
||||||
Column("traitText", String))
|
Column("traitText", String))
|
||||||
|
|
||||||
mapper(Traits, traits_table);
|
mapper(Traits, traits_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,19 +15,21 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, Integer, String
|
from sqlalchemy import Column, Table, Integer, String
|
||||||
from sqlalchemy.orm import mapper, synonym
|
from sqlalchemy.orm import mapper, synonym
|
||||||
|
|
||||||
from eos.db import gamedata_meta
|
from eos.db import gamedata_meta
|
||||||
from eos.types import Unit
|
from eos.gamedata import Unit
|
||||||
|
|
||||||
groups_table = Table("dgmunits", gamedata_meta,
|
groups_table = Table("dgmunits", gamedata_meta,
|
||||||
Column("unitID", Integer, primary_key = True),
|
Column("unitID", Integer, primary_key=True),
|
||||||
Column("unitName", String),
|
Column("unitName", String),
|
||||||
Column("displayName", String))
|
Column("displayName", String))
|
||||||
|
|
||||||
mapper(Unit, groups_table,
|
mapper(Unit, groups_table,
|
||||||
properties = {"ID" : synonym("unitID"),
|
properties={
|
||||||
"name" : synonym("unitName")})
|
"ID" : synonym("unitID"),
|
||||||
|
"name": synonym("unitName")
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
import config
|
from logbook import Logger
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
import re
|
|
||||||
import os
|
import config
|
||||||
import migrations
|
from . import migrations
|
||||||
|
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def getVersion(db):
|
def getVersion(db):
|
||||||
cursor = db.execute('PRAGMA user_version')
|
cursor = db.execute('PRAGMA user_version')
|
||||||
return cursor.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
|
|
||||||
|
|
||||||
def getAppVersion():
|
def getAppVersion():
|
||||||
return migrations.appVersion
|
return migrations.appVersion
|
||||||
|
|
||||||
|
|
||||||
def update(saveddata_engine):
|
def update(saveddata_engine):
|
||||||
dbVersion = getVersion(saveddata_engine)
|
dbVersion = getVersion(saveddata_engine)
|
||||||
appVersion = getAppVersion()
|
appVersion = getAppVersion()
|
||||||
@@ -21,7 +26,7 @@ def update(saveddata_engine):
|
|||||||
|
|
||||||
if dbVersion < appVersion:
|
if dbVersion < appVersion:
|
||||||
# Automatically backup database
|
# Automatically backup database
|
||||||
toFile = "%s/saveddata_migration_%d-%d_%s.db"%(
|
toFile = "%s/saveddata_migration_%d-%d_%s.db" % (
|
||||||
config.savePath,
|
config.savePath,
|
||||||
dbVersion,
|
dbVersion,
|
||||||
appVersion,
|
appVersion,
|
||||||
@@ -29,12 +34,11 @@ def update(saveddata_engine):
|
|||||||
|
|
||||||
shutil.copyfile(config.saveDB, toFile)
|
shutil.copyfile(config.saveDB, toFile)
|
||||||
|
|
||||||
for version in xrange(dbVersion, appVersion):
|
for version in range(dbVersion, appVersion):
|
||||||
|
func = migrations.updates[version + 1]
|
||||||
func = migrations.updates[version+1]
|
|
||||||
if func:
|
if func:
|
||||||
print "applying update",version+1
|
pyfalog.info("Applying database update: {0}", version + 1)
|
||||||
func(saveddata_engine)
|
func(saveddata_engine)
|
||||||
|
|
||||||
# when all is said and done, set version to current
|
# when all is said and done, set version to current
|
||||||
# saveddata_engine.execute("PRAGMA user_version = {}".format(appVersion))
|
saveddata_engine.execute("PRAGMA user_version = {}".format(appVersion))
|
||||||
|
|||||||
@@ -11,12 +11,31 @@ upgrade files 1-5)
|
|||||||
import pkgutil
|
import pkgutil
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
updates = {}
|
updates = {}
|
||||||
appVersion = 0
|
appVersion = 0
|
||||||
|
|
||||||
prefix = __name__ + "."
|
prefix = __name__ + "."
|
||||||
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
|
|
||||||
|
# load modules to work based with and without pyinstaller
|
||||||
|
# from: https://github.com/webcomics/dosage/blob/master/dosagelib/loader.py
|
||||||
|
# see: https://github.com/pyinstaller/pyinstaller/issues/1905
|
||||||
|
|
||||||
|
# load modules using iter_modules()
|
||||||
|
# (should find all filters in normal build, but not pyinstaller)
|
||||||
|
module_names = [m[1] for m in pkgutil.iter_modules(__path__, prefix)]
|
||||||
|
|
||||||
|
# special handling for PyInstaller
|
||||||
|
importers = map(pkgutil.get_importer, __path__)
|
||||||
|
toc = set()
|
||||||
|
for i in importers:
|
||||||
|
if hasattr(i, 'toc'):
|
||||||
|
toc |= i.toc
|
||||||
|
|
||||||
|
for elm in toc:
|
||||||
|
if elm.startswith(prefix):
|
||||||
|
module_names.append(elm)
|
||||||
|
|
||||||
|
for modname in module_names:
|
||||||
# loop through python files, extracting update number and function, and
|
# loop through python files, extracting update number and function, and
|
||||||
# adding it to a list
|
# adding it to a list
|
||||||
modname_tail = modname.rsplit('.', 1)[-1]
|
modname_tail = modname.rsplit('.', 1)[-1]
|
||||||
|
|||||||
@@ -14,50 +14,50 @@ Migration 1
|
|||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
6135: [ # Scoped Cargo Scanner
|
6135 : [ # Scoped Cargo Scanner
|
||||||
6133, # Interior Type-E Cargo Identifier
|
6133, # Interior Type-E Cargo Identifier
|
||||||
],
|
],
|
||||||
6527: [ # Compact Ship Scanner
|
6527 : [ # Compact Ship Scanner
|
||||||
6525, # Ta3 Perfunctory Vessel Probe
|
6525, # Ta3 Perfunctory Vessel Probe
|
||||||
6529, # Speculative Ship Identifier I
|
6529, # Speculative Ship Identifier I
|
||||||
6531, # Practical Type-E Ship Probe
|
6531, # Practical Type-E Ship Probe
|
||||||
],
|
],
|
||||||
6569: [ # Scoped Survey Scanner
|
6569 : [ # Scoped Survey Scanner
|
||||||
6567, # ML-3 Amphilotite Mining Probe
|
6567, # ML-3 Amphilotite Mining Probe
|
||||||
6571, # Rock-Scanning Sensor Array I
|
6571, # Rock-Scanning Sensor Array I
|
||||||
6573, # 'Dactyl' Type-E Asteroid Analyzer
|
6573, # 'Dactyl' Type-E Asteroid Analyzer
|
||||||
],
|
],
|
||||||
509: [ # 'Basic' Capacitor Flux Coil
|
509 : [ # 'Basic' Capacitor Flux Coil
|
||||||
8163, # Partial Power Plant Manager: Capacitor Flux
|
8163, # Partial Power Plant Manager: Capacitor Flux
|
||||||
8165, # Alpha Reactor Control: Capacitor Flux
|
8165, # Alpha Reactor Control: Capacitor Flux
|
||||||
8167, # Type-E Power Core Modification: Capacitor Flux
|
8167, # Type-E Power Core Modification: Capacitor Flux
|
||||||
8169, # Marked Generator Refitting: Capacitor Flux
|
8169, # Marked Generator Refitting: Capacitor Flux
|
||||||
],
|
],
|
||||||
8135: [ # Restrained Capacitor Flux Coil
|
8135 : [ # Restrained Capacitor Flux Coil
|
||||||
8131, # Local Power Plant Manager: Capacitor Flux I
|
8131, # Local Power Plant Manager: Capacitor Flux I
|
||||||
],
|
],
|
||||||
8133: [ # Compact Capacitor Flux Coil
|
8133 : [ # Compact Capacitor Flux Coil
|
||||||
8137, # Mark I Generator Refitting: Capacitor Flux
|
8137, # Mark I Generator Refitting: Capacitor Flux
|
||||||
],
|
],
|
||||||
3469: [ # Basic Co-Processor
|
3469 : [ # Basic Co-Processor
|
||||||
8744, # Nanoelectrical Co-Processor
|
8744, # Nanoelectrical Co-Processor
|
||||||
8743, # Nanomechanical CPU Enhancer
|
8743, # Nanomechanical CPU Enhancer
|
||||||
8746, # Quantum Co-Processor
|
8746, # Quantum Co-Processor
|
||||||
8745, # Photonic CPU Enhancer
|
8745, # Photonic CPU Enhancer
|
||||||
15425, # Naiyon's Modified Co-Processor (never existed but convert
|
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
|
8748 : [ # Upgraded Co-Processor
|
||||||
8747, # Nanomechanical CPU Enhancer I
|
8747, # Nanomechanical CPU Enhancer I
|
||||||
8750, # Quantum Co-Processor I
|
8750, # Quantum Co-Processor I
|
||||||
8749, # Photonic CPU Enhancer I
|
8749, # Photonic CPU Enhancer I
|
||||||
],
|
],
|
||||||
1351: [ # Basic Reactor Control Unit
|
1351 : [ # Basic Reactor Control Unit
|
||||||
8251, # Partial Power Plant Manager: Reaction Control
|
8251, # Partial Power Plant Manager: Reaction Control
|
||||||
8253, # Alpha Reactor Control: Reaction Control
|
8253, # Alpha Reactor Control: Reaction Control
|
||||||
8257, # Marked Generator Refitting: Reaction Control
|
8257, # Marked Generator Refitting: Reaction Control
|
||||||
],
|
],
|
||||||
8263: [ # Compact Reactor Control Unit
|
8263 : [ # Compact Reactor Control Unit
|
||||||
8259, # Local Power Plant Manager: Reaction Control I
|
8259, # Local Power Plant Manager: Reaction Control I
|
||||||
8265, # Mark I Generator Refitting: Reaction Control
|
8265, # Mark I Generator Refitting: Reaction Control
|
||||||
8261, # Beta Reactor Control: Reaction Control I
|
8261, # Beta Reactor Control: Reaction Control I
|
||||||
@@ -69,19 +69,20 @@ CONVERSIONS = {
|
|||||||
31936: [ # Navy Micro Auxiliary Power Core
|
31936: [ # Navy Micro Auxiliary Power Core
|
||||||
16543, # Micro 'Vigor' Core Augmentation
|
16543, # Micro 'Vigor' Core Augmentation
|
||||||
],
|
],
|
||||||
8089: [ # Compact Light Missile Launcher
|
8089 : [ # Compact Light Missile Launcher
|
||||||
8093, # Prototype 'Arbalest' Light Missile Launcher
|
8093, # Prototype 'Arbalest' Light Missile Launcher
|
||||||
],
|
],
|
||||||
8091: [ # Ample Light Missile Launcher
|
8091 : [ # Ample Light Missile Launcher
|
||||||
7993, # Experimental TE-2100 Light Missile Launcher
|
7993, # Experimental TE-2100 Light Missile Launcher
|
||||||
],
|
],
|
||||||
# Surface Cargo Scanner I was removed from game, however no mention of
|
# Surface Cargo Scanner I was removed from game, however no mention of
|
||||||
# replacement module in patch notes. Morphing it to meta 0 module to be safe
|
# replacement module in patch notes. Morphing it to meta 0 module to be safe
|
||||||
442: [ # Cargo Scanner I
|
442 : [ # Cargo Scanner I
|
||||||
6129, # Surface Cargo Scanner I
|
6129, # Surface Cargo Scanner I
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
# Update fits schema to include target resists attribute
|
# Update fits schema to include target resists attribute
|
||||||
try:
|
try:
|
||||||
@@ -90,8 +91,9 @@ def upgrade(saveddata_engine):
|
|||||||
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;")
|
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN targetResistsID INTEGER;")
|
||||||
|
|
||||||
# Convert modules
|
# Convert modules
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
for retired_item in list:
|
||||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
(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
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
# Update projectedFits schema to include active attribute
|
# Update projectedFits schema to include active attribute
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Migration 11
|
|||||||
modules with their new replacements
|
modules with their new replacements
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
16467: ( # Medium Gremlin Compact Energy Neutralizer
|
16467: ( # Medium Gremlin Compact Energy Neutralizer
|
||||||
16471, # Medium Unstable Power Fluctuator I
|
16471, # Medium Unstable Power Fluctuator I
|
||||||
@@ -15,7 +14,7 @@ CONVERSIONS = {
|
|||||||
22947: ( # 'Beatnik' Small Remote Armor Repairer
|
22947: ( # 'Beatnik' Small Remote Armor Repairer
|
||||||
23414, # 'Brotherhood' Small Remote Armor Repairer
|
23414, # 'Brotherhood' Small Remote Armor Repairer
|
||||||
),
|
),
|
||||||
8295: ( # Type-D Restrained Shield Flux Coil
|
8295 : ( # Type-D Restrained Shield Flux Coil
|
||||||
8293, # Beta Reactor Control: Shield Flux I
|
8293, # Beta Reactor Control: Shield Flux I
|
||||||
),
|
),
|
||||||
16499: ( # Heavy Knave Scoped Energy Nosferatu
|
16499: ( # Heavy Knave Scoped Energy Nosferatu
|
||||||
@@ -30,13 +29,13 @@ CONVERSIONS = {
|
|||||||
16447: ( # Medium Solace Scoped Remote Armor Repairer
|
16447: ( # Medium Solace Scoped Remote Armor Repairer
|
||||||
16445, # Medium 'Arup' Remote Armor Repairer
|
16445, # Medium 'Arup' Remote Armor Repairer
|
||||||
),
|
),
|
||||||
508: ( # 'Basic' Shield Flux Coil
|
508 : ( # 'Basic' Shield Flux Coil
|
||||||
8325, # Alpha Reactor Shield Flux
|
8325, # Alpha Reactor Shield Flux
|
||||||
8329, # Marked Generator Refitting: Shield Flux
|
8329, # Marked Generator Refitting: Shield Flux
|
||||||
8323, # Partial Power Plant Manager: Shield Flux
|
8323, # Partial Power Plant Manager: Shield Flux
|
||||||
8327, # Type-E Power Core Modification: Shield Flux
|
8327, # Type-E Power Core Modification: Shield Flux
|
||||||
),
|
),
|
||||||
1419: ( # 'Basic' Shield Power Relay
|
1419 : ( # 'Basic' Shield Power Relay
|
||||||
8341, # Alpha Reactor Shield Power Relay
|
8341, # Alpha Reactor Shield Power Relay
|
||||||
8345, # Marked Generator Refitting: Shield Power Relay
|
8345, # Marked Generator Refitting: Shield Power Relay
|
||||||
8339, # Partial Power Plant Manager: Shield Power Relay
|
8339, # Partial Power Plant Manager: Shield Power Relay
|
||||||
@@ -48,57 +47,57 @@ CONVERSIONS = {
|
|||||||
16505: ( # Medium Ghoul Compact Energy Nosferatu
|
16505: ( # Medium Ghoul Compact Energy Nosferatu
|
||||||
16511, # Medium Diminishing Power System Drain I
|
16511, # Medium Diminishing Power System Drain I
|
||||||
),
|
),
|
||||||
8297: ( # Mark I Compact Shield Flux Coil
|
8297 : ( # Mark I Compact Shield Flux Coil
|
||||||
8291, # Local Power Plant Manager: Reaction Shield Flux I
|
8291, # Local Power Plant Manager: Reaction Shield Flux I
|
||||||
),
|
),
|
||||||
16455: ( # Large Solace Scoped Remote Armor Repairer
|
16455: ( # Large Solace Scoped Remote Armor Repairer
|
||||||
16453, # Large 'Arup' Remote Armor Repairer
|
16453, # Large 'Arup' Remote Armor Repairer
|
||||||
),
|
),
|
||||||
6485: ( # M51 Benefactor Compact Shield Recharger
|
6485 : ( # M51 Benefactor Compact Shield Recharger
|
||||||
6491, # Passive Barrier Compensator I
|
6491, # Passive Barrier Compensator I
|
||||||
6489, # 'Benefactor' Ward Reconstructor
|
6489, # 'Benefactor' Ward Reconstructor
|
||||||
6487, # Supplemental Screen Generator I
|
6487, # Supplemental Screen Generator I
|
||||||
),
|
),
|
||||||
5137: ( # Small Knave Scoped Energy Nosferatu
|
5137 : ( # Small Knave Scoped Energy Nosferatu
|
||||||
5135, # E5 Prototype Energy Vampire
|
5135, # E5 Prototype Energy Vampire
|
||||||
),
|
),
|
||||||
8579: ( # Medium Murky Compact Remote Shield Booster
|
8579 : ( # Medium Murky Compact Remote Shield Booster
|
||||||
8581, # Medium 'Atonement' Remote Shield Booster
|
8581, # Medium 'Atonement' Remote Shield Booster
|
||||||
),
|
),
|
||||||
8531: ( # Small Murky Compact Remote Shield Booster
|
8531 : ( # Small Murky Compact Remote Shield Booster
|
||||||
8533, # Small 'Atonement' Remote Shield Booster
|
8533, # Small 'Atonement' Remote Shield Booster
|
||||||
),
|
),
|
||||||
16497: ( # Heavy Ghoul Compact Energy Nosferatu
|
16497: ( # Heavy Ghoul Compact Energy Nosferatu
|
||||||
16503, # Heavy Diminishing Power System Drain I
|
16503, # Heavy Diminishing Power System Drain I
|
||||||
),
|
),
|
||||||
4477: ( # Small Gremlin Compact Energy Neutralizer
|
4477 : ( # Small Gremlin Compact Energy Neutralizer
|
||||||
4475, # Small Unstable Power Fluctuator I
|
4475, # Small Unstable Power Fluctuator I
|
||||||
),
|
),
|
||||||
8337: ( # Mark I Compact Shield Power Relay
|
8337 : ( # Mark I Compact Shield Power Relay
|
||||||
8331, # Local Power Plant Manager: Reaction Shield Power Relay I
|
8331, # Local Power Plant Manager: Reaction Shield Power Relay I
|
||||||
),
|
),
|
||||||
23416: ( # 'Peace' Large Remote Armor Repairer
|
23416: ( # 'Peace' Large Remote Armor Repairer
|
||||||
22951, # 'Pacifier' Large Remote Armor Repairer
|
22951, # 'Pacifier' Large Remote Armor Repairer
|
||||||
),
|
),
|
||||||
5141: ( # Small Ghoul Compact Energy Nosferatu
|
5141 : ( # Small Ghoul Compact Energy Nosferatu
|
||||||
5139, # Small Diminishing Power System Drain I
|
5139, # Small Diminishing Power System Drain I
|
||||||
),
|
),
|
||||||
4471: ( # Small Infectious Scoped Energy Neutralizer
|
4471 : ( # Small Infectious Scoped Energy Neutralizer
|
||||||
4473, # Small Rudimentary Energy Destabilizer I
|
4473, # Small Rudimentary Energy Destabilizer I
|
||||||
),
|
),
|
||||||
16469: ( # Medium Infectious Scoped Energy Neutralizer
|
16469: ( # Medium Infectious Scoped Energy Neutralizer
|
||||||
16465, # Medium Rudimentary Energy Destabilizer I
|
16465, # Medium Rudimentary Energy Destabilizer I
|
||||||
),
|
),
|
||||||
8335: ( # Type-D Restrained Shield Power Relay
|
8335 : ( # Type-D Restrained Shield Power Relay
|
||||||
8333, # Beta Reactor Control: Shield Power Relay I
|
8333, # Beta Reactor Control: Shield Power Relay I
|
||||||
),
|
),
|
||||||
405: ( # 'Micro' Remote Shield Booster
|
405 : ( # 'Micro' Remote Shield Booster
|
||||||
8631, # Micro Asymmetric Remote Shield Booster
|
8631, # Micro Asymmetric Remote Shield Booster
|
||||||
8627, # Micro Murky Remote Shield Booster
|
8627, # Micro Murky Remote Shield Booster
|
||||||
8629, # Micro 'Atonement' Remote Shield Booster
|
8629, # Micro 'Atonement' Remote Shield Booster
|
||||||
8633, # Micro S95a Remote Shield Booster
|
8633, # Micro S95a Remote Shield Booster
|
||||||
),
|
),
|
||||||
8635: ( # Large Murky Compact Remote Shield Booster
|
8635 : ( # Large Murky Compact Remote Shield Booster
|
||||||
8637, # Large 'Atonement' Remote Shield Booster
|
8637, # Large 'Atonement' Remote Shield Booster
|
||||||
),
|
),
|
||||||
16507: ( # Medium Knave Scoped Energy Nosferatu
|
16507: ( # Medium Knave Scoped Energy Nosferatu
|
||||||
@@ -106,11 +105,12 @@ CONVERSIONS = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
|
|
||||||
# Convert modules
|
# Convert modules
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
for retired_item in list:
|
||||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
(replacement_item, retired_item))
|
||||||
|
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
|
(replacement_item, retired_item))
|
||||||
|
|||||||
@@ -7,33 +7,32 @@ Migration 12
|
|||||||
modules with their new replacements
|
modules with their new replacements
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
16457: ( # Crosslink Compact Ballistic Control System
|
16457: ( # Crosslink Compact Ballistic Control System
|
||||||
16459, # Muon Coil Bolt Array I
|
16459, # Muon Coil Bolt Array I
|
||||||
16461, # Multiphasic Bolt Array I
|
16461, # Multiphasic Bolt Array I
|
||||||
16463, # 'Pandemonium' Ballistic Enhancement
|
16463, # 'Pandemonium' Ballistic Enhancement
|
||||||
),
|
),
|
||||||
5281: ( # Coadjunct Scoped Remote Sensor Booster
|
5281 : ( # Coadjunct Scoped Remote Sensor Booster
|
||||||
7218, # Piercing ECCM Emitter I
|
7218, # Piercing ECCM Emitter I
|
||||||
),
|
),
|
||||||
5365: ( # Cetus Scoped Burst Jammer
|
5365 : ( # Cetus Scoped Burst Jammer
|
||||||
5359, # 1Z-3 Subversive ECM Eruption
|
5359, # 1Z-3 Subversive ECM Eruption
|
||||||
),
|
),
|
||||||
1973: ( # Sensor Booster I
|
1973 : ( # Sensor Booster I
|
||||||
1947, # ECCM - Radar I
|
1947, # ECCM - Radar I
|
||||||
2002, # ECCM - Ladar I
|
2002, # ECCM - Ladar I
|
||||||
2003, # ECCM - Magnetometric I
|
2003, # ECCM - Magnetometric I
|
||||||
2004, # ECCM - Gravimetric I
|
2004, # ECCM - Gravimetric I
|
||||||
2005, # ECCM - Omni I
|
2005, # ECCM - Omni I
|
||||||
),
|
),
|
||||||
1951: ( # 'Basic' Tracking Enhancer
|
1951 : ( # 'Basic' Tracking Enhancer
|
||||||
6322, # Beta-Nought Tracking Mode
|
6322, # Beta-Nought Tracking Mode
|
||||||
6323, # Azimuth Descalloping Tracking Enhancer
|
6323, # Azimuth Descalloping Tracking Enhancer
|
||||||
6324, # F-AQ Delay-Line Scan Tracking Subroutines
|
6324, # F-AQ Delay-Line Scan Tracking Subroutines
|
||||||
6321, # Beam Parallax Tracking Program
|
6321, # Beam Parallax Tracking Program
|
||||||
),
|
),
|
||||||
521: ( # 'Basic' Damage Control
|
521 : ( # 'Basic' Damage Control
|
||||||
5829, # GLFF Containment Field
|
5829, # GLFF Containment Field
|
||||||
5831, # Interior Force Field Array
|
5831, # Interior Force Field Array
|
||||||
5835, # F84 Local Damage System
|
5835, # F84 Local Damage System
|
||||||
@@ -43,13 +42,13 @@ CONVERSIONS = {
|
|||||||
22939, # 'Boss' Remote Sensor Booster
|
22939, # 'Boss' Remote Sensor Booster
|
||||||
22941, # 'Entrepreneur' Remote Sensor Booster
|
22941, # 'Entrepreneur' Remote Sensor Booster
|
||||||
),
|
),
|
||||||
5443: ( # Faint Epsilon Scoped Warp Scrambler
|
5443 : ( # Faint Epsilon Scoped Warp Scrambler
|
||||||
5441, # Fleeting Progressive Warp Scrambler I
|
5441, # Fleeting Progressive Warp Scrambler I
|
||||||
),
|
),
|
||||||
1963: ( # Remote Sensor Booster I
|
1963 : ( # Remote Sensor Booster I
|
||||||
1959, # ECCM Projector I
|
1959, # ECCM Projector I
|
||||||
),
|
),
|
||||||
6325: ( # Fourier Compact Tracking Enhancer
|
6325 : ( # Fourier Compact Tracking Enhancer
|
||||||
6326, # Sigma-Nought Tracking Mode I
|
6326, # Sigma-Nought Tracking Mode I
|
||||||
6327, # Auto-Gain Control Tracking Enhancer I
|
6327, # Auto-Gain Control Tracking Enhancer I
|
||||||
6328, # F-aQ Phase Code Tracking Subroutines
|
6328, # F-aQ Phase Code Tracking Subroutines
|
||||||
@@ -69,19 +68,19 @@ CONVERSIONS = {
|
|||||||
22919: ( # 'Monopoly' Magnetic Field Stabilizer
|
22919: ( # 'Monopoly' Magnetic Field Stabilizer
|
||||||
22917, # 'Capitalist' Magnetic Field Stabilizer I
|
22917, # 'Capitalist' Magnetic Field Stabilizer I
|
||||||
),
|
),
|
||||||
5839: ( # IFFA Compact Damage Control
|
5839 : ( # IFFA Compact Damage Control
|
||||||
5841, # Emergency Damage Control I
|
5841, # Emergency Damage Control I
|
||||||
5843, # F85 Peripheral Damage System I
|
5843, # F85 Peripheral Damage System I
|
||||||
5837, # Pseudoelectron Containment Field I
|
5837, # Pseudoelectron Containment Field I
|
||||||
),
|
),
|
||||||
522: ( # 'Micro' Cap Battery
|
522 : ( # 'Micro' Cap Battery
|
||||||
4747, # Micro Ld-Acid Capacitor Battery I
|
4747, # Micro Ld-Acid Capacitor Battery I
|
||||||
4751, # Micro Ohm Capacitor Reserve I
|
4751, # Micro Ohm Capacitor Reserve I
|
||||||
4745, # Micro F-4a Ld-Sulfate Capacitor Charge Unit
|
4745, # Micro F-4a Ld-Sulfate Capacitor Charge Unit
|
||||||
4749, # Micro Peroxide Capacitor Power Cell
|
4749, # Micro Peroxide Capacitor Power Cell
|
||||||
3480, # Micro Capacitor Battery II
|
3480, # Micro Capacitor Battery II
|
||||||
),
|
),
|
||||||
518: ( # 'Basic' Gyrostabilizer
|
518 : ( # 'Basic' Gyrostabilizer
|
||||||
5915, # Lateral Gyrostabilizer
|
5915, # Lateral Gyrostabilizer
|
||||||
5919, # F-M2 Weapon Inertial Suspensor
|
5919, # F-M2 Weapon Inertial Suspensor
|
||||||
5913, # Hydraulic Stabilization Actuator
|
5913, # Hydraulic Stabilization Actuator
|
||||||
@@ -90,19 +89,19 @@ CONVERSIONS = {
|
|||||||
19931: ( # Compulsive Scoped Multispectral ECM
|
19931: ( # Compulsive Scoped Multispectral ECM
|
||||||
19933, # 'Hypnos' Multispectral ECM I
|
19933, # 'Hypnos' Multispectral ECM I
|
||||||
),
|
),
|
||||||
5403: ( # Faint Scoped Warp Disruptor
|
5403 : ( # Faint Scoped Warp Disruptor
|
||||||
5401, # Fleeting Warp Disruptor I
|
5401, # Fleeting Warp Disruptor I
|
||||||
),
|
),
|
||||||
23902: ( # 'Trebuchet' Heat Sink I
|
23902: ( # 'Trebuchet' Heat Sink I
|
||||||
23900, # 'Mangonel' Heat Sink I
|
23900, # 'Mangonel' Heat Sink I
|
||||||
),
|
),
|
||||||
1893: ( # 'Basic' Heat Sink
|
1893 : ( # 'Basic' Heat Sink
|
||||||
5845, # Heat Exhaust System
|
5845, # Heat Exhaust System
|
||||||
5856, # C3S Convection Thermal Radiator
|
5856, # C3S Convection Thermal Radiator
|
||||||
5855, # 'Boreas' Coolant System
|
5855, # 'Boreas' Coolant System
|
||||||
5854, # Stamped Heat Sink
|
5854, # Stamped Heat Sink
|
||||||
),
|
),
|
||||||
6160: ( # F-90 Compact Sensor Booster
|
6160 : ( # F-90 Compact Sensor Booster
|
||||||
20214, # Extra Radar ECCM Scanning Array I
|
20214, # Extra Radar ECCM Scanning Array I
|
||||||
20220, # Extra Ladar ECCM Scanning Array I
|
20220, # Extra Ladar ECCM Scanning Array I
|
||||||
20226, # Extra Gravimetric ECCM Scanning Array I
|
20226, # Extra Gravimetric ECCM Scanning Array I
|
||||||
@@ -124,40 +123,40 @@ CONVERSIONS = {
|
|||||||
19952: ( # Umbra Scoped Radar ECM
|
19952: ( # Umbra Scoped Radar ECM
|
||||||
9520, # 'Penumbra' White Noise ECM
|
9520, # 'Penumbra' White Noise ECM
|
||||||
),
|
),
|
||||||
1952: ( # Sensor Booster II
|
1952 : ( # Sensor Booster II
|
||||||
2258, # ECCM - Omni II
|
2258, # ECCM - Omni II
|
||||||
2259, # ECCM - Gravimetric II
|
2259, # ECCM - Gravimetric II
|
||||||
2260, # ECCM - Ladar II
|
2260, # ECCM - Ladar II
|
||||||
2261, # ECCM - Magnetometric II
|
2261, # ECCM - Magnetometric II
|
||||||
2262, # ECCM - Radar II
|
2262, # ECCM - Radar II
|
||||||
),
|
),
|
||||||
5282: ( # Linked Enduring Sensor Booster
|
5282 : ( # Linked Enduring Sensor Booster
|
||||||
7219, # Scattering ECCM Projector I
|
7219, # Scattering ECCM Projector I
|
||||||
),
|
),
|
||||||
1986: ( # Signal Amplifier I
|
1986 : ( # Signal Amplifier I
|
||||||
2579, # Gravimetric Backup Array I
|
2579, # Gravimetric Backup Array I
|
||||||
2583, # Ladar Backup Array I
|
2583, # Ladar Backup Array I
|
||||||
2587, # Magnetometric Backup Array I
|
2587, # Magnetometric Backup Array I
|
||||||
2591, # Multi Sensor Backup Array I
|
2591, # Multi Sensor Backup Array I
|
||||||
4013, # RADAR Backup Array I
|
4013, # RADAR Backup Array I
|
||||||
),
|
),
|
||||||
4871: ( # Large Compact Pb-Acid Cap Battery
|
4871 : ( # Large Compact Pb-Acid Cap Battery
|
||||||
4875, # Large Ohm Capacitor Reserve I
|
4875, # Large Ohm Capacitor Reserve I
|
||||||
4869, # Large F-4a Ld-Sulfate Capacitor Charge Unit
|
4869, # Large F-4a Ld-Sulfate Capacitor Charge Unit
|
||||||
4873, # Large Peroxide Capacitor Power Cell
|
4873, # Large Peroxide Capacitor Power Cell
|
||||||
),
|
),
|
||||||
1964: ( # Remote Sensor Booster II
|
1964 : ( # Remote Sensor Booster II
|
||||||
1960, # ECCM Projector II
|
1960, # ECCM Projector II
|
||||||
),
|
),
|
||||||
5933: ( # Counterbalanced Compact Gyrostabilizer
|
5933 : ( # Counterbalanced Compact Gyrostabilizer
|
||||||
5931, # Cross-Lateral Gyrostabilizer I
|
5931, # Cross-Lateral Gyrostabilizer I
|
||||||
5935, # F-M3 Munition Inertial Suspensor
|
5935, # F-M3 Munition Inertial Suspensor
|
||||||
5929, # Pneumatic Stabilization Actuator I
|
5929, # Pneumatic Stabilization Actuator I
|
||||||
),
|
),
|
||||||
4025: ( # X5 Enduring Stasis Webifier
|
4025 : ( # X5 Enduring Stasis Webifier
|
||||||
4029, # 'Langour' Drive Disruptor I
|
4029, # 'Langour' Drive Disruptor I
|
||||||
),
|
),
|
||||||
4027: ( # Fleeting Compact Stasis Webifier
|
4027 : ( # Fleeting Compact Stasis Webifier
|
||||||
4031, # Patterned Stasis Web I
|
4031, # Patterned Stasis Web I
|
||||||
),
|
),
|
||||||
22937: ( # 'Enterprise' Remote Tracking Computer
|
22937: ( # 'Enterprise' Remote Tracking Computer
|
||||||
@@ -166,7 +165,7 @@ CONVERSIONS = {
|
|||||||
22929: ( # 'Marketeer' Tracking Computer
|
22929: ( # 'Marketeer' Tracking Computer
|
||||||
22927, # 'Economist' Tracking Computer I
|
22927, # 'Economist' Tracking Computer I
|
||||||
),
|
),
|
||||||
1987: ( # Signal Amplifier II
|
1987 : ( # Signal Amplifier II
|
||||||
2580, # Gravimetric Backup Array II
|
2580, # Gravimetric Backup Array II
|
||||||
2584, # Ladar Backup Array II
|
2584, # Ladar Backup Array II
|
||||||
2588, # Magnetometric Backup Array II
|
2588, # Magnetometric Backup Array II
|
||||||
@@ -176,13 +175,13 @@ CONVERSIONS = {
|
|||||||
19939: ( # Enfeebling Scoped Ladar ECM
|
19939: ( # Enfeebling Scoped Ladar ECM
|
||||||
9522, # Faint Phase Inversion ECM I
|
9522, # Faint Phase Inversion ECM I
|
||||||
),
|
),
|
||||||
5340: ( # P-S Compact Remote Tracking Computer
|
5340 : ( # P-S Compact Remote Tracking Computer
|
||||||
5341, # 'Prayer' Remote Tracking Computer
|
5341, # 'Prayer' Remote Tracking Computer
|
||||||
),
|
),
|
||||||
19814: ( # Phased Scoped Target Painter
|
19814: ( # Phased Scoped Target Painter
|
||||||
19808, # Partial Weapon Navigation
|
19808, # Partial Weapon Navigation
|
||||||
),
|
),
|
||||||
1949: ( # 'Basic' Signal Amplifier
|
1949 : ( # 'Basic' Signal Amplifier
|
||||||
1946, # Basic RADAR Backup Array
|
1946, # Basic RADAR Backup Array
|
||||||
1982, # Basic Ladar Backup Array
|
1982, # Basic Ladar Backup Array
|
||||||
1983, # Basic Gravimetric Backup Array
|
1983, # Basic Gravimetric Backup Array
|
||||||
@@ -223,10 +222,10 @@ CONVERSIONS = {
|
|||||||
23416: ( # 'Peace' Large Remote Armor Repairer
|
23416: ( # 'Peace' Large Remote Armor Repairer
|
||||||
None, # 'Pacifier' Large Remote Armor Repairer
|
None, # 'Pacifier' Large Remote Armor Repairer
|
||||||
),
|
),
|
||||||
6176: ( # F-12 Enduring Tracking Computer
|
6176 : ( # F-12 Enduring Tracking Computer
|
||||||
6174, # Monopulse Tracking Mechanism I
|
6174, # Monopulse Tracking Mechanism I
|
||||||
),
|
),
|
||||||
6159: ( # Alumel-Wired Enduring Sensor Booster
|
6159 : ( # Alumel-Wired Enduring Sensor Booster
|
||||||
7917, # Alumel Radar ECCM Sensor Array I
|
7917, # Alumel Radar ECCM Sensor Array I
|
||||||
7918, # Alumel Ladar ECCM Sensor Array I
|
7918, # Alumel Ladar ECCM Sensor Array I
|
||||||
7922, # Alumel Gravimetric ECCM Sensor Array I
|
7922, # Alumel Gravimetric ECCM Sensor Array I
|
||||||
@@ -248,7 +247,7 @@ CONVERSIONS = {
|
|||||||
7914, # Prototype ECCM Magnetometric Sensor Cluster
|
7914, # Prototype ECCM Magnetometric Sensor Cluster
|
||||||
6158, # Prototype Sensor Booster
|
6158, # Prototype Sensor Booster
|
||||||
),
|
),
|
||||||
5849: ( # Extruded Compact Heat Sink
|
5849 : ( # Extruded Compact Heat Sink
|
||||||
5846, # Thermal Exhaust System I
|
5846, # Thermal Exhaust System I
|
||||||
5858, # C4S Coiled Circuit Thermal Radiator
|
5858, # C4S Coiled Circuit Thermal Radiator
|
||||||
5857, # 'Skadi' Coolant System I
|
5857, # 'Skadi' Coolant System I
|
||||||
@@ -264,15 +263,15 @@ CONVERSIONS = {
|
|||||||
22945: ( # 'Executive' Remote Sensor Dampener
|
22945: ( # 'Executive' Remote Sensor Dampener
|
||||||
22943, # 'Broker' Remote Sensor Dampener I
|
22943, # 'Broker' Remote Sensor Dampener I
|
||||||
),
|
),
|
||||||
6173: ( # Optical Compact Tracking Computer
|
6173 : ( # Optical Compact Tracking Computer
|
||||||
6175, # 'Orion' Tracking CPU I
|
6175, # 'Orion' Tracking CPU I
|
||||||
),
|
),
|
||||||
5279: ( # F-23 Compact Remote Sensor Booster
|
5279 : ( # F-23 Compact Remote Sensor Booster
|
||||||
7217, # Spot Pulsing ECCM I
|
7217, # Spot Pulsing ECCM I
|
||||||
7220, # Phased Muon ECCM Caster I
|
7220, # Phased Muon ECCM Caster I
|
||||||
5280, # Connected Remote Sensor Booster
|
5280, # Connected Remote Sensor Booster
|
||||||
),
|
),
|
||||||
4787: ( # Small Compact Pb-Acid Cap Battery
|
4787 : ( # Small Compact Pb-Acid Cap Battery
|
||||||
4791, # Small Ohm Capacitor Reserve I
|
4791, # Small Ohm Capacitor Reserve I
|
||||||
4785, # Small F-4a Ld-Sulfate Capacitor Charge Unit
|
4785, # Small F-4a Ld-Sulfate Capacitor Charge Unit
|
||||||
4789, # Small Peroxide Capacitor Power Cell
|
4789, # Small Peroxide Capacitor Power Cell
|
||||||
@@ -280,7 +279,7 @@ CONVERSIONS = {
|
|||||||
19946: ( # BZ-5 Scoped Gravimetric ECM
|
19946: ( # BZ-5 Scoped Gravimetric ECM
|
||||||
9519, # FZ-3 Subversive Spatial Destabilizer ECM
|
9519, # FZ-3 Subversive Spatial Destabilizer ECM
|
||||||
),
|
),
|
||||||
6073: ( # Medium Compact Pb-Acid Cap Battery
|
6073 : ( # Medium Compact Pb-Acid Cap Battery
|
||||||
6097, # Medium Ohm Capacitor Reserve I
|
6097, # Medium Ohm Capacitor Reserve I
|
||||||
6111, # Medium F-4a Ld-Sulfate Capacitor Charge Unit
|
6111, # Medium F-4a Ld-Sulfate Capacitor Charge Unit
|
||||||
6083, # Medium Peroxide Capacitor Power Cell
|
6083, # Medium Peroxide Capacitor Power Cell
|
||||||
@@ -288,7 +287,7 @@ CONVERSIONS = {
|
|||||||
21484: ( # 'Full Duplex' Ballistic Control System
|
21484: ( # 'Full Duplex' Ballistic Control System
|
||||||
21482, # Ballistic 'Purge' Targeting System I
|
21482, # Ballistic 'Purge' Targeting System I
|
||||||
),
|
),
|
||||||
6296: ( # F-89 Compact Signal Amplifier
|
6296 : ( # F-89 Compact Signal Amplifier
|
||||||
6218, # Protected Gravimetric Backup Cluster I
|
6218, # Protected Gravimetric Backup Cluster I
|
||||||
6222, # Protected Ladar Backup Cluster I
|
6222, # Protected Ladar Backup Cluster I
|
||||||
6226, # Protected Magnetometric Backup Cluster I
|
6226, # Protected Magnetometric Backup Cluster I
|
||||||
@@ -325,16 +324,17 @@ CONVERSIONS = {
|
|||||||
6293, # Wavelength Signal Enhancer I
|
6293, # Wavelength Signal Enhancer I
|
||||||
6295, # Type-D Attenuation Signal Augmentation
|
6295, # Type-D Attenuation Signal Augmentation
|
||||||
),
|
),
|
||||||
5302: ( # Phased Muon Scoped Sensor Dampener
|
5302 : ( # Phased Muon Scoped Sensor Dampener
|
||||||
5300, # Indirect Scanning Dampening Unit I
|
5300, # Indirect Scanning Dampening Unit I
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
|
|
||||||
# Convert modules
|
# Convert modules
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
for retired_item in list:
|
||||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
(replacement_item, retired_item))
|
||||||
|
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
|
(replacement_item, retired_item))
|
||||||
|
|||||||
16
eos/db/migrations/upgrade13.py
Normal file
16
eos/db/migrations/upgrade13.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
Migration 13
|
||||||
|
|
||||||
|
- Alters fits table to introduce implant location attribute
|
||||||
|
"""
|
||||||
|
|
||||||
|
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")
|
||||||
21
eos/db/migrations/upgrade14.py
Normal file
21
eos/db/migrations/upgrade14.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
"""
|
||||||
|
Migration 14
|
||||||
|
|
||||||
|
- This should take care of issue #586.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
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")
|
||||||
|
except sqlalchemy.exc.DatabaseError:
|
||||||
|
# if we don't have the active column, we are on an old pre-release version. Drop the tables and move on
|
||||||
|
# (they will be recreated)
|
||||||
|
|
||||||
|
saveddata_engine.execute("DROP TABLE fighters")
|
||||||
|
saveddata_engine.execute("DROP TABLE fightersAbilities")
|
||||||
19
eos/db/migrations/upgrade15.py
Normal file
19
eos/db/migrations/upgrade15.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
"""
|
||||||
|
Migration 15
|
||||||
|
|
||||||
|
- Delete projected modules on citadels
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
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;")
|
||||||
42
eos/db/migrations/upgrade17.py
Normal file
42
eos/db/migrations/upgrade17.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
"""
|
||||||
|
Migration 17
|
||||||
|
|
||||||
|
- Moves all fleet boosters to the new schema
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
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()
|
||||||
|
except:
|
||||||
|
# Shouldn't fail unless you have updated database without the old fleet schema and manually modify the database version
|
||||||
|
# If it does, simply fail. Fleet data migration isn't critically important here
|
||||||
|
pass
|
||||||
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.items():
|
||||||
|
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))
|
||||||
18
eos/db/migrations/upgrade19.py
Normal file
18
eos/db/migrations/upgrade19.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
"""
|
||||||
|
Migration 19
|
||||||
|
|
||||||
|
- Deletes broken references to fits from the commandFits table (see GH issue #844)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
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
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
# Update characters schema to include default chars
|
# Update characters schema to include default chars
|
||||||
try:
|
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;")
|
||||||
10
eos/db/migrations/upgrade21.py
Normal file
10
eos/db/migrations/upgrade21.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
"""
|
||||||
|
Migration 21
|
||||||
|
|
||||||
|
- Fixes discrepancy in drone table where we may have an amount active that is not equal to the amount in the stack
|
||||||
|
(we don't support activating only 2/5 drones). See GH issue #728
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
saveddata_engine.execute("UPDATE drones SET amountActive = amount where amountActive > 0 AND amountActive <> amount;")
|
||||||
45
eos/db/migrations/upgrade22.py
Normal file
45
eos/db/migrations/upgrade22.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"""
|
||||||
|
Migration 22
|
||||||
|
|
||||||
|
- Adds the created and modified fields to most tables
|
||||||
|
"""
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
|
||||||
|
# 1 = created only
|
||||||
|
# 2 = created and modified
|
||||||
|
tables = {
|
||||||
|
"boosters": 2,
|
||||||
|
"cargo": 2,
|
||||||
|
"characters": 2,
|
||||||
|
"crest": 1,
|
||||||
|
"damagePatterns": 2,
|
||||||
|
"drones": 2,
|
||||||
|
"fighters": 2,
|
||||||
|
"fits": 2,
|
||||||
|
"projectedFits": 2,
|
||||||
|
"commandFits": 2,
|
||||||
|
"implants": 2,
|
||||||
|
"implantSets": 2,
|
||||||
|
"modules": 2,
|
||||||
|
"overrides": 2,
|
||||||
|
"characterSkills": 2,
|
||||||
|
"targetResists": 2
|
||||||
|
}
|
||||||
|
|
||||||
|
for table in list(tables.keys()):
|
||||||
|
|
||||||
|
# midnight brain, there's probably a much more simple way to do this, but fuck it
|
||||||
|
if tables[table] > 0:
|
||||||
|
try:
|
||||||
|
saveddata_engine.execute("SELECT created FROM {0} LIMIT 1;".format(table))
|
||||||
|
except sqlalchemy.exc.DatabaseError:
|
||||||
|
saveddata_engine.execute("ALTER TABLE {} ADD COLUMN created DATETIME;".format(table))
|
||||||
|
|
||||||
|
if tables[table] > 1:
|
||||||
|
try:
|
||||||
|
saveddata_engine.execute("SELECT modified FROM {0} LIMIT 1;".format(table))
|
||||||
|
except sqlalchemy.exc.DatabaseError:
|
||||||
|
saveddata_engine.execute("ALTER TABLE {} ADD COLUMN modified DATETIME;".format(table))
|
||||||
13
eos/db/migrations/upgrade23.py
Normal file
13
eos/db/migrations/upgrade23.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
"""
|
||||||
|
Migration 23
|
||||||
|
|
||||||
|
- Adds a sec status field to the character table
|
||||||
|
"""
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
try:
|
||||||
|
saveddata_engine.execute("SELECT secStatus FROM characters LIMIT 1")
|
||||||
|
except sqlalchemy.exc.DatabaseError:
|
||||||
|
saveddata_engine.execute("ALTER TABLE characters ADD COLUMN secStatus FLOAT;")
|
||||||
14
eos/db/migrations/upgrade24.py
Normal file
14
eos/db/migrations/upgrade24.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
"""
|
||||||
|
Migration 24
|
||||||
|
|
||||||
|
- Adds a boolean value to fit to signify if fit should ignore restrictions
|
||||||
|
"""
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
try:
|
||||||
|
saveddata_engine.execute("SELECT ignoreRestrictions FROM fits LIMIT 1")
|
||||||
|
except sqlalchemy.exc.DatabaseError:
|
||||||
|
saveddata_engine.execute("ALTER TABLE fits ADD COLUMN ignoreRestrictions BOOLEAN")
|
||||||
|
saveddata_engine.execute("UPDATE fits SET ignoreRestrictions = 0")
|
||||||
4246
eos/db/migrations/upgrade25.py
Normal file
4246
eos/db/migrations/upgrade25.py
Normal file
File diff suppressed because it is too large
Load Diff
9
eos/db/migrations/upgrade26.py
Normal file
9
eos/db/migrations/upgrade26.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
Migration 26
|
||||||
|
|
||||||
|
- Deletes invalid command fit relationships caused by a bug (see #1244)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
saveddata_engine.execute("DELETE FROM commandFits WHERE boosterID NOT IN (SELECT ID FROM fits) OR boostedID NOT IN (SELECT ID FROM fits)")
|
||||||
9
eos/db/migrations/upgrade27.py
Normal file
9
eos/db/migrations/upgrade27.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
Migration 27
|
||||||
|
|
||||||
|
- Resets all alpha clones to 1 (CCP consolidated all alpha's into one skillset)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(saveddata_engine):
|
||||||
|
saveddata_engine.execute("UPDATE characters SET alphaCloneID = 1 WHERE alphaCloneID IS NOT NULL")
|
||||||
@@ -6,6 +6,7 @@ Migration 3
|
|||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
try:
|
try:
|
||||||
saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1")
|
saveddata_engine.execute("SELECT modeID FROM fits LIMIT 1")
|
||||||
|
|||||||
@@ -10,66 +10,65 @@ Migration 4
|
|||||||
and output of itemDiff.py
|
and output of itemDiff.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
506: ( # 'Basic' Capacitor Power Relay
|
506 : ( # 'Basic' Capacitor Power Relay
|
||||||
8205, # Alpha Reactor Control: Capacitor Power Relay
|
8205, # Alpha Reactor Control: Capacitor Power Relay
|
||||||
8209, # Marked Generator Refitting: Capacitor Power Relay
|
8209, # Marked Generator Refitting: Capacitor Power Relay
|
||||||
8203, # Partial Power Plant Manager: Capacity Power Relay
|
8203, # Partial Power Plant Manager: Capacity Power Relay
|
||||||
8207, # Type-E Power Core Modification: Capacitor Power Relay
|
8207, # Type-E Power Core Modification: Capacitor Power Relay
|
||||||
),
|
),
|
||||||
8177: ( # Mark I Compact Capacitor Power Relay
|
8177 : ( # Mark I Compact Capacitor Power Relay
|
||||||
8173, # Beta Reactor Control: Capacitor Power Relay I
|
8173, # Beta Reactor Control: Capacitor Power Relay I
|
||||||
),
|
),
|
||||||
8175: ( # Type-D Restrained Capacitor Power Relay
|
8175 : ( # Type-D Restrained Capacitor Power Relay
|
||||||
8171, # Local Power Plant Manager: Capacity Power Relay I
|
8171, # Local Power Plant Manager: Capacity Power Relay I
|
||||||
),
|
),
|
||||||
|
|
||||||
421: ( # 'Basic' Capacitor Recharger
|
421 : ( # 'Basic' Capacitor Recharger
|
||||||
4425, # AGM Capacitor Charge Array,
|
4425, # AGM Capacitor Charge Array,
|
||||||
4421, # F-a10 Buffer Capacitor Regenerator
|
4421, # F-a10 Buffer Capacitor Regenerator
|
||||||
4423, # Industrial Capacitor Recharger
|
4423, # Industrial Capacitor Recharger
|
||||||
4427, # Secondary Parallel Link-Capacitor
|
4427, # Secondary Parallel Link-Capacitor
|
||||||
),
|
),
|
||||||
4435: ( # Eutectic Compact Cap Recharger
|
4435 : ( # Eutectic Compact Cap Recharger
|
||||||
4433, # Barton Reactor Capacitor Recharger I
|
4433, # Barton Reactor Capacitor Recharger I
|
||||||
4431, # F-b10 Nominal Capacitor Regenerator
|
4431, # F-b10 Nominal Capacitor Regenerator
|
||||||
4437, # Fixed Parallel Link-Capacitor I
|
4437, # Fixed Parallel Link-Capacitor I
|
||||||
),
|
),
|
||||||
|
|
||||||
1315: ( # 'Basic' Expanded Cargohold
|
1315 : ( # 'Basic' Expanded Cargohold
|
||||||
5483, # Alpha Hull Mod Expanded Cargo
|
5483, # Alpha Hull Mod Expanded Cargo
|
||||||
5479, # Marked Modified SS Expanded Cargo
|
5479, # Marked Modified SS Expanded Cargo
|
||||||
5481, # Partial Hull Conversion Expanded Cargo
|
5481, # Partial Hull Conversion Expanded Cargo
|
||||||
5485, # Type-E Altered SS Expanded Cargo
|
5485, # Type-E Altered SS Expanded Cargo
|
||||||
),
|
),
|
||||||
5493: ( # Type-D Restrained Expanded Cargo
|
5493 : ( # Type-D Restrained Expanded Cargo
|
||||||
5491, # Beta Hull Mod Expanded Cargo
|
5491, # Beta Hull Mod Expanded Cargo
|
||||||
5489, # Local Hull Conversion Expanded Cargo I
|
5489, # Local Hull Conversion Expanded Cargo I
|
||||||
5487, # Mark I Modified SS Expanded Cargo
|
5487, # Mark I Modified SS Expanded Cargo
|
||||||
),
|
),
|
||||||
|
|
||||||
1401: ( # 'Basic' Inertial Stabilizers
|
1401 : ( # 'Basic' Inertial Stabilizers
|
||||||
5523, # Alpha Hull Mod Inertial Stabilizers
|
5523, # Alpha Hull Mod Inertial Stabilizers
|
||||||
5521, # Partial Hull Conversion Inertial Stabilizers
|
5521, # Partial Hull Conversion Inertial Stabilizers
|
||||||
5525, # Type-E Altered SS Inertial Stabilizers
|
5525, # Type-E Altered SS Inertial Stabilizers
|
||||||
),
|
),
|
||||||
5533: ( # Type-D Restrained Inertial Stabilizers
|
5533 : ( # Type-D Restrained Inertial Stabilizers
|
||||||
5531, # Beta Hull Mod Inertial Stabilizers
|
5531, # Beta Hull Mod Inertial Stabilizers
|
||||||
5529, # Local Hull Conversion Inertial Stabilizers I
|
5529, # Local Hull Conversion Inertial Stabilizers I
|
||||||
5527, # Mark I Modified SS Inertial Stabilizers
|
5527, # Mark I Modified SS Inertial Stabilizers
|
||||||
5519, # Marked Modified SS Inertial Stabilizers
|
5519, # Marked Modified SS Inertial Stabilizers
|
||||||
),
|
),
|
||||||
|
|
||||||
5239: ( # EP-S Gaussian Scoped Mining Laser
|
5239 : ( # EP-S Gaussian Scoped Mining Laser
|
||||||
5241, # Dual Diode Mining Laser I
|
5241, # Dual Diode Mining Laser I
|
||||||
),
|
),
|
||||||
5233: ( # Single Diode Basic Mining Laser
|
5233 : ( # Single Diode Basic Mining Laser
|
||||||
5231, # EP-R Argon Ion Basic Excavation Pulse
|
5231, # EP-R Argon Ion Basic Excavation Pulse
|
||||||
5237, # Rubin Basic Particle Bore Stream
|
5237, # Rubin Basic Particle Bore Stream
|
||||||
5235, # Xenon Basic Drilling Beam
|
5235, # Xenon Basic Drilling Beam
|
||||||
),
|
),
|
||||||
5245: ( # Particle Bore Compact Mining Laser
|
5245 : ( # Particle Bore Compact Mining Laser
|
||||||
5243, # XeCl Drilling Beam I
|
5243, # XeCl Drilling Beam I
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -80,62 +79,63 @@ CONVERSIONS = {
|
|||||||
22609, # Erin Mining Laser Upgrade
|
22609, # Erin Mining Laser Upgrade
|
||||||
),
|
),
|
||||||
|
|
||||||
1242: ( # 'Basic' Nanofiber Internal Structure
|
1242 : ( # 'Basic' Nanofiber Internal Structure
|
||||||
5591, # Alpha Hull Mod Nanofiber Structure
|
5591, # Alpha Hull Mod Nanofiber Structure
|
||||||
5595, # Marked Modified SS Nanofiber Structure
|
5595, # Marked Modified SS Nanofiber Structure
|
||||||
5559, # Partial Hull Conversion Nanofiber Structure
|
5559, # Partial Hull Conversion Nanofiber Structure
|
||||||
5593, # Type-E Altered SS Nanofiber Structure
|
5593, # Type-E Altered SS Nanofiber Structure
|
||||||
),
|
),
|
||||||
5599: ( # Type-D Restrained Nanofiber Structure
|
5599 : ( # Type-D Restrained Nanofiber Structure
|
||||||
5597, # Beta Hull Mod Nanofiber Structure
|
5597, # Beta Hull Mod Nanofiber Structure
|
||||||
5561, # Local Hull Conversion Nanofiber Structure I
|
5561, # Local Hull Conversion Nanofiber Structure I
|
||||||
5601, # Mark I Modified SS Nanofiber Structure
|
5601, # Mark I Modified SS Nanofiber Structure
|
||||||
),
|
),
|
||||||
|
|
||||||
1192: ( # 'Basic' Overdrive Injector System
|
1192 : ( # 'Basic' Overdrive Injector System
|
||||||
5613, # Alpha Hull Mod Overdrive Injector
|
5613, # Alpha Hull Mod Overdrive Injector
|
||||||
5617, # Marked Modified SS Overdrive Injector
|
5617, # Marked Modified SS Overdrive Injector
|
||||||
5611, # Partial Hull Conversion Overdrive Injector
|
5611, # Partial Hull Conversion Overdrive Injector
|
||||||
5615, # Type-E Altered SS Overdrive Injector
|
5615, # Type-E Altered SS Overdrive Injector
|
||||||
),
|
),
|
||||||
5631: ( # Type-D Restrained Overdrive Injector
|
5631 : ( # Type-D Restrained Overdrive Injector
|
||||||
5629, # Beta Hull Mod Overdrive Injector
|
5629, # Beta Hull Mod Overdrive Injector
|
||||||
5627, # Local Hull Conversion Overdrive Injector I
|
5627, # Local Hull Conversion Overdrive Injector I
|
||||||
5633, # Mark I Modified SS Overdrive Injector
|
5633, # Mark I Modified SS Overdrive Injector
|
||||||
),
|
),
|
||||||
|
|
||||||
1537: ( # 'Basic' Power Diagnostic System
|
1537 : ( # 'Basic' Power Diagnostic System
|
||||||
8213, # Alpha Reactor Control: Diagnostic System
|
8213, # Alpha Reactor Control: Diagnostic System
|
||||||
8217, # Marked Generator Refitting: Diagnostic System
|
8217, # Marked Generator Refitting: Diagnostic System
|
||||||
8211, # Partial Power Plant Manager: Diagnostic System
|
8211, # Partial Power Plant Manager: Diagnostic System
|
||||||
8215, # Type-E Power Core Modification: Diagnostic System
|
8215, # Type-E Power Core Modification: Diagnostic System
|
||||||
8255, # Type-E Power Core Modification: Reaction Control
|
8255, # Type-E Power Core Modification: Reaction Control
|
||||||
),
|
),
|
||||||
8225: ( # Mark I Compact Power Diagnostic System
|
8225 : ( # Mark I Compact Power Diagnostic System
|
||||||
8221, # Beta Reactor Control: Diagnostic System I
|
8221, # Beta Reactor Control: Diagnostic System I
|
||||||
8219, # Local Power Plant Manager: Diagnostic System I
|
8219, # Local Power Plant Manager: Diagnostic System I
|
||||||
8223, # Type-D Power Core Modification: Diagnostic System
|
8223, # Type-D Power Core Modification: Diagnostic System
|
||||||
),
|
),
|
||||||
|
|
||||||
1240: ( # 'Basic' Reinforced Bulkheads
|
1240 : ( # 'Basic' Reinforced Bulkheads
|
||||||
5677, # Alpha Hull Mod Reinforced Bulkheads
|
5677, # Alpha Hull Mod Reinforced Bulkheads
|
||||||
5681, # Marked Modified SS Reinforced Bulkheads
|
5681, # Marked Modified SS Reinforced Bulkheads
|
||||||
5675, # Partial Hull Conversion Reinforced Bulkheads
|
5675, # Partial Hull Conversion Reinforced Bulkheads
|
||||||
5679, # Type-E Altered SS Reinforced Bulkheads
|
5679, # Type-E Altered SS Reinforced Bulkheads
|
||||||
),
|
),
|
||||||
5649: ( # Mark I Compact Reinforced Bulkheads
|
5649 : ( # Mark I Compact Reinforced Bulkheads
|
||||||
5645, # Beta Hull Mod Reinforced Bulkheads
|
5645, # Beta Hull Mod Reinforced Bulkheads
|
||||||
),
|
),
|
||||||
5647: ( # Type-D Restrained Reinforced Bulkheads
|
5647 : ( # Type-D Restrained Reinforced Bulkheads
|
||||||
5643, # Local Hull Conversion Reinforced Bulkheads I
|
5643, # Local Hull Conversion Reinforced Bulkheads I
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
|
|
||||||
# Convert modules
|
# Convert modules
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
for retired_item in list:
|
||||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
(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
|
Simply deletes damage profiles with a blank name. See GH issue #256
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ?', ("",))
|
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)
|
Overwrites damage profile 0 to reset bad uniform values (bad values set with bug)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
saveddata_engine.execute('DELETE FROM damagePatterns WHERE name LIKE ? OR ID LIKE ?', ("Uniform", "1"))
|
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 (ID, name, emAmount, thermalAmount, kineticAmount, explosiveAmount, ownerID) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||||
|
(1, "Uniform", 25, 25, 25, 25, None))
|
||||||
|
|||||||
@@ -8,17 +8,16 @@ Migration 7
|
|||||||
Pyfa.
|
Pyfa.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
640: ( # Scorpion
|
640: ( # Scorpion
|
||||||
4005, # Scorpion Ishukone Watch
|
4005, # Scorpion Ishukone Watch
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def upgrade(saveddata_engine):
|
def upgrade(saveddata_engine):
|
||||||
|
|
||||||
# Convert ships
|
# Convert ships
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
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,18 +7,17 @@ Migration 8
|
|||||||
modules with their new replacements
|
modules with their new replacements
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
8529: ( # Large F-S9 Regolith Compact Shield Extender
|
8529 : ( # Large F-S9 Regolith Compact Shield Extender
|
||||||
8409, # Large Subordinate Screen Stabilizer I
|
8409, # Large Subordinate Screen Stabilizer I
|
||||||
),
|
),
|
||||||
8419: ( # Large Azeotropic Restrained Shield Extender
|
8419 : ( # Large Azeotropic Restrained Shield Extender
|
||||||
8489, # Large Supplemental Barrier Emitter I
|
8489, # Large Supplemental Barrier Emitter I
|
||||||
),
|
),
|
||||||
8517: ( # Medium F-S9 Regolith Compact Shield Extender
|
8517 : ( # Medium F-S9 Regolith Compact Shield Extender
|
||||||
8397, # Medium Subordinate Screen Stabilizer I
|
8397, # Medium Subordinate Screen Stabilizer I
|
||||||
),
|
),
|
||||||
8433: ( # Medium Azeotropic Restrained Shield Extender
|
8433 : ( # Medium Azeotropic Restrained Shield Extender
|
||||||
8477, # Medium Supplemental Barrier Emitter I
|
8477, # Medium Supplemental Barrier Emitter I
|
||||||
),
|
),
|
||||||
20627: ( # Small 'Trapper' Shield Extender
|
20627: ( # Small 'Trapper' Shield Extender
|
||||||
@@ -29,10 +28,10 @@ CONVERSIONS = {
|
|||||||
8387, # Micro Subordinate Screen Stabilizer I
|
8387, # Micro Subordinate Screen Stabilizer I
|
||||||
8465, # Micro Supplemental Barrier Emitter I
|
8465, # Micro Supplemental Barrier Emitter I
|
||||||
),
|
),
|
||||||
8521: ( # Small F-S9 Regolith Compact Shield Extender
|
8521 : ( # Small F-S9 Regolith Compact Shield Extender
|
||||||
8401, # Small Subordinate Screen Stabilizer I
|
8401, # Small Subordinate Screen Stabilizer I
|
||||||
),
|
),
|
||||||
8427: ( # Small Azeotropic Restrained Shield Extender
|
8427 : ( # Small Azeotropic Restrained Shield Extender
|
||||||
8481, # Small Supplemental Barrier Emitter I
|
8481, # Small Supplemental Barrier Emitter I
|
||||||
),
|
),
|
||||||
11343: ( # 100mm Crystalline Carbonide Restrained Plates
|
11343: ( # 100mm Crystalline Carbonide Restrained Plates
|
||||||
@@ -71,15 +70,16 @@ CONVERSIONS = {
|
|||||||
11321, # 800mm Reinforced Nanofiber Plates I
|
11321, # 800mm Reinforced Nanofiber Plates I
|
||||||
),
|
),
|
||||||
11317: ( # 800mm Rolled Tungsten Compact Plates
|
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
|
# Convert modules
|
||||||
for replacement_item, list in CONVERSIONS.iteritems():
|
for replacement_item, list in CONVERSIONS.items():
|
||||||
for retired_item in list:
|
for retired_item in list:
|
||||||
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
saveddata_engine.execute('UPDATE "modules" SET "itemID" = ? WHERE "itemID" = ?',
|
||||||
saveddata_engine.execute('UPDATE "cargo" SET "itemID" = ? WHERE "itemID" = ?', (replacement_item, retired_item))
|
(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):
|
def upgrade(saveddata_engine):
|
||||||
saveddata_engine.execute(tmpTable)
|
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("DROP TABLE boosters")
|
||||||
saveddata_engine.execute("ALTER TABLE boostersTemp RENAME TO boosters")
|
saveddata_engine.execute("ALTER TABLE boostersTemp RENAME TO boosters")
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ __all__ = [
|
|||||||
"booster",
|
"booster",
|
||||||
"drone",
|
"drone",
|
||||||
"implant",
|
"implant",
|
||||||
"fleet",
|
|
||||||
"damagePattern",
|
"damagePattern",
|
||||||
"miscData",
|
"miscData",
|
||||||
"targetResists",
|
"targetResists",
|
||||||
"override",
|
"override",
|
||||||
"crest"
|
"implantSet",
|
||||||
|
"loadDefaultDatabaseValues"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,33 +15,41 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, ForeignKey, Integer, UniqueConstraint, Boolean
|
from sqlalchemy import Table, Column, ForeignKey, Integer, Boolean, DateTime
|
||||||
from sqlalchemy.orm import mapper, relation
|
from sqlalchemy.orm import mapper, relation
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Booster
|
from eos.saveddata.booster import Booster
|
||||||
|
from eos.saveddata.boosterSideEffect import BoosterSideEffect
|
||||||
|
|
||||||
boosters_table = Table("boosters", saveddata_meta,
|
boosters_table = Table("boosters", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("itemID", Integer),
|
Column("itemID", Integer),
|
||||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False),
|
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False),
|
||||||
Column("active", Boolean),
|
Column("active", Boolean),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||||
)
|
)
|
||||||
|
|
||||||
activeSideEffects_table = Table("boostersActiveSideEffects", saveddata_meta,
|
|
||||||
Column("boosterID", ForeignKey("boosters.ID"), primary_key = True),
|
|
||||||
Column("effectID", Integer, primary_key = True))
|
|
||||||
|
|
||||||
class ActiveSideEffectsDummy(object):
|
booster_side_effect_table = Table("boosterSideEffects", saveddata_meta,
|
||||||
def __init__(self, effectID):
|
Column("boosterID", Integer, ForeignKey("boosters.ID"), primary_key=True, index=True),
|
||||||
self.effectID = effectID
|
Column("effectID", Integer, nullable=False, primary_key=True),
|
||||||
|
Column("active", Boolean, default=False)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
mapper(ActiveSideEffectsDummy, activeSideEffects_table)
|
|
||||||
mapper(Booster, boosters_table,
|
mapper(Booster, boosters_table,
|
||||||
properties = {"_Booster__activeSideEffectDummies" : relation(ActiveSideEffectsDummy)})
|
properties={
|
||||||
|
"_Booster__sideEffects": relation(
|
||||||
|
BoosterSideEffect,
|
||||||
|
backref="booster",
|
||||||
|
cascade='all, delete, delete-orphan'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
Booster._Booster__activeSideEffectIDs = association_proxy("_Booster__activeSideEffectDummies", "effectID")
|
|
||||||
|
mapper(BoosterSideEffect, booster_side_effect_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,18 +15,27 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Cargo
|
from eos.saveddata.cargo import Cargo
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
|
||||||
cargo_table = Table("cargo", saveddata_meta,
|
cargo_table = Table("cargo", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key=True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||||
Column("itemID", Integer, nullable = False),
|
Column("itemID", Integer, nullable=False),
|
||||||
Column("amount", Integer, nullable = False))
|
Column("amount", Integer, nullable=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||||
|
)
|
||||||
|
|
||||||
mapper(Cargo, cargo_table)
|
mapper(Cargo, cargo_table,
|
||||||
|
properties={
|
||||||
|
"owner": relation(Fit)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,30 +15,80 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, ForeignKey, String, DateTime, Float, UniqueConstraint
|
||||||
from sqlalchemy.orm import relation, mapper
|
from sqlalchemy.orm import relation, mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.db.saveddata.implant import charImplants_table
|
from eos.db.saveddata.implant import charImplants_table
|
||||||
from eos.types import Character, User, Skill, Implant
|
from eos.effectHandlerHelpers import HandledImplantBoosterList, HandledSsoCharacterList
|
||||||
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
from eos.saveddata.implant import Implant
|
||||||
|
from eos.saveddata.user import User
|
||||||
|
from eos.saveddata.character import Character, Skill
|
||||||
|
from eos.saveddata.ssocharacter import SsoCharacter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
characters_table = Table("characters", saveddata_meta,
|
characters_table = Table("characters", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("name", String, nullable = False),
|
Column("name", String, nullable=False),
|
||||||
Column("apiID", Integer),
|
|
||||||
Column("apiKey", String),
|
|
||||||
Column("defaultChar", Integer),
|
|
||||||
Column("chars", String, nullable = True),
|
|
||||||
Column("defaultLevel", Integer, 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),
|
||||||
|
Column("secStatus", Float, nullable=True, default=0.0),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
|
||||||
|
|
||||||
|
sso_table = Table("ssoCharacter", saveddata_meta,
|
||||||
|
Column("ID", Integer, primary_key=True),
|
||||||
|
Column("client", String, nullable=False),
|
||||||
|
Column("characterID", Integer, nullable=False),
|
||||||
|
Column("characterName", String, nullable=False),
|
||||||
|
Column("refreshToken", String, nullable=False),
|
||||||
|
Column("accessToken", String, nullable=False),
|
||||||
|
Column("accessTokenExpires", DateTime, nullable=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||||
|
UniqueConstraint('client', 'characterID', name='uix_client_characterID'),
|
||||||
|
UniqueConstraint('client', 'characterName', name='uix_client_characterName')
|
||||||
|
)
|
||||||
|
|
||||||
|
sso_character_map_table = Table("ssoCharacterMap", saveddata_meta,
|
||||||
|
Column("characterID", ForeignKey("characters.ID"), primary_key=True),
|
||||||
|
Column("ssoCharacterID", ForeignKey("ssoCharacter.ID"), primary_key=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
mapper(SsoCharacter, sso_table)
|
||||||
|
|
||||||
mapper(Character, characters_table,
|
mapper(Character, characters_table,
|
||||||
properties = {"_Character__owner" : relation(User, backref = "characters"),
|
properties={
|
||||||
"_Character__skills" : relation(Skill, backref="character", cascade = "all,delete-orphan"),
|
"_Character__alphaCloneID": characters_table.c.alphaCloneID,
|
||||||
"_Character__implants" : relation(Implant, collection_class = HandledImplantBoosterList, cascade='all,delete-orphan', single_parent=True,
|
"savedName" : characters_table.c.name,
|
||||||
primaryjoin = charImplants_table.c.charID == characters_table.c.ID,
|
"_Character__secStatus": characters_table.c.secStatus,
|
||||||
secondaryjoin = charImplants_table.c.implantID == Implant.ID,
|
"_Character__owner" : relation(
|
||||||
secondary = charImplants_table),})
|
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),
|
||||||
|
"_Character__ssoCharacters" : relation(
|
||||||
|
SsoCharacter,
|
||||||
|
collection_class=HandledSsoCharacterList,
|
||||||
|
backref='characters',
|
||||||
|
secondary=sso_character_map_table)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,31 +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, String, Boolean
|
|
||||||
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))
|
|
||||||
|
|
||||||
mapper(CrestChar, crest_table)
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,21 +15,25 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, ForeignKey, String, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import DamagePattern
|
from eos.saveddata.damagePattern import DamagePattern
|
||||||
|
|
||||||
damagePatterns_table = Table("damagePatterns", saveddata_meta,
|
damagePatterns_table = Table("damagePatterns", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("name", String),
|
Column("name", String),
|
||||||
Column("emAmount", Integer),
|
Column("emAmount", Integer),
|
||||||
Column("thermalAmount", Integer),
|
Column("thermalAmount", Integer),
|
||||||
Column("kineticAmount", Integer),
|
Column("kineticAmount", Integer),
|
||||||
Column("explosiveAmount", Integer),
|
Column("explosiveAmount", Integer),
|
||||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
mapper(DamagePattern, damagePatterns_table)
|
mapper(DamagePattern, damagePatterns_table)
|
||||||
|
|||||||
239
eos/db/saveddata/databaseRepair.py
Normal file
239
eos/db/saveddata/databaseRepair.py
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# Copyright (C) 2010 Diego Duclos
|
||||||
|
#
|
||||||
|
# This file is part of pyfa.
|
||||||
|
#
|
||||||
|
# pyfa is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# pyfa is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
# ===============================================================================
|
||||||
|
|
||||||
|
from sqlalchemy.exc import DatabaseError
|
||||||
|
from logbook import Logger
|
||||||
|
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseCleanup(object):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ExecuteSQLQuery(saveddata_engine, query):
|
||||||
|
try:
|
||||||
|
results = saveddata_engine.execute(query)
|
||||||
|
return results
|
||||||
|
except DatabaseError:
|
||||||
|
pyfalog.error("Failed to connect to database or error executing query:\n{0}", 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
|
||||||
|
pyfalog.debug("Running database cleanup for character skills.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM characterSkills WHERE characterID NOT IN (SELECT ID from characters)"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
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)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def OrphanedFitDamagePatterns(saveddata_engine):
|
||||||
|
# Find orphaned damage patterns.
|
||||||
|
# This solves an issue where the damage pattern doesn't exist, but fits reference the pattern.
|
||||||
|
# See issue #777
|
||||||
|
pyfalog.debug("Running database cleanup for orphaned damage patterns attached to fits.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM fits WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
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:
|
||||||
|
pyfalog.error("Missing uniform damage pattern.")
|
||||||
|
elif len(rows) > 1:
|
||||||
|
pyfalog.error("More than one uniform damage pattern found.")
|
||||||
|
else:
|
||||||
|
uniform_damage_pattern_id = rows[0]['ID']
|
||||||
|
update_query = "UPDATE 'fits' SET 'damagePatternID' = {} " \
|
||||||
|
"WHERE damagePatternID NOT IN (SELECT ID FROM damagePatterns) OR damagePatternID IS NULL".format(uniform_damage_pattern_id)
|
||||||
|
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", update_results.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def OrphanedFitCharacterIDs(saveddata_engine):
|
||||||
|
# Find orphaned character IDs. This solves an issue where the character doesn't exist, but fits reference the pattern.
|
||||||
|
pyfalog.debug("Running database cleanup for orphaned characters attached to fits.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM fits WHERE characterID NOT IN (SELECT ID FROM characters) OR characterID IS NULL"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
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:
|
||||||
|
pyfalog.error("Missing 'All 5' character.")
|
||||||
|
elif len(rows) > 1:
|
||||||
|
pyfalog.error("More than one 'All 5' character found.")
|
||||||
|
else:
|
||||||
|
all5_id = rows[0]['ID']
|
||||||
|
update_query = "UPDATE 'fits' SET 'characterID' = " + str(all5_id) + \
|
||||||
|
" WHERE characterID not in (select ID from characters) OR characterID IS NULL"
|
||||||
|
update_results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, update_query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", update_results.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def NullDamagePatternNames(saveddata_engine):
|
||||||
|
# Find damage patterns that are missing the name.
|
||||||
|
# This solves an issue where the damage pattern ends up with a name that is null.
|
||||||
|
# See issue #949
|
||||||
|
pyfalog.debug("Running database cleanup for missing damage pattern names.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name IS NULL OR name = ''"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
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)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def NullTargetResistNames(saveddata_engine):
|
||||||
|
# Find target resists that are missing the name.
|
||||||
|
# This solves an issue where the target resist ends up with a name that is null.
|
||||||
|
# See issue #949
|
||||||
|
pyfalog.debug("Running database cleanup for missing target resist names.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM targetResists WHERE name IS NULL OR name = ''"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
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)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def OrphanedFitIDItemID(saveddata_engine):
|
||||||
|
# Orphaned items that are missing the fit ID or item ID.
|
||||||
|
# See issue #954
|
||||||
|
for table in ['drones', 'cargo', 'fighters']:
|
||||||
|
pyfalog.debug("Running database cleanup for orphaned {0} items.", table)
|
||||||
|
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||||
|
table)
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
if results is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
row = results.first()
|
||||||
|
|
||||||
|
if row and row['num']:
|
||||||
|
query = "DELETE FROM {} WHERE itemID IS NULL OR itemID = '' or itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||||
|
table)
|
||||||
|
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
for table in ['modules']:
|
||||||
|
pyfalog.debug("Running database cleanup for orphaned {0} items.", table)
|
||||||
|
query = "SELECT COUNT(*) AS num FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(
|
||||||
|
table)
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
if results is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
row = results.first()
|
||||||
|
|
||||||
|
if row and row['num']:
|
||||||
|
query = "DELETE FROM {} WHERE itemID = '0' or fitID IS NULL OR fitID = '' or fitID = '0'".format(table)
|
||||||
|
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def NullDamageTargetPatternValues(saveddata_engine):
|
||||||
|
# Find patterns that have null values
|
||||||
|
# See issue #954
|
||||||
|
for profileType in ['damagePatterns', 'targetResists']:
|
||||||
|
for damageType in ['em', 'thermal', 'kinetic', 'explosive']:
|
||||||
|
pyfalog.debug("Running database cleanup for null {0} values. ({1})", profileType, damageType)
|
||||||
|
query = "SELECT COUNT(*) AS num FROM {0} WHERE {1}Amount IS NULL OR {1}Amount = ''".format(profileType,
|
||||||
|
damageType)
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
if results is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
row = results.first()
|
||||||
|
|
||||||
|
if row and row['num']:
|
||||||
|
query = "UPDATE '{0}' SET '{1}Amount' = '0' WHERE {1}Amount IS NULL OR {1}Amount = ''".format(profileType,
|
||||||
|
damageType)
|
||||||
|
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def DuplicateSelectedAmmoName(saveddata_engine):
|
||||||
|
# Orphaned items that are missing the fit ID or item ID.
|
||||||
|
# See issue #954
|
||||||
|
pyfalog.debug("Running database cleanup for duplicated selected ammo profiles.")
|
||||||
|
query = "SELECT COUNT(*) AS num FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||||
|
results = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
|
||||||
|
if results is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
row = results.first()
|
||||||
|
|
||||||
|
if row and row['num'] > 1:
|
||||||
|
query = "DELETE FROM damagePatterns WHERE name = 'Selected Ammo'"
|
||||||
|
delete = DatabaseCleanup.ExecuteSQLQuery(saveddata_engine, query)
|
||||||
|
pyfalog.error("Database corruption found. Cleaning up {0} records.", delete.rowcount)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,19 +15,29 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
|
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime
|
||||||
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
import datetime
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
|
|
||||||
from sqlalchemy.orm import mapper
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Drone
|
from eos.saveddata.drone import Drone
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
|
||||||
drones_table = Table("drones", saveddata_meta,
|
drones_table = Table("drones", saveddata_meta,
|
||||||
Column("groupID", Integer, primary_key=True),
|
Column("groupID", Integer, primary_key=True),
|
||||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||||
Column("itemID", Integer, nullable = False),
|
Column("itemID", Integer, nullable=False),
|
||||||
Column("amount", Integer, nullable = False),
|
Column("amount", Integer, nullable=False),
|
||||||
Column("amountActive", Integer, nullable = False),
|
Column("amountActive", Integer, nullable=False),
|
||||||
Column("projected", Boolean, default = False))
|
Column("projected", Boolean, default=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
mapper(Drone, drones_table)
|
mapper(Drone, drones_table,
|
||||||
|
properties={
|
||||||
|
"owner": relation(Fit)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
55
eos/db/saveddata/fighter.py
Normal file
55
eos/db/saveddata/fighter.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# 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, Boolean, DateTime
|
||||||
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from eos.db import saveddata_meta
|
||||||
|
from eos.saveddata.fighterAbility import FighterAbility
|
||||||
|
from eos.saveddata.fighter import Fighter
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
|
||||||
|
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("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
mapper(Fighter, fighters_table,
|
||||||
|
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
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,41 +15,71 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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.ext.associationproxy import association_proxy
|
||||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
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, DateTime
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.db.saveddata.module import modules_table
|
from eos.db import saveddata_session
|
||||||
from eos.db.saveddata.drone import drones_table
|
|
||||||
from eos.db.saveddata.cargo import cargo_table
|
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.implant import fitImplants_table
|
from eos.db.saveddata.implant import fitImplants_table
|
||||||
from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists
|
from eos.db.saveddata.module import modules_table
|
||||||
from eos.effectHandlerHelpers import *
|
from eos.effectHandlerHelpers import HandledModuleList, HandledImplantBoosterList, HandledProjectedModList, \
|
||||||
|
HandledDroneCargoList, HandledProjectedDroneList
|
||||||
|
from eos.saveddata.implant import Implant
|
||||||
|
from eos.saveddata.character import Character
|
||||||
|
from eos.saveddata.user import User
|
||||||
|
from eos.saveddata.fighter import Fighter
|
||||||
|
from eos.saveddata.fit import Fit as es_Fit, ImplantLocation
|
||||||
|
from eos.saveddata.drone import Drone
|
||||||
|
from eos.saveddata.booster import Booster
|
||||||
|
from eos.saveddata.module import Module
|
||||||
|
from eos.saveddata.cargo import Cargo
|
||||||
|
from eos.saveddata.damagePattern import DamagePattern
|
||||||
|
from eos.saveddata.targetResists import TargetResists
|
||||||
|
|
||||||
fits_table = Table("fits", saveddata_meta,
|
fits_table = Table("fits", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
|
Column("ownerID", ForeignKey("users.ID"), nullable=True, index=True),
|
||||||
Column("shipID", Integer, nullable = False, index = True),
|
Column("shipID", Integer, nullable=False, index=True),
|
||||||
Column("name", String, nullable = False),
|
Column("name", String, nullable=False),
|
||||||
Column("timestamp", Integer, nullable = False),
|
Column("timestamp", Integer, nullable=False),
|
||||||
Column("characterID", ForeignKey("characters.ID"), nullable = True),
|
Column("characterID", ForeignKey("characters.ID"), nullable=True),
|
||||||
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
|
||||||
Column("booster", Boolean, nullable = False, index = True, default = 0),
|
Column("booster", Boolean, nullable=False, index=True, default=0),
|
||||||
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True),
|
||||||
Column("modeID", Integer, nullable=True),
|
Column("modeID", Integer, nullable=True),
|
||||||
)
|
Column("implantLocation", Integer, nullable=False, default=ImplantLocation.FIT),
|
||||||
|
Column("notes", String, nullable=True),
|
||||||
|
Column("ignoreRestrictions", Boolean, default=0),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, default=datetime.datetime.now, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
projectedFits_table = Table("projectedFits", saveddata_meta,
|
projectedFits_table = Table("projectedFits", saveddata_meta,
|
||||||
Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
|
Column("sourceID", ForeignKey("fits.ID"), primary_key=True),
|
||||||
Column("victimID", ForeignKey("fits.ID"), primary_key = True),
|
Column("victimID", ForeignKey("fits.ID"), primary_key=True),
|
||||||
Column("amount", Integer, nullable = False, default = 1),
|
Column("amount", Integer, nullable=False, default=1),
|
||||||
Column("active", Boolean, nullable = False, default = 1),
|
Column("active", Boolean, nullable=False, default=1),
|
||||||
)
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
|
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),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProjectedFit(object):
|
class ProjectedFit(object):
|
||||||
def __init__(self, sourceID, source_fit, amount=1, active=True):
|
def __init__(self, sourceID, source_fit, amount=1, active=True):
|
||||||
@@ -62,9 +92,9 @@ class ProjectedFit(object):
|
|||||||
def init(self):
|
def init(self):
|
||||||
if self.source_fit.isInvalid:
|
if self.source_fit.isInvalid:
|
||||||
# Very rare for this to happen, but be prepared for it
|
# Very rare for this to happen, but be prepared for it
|
||||||
eos.db.saveddata_session.delete(self.source_fit)
|
saveddata_session.delete(self.source_fit)
|
||||||
eos.db.saveddata_session.flush()
|
saveddata_session.flush()
|
||||||
eos.db.saveddata_session.refresh(self.victim_fit)
|
saveddata_session.refresh(self.victim_fit)
|
||||||
|
|
||||||
# We have a series of setters and getters here just in case someone
|
# We have a series of setters and getters here just in case someone
|
||||||
# downgrades and screws up the table with NULL values
|
# downgrades and screws up the table with NULL values
|
||||||
@@ -78,88 +108,151 @@ class ProjectedFit(object):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "ProjectedFit(sourceID={}, victimID={}, amount={}, active={}) at {}".format(
|
return "ProjectedFit(sourceID={}, victimID={}, amount={}, active={}) at {}".format(
|
||||||
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
|
self.sourceID, self.victimID, self.amount, self.active, hex(id(self))
|
||||||
)
|
)
|
||||||
|
|
||||||
Fit._Fit__projectedFits = association_proxy(
|
|
||||||
"victimOf", # look at the victimOf association...
|
class CommandFit(object):
|
||||||
"source_fit", # .. and return the source fits
|
def __init__(self, boosterID, booster_fit, active=True):
|
||||||
creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit)
|
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,
|
es_Fit._Fit__commandFits = association_proxy(
|
||||||
properties = {
|
"boostedOf", # look at the boostedOf association...
|
||||||
"_Fit__modules": relation(
|
"booster_fit", # .. and return the booster fit
|
||||||
Module,
|
creator=lambda boosterID, booster_fit: CommandFit(boosterID, booster_fit)
|
||||||
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'),
|
# These relationships are broken out so that we can easily access it in the events stuff
|
||||||
"_Fit__projectedModules": relation(
|
# We sometimes don't want particular relationships to cause a fit modified update (eg: projecting
|
||||||
Module,
|
# a fit onto another would 'modify' both fits unless the following relationship is ignored)
|
||||||
collection_class=HandledProjectedModList,
|
projectedFitSourceRel = relationship(
|
||||||
cascade='all, delete, delete-orphan',
|
ProjectedFit,
|
||||||
single_parent=True,
|
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
||||||
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)),
|
backref='source_fit',
|
||||||
"owner": relation(
|
collection_class=attribute_mapped_collection('victimID'),
|
||||||
User,
|
cascade='all, delete, delete-orphan')
|
||||||
backref="fits"),
|
|
||||||
"itemID": fits_table.c.shipID,
|
|
||||||
"shipID": fits_table.c.shipID,
|
boostedOntoRel = relationship(
|
||||||
"_Fit__boosters": relation(
|
CommandFit,
|
||||||
Booster,
|
primaryjoin=commandFits_table.c.boosterID == fits_table.c.ID,
|
||||||
collection_class=HandledImplantBoosterList,
|
backref='booster_fit',
|
||||||
cascade='all, delete, delete-orphan',
|
collection_class=attribute_mapped_collection('boostedID'),
|
||||||
single_parent=True),
|
cascade='all, delete, delete-orphan')
|
||||||
"_Fit__drones": relation(
|
|
||||||
Drone,
|
mapper(es_Fit, fits_table,
|
||||||
collection_class=HandledDroneCargoList,
|
properties={
|
||||||
cascade='all, delete, delete-orphan',
|
"_Fit__modules": relation(
|
||||||
single_parent=True,
|
Module,
|
||||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
|
collection_class=HandledModuleList,
|
||||||
"_Fit__cargo": relation(
|
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False), # noqa
|
||||||
Cargo,
|
order_by=modules_table.c.position,
|
||||||
collection_class=HandledDroneCargoList,
|
cascade='all, delete, delete-orphan'),
|
||||||
cascade='all, delete, delete-orphan',
|
"_Fit__projectedModules": relation(
|
||||||
single_parent=True,
|
Module,
|
||||||
primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)),
|
collection_class=HandledProjectedModList,
|
||||||
"_Fit__projectedDrones": relation(
|
cascade='all, delete, delete-orphan',
|
||||||
Drone,
|
single_parent=True,
|
||||||
collection_class=HandledProjectedDroneList,
|
primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)), # noqa
|
||||||
cascade='all, delete, delete-orphan',
|
"owner": relation(
|
||||||
single_parent=True,
|
User,
|
||||||
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)),
|
backref="fits"),
|
||||||
"_Fit__implants": relation(
|
"itemID": fits_table.c.shipID,
|
||||||
Implant,
|
"shipID": fits_table.c.shipID,
|
||||||
collection_class=HandledImplantBoosterList,
|
"_Fit__boosters": relation(
|
||||||
cascade='all, delete, delete-orphan',
|
Booster,
|
||||||
backref='fit',
|
collection_class=HandledImplantBoosterList,
|
||||||
single_parent=True,
|
cascade='all, delete, delete-orphan',
|
||||||
primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID,
|
backref='owner',
|
||||||
secondaryjoin=fitImplants_table.c.implantID == Implant.ID,
|
single_parent=True),
|
||||||
secondary=fitImplants_table),
|
"_Fit__drones": relation(
|
||||||
"_Fit__character": relation(
|
Drone,
|
||||||
Character,
|
collection_class=HandledDroneCargoList,
|
||||||
backref="fits"),
|
cascade='all, delete, delete-orphan',
|
||||||
"_Fit__damagePattern": relation(DamagePattern),
|
single_parent=True,
|
||||||
"_Fit__targetResists": relation(TargetResists),
|
primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)), # noqa
|
||||||
"projectedOnto": relationship(
|
"_Fit__fighters": relation(
|
||||||
ProjectedFit,
|
Fighter,
|
||||||
primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID,
|
collection_class=HandledDroneCargoList,
|
||||||
backref='source_fit',
|
cascade='all, delete, delete-orphan',
|
||||||
collection_class=attribute_mapped_collection('victimID'),
|
single_parent=True,
|
||||||
cascade='all, delete, delete-orphan'),
|
primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == False)), # noqa
|
||||||
"victimOf": relationship(
|
"_Fit__cargo": relation(
|
||||||
ProjectedFit,
|
Cargo,
|
||||||
primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID,
|
collection_class=HandledDroneCargoList,
|
||||||
backref='victim_fit',
|
cascade='all, delete, delete-orphan',
|
||||||
collection_class=attribute_mapped_collection('sourceID'),
|
single_parent=True,
|
||||||
cascade='all, delete, delete-orphan'),
|
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='owner',
|
||||||
|
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": projectedFitSourceRel,
|
||||||
|
"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": boostedOntoRel,
|
||||||
|
"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,
|
mapper(ProjectedFit, projectedFits_table,
|
||||||
properties = {
|
properties={
|
||||||
"_ProjectedFit__amount": projectedFits_table.c.amount,
|
"_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
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,25 +15,33 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, Boolean, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Implant
|
from eos.saveddata.implant import Implant
|
||||||
|
|
||||||
implants_table = Table("implants", saveddata_meta,
|
implants_table = Table("implants", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("itemID", Integer),
|
Column("itemID", Integer),
|
||||||
Column("active", Boolean))
|
Column("active", Boolean),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
fitImplants_table = Table("fitImplants", saveddata_meta,
|
fitImplants_table = Table("fitImplants", saveddata_meta,
|
||||||
Column("fitID", ForeignKey("fits.ID"), index = True),
|
Column("fitID", ForeignKey("fits.ID"), index=True),
|
||||||
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
|
Column("implantID", ForeignKey("implants.ID"), primary_key=True))
|
||||||
|
|
||||||
charImplants_table = Table("charImplants", saveddata_meta,
|
charImplants_table = Table("charImplants", saveddata_meta,
|
||||||
Column("charID", ForeignKey("characters.ID"), index = True),
|
Column("charID", ForeignKey("characters.ID"), index=True),
|
||||||
Column("implantID", ForeignKey("implants.ID"), primary_key = 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))
|
||||||
|
|
||||||
mapper(Implant, implants_table)
|
mapper(Implant, implants_table)
|
||||||
|
|||||||
49
eos/db/saveddata/implantSet.py
Normal file
49
eos/db/saveddata/implantSet.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# Copyright (C) 2016 Ryan Holmes
|
||||||
|
#
|
||||||
|
# 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, String, DateTime
|
||||||
|
from sqlalchemy.orm import relation, mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from eos.db import saveddata_meta
|
||||||
|
from eos.db.saveddata.implant import implantsSetMap_table
|
||||||
|
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
||||||
|
from eos.saveddata.implant import Implant
|
||||||
|
from eos.saveddata.implantSet import ImplantSet
|
||||||
|
|
||||||
|
implant_set_table = Table("implantSets", saveddata_meta,
|
||||||
|
Column("ID", Integer, primary_key=True),
|
||||||
|
Column("name", String, nullable=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
)
|
||||||
198
eos/db/saveddata/loadDefaultDatabaseValues.py
Normal file
198
eos/db/saveddata/loadDefaultDatabaseValues.py
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# 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 eos.db
|
||||||
|
from eos.saveddata.damagePattern import DamagePattern as es_DamagePattern
|
||||||
|
from eos.saveddata.targetResists import TargetResists as es_TargetResists
|
||||||
|
|
||||||
|
|
||||||
|
class ImportError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultDatabaseValues(object):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
instance = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
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 = es_DamagePattern(em, therm, kin, exp)
|
||||||
|
damageProfile.name = name
|
||||||
|
eos.db.save(damageProfile)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
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 = es_TargetResists(em, therm, kin, exp)
|
||||||
|
resistsProfile.name = name
|
||||||
|
eos.db.save(resistsProfile)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
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 = es_DamagePattern(em, therm, kin, exp)
|
||||||
|
damageProfile.name = name
|
||||||
|
eos.db.save(damageProfile)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2011 Anton Vorobyov
|
# Copyright (C) 2011 Anton Vorobyov
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,15 +15,16 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, String
|
from sqlalchemy import Column, Table, String
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
from eos.types import MiscData
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
|
from eos.saveddata.miscData import MiscData
|
||||||
|
|
||||||
miscdata_table = Table("miscdata", saveddata_meta,
|
miscdata_table = Table("miscdata", saveddata_meta,
|
||||||
Column("fieldName", String, primary_key=True),
|
Column("fieldName", String, primary_key=True),
|
||||||
Column("fieldValue", String))
|
Column("fieldValue", String))
|
||||||
|
|
||||||
mapper(MiscData, miscdata_table)
|
mapper(MiscData, miscdata_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,25 +15,28 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean
|
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean, DateTime
|
||||||
from sqlalchemy.orm import relation, mapper
|
from sqlalchemy.orm import relation, mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Module, Fit
|
from eos.saveddata.module import Module
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
|
||||||
modules_table = Table("modules", saveddata_meta,
|
modules_table = Table("modules", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
|
||||||
Column("itemID", Integer, nullable = True),
|
Column("itemID", Integer, nullable=True),
|
||||||
Column("dummySlot", Integer, nullable = True, default = None),
|
Column("dummySlot", Integer, nullable=True, default=None),
|
||||||
Column("chargeID", Integer),
|
Column("chargeID", Integer),
|
||||||
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),
|
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),
|
Column("position", Integer),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now),
|
||||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||||
|
|
||||||
mapper(Module, modules_table,
|
mapper(Module, modules_table,
|
||||||
properties = {"owner" : relation(Fit)})
|
properties={"owner": relation(Fit)})
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,17 +15,21 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, Float
|
from sqlalchemy import Table, Column, Integer, Float, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Override
|
from eos.saveddata.override import Override
|
||||||
|
|
||||||
overrides_table = Table("overrides", saveddata_meta,
|
overrides_table = Table("overrides", saveddata_meta,
|
||||||
Column("itemID", Integer, primary_key=True, index = True),
|
Column("itemID", Integer, primary_key=True, index=True),
|
||||||
Column("attrID", Integer, primary_key=True, index = True),
|
Column("attrID", Integer, primary_key=True, index=True),
|
||||||
Column("value", Float, nullable = False))
|
Column("value", Float, nullable=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
mapper(Override, overrides_table)
|
mapper(Override, overrides_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,17 +15,20 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Float, Integer
|
from sqlalchemy import Table, Column, Float, Integer
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Price
|
from eos.saveddata.price import Price
|
||||||
|
|
||||||
prices_table = Table("prices", saveddata_meta,
|
prices_table = Table("prices", saveddata_meta,
|
||||||
Column("typeID", Integer, primary_key=True),
|
Column("typeID", Integer, primary_key=True),
|
||||||
Column("price", Float),
|
Column("price", Float, default=0.0),
|
||||||
Column("time", Integer, nullable = False),
|
Column("time", Integer, nullable=False),
|
||||||
Column("failed", Integer))
|
Column("failed", Integer))
|
||||||
|
|
||||||
mapper(Price, prices_table)
|
mapper(Price, prices_table, properties={
|
||||||
|
"_Price__price": prices_table.c.price,
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,27 +15,44 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from eos.db.util import processEager, processWhere
|
import sys
|
||||||
from eos.db import saveddata_session, sd_lock
|
|
||||||
|
|
||||||
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar
|
|
||||||
from eos.db.saveddata.fleet import squadmembers_table
|
|
||||||
from eos.db.saveddata.fit import projectedFits_table
|
|
||||||
from sqlalchemy.sql import and_
|
from sqlalchemy.sql import and_
|
||||||
|
from sqlalchemy import desc, select
|
||||||
|
|
||||||
|
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.saveddata.price import Price
|
||||||
|
from eos.saveddata.user import User
|
||||||
|
from eos.saveddata.ssocharacter import SsoCharacter
|
||||||
|
from eos.saveddata.damagePattern import DamagePattern
|
||||||
|
from eos.saveddata.targetResists import TargetResists
|
||||||
|
from eos.saveddata.character import Character
|
||||||
|
from eos.saveddata.implantSet import ImplantSet
|
||||||
|
from eos.saveddata.fit import Fit
|
||||||
|
from eos.saveddata.module import Module
|
||||||
|
from eos.saveddata.miscData import MiscData
|
||||||
|
from eos.saveddata.override import Override
|
||||||
|
|
||||||
import eos.config
|
import eos.config
|
||||||
|
|
||||||
configVal = getattr(eos.config, "saveddataCache", None)
|
configVal = getattr(eos.config, "saveddataCache", None)
|
||||||
if configVal is True:
|
if configVal is True:
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
itemCache = {}
|
itemCache = {}
|
||||||
queryCache = {}
|
queryCache = {}
|
||||||
|
|
||||||
def cachedQuery(type, amount, *keywords):
|
def cachedQuery(type, amount, *keywords):
|
||||||
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
|
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
|
||||||
queryCache[type] = typeQueryCache = {}
|
queryCache[type] = typeQueryCache = {}
|
||||||
|
|
||||||
def deco(function):
|
def deco(function):
|
||||||
localQueryCache = typeQueryCache[function] = {}
|
localQueryCache = typeQueryCache[function] = {}
|
||||||
|
|
||||||
def setCache(cacheKey, args, kwargs):
|
def setCache(cacheKey, args, kwargs):
|
||||||
items = function(*args, **kwargs)
|
items = function(*args, **kwargs)
|
||||||
IDs = set()
|
IDs = set()
|
||||||
@@ -44,7 +61,7 @@ if configVal is True:
|
|||||||
for item in stuff:
|
for item in stuff:
|
||||||
ID = getattr(item, "ID", None)
|
ID = getattr(item, "ID", None)
|
||||||
if ID is None:
|
if ID is None:
|
||||||
#Some uncachable data, don't cache this query
|
# Some uncachable data, don't cache this query
|
||||||
del localQueryCache[cacheKey]
|
del localQueryCache[cacheKey]
|
||||||
break
|
break
|
||||||
localItemCache[ID] = item
|
localItemCache[ID] = item
|
||||||
@@ -55,6 +72,7 @@ if configVal is True:
|
|||||||
def checkAndReturn(*args, **kwargs):
|
def checkAndReturn(*args, **kwargs):
|
||||||
useCache = kwargs.pop("useCache", True)
|
useCache = kwargs.pop("useCache", True)
|
||||||
cacheKey = []
|
cacheKey = []
|
||||||
|
items = None
|
||||||
cacheKey.extend(args)
|
cacheKey.extend(args)
|
||||||
for keyword in keywords:
|
for keyword in keywords:
|
||||||
cacheKey.append(kwargs.get(keyword))
|
cacheKey.append(kwargs.get(keyword))
|
||||||
@@ -70,7 +88,7 @@ if configVal is True:
|
|||||||
for ID in IDs:
|
for ID in IDs:
|
||||||
data = localItemCache.get(ID)
|
data = localItemCache.get(ID)
|
||||||
if data is None:
|
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)
|
items = setCache(cacheKey, args, kwargs)
|
||||||
break
|
break
|
||||||
items.append(data)
|
items.append(data)
|
||||||
@@ -82,16 +100,18 @@ if configVal is True:
|
|||||||
break
|
break
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
return checkAndReturn
|
return checkAndReturn
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
||||||
def removeCachedEntry(type, ID):
|
def removeCachedEntry(type, ID):
|
||||||
if not type in queryCache:
|
if type not in queryCache:
|
||||||
return
|
return
|
||||||
functionCache = queryCache[type]
|
functionCache = queryCache[type]
|
||||||
for _, localCache in functionCache.iteritems():
|
for _, localCache in functionCache.items():
|
||||||
toDelete = set()
|
toDelete = set()
|
||||||
for cacheKey, info in localCache.iteritems():
|
for cacheKey, info in localCache.items():
|
||||||
IDs = info[1]
|
IDs = info[1]
|
||||||
if ID in IDs:
|
if ID in IDs:
|
||||||
toDelete.add(cacheKey)
|
toDelete.add(cacheKey)
|
||||||
@@ -111,11 +131,13 @@ else:
|
|||||||
return function(*args, **kwargs)
|
return function(*args, **kwargs)
|
||||||
|
|
||||||
return checkAndReturn
|
return checkAndReturn
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
||||||
def removeCachedEntry(*args, **kwargs):
|
def removeCachedEntry(*args, **kwargs):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def sqlizeString(line):
|
def sqlizeString(line):
|
||||||
# Escape backslashes first, as they will be as escape symbol in queries
|
# Escape backslashes first, as they will be as escape symbol in queries
|
||||||
# Then escape percent and underscore signs
|
# Then escape percent and underscore signs
|
||||||
@@ -123,6 +145,7 @@ def sqlizeString(line):
|
|||||||
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(User, 1, "lookfor")
|
@cachedQuery(User, 1, "lookfor")
|
||||||
def getUser(lookfor, eager=None):
|
def getUser(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -133,7 +156,7 @@ def getUser(lookfor, eager=None):
|
|||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
user = saveddata_session.query(User).options(*eager).filter(User.ID == lookfor).first()
|
user = saveddata_session.query(User).options(*eager).filter(User.ID == lookfor).first()
|
||||||
elif isinstance(lookfor, basestring):
|
elif isinstance(lookfor, str):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
user = saveddata_session.query(User).options(*eager).filter(User.username == lookfor).first()
|
user = saveddata_session.query(User).options(*eager).filter(User.username == lookfor).first()
|
||||||
@@ -141,6 +164,7 @@ def getUser(lookfor, eager=None):
|
|||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(Character, 1, "lookfor")
|
@cachedQuery(Character, 1, "lookfor")
|
||||||
def getCharacter(lookfor, eager=None):
|
def getCharacter(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -151,20 +175,23 @@ def getCharacter(lookfor, eager=None):
|
|||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
character = saveddata_session.query(Character).options(*eager).filter(Character.ID == lookfor).first()
|
character = saveddata_session.query(Character).options(*eager).filter(Character.ID == lookfor).first()
|
||||||
elif isinstance(lookfor, basestring):
|
elif isinstance(lookfor, str):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
character = saveddata_session.query(Character).options(*eager).filter(Character.name == lookfor).first()
|
character = saveddata_session.query(Character).options(*eager).filter(
|
||||||
|
Character.savedName == lookfor).first()
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return character
|
return character
|
||||||
|
|
||||||
|
|
||||||
def getCharacterList(eager=None):
|
def getCharacterList(eager=None):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
characters = saveddata_session.query(Character).options(*eager).all()
|
characters = saveddata_session.query(Character).options(*eager).all()
|
||||||
return characters
|
return characters
|
||||||
|
|
||||||
|
|
||||||
def getCharactersForUser(lookfor, eager=None):
|
def getCharactersForUser(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
@@ -174,6 +201,7 @@ def getCharactersForUser(lookfor, eager=None):
|
|||||||
raise TypeError("Need integer as argument")
|
raise TypeError("Need integer as argument")
|
||||||
return characters
|
return characters
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(Fit, 1, "lookfor")
|
@cachedQuery(Fit, 1, "lookfor")
|
||||||
def getFit(lookfor, eager=None):
|
def getFit(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -194,47 +222,6 @@ def getFit(lookfor, eager=None):
|
|||||||
|
|
||||||
return fit
|
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):
|
def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
||||||
"""
|
"""
|
||||||
@@ -257,50 +244,73 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
|
|||||||
|
|
||||||
return fits
|
return fits
|
||||||
|
|
||||||
def getBoosterFits(ownerID=None, where=None, eager=None):
|
|
||||||
"""
|
|
||||||
Get all the fits that are flagged as a boosting ship
|
|
||||||
If no user is passed, do this for all users.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if ownerID is not None and not isinstance(ownerID, int):
|
def getRecentFits(ownerID=None, where=None, eager=None):
|
||||||
raise TypeError("OwnerID must be integer")
|
|
||||||
filter = Fit.booster == 1
|
|
||||||
if ownerID is not None:
|
|
||||||
filter = and_(filter, Fit.ownerID == ownerID)
|
|
||||||
|
|
||||||
filter = processWhere(filter, where)
|
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
fits = removeInvalid(saveddata_session.query(Fit).options(*eager).filter(filter).all())
|
q = select((
|
||||||
|
Fit.ID,
|
||||||
|
Fit.shipID,
|
||||||
|
Fit.name,
|
||||||
|
Fit.modified,
|
||||||
|
Fit.created,
|
||||||
|
Fit.timestamp,
|
||||||
|
Fit.notes
|
||||||
|
)).order_by(desc(Fit.modified), desc(Fit.timestamp)).limit(50)
|
||||||
|
fits = eos.db.saveddata_session.execute(q).fetchall()
|
||||||
|
|
||||||
return fits
|
return fits
|
||||||
|
|
||||||
|
|
||||||
|
def getFitsWithModules(typeIDs, eager=None):
|
||||||
|
"""
|
||||||
|
Get all the fits that have typeIDs fitted to them
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not hasattr(typeIDs, "__iter__"):
|
||||||
|
typeIDs = (typeIDs,)
|
||||||
|
|
||||||
|
eager = processEager(eager)
|
||||||
|
with sd_lock:
|
||||||
|
fits = removeInvalid(saveddata_session.query(Fit).join(Module).options(*eager).filter(Module.itemID.in_(typeIDs)).all())
|
||||||
|
|
||||||
|
return fits
|
||||||
|
|
||||||
|
|
||||||
def countAllFits():
|
def countAllFits():
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
count = saveddata_session.query(Fit).count()
|
count = saveddata_session.query(Fit).count()
|
||||||
return 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.
|
Get all the fits using a certain ship.
|
||||||
If no user is passed, do this for all users.
|
If no user is passed, do this for all users.
|
||||||
"""
|
"""
|
||||||
if isinstance(shipID, int):
|
if ownerID is not None and not isinstance(ownerID, int):
|
||||||
if ownerID is not None and not isinstance(ownerID, int):
|
raise TypeError("OwnerID must be integer")
|
||||||
raise TypeError("OwnerID must be integer")
|
|
||||||
filter = Fit.shipID == shipID
|
|
||||||
if ownerID is not None:
|
|
||||||
filter = and_(filter, Fit.ownerID == ownerID)
|
|
||||||
|
|
||||||
filter = processWhere(filter, where)
|
if isinstance(lookfor, int):
|
||||||
eager = processEager(eager)
|
filter = Fit.shipID == lookfor
|
||||||
with sd_lock:
|
elif isinstance(lookfor, list):
|
||||||
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
|
if len(lookfor) == 0:
|
||||||
|
return 0
|
||||||
|
filter = Fit.shipID.in_(lookfor)
|
||||||
else:
|
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
|
return count
|
||||||
|
|
||||||
|
|
||||||
def getFitList(eager=None):
|
def getFitList(eager=None):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
@@ -308,11 +318,6 @@ def getFitList(eager=None):
|
|||||||
|
|
||||||
return fits
|
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")
|
@cachedQuery(Price, 1, "typeID")
|
||||||
def getPrice(typeID):
|
def getPrice(typeID):
|
||||||
@@ -323,32 +328,58 @@ def getPrice(typeID):
|
|||||||
raise TypeError("Need integer as argument")
|
raise TypeError("Need integer as argument")
|
||||||
return price
|
return price
|
||||||
|
|
||||||
|
|
||||||
def clearPrices():
|
def clearPrices():
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
deleted_rows = saveddata_session.query(Price).delete()
|
deleted_rows = saveddata_session.query(Price).delete()
|
||||||
commit()
|
commit()
|
||||||
return deleted_rows
|
return deleted_rows
|
||||||
|
|
||||||
|
|
||||||
def getMiscData(field):
|
def getMiscData(field):
|
||||||
if isinstance(field, basestring):
|
if isinstance(field, str):
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
data = saveddata_session.query(MiscData).get(field)
|
data = saveddata_session.query(MiscData).get(field)
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need string as argument")
|
raise TypeError("Need string as argument")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def getDamagePatternList(eager=None):
|
def getDamagePatternList(eager=None):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
patterns = saveddata_session.query(DamagePattern).options(*eager).all()
|
patterns = saveddata_session.query(DamagePattern).options(*eager).all()
|
||||||
return patterns
|
return patterns
|
||||||
|
|
||||||
|
|
||||||
|
def clearDamagePatterns():
|
||||||
|
with sd_lock:
|
||||||
|
deleted_rows = saveddata_session.query(DamagePattern).filter(DamagePattern.name != 'Uniform').delete()
|
||||||
|
commit()
|
||||||
|
return deleted_rows
|
||||||
|
|
||||||
|
|
||||||
def getTargetResistsList(eager=None):
|
def getTargetResistsList(eager=None):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
patterns = saveddata_session.query(TargetResists).options(*eager).all()
|
patterns = saveddata_session.query(TargetResists).options(*eager).all()
|
||||||
return patterns
|
return patterns
|
||||||
|
|
||||||
|
|
||||||
|
def clearTargetResists():
|
||||||
|
with sd_lock:
|
||||||
|
deleted_rows = saveddata_session.query(TargetResists).delete()
|
||||||
|
commit()
|
||||||
|
return deleted_rows
|
||||||
|
|
||||||
|
|
||||||
|
def getImplantSetList(eager=None):
|
||||||
|
eager = processEager(eager)
|
||||||
|
with sd_lock:
|
||||||
|
sets = saveddata_session.query(ImplantSet).options(*eager).all()
|
||||||
|
return sets
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(DamagePattern, 1, "lookfor")
|
@cachedQuery(DamagePattern, 1, "lookfor")
|
||||||
def getDamagePattern(lookfor, eager=None):
|
def getDamagePattern(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -358,15 +389,18 @@ def getDamagePattern(lookfor, eager=None):
|
|||||||
else:
|
else:
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.ID == lookfor).first()
|
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(
|
||||||
elif isinstance(lookfor, basestring):
|
DamagePattern.ID == lookfor).first()
|
||||||
|
elif isinstance(lookfor, str):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
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:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return pattern
|
return pattern
|
||||||
|
|
||||||
|
|
||||||
@cachedQuery(TargetResists, 1, "lookfor")
|
@cachedQuery(TargetResists, 1, "lookfor")
|
||||||
def getTargetResists(lookfor, eager=None):
|
def getTargetResists(lookfor, eager=None):
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
@@ -376,22 +410,45 @@ def getTargetResists(lookfor, eager=None):
|
|||||||
else:
|
else:
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.ID == lookfor).first()
|
pattern = saveddata_session.query(TargetResists).options(*eager).filter(
|
||||||
elif isinstance(lookfor, basestring):
|
TargetResists.ID == lookfor).first()
|
||||||
|
elif isinstance(lookfor, str):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
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:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
return pattern
|
return pattern
|
||||||
|
|
||||||
|
|
||||||
|
@cachedQuery(ImplantSet, 1, "lookfor")
|
||||||
|
def getImplantSet(lookfor, eager=None):
|
||||||
|
if isinstance(lookfor, int):
|
||||||
|
if eager is None:
|
||||||
|
with sd_lock:
|
||||||
|
pattern = saveddata_session.query(ImplantSet).get(lookfor)
|
||||||
|
else:
|
||||||
|
eager = processEager(eager)
|
||||||
|
with sd_lock:
|
||||||
|
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(
|
||||||
|
TargetResists.ID == lookfor).first()
|
||||||
|
elif isinstance(lookfor, str):
|
||||||
|
eager = processEager(eager)
|
||||||
|
with sd_lock:
|
||||||
|
pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.name == lookfor).first()
|
||||||
|
else:
|
||||||
|
raise TypeError("Improper argument")
|
||||||
|
return pattern
|
||||||
|
|
||||||
|
|
||||||
def searchFits(nameLike, where=None, eager=None):
|
def searchFits(nameLike, where=None, eager=None):
|
||||||
if not isinstance(nameLike, basestring):
|
if not isinstance(nameLike, str):
|
||||||
raise TypeError("Need string as argument")
|
raise TypeError("Need string as argument")
|
||||||
# Prepare our string for request
|
# Prepare our string for request
|
||||||
nameLike = u"%{0}%".format(sqlizeString(nameLike))
|
nameLike = "%{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)
|
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
@@ -399,14 +456,6 @@ def searchFits(nameLike, where=None, eager=None):
|
|||||||
|
|
||||||
return fits
|
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):
|
def getProjectedFits(fitID):
|
||||||
if isinstance(fitID, int):
|
if isinstance(fitID, int):
|
||||||
@@ -417,63 +466,71 @@ def getProjectedFits(fitID):
|
|||||||
else:
|
else:
|
||||||
raise TypeError("Need integer as argument")
|
raise TypeError("Need integer as argument")
|
||||||
|
|
||||||
def getCrestCharacters(eager=None):
|
|
||||||
|
def getSsoCharacters(clientHash, eager=None):
|
||||||
eager = processEager(eager)
|
eager = processEager(eager)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
characters = saveddata_session.query(CrestChar).options(*eager).all()
|
characters = saveddata_session.query(SsoCharacter).filter(SsoCharacter.client == clientHash).options(*eager).all()
|
||||||
return characters
|
return characters
|
||||||
|
|
||||||
@cachedQuery(CrestChar, 1, "lookfor")
|
|
||||||
def getCrestCharacter(lookfor, eager=None):
|
@cachedQuery(SsoCharacter, 1, "lookfor", "clientHash")
|
||||||
|
def getSsoCharacter(lookfor, clientHash, eager=None):
|
||||||
|
filter = SsoCharacter.client == clientHash
|
||||||
|
|
||||||
if isinstance(lookfor, int):
|
if isinstance(lookfor, int):
|
||||||
if eager is None:
|
filter = and_(filter, SsoCharacter.ID == lookfor)
|
||||||
with sd_lock:
|
elif isinstance(lookfor, str):
|
||||||
character = saveddata_session.query(CrestChar).get(lookfor)
|
filter = and_(filter, SsoCharacter.characterName == lookfor)
|
||||||
else:
|
|
||||||
eager = processEager(eager)
|
|
||||||
with sd_lock:
|
|
||||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
|
|
||||||
elif isinstance(lookfor, basestring):
|
|
||||||
eager = processEager(eager)
|
|
||||||
with sd_lock:
|
|
||||||
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
|
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer or string as argument")
|
raise TypeError("Need integer or string as argument")
|
||||||
|
|
||||||
|
eager = processEager(eager)
|
||||||
|
with sd_lock:
|
||||||
|
character = saveddata_session.query(SsoCharacter).options(*eager).filter(filter).first()
|
||||||
|
|
||||||
return character
|
return character
|
||||||
|
|
||||||
|
|
||||||
def getOverrides(itemID, eager=None):
|
def getOverrides(itemID, eager=None):
|
||||||
if isinstance(itemID, int):
|
if isinstance(itemID, int):
|
||||||
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
|
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
|
||||||
else:
|
else:
|
||||||
raise TypeError("Need integer as argument")
|
raise TypeError("Need integer as argument")
|
||||||
|
|
||||||
|
|
||||||
def clearOverrides():
|
def clearOverrides():
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
deleted_rows = saveddata_session.query(Override).delete()
|
deleted_rows = saveddata_session.query(Override).delete()
|
||||||
commit()
|
commit()
|
||||||
return deleted_rows
|
return deleted_rows
|
||||||
|
|
||||||
|
|
||||||
def getAllOverrides(eager=None):
|
def getAllOverrides(eager=None):
|
||||||
return saveddata_session.query(Override).all()
|
return saveddata_session.query(Override).all()
|
||||||
|
|
||||||
|
|
||||||
def removeInvalid(fits):
|
def removeInvalid(fits):
|
||||||
invalids = [f for f in fits if f.isInvalid]
|
invalids = [f for f in fits if f.isInvalid]
|
||||||
|
|
||||||
if invalids:
|
if invalids:
|
||||||
map(fits.remove, invalids)
|
list(map(fits.remove, invalids))
|
||||||
map(saveddata_session.delete, invalids)
|
list(map(saveddata_session.delete, invalids))
|
||||||
saveddata_session.commit()
|
saveddata_session.commit()
|
||||||
|
|
||||||
return fits
|
return fits
|
||||||
|
|
||||||
|
|
||||||
def add(stuff):
|
def add(stuff):
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
saveddata_session.add(stuff)
|
saveddata_session.add(stuff)
|
||||||
|
|
||||||
|
|
||||||
def save(stuff):
|
def save(stuff):
|
||||||
add(stuff)
|
add(stuff)
|
||||||
commit()
|
commit()
|
||||||
|
|
||||||
|
|
||||||
def remove(stuff):
|
def remove(stuff):
|
||||||
removeCachedEntry(type(stuff), stuff.ID)
|
removeCachedEntry(type(stuff), stuff.ID)
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
@@ -483,5 +540,10 @@ def remove(stuff):
|
|||||||
|
|
||||||
def commit():
|
def commit():
|
||||||
with sd_lock:
|
with sd_lock:
|
||||||
saveddata_session.commit()
|
try:
|
||||||
saveddata_session.flush()
|
saveddata_session.commit()
|
||||||
|
saveddata_session.flush()
|
||||||
|
except Exception as ex:
|
||||||
|
saveddata_session.rollback()
|
||||||
|
exc_info = sys.exc_info()
|
||||||
|
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,17 +15,22 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, ForeignKey
|
from sqlalchemy import Table, Column, Integer, ForeignKey, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import Skill
|
from eos.saveddata.character import Skill
|
||||||
|
|
||||||
|
|
||||||
skills_table = Table("characterSkills", saveddata_meta,
|
skills_table = Table("characterSkills", saveddata_meta,
|
||||||
Column("characterID", ForeignKey("characters.ID"), primary_key = True, index = True),
|
Column("characterID", ForeignKey("characters.ID"), primary_key=True, index=True),
|
||||||
Column("itemID", Integer, primary_key = True),
|
Column("itemID", Integer, primary_key=True),
|
||||||
Column("_Skill__level", Integer, nullable = True))
|
Column("_Skill__level", Integer, nullable=True),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
mapper(Skill, skills_table)
|
mapper(Skill, skills_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2014 Ryan Holmes
|
# Copyright (C) 2014 Ryan Holmes
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,21 +15,25 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String
|
from sqlalchemy import Table, Column, Integer, Float, ForeignKey, String, DateTime
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import TargetResists
|
from eos.saveddata.targetResists import TargetResists
|
||||||
|
|
||||||
targetResists_table = Table("targetResists", saveddata_meta,
|
targetResists_table = Table("targetResists", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("name", String),
|
Column("name", String),
|
||||||
Column("emAmount", Float),
|
Column("emAmount", Float),
|
||||||
Column("thermalAmount", Float),
|
Column("thermalAmount", Float),
|
||||||
Column("kineticAmount", Float),
|
Column("kineticAmount", Float),
|
||||||
Column("explosiveAmount", Float),
|
Column("explosiveAmount", Float),
|
||||||
Column("ownerID", ForeignKey("users.ID"), nullable=True))
|
Column("ownerID", ForeignKey("users.ID"), nullable=True),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
mapper(TargetResists, targetResists_table)
|
mapper(TargetResists, targetResists_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,18 +15,18 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# 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, Boolean
|
||||||
from sqlalchemy.orm import mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.types import User
|
from eos.saveddata.user import User
|
||||||
|
|
||||||
users_table = Table("users", saveddata_meta,
|
users_table = Table("users", saveddata_meta,
|
||||||
Column("ID", Integer, primary_key = True),
|
Column("ID", Integer, primary_key=True),
|
||||||
Column("username", String, nullable = False, unique = True),
|
Column("username", String, nullable=False, unique=True),
|
||||||
Column("password", String, nullable = False),
|
Column("password", String, nullable=False),
|
||||||
Column("admin", Boolean, nullable = False))
|
Column("admin", Boolean, nullable=False))
|
||||||
|
|
||||||
mapper(User, users_table)
|
mapper(User, users_table)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,28 +15,31 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
from sqlalchemy.orm import eagerload
|
from sqlalchemy.orm import eagerload
|
||||||
from sqlalchemy.sql import and_
|
from sqlalchemy.sql import and_
|
||||||
|
|
||||||
replace = {"attributes": "_Item__attributes",
|
replace = {
|
||||||
"modules": "_Fit__modules",
|
"attributes" : "_Item__attributes",
|
||||||
"projectedModules": "_Fit__projectedModules",
|
"modules" : "_Fit__modules",
|
||||||
"boosters": "_Fit__boosters",
|
"projectedModules": "_Fit__projectedModules",
|
||||||
"drones": "_Fit__drones",
|
"boosters" : "_Fit__boosters",
|
||||||
"projectedDrones": "_Fit__projectedDrones",
|
"drones" : "_Fit__drones",
|
||||||
"implants": "_Fit__implants",
|
"projectedDrones" : "_Fit__projectedDrones",
|
||||||
"character": "_Fit__character",
|
"implants" : "_Fit__implants",
|
||||||
"damagePattern": "_Fit__damagePattern",
|
"character" : "_Fit__character",
|
||||||
"projectedFits": "_Fit__projectedFits"}
|
"damagePattern" : "_Fit__damagePattern",
|
||||||
|
"projectedFits" : "_Fit__projectedFits"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def processEager(eager):
|
def processEager(eager):
|
||||||
if eager == None:
|
if eager is None:
|
||||||
return tuple()
|
return tuple()
|
||||||
else:
|
else:
|
||||||
l = []
|
l = []
|
||||||
if isinstance(eager, basestring):
|
if isinstance(eager, str):
|
||||||
eager = (eager,)
|
eager = (eager,)
|
||||||
|
|
||||||
for e in eager:
|
for e in eager:
|
||||||
@@ -44,9 +47,10 @@ def processEager(eager):
|
|||||||
|
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
def _replacements(eagerString):
|
def _replacements(eagerString):
|
||||||
splitEager = eagerString.split(".")
|
splitEager = eagerString.split(".")
|
||||||
for i in xrange(len(splitEager)):
|
for i in range(len(splitEager)):
|
||||||
part = splitEager[i]
|
part = splitEager[i]
|
||||||
replacement = replace.get(part)
|
replacement = replace.get(part)
|
||||||
if replacement:
|
if replacement:
|
||||||
@@ -54,6 +58,7 @@ def _replacements(eagerString):
|
|||||||
|
|
||||||
return ".".join(splitEager)
|
return ".".join(splitEager)
|
||||||
|
|
||||||
|
|
||||||
def processWhere(clause, where):
|
def processWhere(clause, where):
|
||||||
if where is not None:
|
if where is not None:
|
||||||
if not hasattr(where, "__iter__"):
|
if not hasattr(where, "__iter__"):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
#
|
#
|
||||||
# This file is part of eos.
|
# This file is part of eos.
|
||||||
@@ -15,14 +15,12 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|
||||||
#from sqlalchemy.orm.attributes import flag_modified
|
from logbook import Logger
|
||||||
import eos.db
|
|
||||||
import eos.types
|
pyfalog = Logger(__name__)
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class HandledList(list):
|
class HandledList(list):
|
||||||
def filteredItemPreAssign(self, filter, *args, **kwargs):
|
def filteredItemPreAssign(self, filter, *args, **kwargs):
|
||||||
@@ -108,15 +106,16 @@ class HandledList(list):
|
|||||||
def remove(self, thing):
|
def remove(self, thing):
|
||||||
# We must flag it as modified, otherwise it not be removed from the database
|
# 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
|
# @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
|
if thing.isInvalid: # see GH issue #324
|
||||||
thing.itemID = 0
|
thing.itemID = 0
|
||||||
list.remove(self, thing)
|
list.remove(self, thing)
|
||||||
|
|
||||||
|
|
||||||
class HandledModuleList(HandledList):
|
class HandledModuleList(HandledList):
|
||||||
def append(self, mod):
|
def append(self, mod):
|
||||||
emptyPosition = float("Inf")
|
emptyPosition = float("Inf")
|
||||||
for i in xrange(len(self)):
|
for i in range(len(self)):
|
||||||
currMod = self[i]
|
currMod = self[i]
|
||||||
if currMod.isEmpty and not mod.isEmpty and currMod.slot == mod.slot:
|
if currMod.isEmpty and not mod.isEmpty and currMod.slot == mod.slot:
|
||||||
currPos = mod.position or i
|
currPos = mod.position or i
|
||||||
@@ -135,6 +134,7 @@ class HandledModuleList(HandledList):
|
|||||||
HandledList.append(self, mod)
|
HandledList.append(self, mod)
|
||||||
if mod.isInvalid:
|
if mod.isInvalid:
|
||||||
self.remove(mod)
|
self.remove(mod)
|
||||||
|
return
|
||||||
|
|
||||||
def insert(self, index, mod):
|
def insert(self, index, mod):
|
||||||
mod.position = index
|
mod.position = index
|
||||||
@@ -149,13 +149,13 @@ class HandledModuleList(HandledList):
|
|||||||
oldPos = mod.position
|
oldPos = mod.position
|
||||||
|
|
||||||
mod.position = None
|
mod.position = None
|
||||||
for i in xrange(oldPos, len(self)):
|
for i in range(oldPos, len(self)):
|
||||||
self[i].position -= 1
|
self[i].position -= 1
|
||||||
|
|
||||||
def toDummy(self, index):
|
def toDummy(self, index):
|
||||||
mod = self[index]
|
mod = self[index]
|
||||||
if not mod.isEmpty:
|
if not mod.isEmpty:
|
||||||
dummy = eos.types.Module.buildEmpty(mod.slot)
|
dummy = mod.buildEmpty(mod.slot)
|
||||||
dummy.position = index
|
dummy.position = index
|
||||||
self[index] = dummy
|
self[index] = dummy
|
||||||
|
|
||||||
@@ -164,10 +164,12 @@ class HandledModuleList(HandledList):
|
|||||||
self[index] = mod
|
self[index] = mod
|
||||||
|
|
||||||
def freeSlot(self, slot):
|
def freeSlot(self, slot):
|
||||||
for i in range(len(self) -1, -1, -1):
|
for i in range(len(self)):
|
||||||
mod = self[i]
|
mod = self[i]
|
||||||
if mod.getModifiedItemAttr("subSystemSlot") == slot:
|
if mod.getModifiedItemAttr("subSystemSlot") == slot:
|
||||||
del self[i]
|
self.toDummy(i)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
class HandledDroneCargoList(HandledList):
|
class HandledDroneCargoList(HandledList):
|
||||||
def find(self, item):
|
def find(self, item):
|
||||||
@@ -185,6 +187,7 @@ class HandledDroneCargoList(HandledList):
|
|||||||
if thing.isInvalid:
|
if thing.isInvalid:
|
||||||
self.remove(thing)
|
self.remove(thing)
|
||||||
|
|
||||||
|
|
||||||
class HandledImplantBoosterList(HandledList):
|
class HandledImplantBoosterList(HandledList):
|
||||||
def append(self, thing):
|
def append(self, thing):
|
||||||
if thing.isInvalid:
|
if thing.isInvalid:
|
||||||
@@ -195,12 +198,23 @@ class HandledImplantBoosterList(HandledList):
|
|||||||
# if needed, remove booster that was occupying slot
|
# if needed, remove booster that was occupying slot
|
||||||
oldObj = next((m for m in self if m.slot == thing.slot), None)
|
oldObj = next((m for m in self if m.slot == thing.slot), None)
|
||||||
if oldObj:
|
if oldObj:
|
||||||
logging.info("Slot %d occupied with %s, replacing with %s", thing.slot, oldObj.item.name, thing.item.name)
|
pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", thing.slot, oldObj.item.name, thing.item.name)
|
||||||
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
|
oldObj.itemID = 0 # hack to remove from DB. See GH issue #324
|
||||||
self.remove(oldObj)
|
self.remove(oldObj)
|
||||||
|
|
||||||
HandledList.append(self, thing)
|
HandledList.append(self, thing)
|
||||||
|
|
||||||
|
|
||||||
|
class HandledSsoCharacterList(list):
|
||||||
|
def append(self, character):
|
||||||
|
old = next((x for x in self if x.client == character.client), None)
|
||||||
|
if old is not None:
|
||||||
|
pyfalog.warning("Removing SSO Character with same hash: {}".format(repr(old)))
|
||||||
|
list.remove(self, old)
|
||||||
|
|
||||||
|
list.append(self, character)
|
||||||
|
|
||||||
|
|
||||||
class HandledProjectedModList(HandledList):
|
class HandledProjectedModList(HandledList):
|
||||||
def append(self, proj):
|
def append(self, proj):
|
||||||
if proj.isInvalid:
|
if proj.isInvalid:
|
||||||
@@ -218,7 +232,7 @@ class HandledProjectedModList(HandledList):
|
|||||||
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
oldEffect = next((m for m in self if m.item.group.name == "Effect Beacon"), None)
|
||||||
|
|
||||||
if oldEffect:
|
if oldEffect:
|
||||||
logging.info("System effect occupied with %s, replacing with %s", oldEffect.item.name, proj.item.name)
|
pyfalog.info("System effect occupied with {0}, replacing with {1}", oldEffect.item.name, proj.item.name)
|
||||||
self.remove(oldEffect)
|
self.remove(oldEffect)
|
||||||
|
|
||||||
HandledList.append(self, proj)
|
HandledList.append(self, proj)
|
||||||
@@ -227,6 +241,7 @@ class HandledProjectedModList(HandledList):
|
|||||||
if not proj.item.isType("projected") and not isSystemEffect:
|
if not proj.item.isType("projected") and not isSystemEffect:
|
||||||
self.remove(proj)
|
self.remove(proj)
|
||||||
|
|
||||||
|
|
||||||
class HandledProjectedDroneList(HandledDroneCargoList):
|
class HandledProjectedDroneList(HandledDroneCargoList):
|
||||||
def append(self, proj):
|
def append(self, proj):
|
||||||
proj.projected = True
|
proj.projected = True
|
||||||
@@ -236,6 +251,7 @@ class HandledProjectedDroneList(HandledDroneCargoList):
|
|||||||
if proj.isInvalid or not proj.item.isType("projected"):
|
if proj.isInvalid or not proj.item.isType("projected"):
|
||||||
self.remove(proj)
|
self.remove(proj)
|
||||||
|
|
||||||
|
|
||||||
class HandledItem(object):
|
class HandledItem(object):
|
||||||
def preAssignItemAttr(self, *args, **kwargs):
|
def preAssignItemAttr(self, *args, **kwargs):
|
||||||
self.itemModifiedAttributes.preAssign(*args, **kwargs)
|
self.itemModifiedAttributes.preAssign(*args, **kwargs)
|
||||||
@@ -252,6 +268,7 @@ class HandledItem(object):
|
|||||||
def forceItemAttr(self, *args, **kwargs):
|
def forceItemAttr(self, *args, **kwargs):
|
||||||
self.itemModifiedAttributes.force(*args, **kwargs)
|
self.itemModifiedAttributes.force(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class HandledCharge(object):
|
class HandledCharge(object):
|
||||||
def preAssignChargeAttr(self, *args, **kwargs):
|
def preAssignChargeAttr(self, *args, **kwargs):
|
||||||
self.chargeModifiedAttributes.preAssign(*args, **kwargs)
|
self.chargeModifiedAttributes.preAssign(*args, **kwargs)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#===============================================================================
|
# ===============================================================================
|
||||||
# Copyright (C) 2010 Diego Duclos
|
# Copyright (C) 2010 Diego Duclos
|
||||||
# 2010 Anton Vorobyov
|
# 2010 Anton Vorobyov
|
||||||
#
|
#
|
||||||
@@ -16,4 +16,4 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#===============================================================================
|
# ===============================================================================
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
# Used by:
|
# Used by:
|
||||||
# Modules named like: Dynamic Fuel Valve (8 of 8)
|
# Modules named like: Dynamic Fuel Valve (8 of 8)
|
||||||
type = "passive"
|
type = "passive"
|
||||||
|
|
||||||
|
|
||||||
def handler(fit, container, context):
|
def handler(fit, container, context):
|
||||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||||
"capacitorNeed", container.getModifiedItemAttr("capNeedBonus"))
|
"capacitorNeed", container.getModifiedItemAttr("capNeedBonus"))
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
# Implant: Zor's Custom Navigation Hyper-Link
|
# Implant: Zor's Custom Navigation Hyper-Link
|
||||||
# Skill: Acceleration Control
|
# Skill: Acceleration Control
|
||||||
type = "passive"
|
type = "passive"
|
||||||
|
|
||||||
|
|
||||||
def handler(fit, container, context):
|
def handler(fit, container, context):
|
||||||
level = container.level if "skill" in context else 1
|
level = container.level if "skill" in context else 1
|
||||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
# Used by:
|
# Used by:
|
||||||
# Implants named like: Eifyr and Co. 'Rogue' Acceleration Control AC (6 of 6)
|
# Implants named like: Eifyr and Co. 'Rogue' Acceleration Control AC (6 of 6)
|
||||||
type = "passive"
|
type = "passive"
|
||||||
|
|
||||||
|
|
||||||
def handler(fit, implant, context):
|
def handler(fit, implant, context):
|
||||||
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Propulsion Module",
|
||||||
"speedFactor", implant.getModifiedItemAttr("speedFBonus"))
|
"speedFactor", implant.getModifiedItemAttr("speedFBonus"))
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
# Implant: Poteque 'Prospector' Archaeology AC-905
|
# Implant: Poteque 'Prospector' Archaeology AC-905
|
||||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||||
type = "passive"
|
type = "passive"
|
||||||
|
|
||||||
|
|
||||||
def handler(fit, container, context):
|
def handler(fit, container, context):
|
||||||
fit.modules.filteredItemIncrease(lambda module: module.item.requiresSkill("Archaeology"),
|
fit.modules.filteredItemIncrease(lambda module: module.item.requiresSkill("Archaeology"),
|
||||||
"accessDifficultyBonus",
|
"accessDifficultyBonus",
|
||||||
|
|||||||
@@ -2,10 +2,13 @@
|
|||||||
#
|
#
|
||||||
# Used by:
|
# Used by:
|
||||||
# Modules named like: Memetic Algorithm Bank (8 of 8)
|
# Modules named like: Memetic Algorithm Bank (8 of 8)
|
||||||
|
# Implant: Neural Lace 'Blackglass' Net Intrusion 920-40
|
||||||
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
# Implant: Poteque 'Prospector' Environmental Analysis EY-1005
|
||||||
# Implant: Poteque 'Prospector' Hacking HC-905
|
# Implant: Poteque 'Prospector' Hacking HC-905
|
||||||
type = "passive"
|
type = "passive"
|
||||||
|
|
||||||
|
|
||||||
def handler(fit, container, context):
|
def handler(fit, container, context):
|
||||||
fit.modules.filteredItemIncrease(lambda c: c.item.requiresSkill("Hacking"),
|
fit.modules.filteredItemIncrease(lambda c: c.item.requiresSkill("Hacking"),
|
||||||
"accessDifficultyBonus",
|
"accessDifficultyBonus",
|
||||||
container.getModifiedItemAttr("accessDifficultyBonusModifier"), position="post")
|
container.getModifiedItemAttr("accessDifficultyBonusModifier"), position="post")
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user