Compare commits
593 Commits
feature/fi
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
1518685848 | 8 years ago |
|
|
d244cac2fa | 8 years ago |
|
|
362bf6dd53 | 8 years ago |
|
|
9b5700a51a | 8 years ago |
|
|
fdaa98ec94 | 8 years ago |
|
|
782aa02c28 | 8 years ago |
|
|
c27e7462b4 | 8 years ago |
|
|
390a7f5de4 | 8 years ago |
|
|
ff02ba5b16 | 8 years ago |
|
|
a4132dacd1 | 8 years ago |
|
|
4850676b6f | 8 years ago |
|
|
d8e641343d | 8 years ago |
|
|
4bf5a28dfd | 8 years ago |
|
|
4652d67c37 | 8 years ago |
|
|
b866f0e7cc | 8 years ago |
|
|
6d879fe871 | 8 years ago |
|
|
25a4de0ed0 | 8 years ago |
|
|
ad10e269d8 | 8 years ago |
|
|
713e878a25 | 8 years ago |
|
|
248c430ffa | 8 years ago |
|
|
a2ab9a9119 | 8 years ago |
|
|
fed96bda41 | 8 years ago |
|
|
713649c90c | 8 years ago |
|
|
6758de45bc | 8 years ago |
|
|
b299f4cef9 | 8 years ago |
|
|
74d93d00d3 | 8 years ago |
|
|
17bc7be7d5 | 8 years ago |
|
|
c01faff08b | 8 years ago |
|
|
6d3fd541e3 | 8 years ago |
|
|
5f40593093 | 8 years ago |
|
|
1db666208a | 8 years ago |
|
|
55629451c8 | 8 years ago |
|
|
5e968a09ed | 8 years ago |
|
|
df8d6b5b51 | 8 years ago |
|
|
9302a2aeaa | 8 years ago |
|
|
90d8acd615 | 8 years ago |
|
|
a6d279183f | 8 years ago |
|
|
da3992c341 | 8 years ago |
|
|
493e5decc8 | 8 years ago |
|
|
bf454987d9 | 8 years ago |
|
|
2f4c1c8c72 | 8 years ago |
|
|
a78149c805 | 8 years ago |
|
|
6e1cc14cbf | 8 years ago |
|
|
0b234bf4e0 | 8 years ago |
|
|
c053a0efc9 | 8 years ago |
|
|
557a343155 | 8 years ago |
|
|
e9580c4d5d | 8 years ago |
|
|
79ca9ba502 | 8 years ago |
|
|
76d357ef3f | 8 years ago |
|
|
6c5deb32b8 | 8 years ago |
|
|
d5dc62a46c | 8 years ago |
|
|
857fc5c99f | 8 years ago |
|
|
cd0df8232f | 8 years ago |
|
|
983d92b7a8 | 8 years ago |
|
|
3ec1a5ffad | 8 years ago |
|
|
cb33ac7890 | 8 years ago |
|
|
8bc648feaa | 8 years ago |
|
|
246db4d134 | 8 years ago |
|
|
45ddda45c2 | 8 years ago |
|
|
68e7aa0257 | 8 years ago |
|
|
02032f3907 | 8 years ago |
|
|
370de428f3 | 8 years ago |
|
|
7e0a513056 | 8 years ago |
|
|
e238a72eed | 8 years ago |
|
|
3f12eac7d7 | 8 years ago |
|
|
422b98f2d7 | 8 years ago |
|
|
9db3582b83 | 8 years ago |
|
|
10a40fac71 | 8 years ago |
|
|
30bfc69ab7 | 8 years ago |
|
|
3a7b3825f7 | 8 years ago |
|
|
a81642a530 | 8 years ago |
|
|
7031294f13 | 8 years ago |
|
|
e9bd627f57 | 8 years ago |
|
|
60aaaafb04 | 8 years ago |
|
|
6f0c6500a5 | 8 years ago |
|
|
a674bbe3ff | 8 years ago |
|
|
a05f4e4151 | 8 years ago |
|
|
566ad12866 | 8 years ago |
|
|
ece11c0dd6 | 8 years ago |
|
|
1989045af4 | 8 years ago |
|
|
ca0cc861fd | 8 years ago |
|
|
4406bc91f7 | 8 years ago |
|
|
30343178cc | 8 years ago |
|
|
765d83d8fe | 8 years ago |
|
|
d1cbee1cae | 8 years ago |
|
|
1cd912d483 | 8 years ago |
|
|
ab1529ea95 | 8 years ago |
|
|
b7ff53b5be | 8 years ago |
|
|
efa2f6037b | 8 years ago |
|
|
fb99799ec3 | 8 years ago |
|
|
c17935b3ad | 8 years ago |
|
|
861a4b2598 | 8 years ago |
|
|
ffd8c3cef1 | 8 years ago |
|
|
07401183a9 | 8 years ago |
|
|
496244cbe9 | 8 years ago |
|
|
a252a7c316 | 8 years ago |
|
|
81974e7c2c | 8 years ago |
|
|
031fec5f8d | 8 years ago |
|
|
8329c9d398 | 8 years ago |
|
|
e9c7cdf90e | 8 years ago |
|
|
6b6d987a48 | 8 years ago |
|
|
081353eed1 | 8 years ago |
|
|
1f047201f4 | 8 years ago |
|
|
78271b9176 | 8 years ago |
|
|
e0991bf7cd | 8 years ago |
|
|
57678227b7 | 8 years ago |
|
|
f83206db67 | 8 years ago |
|
|
87d37636e5 | 8 years ago |
|
|
49bc0da9ca | 8 years ago |
|
|
2ab0a525bb | 8 years ago |
|
|
aa6dca7138 | 8 years ago |
|
|
8d77f0bcef | 8 years ago |
|
|
94d9cfb460 | 8 years ago |
|
|
1e46979271 | 8 years ago |
|
|
e4a148d383 | 8 years ago |
|
|
ec86ec1316 | 8 years ago |
|
|
16d87160b5 | 8 years ago |
|
|
5b56a3c1ca | 8 years ago |
|
|
27400b3fa9 | 8 years ago |
|
|
0274c62c09 | 8 years ago |
|
|
6ccf164f49 | 8 years ago |
|
|
54412f7a56 | 8 years ago |
|
|
7e888ef3ec | 8 years ago |
|
|
1f3f547960 | 8 years ago |
|
|
1e4f69ef5b | 8 years ago |
|
|
f6cee6f168 | 8 years ago |
|
|
2a2c10a4a7 | 8 years ago |
|
|
e66c95949e | 8 years ago |
|
|
e1869b3407 | 8 years ago |
|
|
d86cdb253d | 8 years ago |
|
|
e67eb93f5b | 8 years ago |
|
|
396af1d044 | 8 years ago |
|
|
79eb12c6b1 | 8 years ago |
|
|
712a25fc3e | 8 years ago |
|
|
b4eef66cbd | 8 years ago |
|
|
8168850346 | 8 years ago |
|
|
1da0840d6b | 8 years ago |
|
|
dee52931f4 | 8 years ago |
|
|
1af60a058f | 8 years ago |
|
|
959445d23e | 8 years ago |
|
|
8bd2d82f0a | 8 years ago |
|
|
e55250a541 | 8 years ago |
|
|
5457fd8288 | 8 years ago |
|
|
33e823c204 | 8 years ago |
|
|
86e3ec3ae8 | 8 years ago |
|
|
3a38c745a1 | 8 years ago |
|
|
a6edceb9b6 | 8 years ago |
|
|
6102965a77 | 8 years ago |
|
|
4dc4a23040 | 8 years ago |
|
|
a4302d675e | 8 years ago |
|
|
d522908092 | 8 years ago |
|
|
a4df17bf44 | 8 years ago |
|
|
9259cb8ddb | 8 years ago |
|
|
d188f5fbe2 | 8 years ago |
|
|
91a8f13e6a | 8 years ago |
|
|
b6c9bfde27 | 8 years ago |
|
|
b32750ff21 | 8 years ago |
|
|
755c4e9aba | 8 years ago |
|
|
d4a4abea53 | 8 years ago |
|
|
ecdb763a97 | 8 years ago |
|
|
fe24836086 | 8 years ago |
|
|
1d080bbb04 | 8 years ago |
|
|
535557aabc | 8 years ago |
|
|
385928bd54 | 8 years ago |
|
|
54f02b5dc9 | 8 years ago |
|
|
cce1109c19 | 8 years ago |
|
|
5be5f6ecf7 | 8 years ago |
|
|
2db52b412a | 8 years ago |
|
|
a63a40eefd | 8 years ago |
|
|
7d268ba268 | 8 years ago |
|
|
bee7aa0543 | 8 years ago |
|
|
bd6f4f9611 | 8 years ago |
|
|
d9cb7d047f | 8 years ago |
|
|
b5167beb04 | 8 years ago |
|
|
fa13c04d03 | 8 years ago |
|
|
60283a5199 | 8 years ago |
|
|
eb68769e7e | 8 years ago |
|
|
dd4b4d18b5 | 8 years ago |
|
|
a9e9957563 | 8 years ago |
|
|
c2ff3a2859 | 8 years ago |
|
|
c5182cb581 | 8 years ago |
|
|
ddac3c990d | 8 years ago |
|
|
e259b90908 | 8 years ago |
|
|
e19a813c9e | 8 years ago |
|
|
b959463376 | 8 years ago |
|
|
5336c2c487 | 8 years ago |
|
|
5f1e130200 | 8 years ago |
|
|
922430124e | 8 years ago |
|
|
c398426fea | 8 years ago |
|
|
c500405271 | 8 years ago |
|
|
79591f16d2 | 8 years ago |
|
|
19333f4249 | 8 years ago |
|
|
d2c8e14668 | 8 years ago |
|
|
1c52a1a3cf | 8 years ago |
|
|
8499ce7860 | 8 years ago |
|
|
5472ee6ef4 | 8 years ago |
|
|
141bbb47eb | 8 years ago |
|
|
c1149e2c00 | 8 years ago |
|
|
e324426bf9 | 8 years ago |
|
|
846cdf8bd9 | 8 years ago |
|
|
f68df6ba35 | 8 years ago |
|
|
64442b7ca4 | 8 years ago |
|
|
19a460853b | 8 years ago |
|
|
cf07fde91a | 8 years ago |
|
|
c633413d1c | 8 years ago |
|
|
d898ab95ee | 8 years ago |
|
|
c9c7400259 | 8 years ago |
|
|
8ae4d09a3d | 8 years ago |
|
|
b697fa7ff7 | 8 years ago |
|
|
73d62c897d | 8 years ago |
|
|
06ef42dc1c | 8 years ago |
|
|
cbef6e6fd1 | 8 years ago |
|
|
5bacd40631 | 8 years ago |
|
|
a8657d8b5a | 8 years ago |
|
|
706c376114 | 8 years ago |
|
|
79f9b02260 | 8 years ago |
|
|
9495dcfcf0 | 8 years ago |
|
|
419f50c138 | 8 years ago |
|
|
ed61ad23b2 | 8 years ago |
|
|
4bb02cf404 | 8 years ago |
|
|
149e4d67e7 | 8 years ago |
|
|
dfbf23a3b2 | 8 years ago |
|
|
ad2ed57f25 | 8 years ago |
|
|
d3c79bb776 | 8 years ago |
|
|
846dbe0c4e | 8 years ago |
|
|
4f0a7c24f1 | 8 years ago |
|
|
71a370d47f | 8 years ago |
|
|
8da89783ae | 8 years ago |
|
|
5401144913 | 8 years ago |
|
|
9575a63088 | 8 years ago |
|
|
a7b402b3c0 | 8 years ago |
|
|
3812dd75c6 | 8 years ago |
|
|
8b6b1f3de7 | 8 years ago |
|
|
04865e46a4 | 8 years ago |
|
|
71bc1c2e15 | 8 years ago |
|
|
f023fa9d77 | 8 years ago |
|
|
08341cc22f | 8 years ago |
|
|
a01deaf5b6 | 8 years ago |
|
|
f4fccb520b | 8 years ago |
|
|
9e6e0534d7 | 8 years ago |
|
|
da12a18e98 | 8 years ago |
|
|
649da1414e | 8 years ago |
|
|
8dc230673b | 8 years ago |
|
|
cb019e9bb7 | 8 years ago |
|
|
68950d25ed | 8 years ago |
|
|
5e8b6a8c1b | 8 years ago |
|
|
6f711d1ffd | 8 years ago |
|
|
b9871d417a | 8 years ago |
|
|
ff2e308aa4 | 8 years ago |
|
|
0f9b20767c | 8 years ago |
|
|
6414be8541 | 8 years ago |
|
|
f7ead49ac0 | 8 years ago |
|
|
0910b8f4b6 | 8 years ago |
|
|
4d9c9b25cc | 8 years ago |
|
|
5fa5bc11d4 | 8 years ago |
|
|
2f7dc5384e | 8 years ago |
|
|
88e5495b7a | 8 years ago |
|
|
f6d2d947a1 | 8 years ago |
|
|
712c5fe9ac | 8 years ago |
|
|
a4a1f0171f | 8 years ago |
|
|
a49689ce81 | 8 years ago |
|
|
548645fb7f | 8 years ago |
|
|
91d575815c | 8 years ago |
|
|
f4204913b2 | 8 years ago |
|
|
9de142751a | 8 years ago |
|
|
3d1ab96d51 | 8 years ago |
|
|
6178f6b7e8 | 8 years ago |
|
|
55eaf91875 | 8 years ago |
|
|
e647cadc91 | 8 years ago |
|
|
309e513bb5 | 8 years ago |
|
|
a4cbc484c9 | 8 years ago |
|
|
861ec28559 | 8 years ago |
|
|
3df32909e2 | 8 years ago |
|
|
8a15099464 | 8 years ago |
|
|
aacd041543 | 8 years ago |
|
|
3e55aca89c | 8 years ago |
|
|
f3526352cd | 8 years ago |
|
|
432f52255d | 8 years ago |
|
|
da6331c8b8 | 8 years ago |
|
|
f3bc397b99 | 8 years ago |
|
|
a224a60d72 | 8 years ago |
|
|
ef5baf777a | 8 years ago |
|
|
82926708b7 | 8 years ago |
|
|
91f9fdde67 | 8 years ago |
|
|
d1bccffaee | 8 years ago |
|
|
a609141dd4 | 8 years ago |
|
|
3ab14c1404 | 8 years ago |
|
|
19e5565c0a | 8 years ago |
|
|
af7e8f64b6 | 8 years ago |
|
|
684e255f90 | 8 years ago |
|
|
c0b6d529bb | 8 years ago |
|
|
fef04d9ae1 | 8 years ago |
|
|
11aa0e2b20 | 8 years ago |
|
|
031ab8914e | 8 years ago |
|
|
c67385c21c | 8 years ago |
|
|
866855ddd2 | 8 years ago |
|
|
6cf99a0a7e | 8 years ago |
|
|
610500446a | 8 years ago |
|
|
fc76f58f17 | 8 years ago |
|
|
b815f04472 | 8 years ago |
|
|
f027b109a5 | 8 years ago |
|
|
7bf6eca3c4 | 8 years ago |
|
|
32e76a32a8 | 8 years ago |
|
|
cbb20966cc | 8 years ago |
|
|
08b4a28e6e | 8 years ago |
|
|
3976bbf2ff | 8 years ago |
|
|
2239a94edf | 8 years ago |
|
|
7506946cd4 | 8 years ago |
|
|
55ace09705 | 8 years ago |
|
|
6c61b81e13 | 8 years ago |
|
|
d7e89aff1d | 8 years ago |
|
|
82d81344e4 | 8 years ago |
|
|
11c7f750d0 | 8 years ago |
|
|
a3a5011a06 | 8 years ago |
|
|
52ff5e6681 | 8 years ago |
|
|
b79883cee4 | 8 years ago |
|
|
8c4aec26fa | 8 years ago |
|
|
21f576b188 | 8 years ago |
|
|
29ec341c47 | 8 years ago |
|
|
a0fc46bdb2 | 8 years ago |
|
|
0754ec2dfc | 8 years ago |
|
|
53441959d8 | 8 years ago |
|
|
63ccf9f085 | 8 years ago |
|
|
cd7dfed780 | 8 years ago |
|
|
77bcaa95f6 | 8 years ago |
|
|
36e2c162b2 | 8 years ago |
|
|
71fd94d61f | 8 years ago |
|
|
e6d4988b9e | 8 years ago |
|
|
6ea7cf3b9a | 8 years ago |
|
|
8673fd6ad3 | 8 years ago |
|
|
9293ae5697 | 8 years ago |
|
|
36fce7172c | 8 years ago |
|
|
eebc1397b8 | 8 years ago |
|
|
b6ada6ebbf | 8 years ago |
|
|
3c28c27bd5 | 8 years ago |
|
|
07e02ca1a2 | 8 years ago |
|
|
9364171ac0 | 8 years ago |
|
|
641842e1b1 | 8 years ago |
|
|
b4d4402c73 | 8 years ago |
|
|
bb8c4b20c2 | 8 years ago |
|
|
2fb8c17f97 | 8 years ago |
|
|
f1b91d347e | 8 years ago |
|
|
6452b5642e | 8 years ago |
|
|
05c825c469 | 8 years ago |
|
|
a11d6c698f | 8 years ago |
|
|
954bb35d1a | 8 years ago |
|
|
524c94f15c | 8 years ago |
|
|
19021a4eab | 8 years ago |
|
|
a57bc94288 | 8 years ago |
|
|
02c4bf178b | 8 years ago |
|
|
53cb094345 | 8 years ago |
|
|
995c3702fc | 8 years ago |
|
|
8db06d2096 | 8 years ago |
|
|
8da2c4205d | 8 years ago |
|
|
197b1af506 | 8 years ago |
|
|
fc5cfcc77a | 8 years ago |
|
|
fa7261821c | 8 years ago |
|
|
7053050520 | 8 years ago |
|
|
52d7244e9f | 8 years ago |
|
|
0adfde03b4 | 8 years ago |
|
|
c56fc877df | 8 years ago |
|
|
256a017d77 | 8 years ago |
|
|
35c0f4c591 | 8 years ago |
|
|
44ac7ddf0e | 8 years ago |
|
|
a3d4d2b1fb | 8 years ago |
|
|
fad1ac9b04 | 8 years ago |
|
|
4c739c9b3c | 8 years ago |
|
|
eda8a29e53 | 8 years ago |
|
|
084d866172 | 8 years ago |
|
|
27a68857b5 | 8 years ago |
|
|
49760d62e4 | 8 years ago |
|
|
6de90bb286 | 8 years ago |
|
|
c708310e43 | 8 years ago |
|
|
f265006d98 | 8 years ago |
|
|
c27f4fb103 | 8 years ago |
|
|
aa3128b718 | 8 years ago |
|
|
dbbcb508bc | 8 years ago |
|
|
118745d30f | 8 years ago |
|
|
543410d92c | 8 years ago |
|
|
8f61bdc5b1 | 8 years ago |
|
|
c8f65dc71a | 8 years ago |
|
|
b9eb5c552d | 8 years ago |
|
|
f9e17885d5 | 8 years ago |
|
|
5bd0e0bb13 | 8 years ago |
|
|
334321cd1e | 8 years ago |
|
|
ab411b615f | 8 years ago |
|
|
9fbaed714b | 8 years ago |
|
|
5981e69f4d | 8 years ago |
|
|
bdc7243921 | 8 years ago |
|
|
cfe82db713 | 8 years ago |
|
|
95b9f40a9f | 8 years ago |
|
|
ef3e132431 | 8 years ago |
|
|
6484330fff | 8 years ago |
|
|
cc6528d755 | 8 years ago |
|
|
be41248e3d | 8 years ago |
|
|
e458765e54 | 8 years ago |
|
|
183c209db5 | 8 years ago |
|
|
f997850145 | 8 years ago |
|
|
ee1c7f9296 | 8 years ago |
|
|
f94288868c | 8 years ago |
|
|
c2eff111fa | 8 years ago |
|
|
c1ae87835b | 8 years ago |
|
|
0c9e23a5d8 | 8 years ago |
|
|
fa75dcf908 | 8 years ago |
|
|
5084828565 | 8 years ago |
|
|
3089617c0b | 8 years ago |
|
|
7560c09b87 | 8 years ago |
|
|
0bf4ef6ace | 8 years ago |
|
|
29c48f15b3 | 8 years ago |
|
|
3cf3888961 | 8 years ago |
|
|
a7e9dd4e4b | 8 years ago |
|
|
66bfc57c15 | 8 years ago |
|
|
0b1409e45d | 8 years ago |
|
|
9bb5971ecd | 8 years ago |
|
|
bafa4d1069 | 8 years ago |
|
|
5096fc0233 | 8 years ago |
|
|
f2f0f8cc44 | 8 years ago |
|
|
3679d31293 | 8 years ago |
|
|
80cc25a92a | 8 years ago |
|
|
eabc1745d1 | 8 years ago |
|
|
d718f99915 | 8 years ago |
|
|
91c0073856 | 8 years ago |
|
|
8972d465ed | 8 years ago |
|
|
25b98cdc2c | 8 years ago |
|
|
4892dd8a1b | 8 years ago |
|
|
368b715125 | 8 years ago |
|
|
6bb57c371d | 8 years ago |
|
|
fc647e1eeb | 8 years ago |
|
|
5249fb219d | 8 years ago |
|
|
020ca8a79a | 8 years ago |
|
|
1a0aeca720 | 8 years ago |
|
|
f2e0d062a5 | 8 years ago |
|
|
2ceb8ac8f4 | 8 years ago |
|
|
bec31b7428 | 8 years ago |
|
|
c9e9a5611a | 8 years ago |
|
|
59c8484362 | 8 years ago |
|
|
4bef5341e0 | 8 years ago |
|
|
8dd2ff5124 | 8 years ago |
|
|
4d5a41779b | 8 years ago |
|
|
f122227418 | 8 years ago |
|
|
638c917b45 | 8 years ago |
|
|
3d0953cff6 | 8 years ago |
|
|
d88519d0f7 | 8 years ago |
|
|
a1f12c9d28 | 8 years ago |
|
|
9981fec18e | 8 years ago |
|
|
a807842958 | 8 years ago |
|
|
7237ad35dc | 8 years ago |
|
|
0631688de8 | 8 years ago |
|
|
7742b3d4eb | 8 years ago |
|
|
0349885dae | 8 years ago |
|
|
c9962206c2 | 8 years ago |
|
|
e3a259a50b | 8 years ago |
|
|
8f733b95cc | 8 years ago |
|
|
a5ce058b4c | 8 years ago |
|
|
d081e3f890 | 8 years ago |
|
|
f9ece0d0ac | 8 years ago |
|
|
2b9ef4f081 | 8 years ago |
|
|
6251badfea | 8 years ago |
|
|
96605cd319 | 8 years ago |
|
|
298128069d | 8 years ago |
|
|
d7d32e1a07 | 8 years ago |
|
|
b30a4e5405 | 8 years ago |
|
|
068e892e98 | 8 years ago |
|
|
eb0712a1d9 | 8 years ago |
|
|
d7b88ad59c | 8 years ago |
|
|
191b314709 | 8 years ago |
|
|
05965cc728 | 8 years ago |
|
|
9cb2c704eb | 8 years ago |
|
|
d1a00260d9 | 8 years ago |
|
|
ce535aca4d | 8 years ago |
|
|
85ac17b576 | 8 years ago |
|
|
aca4e00c17 | 8 years ago |
|
|
5aa8bfefa4 | 8 years ago |
|
|
6a767093ba | 8 years ago |
|
|
fb1f851981 | 8 years ago |
|
|
57ee5a588d | 8 years ago |
|
|
feb024a629 | 8 years ago |
|
|
a2ebf436d4 | 8 years ago |
|
|
a94f0d9c62 | 8 years ago |
|
|
3e3cb74b86 | 8 years ago |
|
|
5de066244d | 8 years ago |
|
|
01c211700e | 8 years ago |
|
|
eba4ba461b | 8 years ago |
|
|
0d57f4a77d | 8 years ago |
|
|
012c2150c6 | 8 years ago |
|
|
6058f1777c | 8 years ago |
|
|
9ccf0af150 | 8 years ago |
|
|
8cc85637f5 | 8 years ago |
|
|
f04c4471dd | 8 years ago |
|
|
1891fbbc7d | 8 years ago |
|
|
dfae514fe4 | 8 years ago |
|
|
17b6ba0256 | 8 years ago |
|
|
58cd2dae27 | 8 years ago |
|
|
bbbb8bb6f2 | 8 years ago |
|
|
2a74038074 | 8 years ago |
|
|
3edad835e7 | 8 years ago |
|
|
b12e0ef56e | 8 years ago |
|
|
c26103bd61 | 8 years ago |
|
|
bb595cb12e | 8 years ago |
|
|
2b4ae43b29 | 8 years ago |
|
|
542ef29b95 | 8 years ago |
|
|
0936a2db8d | 8 years ago |
|
|
5b18561aa4 | 8 years ago |
|
|
1470c34980 | 8 years ago |
|
|
958f8e4a14 | 8 years ago |
|
|
a14a11bde7 | 8 years ago |
|
|
fef2591e99 | 8 years ago |
|
|
1e917332dd | 8 years ago |
|
|
243ea74bab | 8 years ago |
|
|
11fce2f2fb | 8 years ago |
|
|
3ef091fced | 8 years ago |
|
|
9b9523f760 | 8 years ago |
|
|
2732f6cee6 | 8 years ago |
|
|
cdea05af83 | 8 years ago |
|
|
a42afda6b7 | 8 years ago |
|
|
7134f46430 | 8 years ago |
|
|
738be9972d | 8 years ago |
|
|
b0b2c6d8b2 | 8 years ago |
|
|
03fb31ce0a | 8 years ago |
|
|
9f50307d14 | 8 years ago |
|
|
d70a6122d6 | 8 years ago |
|
|
496e053e0d | 8 years ago |
|
|
1b67ee97bc | 8 years ago |
|
|
ce187a2147 | 8 years ago |
|
|
0c79de15f6 | 8 years ago |
|
|
31b14cc293 | 8 years ago |
|
|
3b9e4d8d8b | 8 years ago |
|
|
f7b0551d09 | 8 years ago |
|
|
b98b46239a | 8 years ago |
|
|
b13a716def | 8 years ago |
|
|
0a65021bb6 | 8 years ago |
|
|
4c4f65da46 | 8 years ago |
|
|
958e06a084 | 8 years ago |
|
|
e9b157c387 | 8 years ago |
|
|
c5a0356352 | 8 years ago |
|
|
8a0f50504a | 8 years ago |
|
|
ee664523d3 | 8 years ago |
|
|
1fcb8d2eb0 | 8 years ago |
|
|
b3838ce297 | 8 years ago |
|
|
01dd3e9715 | 8 years ago |
|
|
b3e290a89a | 8 years ago |
|
|
e7f2936ded | 8 years ago |
|
|
61b2726004 | 8 years ago |
|
|
68fdd77e07 | 8 years ago |
|
|
ea39c1815d | 8 years ago |
|
|
30d39afa87 | 8 years ago |
|
|
239181251b | 8 years ago |
|
|
ec8d7ae971 | 8 years ago |
|
|
45793813b1 | 8 years ago |
|
|
1d686ee2cc | 8 years ago |
|
|
adecb5dfdb | 8 years ago |
|
|
d3a97cbf16 | 8 years ago |
|
|
00f37e18ef | 8 years ago |
|
|
aaf0d79b08 | 8 years ago |
|
|
7e6f4b7149 | 8 years ago |
|
|
919cb63adb | 8 years ago |
|
|
c47c68cfb7 | 8 years ago |
|
|
e10afd6796 | 8 years ago |
|
|
43766b2784 | 8 years ago |
|
|
65f1ceaf2d | 8 years ago |
|
|
07b22a3c53 | 8 years ago |
|
|
cf53e05e1f | 8 years ago |
|
|
eda24e5745 | 8 years ago |
|
|
640359faee | 8 years ago |
|
|
25402592a3 | 8 years ago |
|
|
e0c80361c4 | 8 years ago |
|
|
6bbddd8669 | 8 years ago |
|
|
48a7af8e29 | 8 years ago |
|
|
57fdafcee3 | 8 years ago |
|
|
372372c8ff | 8 years ago |
|
|
7b52baf4a6 | 8 years ago |
|
|
335d73363a | 8 years ago |
|
|
fa0caec171 | 8 years ago |
|
|
a5ea723a17 | 8 years ago |
|
|
e8ef6c98a9 | 8 years ago |
|
|
f51d20b960 | 8 years ago |
|
|
ed5ab25438 | 8 years ago |
|
|
ec5f8ab906 | 8 years ago |
|
|
215d70d518 | 8 years ago |
|
|
26059bcb01 | 8 years ago |
|
|
31a2eec8bf | 8 years ago |
|
|
6026a2a39a | 8 years ago |
|
|
deb70877e7 | 8 years ago |
|
|
197a9a78e4 | 8 years ago |
|
|
41370c8ccc | 8 years ago |
|
|
f6cccdba22 | 8 years ago |
|
|
7c717a078d | 8 years ago |
|
|
023c531483 | 8 years ago |
|
|
a29b2560d3 | 8 years ago |
|
|
2f5a06f0b2 | 8 years ago |
|
|
3a713f9623 | 8 years ago |
|
|
290bd5e96a | 8 years ago |
|
|
8365c1bd5b | 8 years ago |
@ -0,0 +1,42 @@ |
|||||||
|
import csv |
||||||
|
import jwt |
||||||
|
from django.conf import settings |
||||||
|
from django.core.management.base import BaseCommand |
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): |
||||||
|
help = 'Добавляет 1 или нескольких юзеров в указанные группы' |
||||||
|
|
||||||
|
def add_arguments(self, parser): |
||||||
|
parser.add_argument( |
||||||
|
'--from', |
||||||
|
type=str, |
||||||
|
dest='from', |
||||||
|
help='Файл подгрузки данных' |
||||||
|
) |
||||||
|
parser.add_argument( |
||||||
|
'--to', |
||||||
|
type=str, |
||||||
|
dest='to', |
||||||
|
help='Файл выгрузки' |
||||||
|
) |
||||||
|
|
||||||
|
def handle(self, *args, **options): |
||||||
|
from_path = options['from'] |
||||||
|
to_path = options['to'] |
||||||
|
with open(from_path) as f: |
||||||
|
with open(to_path, 'w') as out_f: |
||||||
|
fw = csv.writer(out_f) |
||||||
|
fr = csv.reader(f, delimiter=';') |
||||||
|
for row in fr: |
||||||
|
email = row[0] |
||||||
|
course_token = row[1] |
||||||
|
period = row[2] |
||||||
|
payload = { |
||||||
|
'period': period, |
||||||
|
'course_token': course_token, |
||||||
|
'email': email.lower(), |
||||||
|
} |
||||||
|
token = jwt.encode(payload, settings.COURSE_PROGRESS_SECRET_KEY, algorithm='HS256').decode("utf-8") |
||||||
|
url = "https://go.skillbox.ru/api/v1/progress/progress_token/?token=%s" % str(token) |
||||||
|
fw.writerow([email.lower(), url]) |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
from django.core.management.base import BaseCommand |
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): |
||||||
|
help = 'Команда для тестов' |
||||||
|
|
||||||
|
def handle(self, *args, **options): |
||||||
|
from xml.dom import minidom |
||||||
|
|
||||||
|
xx = """<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<repeatCardPaymentResponse status="3" error="112" processedDT="2018-04-23T19:37:04.544+03:00" techMessage="Неверное значение параметра invoiceId" clientOrderId="unknown"/>""" |
||||||
|
dom = minidom.parseString(xx) |
||||||
|
dom.normalize() |
||||||
|
node1 = dom.getElementsByTagName("repeatCardPaymentResponse")[0] |
||||||
|
print(node1) |
||||||
|
print(node1.getAttribute('error')) |
||||||
|
print(node1.getAttribute('processedDT')) |
||||||
|
print(node1.getAttribute('techMessage')) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# def handle(self, *args, **options): |
||||||
|
# from finance.loggers import FinanceLogger |
||||||
|
# logger = FinanceLogger() |
||||||
|
# try: |
||||||
|
# 10 / 0 |
||||||
|
# except Exception as exc: |
||||||
|
# logger.exception('FinanceLogger test log record', extra={'asdf': 3246523}, |
||||||
|
# invoice_id=42, some_param={'a': 1, 'b': 3, 'привет': 'медвед'} |
||||||
|
# ) |
||||||
|
# |
||||||
@ -1,5 +0,0 @@ |
|||||||
DEBUG=False |
|
||||||
SECRET_KEY='!eiquy7_+2#vn3z%zfp51$m-=tmvtcv*cj*@x$!v(_9btq0w=$' |
|
||||||
DATABASE_URL='psql://team:nu5Xefise@127.0.0.1:5432/new_lms' |
|
||||||
EMAIL_URL='smtp+tls://robo@skillbox.ru:nu5Xefise@smtp.gmail.com:587' |
|
||||||
CACHE_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient |
|
||||||
@ -0,0 +1,5 @@ |
|||||||
|
DEBUG=False |
||||||
|
SECRET_KEY='....' |
||||||
|
DATABASE_URL='psql://<name>:<password>@127.0.0.1:5432/<db_name>' |
||||||
|
EMAIL_URL='smtp+tls://<name>:<password>@smtp.gmail.com:587' |
||||||
|
CACHE_URL=rediscache://127.0.0.1:6379/<db>?client_class=django_redis.client.DefaultClient |
||||||
@ -1,5 +0,0 @@ |
|||||||
DEBUG=True |
|
||||||
SECRET_KEY='!eiquy7_+2#vn3z%zfp51$m-=tmvtcv*cj*@x$!v(_9btq0w=$' |
|
||||||
DATABASE_URL='psql://postgres@127.0.0.1:5432/test_lms' |
|
||||||
EMAIL_URL='smtp+tls://9ae31a1a770138:a7d79ee373a14c@smtp.mailtrap.io:2525' |
|
||||||
CACHE_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient |
|
||||||
@ -0,0 +1,23 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-23 17:43 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('courses', '0005_auto_20180222_1911'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='topic', |
||||||
|
name='description', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='topic', |
||||||
|
name='icon', |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
from progress.models import ProgressLesson, Progress |
||||||
|
from django.contrib.auth import get_user_model |
||||||
|
|
||||||
|
|
||||||
|
def add_lesson(user_out_key: str, course_token: str, lesson_token: str, teacher_key: str, is_hm: bool): |
||||||
|
|
||||||
|
p = Progress.objects.get(course_token=course_token, user__out_key=user_out_key) |
||||||
|
|
||||||
|
ProgressLesson.objects.get_or_create( |
||||||
|
progress=p, |
||||||
|
lesson_token=lesson_token, |
||||||
|
checker=get_user_model().objects.get(out_key=(teacher_key if is_hm else user_out_key)), |
||||||
|
) |
||||||
@ -1,7 +1,13 @@ |
|||||||
# coding=utf-8 |
# coding=utf-8 |
||||||
from django.contrib import admin |
from django.contrib import admin |
||||||
|
|
||||||
from finance.models import Bill, Invoice |
from finance.models import Bill, Invoice, InvoiceRebilling |
||||||
|
|
||||||
|
|
||||||
|
class InvoiceAdmin(admin.ModelAdmin): |
||||||
|
list_display = ('__str__', 'rebilling_on',) |
||||||
|
|
||||||
|
|
||||||
admin.site.register(Bill) |
admin.site.register(Bill) |
||||||
admin.site.register(Invoice) |
admin.site.register(Invoice) |
||||||
|
admin.site.register(InvoiceRebilling, InvoiceAdmin) |
||||||
|
|||||||
@ -0,0 +1,56 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
|
||||||
|
import logging |
||||||
|
|
||||||
|
_logger = logging.getLogger('finance_data') |
||||||
|
|
||||||
|
|
||||||
|
class FinanceLogger: |
||||||
|
""" |
||||||
|
Все kwargs попадют в %(finance_data)s и логируются |
||||||
|
'format': '%(asctime)s - %(levelname)s - %(message)s - %(finance_data)s' |
||||||
|
""" |
||||||
|
|
||||||
|
def __init__(self, prefix=None): |
||||||
|
self.prefix = prefix |
||||||
|
|
||||||
|
def log(self, level, msg, *args, **kwargs): |
||||||
|
_logger.log(level=level, msg=self._get_msg(msg), *args, **self._make_kwargs(kwargs)) |
||||||
|
|
||||||
|
def _get_msg(self, msg): |
||||||
|
if self.prefix: |
||||||
|
msg = '{}: {}'.format(self.prefix, msg) |
||||||
|
return msg |
||||||
|
|
||||||
|
def _make_kwargs(self, kwargs): |
||||||
|
new_kwargs = {} |
||||||
|
for inspected_kwarg in ('exc_info', 'stack_info', 'extra'): |
||||||
|
try: |
||||||
|
new_kwargs[inspected_kwarg] = kwargs.pop(inspected_kwarg) |
||||||
|
except KeyError: |
||||||
|
pass |
||||||
|
if 'extra' in new_kwargs: |
||||||
|
new_kwargs['extra']['finance_data'] = kwargs |
||||||
|
else: |
||||||
|
new_kwargs['extra'] = dict(finance_data=kwargs) |
||||||
|
return new_kwargs |
||||||
|
|
||||||
|
def debug(self, msg, *args, **kwargs): |
||||||
|
self.log(level=logging.DEBUG, msg=msg, *args, **kwargs) |
||||||
|
|
||||||
|
def info(self, msg, *args, **kwargs): |
||||||
|
self.log(level=logging.INFO, msg=msg, *args, **kwargs) |
||||||
|
|
||||||
|
def warning(self, msg, *args, **kwargs): |
||||||
|
self.log(level=logging.WARNING, msg=msg, *args, **kwargs) |
||||||
|
|
||||||
|
# TODO отделить логирование ошибок в другой лог |
||||||
|
def error(self, msg, *args, **kwargs): |
||||||
|
self.log(level=logging.ERROR, msg=msg, *args, **kwargs) |
||||||
|
|
||||||
|
def critical(self, msg, *args, **kwargs): |
||||||
|
self.log(level=logging.CRITICAL, msg=msg, *args, **kwargs) |
||||||
|
|
||||||
|
def exception(self, msg, *args, **kwargs): |
||||||
|
kwargs['stack_info'] = True |
||||||
|
_logger.exception(self._get_msg(msg), *args, **self._make_kwargs(kwargs)) |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
from django.core.management.base import BaseCommand |
||||||
|
|
||||||
|
from finance.loggers import FinanceLogger |
||||||
|
from finance.tasks import periodic_billing |
||||||
|
|
||||||
|
finance_logger = FinanceLogger() # prefix='YandexMoney' |
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): |
||||||
|
|
||||||
|
def handle(self, *args, **options): |
||||||
|
finance_logger.info("start console repeat payment command") |
||||||
|
print('Started') |
||||||
|
periodic_billing() |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-15 13:58 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0002_auto_20180202_1301'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='invoice', |
||||||
|
name='real_price', |
||||||
|
field=models.FloatField(blank=True, editable=False, help_text='Сумма, минус комиссия', null=True, verbose_name='Полученная сумма'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-23 17:43 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.utils.timezone |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0003_auto_20180315_1358'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='bill', |
||||||
|
name='date', |
||||||
|
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='Дата выставления'), |
||||||
|
preserve_default=False, |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-29 13:46 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0004_bill_date'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.CreateModel( |
||||||
|
name='InstallmentPlan', |
||||||
|
fields=[ |
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||||
|
('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), |
||||||
|
('invoice_amount', models.IntegerField(verbose_name='Количество платежей')), |
||||||
|
('price', models.IntegerField(verbose_name='Цена одного платежа')), |
||||||
|
('bill', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='finance.Bill', verbose_name='Связный счёт')), |
||||||
|
], |
||||||
|
options={ |
||||||
|
'verbose_name': 'Рассрочка', |
||||||
|
'verbose_name_plural': 'Рассрочки', |
||||||
|
}, |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='invoice', |
||||||
|
name='date', |
||||||
|
field=models.DateTimeField(auto_now_add=True, verbose_name='Дата создания'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-30 11:21 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0005_auto_20180329_1346'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='installmentplan', |
||||||
|
name='bill', |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='invoice', |
||||||
|
name='rebilling', |
||||||
|
field=models.BooleanField(default=False, editable=False, verbose_name='Повторный платеж'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='invoice', |
||||||
|
name='rebilling_on', |
||||||
|
field=models.BooleanField(default=False, editable=False, verbose_name='Повторять платеж'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='invoice', |
||||||
|
name='date', |
||||||
|
field=models.DateTimeField(auto_now_add=True), |
||||||
|
), |
||||||
|
migrations.DeleteModel( |
||||||
|
name='InstallmentPlan', |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-30 14:52 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0006_auto_20180330_1121'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='invoice', |
||||||
|
name='rebilling', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='invoice', |
||||||
|
name='rebilling_on', |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-30 14:52 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0007_auto_20180330_1452'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.CreateModel( |
||||||
|
name='InvoiceRebilling', |
||||||
|
fields=[ |
||||||
|
('invoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='finance.Invoice')), |
||||||
|
('rebilling_on', models.BooleanField(default=False, editable=False, verbose_name='Повторять платеж')), |
||||||
|
], |
||||||
|
options={ |
||||||
|
'verbose_name': 'Повторный платёж', |
||||||
|
'verbose_name_plural': 'Повторные платежи', |
||||||
|
}, |
||||||
|
bases=('finance.invoice',), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-30 15:03 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0008_invoicerebilling'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='invoicerebilling', |
||||||
|
name='pay_count', |
||||||
|
field=models.SmallIntegerField(default=2, editable=False, verbose_name='Всего платежей'), |
||||||
|
preserve_default=False, |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-04-12 16:28 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.utils.timezone |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('finance', '0009_invoicerebilling_pay_count'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='invoicerebilling', |
||||||
|
name='pay_count', |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='bill', |
||||||
|
name='freeze', |
||||||
|
field=models.BooleanField(default=False, verbose_name='Отказ от платежей'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='invoice', |
||||||
|
name='date_of_payment', |
||||||
|
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата фактической оплаты'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='invoice', |
||||||
|
name='expected_date', |
||||||
|
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='Ожидаемая дата платежа'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='invoice', |
||||||
|
name='date', |
||||||
|
field=models.DateTimeField(auto_now_add=True, verbose_name='Дата создания платежа'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,81 @@ |
|||||||
|
import logging |
||||||
|
import os |
||||||
|
|
||||||
|
import requests |
||||||
|
from django.conf import settings |
||||||
|
from django.db import transaction |
||||||
|
from django.utils import timezone |
||||||
|
from yandex_money.models import Payment |
||||||
|
|
||||||
|
from finance.loggers import FinanceLogger |
||||||
|
from finance.models import InvoiceRebilling, Invoice |
||||||
|
from lms import celery_app |
||||||
|
|
||||||
|
finance_logger = FinanceLogger() |
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task |
||||||
|
def periodic_billing(): |
||||||
|
finance_logger.info("start periodic billing task") |
||||||
|
# TODO заюзать Invoice.BILL_STATUSES |
||||||
|
invoices = InvoiceRebilling.objects.filter(method='Y', status='W') |
||||||
|
# TODO тут был exclude('F') то есть все неоплаченные... но это не верно! |
||||||
|
for invoice in invoices.filter(expected_date__lt=timezone.now()): |
||||||
|
# выбираем все необработанные из прошлого |
||||||
|
with transaction.atomic(): |
||||||
|
try: |
||||||
|
_yandex_repeat_card_payment(invoice) |
||||||
|
except Exception as exc: |
||||||
|
finance_logger.exception('Yandex Money repeatCardPayment Exception', invoice_id=invoice.id) |
||||||
|
invoice.comment += 'Yandex Money: Ошибка при попытке повторного платежа, свяжитесь с клиентской службой' |
||||||
|
invoice.save() |
||||||
|
|
||||||
|
|
||||||
|
def _yandex_repeat_card_payment(invoice): |
||||||
|
user = invoice.bill.user |
||||||
|
yandex_pay = Payment.objects.create( |
||||||
|
order_amount=invoice.price, |
||||||
|
customer_number=user.id, |
||||||
|
user=user, |
||||||
|
cps_email=user.email, |
||||||
|
shop_id=settings.YANDEX_MONEY_REBILLING_SHOP_ID, |
||||||
|
scid=settings.YANDEX_MONEY_REBILLING_SCID |
||||||
|
) |
||||||
|
invoice.yandex_pay = yandex_pay |
||||||
|
|
||||||
|
finance_logger.info('YandexMoney repeatCardPayment start', invoice_id=invoice.id) |
||||||
|
resp = requests.post( |
||||||
|
url=settings.YANDEX_MONEY_MWS_URL + 'repeatCardPayment', |
||||||
|
data={ |
||||||
|
'clientOrderId': invoice.id, # уникальное возрастающее целое число |
||||||
|
'invoiceId': invoice.key, |
||||||
|
'amount': invoice.price, |
||||||
|
'orderNumber': invoice.yandex_pay.order_number |
||||||
|
}, |
||||||
|
cert=( |
||||||
|
os.path.join(settings.SSL_ROOT, 'skillbox.cer'), |
||||||
|
os.path.join(settings.SSL_ROOT, 'skillbox.key') |
||||||
|
), |
||||||
|
verify=os.path.join(settings.SSL_ROOT, 'yamoney_chain.cer') |
||||||
|
) |
||||||
|
resp_text = resp.text |
||||||
|
finance_logger.info('YandexMoney repeatCardPayment response', |
||||||
|
invoice_id=invoice.id, response=resp_text, code=resp.status_code, ) |
||||||
|
try: |
||||||
|
_check_yandex_response_status(invoice, resp_text) |
||||||
|
except Exception as exc: |
||||||
|
finance_logger.exception("Can't parse yandex response", invoice_id=invoice.id, response=resp_text) |
||||||
|
|
||||||
|
|
||||||
|
def _check_yandex_response_status(invoice, resp_text): |
||||||
|
from xml.dom import minidom |
||||||
|
dom = minidom.parseString(resp_text) |
||||||
|
dom.normalize() |
||||||
|
resp_node = dom.getElementsByTagName("repeatCardPaymentResponse")[0] |
||||||
|
status = resp_node.getAttribute('status') |
||||||
|
if status != '0': |
||||||
|
error = resp_node.getAttribute('error') |
||||||
|
processed_dt = resp_node.getAttribute('processedDT') |
||||||
|
tech_message = resp_node.getAttribute('techMessage') |
||||||
|
invoice.status = Invoice.BILL_STATUSES[-1][0] |
||||||
|
invoice.comment += 'Yandex Money: ошибка № {}, сообщение {} от {}'.format(error, tech_message, processed_dt) |
||||||
@ -1,520 +0,0 @@ |
|||||||
[2017-10-20 13:12:58,041: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 13:12:58,049: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 13:12:59,065: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 13:12:59,110: WARNING/MainProcess] /home/andrey/skillbox/lib/python3.6/site-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments! |
|
||||||
warnings.warn('Using settings.DEBUG leads to a memory leak, never ' |
|
||||||
[2017-10-20 13:12:59,113: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 13:13:02,946: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
[2017-10-20 13:17:23,104: INFO/MainProcess] Received task: lms.celery.debug_task[e7d9bdc2-a3a8-44b2-b3c6-935acfa092d7] |
|
||||||
[2017-10-20 13:17:23,106: WARNING/ForkPoolWorker-2] Request: <Context: {'lang': 'py', 'task': 'lms.celery.debug_task', 'id': 'e7d9bdc2-a3a8-44b2-b3c6-935acfa092d7', 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': 'e7d9bdc2-a3a8-44b2-b3c6-935acfa092d7', 'parent_id': None, 'argsrepr': '()', 'kwargsrepr': '{}', 'origin': 'gen13641@andrey-desktop', 'reply_to': 'b8c6ce7f-8ee0-35c7-ad70-026ad2f36d4a', 'correlation_id': 'e7d9bdc2-a3a8-44b2-b3c6-935acfa092d7', 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': False}, 'args': [], 'kwargs': {}, 'hostname': 'celery@andrey-desktop', 'is_eager': False, 'callbacks': None, 'errbacks': None, 'chain': None, 'chord': None, 'called_directly': False, '_protected': 1}> |
|
||||||
[2017-10-20 13:17:23,124: INFO/ForkPoolWorker-2] Task lms.celery.debug_task[e7d9bdc2-a3a8-44b2-b3c6-935acfa092d7] succeeded in 0.018874458000027516s: None |
|
||||||
[2017-10-20 13:17:29,057: INFO/MainProcess] Received task: lms.celery.debug_task[88f178fc-7222-4de0-b671-57e7472a9be1] |
|
||||||
[2017-10-20 13:17:29,059: WARNING/ForkPoolWorker-1] Request: <Context: {'lang': 'py', 'task': 'lms.celery.debug_task', 'id': '88f178fc-7222-4de0-b671-57e7472a9be1', 'eta': None, 'expires': None, 'group': None, 'retries': 0, 'timelimit': [None, None], 'root_id': '88f178fc-7222-4de0-b671-57e7472a9be1', 'parent_id': None, 'argsrepr': '()', 'kwargsrepr': '{}', 'origin': 'gen13641@andrey-desktop', 'reply_to': 'b8c6ce7f-8ee0-35c7-ad70-026ad2f36d4a', 'correlation_id': '88f178fc-7222-4de0-b671-57e7472a9be1', 'delivery_info': {'exchange': '', 'routing_key': 'celery', 'priority': 0, 'redelivered': False}, 'args': [], 'kwargs': {}, 'hostname': 'celery@andrey-desktop', 'is_eager': False, 'callbacks': None, 'errbacks': None, 'chain': None, 'chord': None, 'called_directly': False, '_protected': 1}> |
|
||||||
[2017-10-20 13:17:29,081: INFO/ForkPoolWorker-1] Task lms.celery.debug_task[88f178fc-7222-4de0-b671-57e7472a9be1] succeeded in 0.022606980999626103s: None |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 13:12:57 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f47cb927be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 13:32:32,128: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 13:32:32,135: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 13:32:33,150: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 13:32:33,201: WARNING/MainProcess] /home/andrey/skillbox/lib/python3.6/site-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments! |
|
||||||
warnings.warn('Using settings.DEBUG leads to a memory leak, never ' |
|
||||||
[2017-10-20 13:32:33,202: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 13:32:36,911: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 13:32:32 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f34afe2fbe0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 13:38:00,333: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 13:38:00,341: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 13:38:01,361: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 13:38:01,408: WARNING/MainProcess] /home/andrey/skillbox/lib/python3.6/site-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments! |
|
||||||
warnings.warn('Using settings.DEBUG leads to a memory leak, never ' |
|
||||||
[2017-10-20 13:38:01,409: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 13:38:05,171: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 13:38:00 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7fd8781acbe0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 13:47:50,974: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 13:47:50,985: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 13:47:52,012: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 13:47:52,069: WARNING/MainProcess] /home/andrey/skillbox/lib/python3.6/site-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments! |
|
||||||
warnings.warn('Using settings.DEBUG leads to a memory leak, never ' |
|
||||||
[2017-10-20 13:47:52,069: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 13:47:56,047: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 13:47:50 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7fc6511c1b70 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 14:42:47,658: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 14:42:47,664: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 14:42:48,682: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 14:42:48,727: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 14:42:52,394: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
[2017-10-20 14:47:53,063: INFO/MainProcess] Tasks flagged as revoked: ff8246ff-1904-47da-ac57-1a844272c826 |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 14:42:47 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f89a2228be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 14:56:43,024: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 14:56:43,031: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 14:56:44,048: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 14:56:44,112: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 14:56:47,869: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 14:56:42 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f4f0c601be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 15:14:13,071: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 15:14:13,086: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 15:14:14,109: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 15:14:14,123: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 15:14:18,076: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 15:14:12 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7fd94e575b70 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 15:18:26,330: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 15:18:26,337: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 15:18:27,355: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 15:18:27,417: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 15:18:31,190: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 15:18:26 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f4b2ac05be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 15:31:17,246: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 15:31:17,253: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 15:31:18,269: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 15:31:18,311: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 15:31:22,075: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 15:31:17 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f2e6cc96be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send_multiple |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-20 16:52:27,050: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-20 16:52:27,057: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-20 16:52:28,074: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-20 16:52:28,128: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-20 16:52:31,818: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
[2017-10-20 17:00:17,556: INFO/MainProcess] Received task: djcelery_email_send[8735440e-9760-43c7-b84c-c6efdac4e64d] |
|
||||||
[2017-10-20 17:00:19,202: INFO/ForkPoolWorker-2] Task djcelery_email_send[8735440e-9760-43c7-b84c-c6efdac4e64d] succeeded in 1.4465199199985364s: 1 |
|
||||||
[2017-10-20 17:39:12,619: INFO/MainProcess] Received task: djcelery_email_send[243eb7a2-b4e0-4221-8ab2-c83c94d8f241] |
|
||||||
[2017-10-20 17:39:14,523: INFO/ForkPoolWorker-1] Task djcelery_email_send[243eb7a2-b4e0-4221-8ab2-c83c94d8f241] succeeded in 1.4357735300000058s: 1 |
|
||||||
[2017-10-20 17:40:33,125: INFO/MainProcess] Received task: djcelery_email_send[863adc65-6bf5-4a1d-a2b9-91ebb9737520] |
|
||||||
[2017-10-20 17:40:34,548: INFO/ForkPoolWorker-2] Task djcelery_email_send[863adc65-6bf5-4a1d-a2b9-91ebb9737520] succeeded in 1.3558088320023671s: 1 |
|
||||||
[2017-10-20 17:42:16,950: INFO/MainProcess] Received task: djcelery_email_send[a60b5727-8d77-49f8-8008-82ae064ed682] |
|
||||||
[2017-10-20 17:42:18,493: INFO/ForkPoolWorker-1] Task djcelery_email_send[a60b5727-8d77-49f8-8008-82ae064ed682] succeeded in 1.1552653329999885s: 1 |
|
||||||
[2017-10-20 17:57:36,541: INFO/MainProcess] Received task: djcelery_email_send[8184ca5f-b2e2-42ee-a096-b3c2ecf152e2] |
|
||||||
[2017-10-20 17:57:37,905: INFO/ForkPoolWorker-2] Task djcelery_email_send[8184ca5f-b2e2-42ee-a096-b3c2ecf152e2] succeeded in 1.251813505001337s: 1 |
|
||||||
[2017-10-20 19:20:51,999: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection... |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 320, in start |
|
||||||
blueprint.start(self) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start |
|
||||||
step.start(parent) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 596, in start |
|
||||||
c.loop(*c.loop_args()) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/loops.py", line 88, in asynloop |
|
||||||
next(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/async/hub.py", line 354, in create_loop |
|
||||||
cb(*cbargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 236, in on_readable |
|
||||||
reader(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 218, in _read |
|
||||||
drain_events(timeout=0) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 471, in drain_events |
|
||||||
while not self.blocking_read(timeout): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 477, in blocking_read |
|
||||||
return self.on_inbound_frame(frame) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 55, in on_frame |
|
||||||
callback(channel, method_sig, buf, None) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 481, in on_inbound_method |
|
||||||
method_sig, payload, content, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 128, in dispatch_method |
|
||||||
listener(*args) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 603, in _on_close |
|
||||||
(class_id, method_id), ConnectionError) |
|
||||||
amqp.exceptions.ConnectionForced: (0, 0): (320) CONNECTION_FORCED - broker forced connection closure with reason 'shutdown' |
|
||||||
[2017-10-20 19:20:52,012: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 2.00 seconds... |
|
||||||
|
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-20 16:52:26 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7fe25f735be0 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
[2017-10-23 08:32:22,988: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-23 08:32:22,998: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-23 08:32:24,013: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-23 08:32:24,021: INFO/MainProcess] celery@andrey-desktop ready. |
|
||||||
[2017-10-23 08:32:27,769: INFO/MainProcess] Events of group {task} enabled by remote. |
|
||||||
[2017-10-23 11:42:09,222: INFO/MainProcess] Received task: djcelery_email_send[54f16e2a-a437-4000-850f-0bf29ff758b8] |
|
||||||
[2017-10-23 11:42:10,844: INFO/ForkPoolWorker-2] Task djcelery_email_send[54f16e2a-a437-4000-850f-0bf29ff758b8] succeeded in 1.4740454479997425s: 1 |
|
||||||
[2017-10-23 11:44:36,901: INFO/MainProcess] Received task: djcelery_email_send[2ef60ead-2523-4bf8-b117-366bb120359d] |
|
||||||
[2017-10-23 11:44:39,194: INFO/ForkPoolWorker-1] Task djcelery_email_send[2ef60ead-2523-4bf8-b117-366bb120359d] succeeded in 1.4229817790001107s: 1 |
|
||||||
[2017-10-23 11:45:49,202: INFO/MainProcess] Received task: djcelery_email_send[3e60e35a-c846-4f37-bd88-1d92afc9dcac] |
|
||||||
[2017-10-23 11:45:50,624: INFO/ForkPoolWorker-2] Task djcelery_email_send[3e60e35a-c846-4f37-bd88-1d92afc9dcac] succeeded in 1.1725643370009493s: 1 |
|
||||||
[2017-10-23 11:47:18,371: INFO/MainProcess] Received task: djcelery_email_send[4530e853-0db4-499d-8a65-7128121ee5bc] |
|
||||||
[2017-10-23 11:47:20,136: INFO/ForkPoolWorker-1] Task djcelery_email_send[4530e853-0db4-499d-8a65-7128121ee5bc] succeeded in 1.3828427380012727s: 1 |
|
||||||
[2017-10-23 11:56:05,834: INFO/MainProcess] Received task: djcelery_email_send[9fc201ce-f3ec-40af-9dd1-bf998f34a57d] |
|
||||||
[2017-10-23 11:56:08,831: INFO/ForkPoolWorker-2] Task djcelery_email_send[9fc201ce-f3ec-40af-9dd1-bf998f34a57d] succeeded in 1.293271452001136s: 1 |
|
||||||
[2017-10-23 11:59:57,509: INFO/MainProcess] Received task: djcelery_email_send[7945e9d6-ef7c-4e19-9c59-422100ac9f73] |
|
||||||
[2017-10-23 11:59:58,959: INFO/ForkPoolWorker-1] Task djcelery_email_send[7945e9d6-ef7c-4e19-9c59-422100ac9f73] succeeded in 1.1895115009992878s: 1 |
|
||||||
[2017-10-23 12:08:24,457: INFO/MainProcess] Received task: djcelery_email_send[f0968ae1-8fbd-4d2c-905a-2ecf445aa10e] |
|
||||||
[2017-10-23 12:08:25,890: INFO/ForkPoolWorker-2] Task djcelery_email_send[f0968ae1-8fbd-4d2c-905a-2ecf445aa10e] succeeded in 1.3443215190000046s: 1 |
|
||||||
[2017-10-23 12:20:29,414: INFO/MainProcess] Received task: djcelery_email_send[4438a0d4-228c-40a9-b91d-612f82ea791b] |
|
||||||
[2017-10-23 12:20:31,027: INFO/ForkPoolWorker-1] Task djcelery_email_send[4438a0d4-228c-40a9-b91d-612f82ea791b] succeeded in 1.452125650999733s: 1 |
|
||||||
[2017-10-23 12:21:31,101: INFO/MainProcess] Received task: djcelery_email_send[c3793dcb-e5f9-42bd-83b2-dd94f166c741] |
|
||||||
[2017-10-23 12:21:32,804: INFO/ForkPoolWorker-2] Task djcelery_email_send[c3793dcb-e5f9-42bd-83b2-dd94f166c741] succeeded in 1.1413313480006764s: 1 |
|
||||||
[2017-10-23 12:38:27,027: INFO/MainProcess] Received task: djcelery_email_send[ea55b25a-8e6d-4e88-8b18-52d561bd7c95] |
|
||||||
[2017-10-23 12:38:28,225: INFO/ForkPoolWorker-1] Task djcelery_email_send[ea55b25a-8e6d-4e88-8b18-52d561bd7c95] succeeded in 1.150906519000273s: 1 |
|
||||||
[2017-10-23 13:47:05,338: INFO/MainProcess] Received task: djcelery_email_send[b05bd9eb-848d-49b6-9725-d190e256527e] |
|
||||||
[2017-10-23 13:47:08,582: INFO/ForkPoolWorker-2] Task djcelery_email_send[b05bd9eb-848d-49b6-9725-d190e256527e] succeeded in 1.5058496720012045s: 1 |
|
||||||
[2017-10-23 13:48:09,314: INFO/MainProcess] Received task: djcelery_email_send[fe0bd44a-f23e-476b-a447-c03d8b5bb266] |
|
||||||
[2017-10-23 13:48:12,620: INFO/ForkPoolWorker-1] Task djcelery_email_send[fe0bd44a-f23e-476b-a447-c03d8b5bb266] succeeded in 1.340003754998179s: 1 |
|
||||||
[2017-10-23 14:36:33,382: INFO/MainProcess] Received task: djcelery_email_send[33418ad8-1f87-4a6f-ba11-a2fc0f52374a] |
|
||||||
[2017-10-23 14:36:35,323: INFO/ForkPoolWorker-2] Task djcelery_email_send[33418ad8-1f87-4a6f-ba11-a2fc0f52374a] succeeded in 1.3137642000001506s: 1 |
|
||||||
[2017-10-23 14:36:49,212: INFO/MainProcess] Received task: djcelery_email_send[5f3beb45-7d03-447a-be90-41506efb897b] |
|
||||||
[2017-10-23 14:36:51,271: INFO/ForkPoolWorker-1] Task djcelery_email_send[5f3beb45-7d03-447a-be90-41506efb897b] succeeded in 1.23961846200109s: 1 |
|
||||||
[2017-10-23 14:46:42,199: INFO/MainProcess] Received task: djcelery_email_send[69d6f018-e571-4d65-93a4-151fa78361ae] |
|
||||||
[2017-10-23 14:46:44,060: INFO/ForkPoolWorker-2] Task djcelery_email_send[69d6f018-e571-4d65-93a4-151fa78361ae] succeeded in 1.2866839900016203s: 1 |
|
||||||
[2017-10-23 14:55:56,121: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection... |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 320, in start |
|
||||||
blueprint.start(self) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start |
|
||||||
step.start(parent) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 596, in start |
|
||||||
c.loop(*c.loop_args()) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/loops.py", line 88, in asynloop |
|
||||||
next(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/async/hub.py", line 354, in create_loop |
|
||||||
cb(*cbargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 236, in on_readable |
|
||||||
reader(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 218, in _read |
|
||||||
drain_events(timeout=0) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 471, in drain_events |
|
||||||
while not self.blocking_read(timeout): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 477, in blocking_read |
|
||||||
return self.on_inbound_frame(frame) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 55, in on_frame |
|
||||||
callback(channel, method_sig, buf, None) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 481, in on_inbound_method |
|
||||||
method_sig, payload, content, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 128, in dispatch_method |
|
||||||
listener(*args) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 601, in _on_close |
|
||||||
self._x_close_ok() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 616, in _x_close_ok |
|
||||||
self.send_method(spec.Connection.CloseOk, callback=self._on_close_ok) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method |
|
||||||
conn.frame_writer(1, self.channel_id, sig, args, content) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame |
|
||||||
write(view[:offset]) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/transport.py", line 258, in write |
|
||||||
self._write(s) |
|
||||||
ConnectionResetError: [Errno 104] Connection reset by peer |
|
||||||
[2017-10-23 14:55:56,137: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 2.00 seconds... |
|
||||||
|
|
||||||
[2017-10-23 14:55:58,150: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 4.00 seconds... |
|
||||||
|
|
||||||
[2017-10-23 14:56:02,176: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 6.00 seconds... |
|
||||||
|
|
||||||
[2017-10-23 14:56:08,193: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 8.00 seconds... |
|
||||||
|
|
||||||
[2017-10-23 14:56:16,210: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 10.00 seconds... |
|
||||||
|
|
||||||
[2017-10-23 14:56:26,228: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-23 14:56:26,237: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-23 14:56:26,241: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection... |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 320, in start |
|
||||||
blueprint.start(self) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start |
|
||||||
step.start(parent) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 38, in start |
|
||||||
self.sync(c) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 42, in sync |
|
||||||
replies = self.send_hello(c) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 55, in send_hello |
|
||||||
replies = inspect.hello(c.hostname, our_revoked._data) or {} |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/control.py", line 129, in hello |
|
||||||
return self._request('hello', from_node=from_node, revoked=revoked) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/control.py", line 81, in _request |
|
||||||
timeout=self.timeout, reply=True, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/control.py", line 436, in broadcast |
|
||||||
limit, callback, channel=channel, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/pidbox.py", line 315, in _broadcast |
|
||||||
serializer=serializer) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/pidbox.py", line 290, in _publish |
|
||||||
serializer=serializer, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/messaging.py", line 181, in publish |
|
||||||
exchange_name, declare, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/messaging.py", line 203, in _publish |
|
||||||
mandatory=mandatory, immediate=immediate, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/channel.py", line 1734, in _basic_publish |
|
||||||
(0, exchange, routing_key, mandatory, immediate), msg |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method |
|
||||||
conn.frame_writer(1, self.channel_id, sig, args, content) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame |
|
||||||
write(view[:offset]) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/transport.py", line 258, in write |
|
||||||
self._write(s) |
|
||||||
ConnectionResetError: [Errno 104] Connection reset by peer |
|
||||||
[2017-10-23 14:56:26,250: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[2017-10-23 14:56:26,256: INFO/MainProcess] mingle: searching for neighbors |
|
||||||
[2017-10-23 14:56:27,273: INFO/MainProcess] mingle: all alone |
|
||||||
[2017-10-23 14:56:27,310: INFO/MainProcess] Received task: djcelery_email_send[455cf8cb-b29f-4159-a81b-b33e5dbee1f3] |
|
||||||
[2017-10-23 14:56:28,959: INFO/ForkPoolWorker-2] Task djcelery_email_send[455cf8cb-b29f-4159-a81b-b33e5dbee1f3] succeeded in 1.1903551169998536s: 1 |
|
||||||
[2017-10-23 18:52:13,477: INFO/MainProcess] Received task: djcelery_email_send[0fb5c171-4123-47fa-8089-823904fde5fd] |
|
||||||
[2017-10-23 18:52:16,661: INFO/ForkPoolWorker-1] Task djcelery_email_send[0fb5c171-4123-47fa-8089-823904fde5fd] succeeded in 1.222238110996841s: 1 |
|
||||||
[2017-10-23 19:05:28,619: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection... |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 320, in start |
|
||||||
blueprint.start(self) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start |
|
||||||
step.start(parent) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 596, in start |
|
||||||
c.loop(*c.loop_args()) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/worker/loops.py", line 88, in asynloop |
|
||||||
next(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/async/hub.py", line 354, in create_loop |
|
||||||
cb(*cbargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 236, in on_readable |
|
||||||
reader(loop) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/kombu/transport/base.py", line 218, in _read |
|
||||||
drain_events(timeout=0) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 471, in drain_events |
|
||||||
while not self.blocking_read(timeout): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 477, in blocking_read |
|
||||||
return self.on_inbound_frame(frame) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 55, in on_frame |
|
||||||
callback(channel, method_sig, buf, None) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 481, in on_inbound_method |
|
||||||
method_sig, payload, content, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 128, in dispatch_method |
|
||||||
listener(*args) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 601, in _on_close |
|
||||||
self._x_close_ok() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/connection.py", line 616, in _x_close_ok |
|
||||||
self.send_method(spec.Connection.CloseOk, callback=self._on_close_ok) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method |
|
||||||
conn.frame_writer(1, self.channel_id, sig, args, content) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame |
|
||||||
write(view[:offset]) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/amqp/transport.py", line 258, in write |
|
||||||
self._write(s) |
|
||||||
ConnectionResetError: [Errno 104] Connection reset by peer |
|
||||||
[2017-10-23 19:05:28,624: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 111] Connection refused. |
|
||||||
Trying again in 2.00 seconds... |
|
||||||
|
|
||||||
|
|
||||||
worker: Warm shutdown (MainProcess) |
|
||||||
|
|
||||||
-------------- celery@andrey-desktop v4.1.0 (latentcall) |
|
||||||
---- **** ----- |
|
||||||
--- * *** * -- Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial 2017-10-23 08:32:22 |
|
||||||
-- * - **** --- |
|
||||||
- ** ---------- [config] |
|
||||||
- ** ---------- .> app: lms:0x7f574ff21ba8 |
|
||||||
- ** ---------- .> transport: amqp://guest:**@localhost:5672// |
|
||||||
- ** ---------- .> results: |
|
||||||
- *** --- * --- .> concurrency: 4 (prefork) |
|
||||||
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) |
|
||||||
--- ***** ----- |
|
||||||
-------------- [queues] |
|
||||||
.> celery exchange=celery(direct) key=celery |
|
||||||
|
|
||||||
|
|
||||||
[tasks] |
|
||||||
. djcelery_email_send |
|
||||||
. lms.celery.debug_task |
|
||||||
|
|
||||||
@ -1,623 +0,0 @@ |
|||||||
[E 171020 13:12:57 signal:232] Signal handler <promise@0x7f84e8f79678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f84e711bbe0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 13:12:57 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 13:12:57 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 13:12:57 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 13:12:57 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 13:13:00 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'active' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 13:13:00 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 13:32:28 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 13:32:31 signal:232] Signal handler <promise@0x7f72af4b2678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f72ad655b70>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 13:32:31 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 13:32:31 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 13:32:31 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 13:32:31 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 13:32:34 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'active' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 13:32:34 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 13:37:56 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 13:38:00 signal:232] Signal handler <promise@0x7f00bb71c678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f00b98bebe0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 13:38:00 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 13:38:00 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 13:38:00 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 13:38:00 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 13:38:02 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'active' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 13:38:02 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 13:47:47 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 13:47:51 signal:232] Signal handler <promise@0x7f7efbb18678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f7ef9cbabe0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 13:47:51 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 13:47:51 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 13:47:51 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 13:47:51 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 13:47:53 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 13:47:53 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 13:47:53 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 13:47:53 control:44] 'scheduled' inspect method failed |
|
||||||
[I 171020 14:42:44 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 14:42:47 signal:232] Signal handler <promise@0x7f9b93353678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f9b914f5be0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 14:42:47 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 14:42:47 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 14:42:47 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 14:42:47 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 14:42:49 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'active' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 14:42:49 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 14:56:39 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 14:56:42 signal:232] Signal handler <promise@0x7f15cad6f678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f15c8f11be0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 14:56:42 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 14:56:42 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 14:56:42 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 14:56:42 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 14:56:45 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'active' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 14:56:45 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 15:14:09 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 15:14:13 signal:232] Signal handler <promise@0x7f60e14ab678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f60df64dbe0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 15:14:13 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 15:14:13 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 15:14:13 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 15:14:13 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 15:14:15 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 15:14:15 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 15:14:15 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 15:14:15 control:44] 'scheduled' inspect method failed |
|
||||||
[I 171020 15:18:22 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 15:18:26 signal:232] Signal handler <promise@0x7ff7eb19f678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7ff7e9341b70>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 15:18:26 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 15:18:26 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 15:18:26 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 15:18:26 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 15:18:28 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'active' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 15:18:28 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 15:31:13 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 15:31:17 signal:232] Signal handler <promise@0x7fcacf94e678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7fcacdaf0be0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 15:31:17 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 15:31:17 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 15:31:17 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send_multiple', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 15:31:17 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 15:31:19 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'active' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 15:31:19 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 16:52:23 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171020 16:52:26 signal:232] Signal handler <promise@0x7fb7bea9a678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7fb7bcc3cb70>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171020 16:52:26 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171020 16:52:26 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171020 16:52:26 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171020 16:52:26 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171020 16:52:28 control:44] 'stats' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'registered' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'active' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'reserved' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'revoked' inspect method failed |
|
||||||
[W 171020 16:52:28 control:44] 'conf' inspect method failed |
|
||||||
[I 171020 19:20:51 command:47] SIGTERM detected, shutting down |
|
||||||
[E 171023 08:32:22 signal:232] Signal handler <promise@0x7f249b502678 --> <bound method Celery._autodiscover_tasks of <Celery lms at 0x7f24996a4be0>>> raised: ImportError("cannot import name 'TrafSource'",) |
|
||||||
Traceback (most recent call last): |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 227, in send |
|
||||||
response = receiver(signal=self, sender=sender, **named) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 143, in __call__ |
|
||||||
return self.throw() |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/vine/promises.py", line 140, in __call__ |
|
||||||
retval = fun(*final_args, **final_kwargs) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 671, in _autodiscover_tasks |
|
||||||
return self._autodiscover_tasks_from_fixups(related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 684, in _autodiscover_tasks_from_fixups |
|
||||||
], related_name=related_name) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/app/base.py", line 676, in _autodiscover_tasks_from_names |
|
||||||
packages() if callable(packages) else packages, related_name, |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 223, in autodiscover_tasks |
|
||||||
related_name) if mod) |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in autodiscover_tasks |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 248, in <listcomp> |
|
||||||
return [find_related_module(pkg, related_name) for pkg in packages] |
|
||||||
File "/home/andrey/skillbox/lib/python3.6/site-packages/celery/loaders/base.py", line 274, in find_related_module |
|
||||||
return importlib.import_module('{0}.{1}'.format(package, related_name)) |
|
||||||
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module |
|
||||||
return _bootstrap._gcd_import(name[level:], package, level) |
|
||||||
File "<frozen importlib._bootstrap>", line 994, in _gcd_import |
|
||||||
File "<frozen importlib._bootstrap>", line 971, in _find_and_load |
|
||||||
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked |
|
||||||
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked |
|
||||||
File "<frozen importlib._bootstrap_external>", line 678, in exec_module |
|
||||||
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed |
|
||||||
File "/home/andrey/skillbox/go.skillbox.ru/access/tasks.py", line 4, in <module> |
|
||||||
from access.models import User, TrafSource, TrafTokenHistory |
|
||||||
ImportError: cannot import name 'TrafSource' |
|
||||||
[I 171023 08:32:22 command:139] Visit me at http://localhost:5555 |
|
||||||
[I 171023 08:32:22 command:144] Broker: amqp://guest:**@localhost:5672// |
|
||||||
[I 171023 08:32:22 command:147] Registered tasks: |
|
||||||
['celery.accumulate', |
|
||||||
'celery.backend_cleanup', |
|
||||||
'celery.chain', |
|
||||||
'celery.chord', |
|
||||||
'celery.chord_unlock', |
|
||||||
'celery.chunks', |
|
||||||
'celery.group', |
|
||||||
'celery.map', |
|
||||||
'celery.starmap', |
|
||||||
'djcelery_email_send', |
|
||||||
'lms.celery.debug_task'] |
|
||||||
[I 171023 08:32:22 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[W 171023 08:32:24 control:44] 'stats' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'active_queues' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'registered' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'scheduled' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'active' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'reserved' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'revoked' inspect method failed |
|
||||||
[W 171023 08:32:24 control:44] 'conf' inspect method failed |
|
||||||
[E 171023 14:55:56 events:123] Failed to capture events: '[Errno 104] Connection reset by peer', trying again in 1 seconds. |
|
||||||
[I 171023 14:56:17 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[E 171023 14:56:17 events:123] Failed to capture events: '[Errno 104] Connection reset by peer', trying again in 1 seconds. |
|
||||||
[I 171023 14:56:18 mixins:224] Connected to amqp://guest:**@127.0.0.1:5672// |
|
||||||
[I 171023 19:05:28 command:47] SIGTERM detected, shutting down |
|
||||||
@ -1,121 +0,0 @@ |
|||||||
[2017-10-20 13:12:57,958: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 13:12:57 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 13:32:31,865: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 13:32:31 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 13:38:00,107: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 13:38:00 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 13:47:51,058: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 13:47:51 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 14:42:47,578: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 14:42:47 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 14:56:42,777: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 14:56:42 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 15:14:13,137: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 15:14:13 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 15:18:26,051: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 15:18:26 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 15:31:17,073: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 15:31:17 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-20 16:52:26,958: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-20 16:52:26 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
[2017-10-23 08:32:22,755: INFO/MainProcess] beat: Starting... |
|
||||||
celery beat v4.1.0 (latentcall) is starting. |
|
||||||
__ - ... __ - _ |
|
||||||
LocalTime -> 2017-10-23 08:32:22 |
|
||||||
Configuration -> |
|
||||||
. broker -> amqp://guest:**@localhost:5672// |
|
||||||
. loader -> celery.loaders.app.AppLoader |
|
||||||
. scheduler -> celery.beat.PersistentScheduler |
|
||||||
. db -> celerybeat-schedule |
|
||||||
. logfile -> [stderr]@%INFO |
|
||||||
. maxinterval -> 5.00 minutes (300s) |
|
||||||
@ -0,0 +1,20 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-03-27 13:29 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('progress', '0008_auto_20180227_1803'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='progress', |
||||||
|
name='is_freeze', |
||||||
|
field=models.BooleanField(default=False, verbose_name='Прохождение было преостановленно'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.11.6 on 2018-04-16 18:50 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('progress', '0009_progress_is_freeze'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='progress', |
||||||
|
name='exp_date', |
||||||
|
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания'), |
||||||
|
), |
||||||
|
] |
||||||
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1,967 @@ |
|||||||
|
/* |
||||||
|
DJANGO Admin styles |
||||||
|
*/ |
||||||
|
|
||||||
|
@import url(fonts.css); |
||||||
|
|
||||||
|
body { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
font-size: 14px; |
||||||
|
font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; |
||||||
|
color: #333; |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
/* LINKS */ |
||||||
|
|
||||||
|
a:link, a:visited { |
||||||
|
color: #447e9b; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
a:focus, a:hover { |
||||||
|
color: #036; |
||||||
|
} |
||||||
|
|
||||||
|
a:focus { |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
a img { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
a.section:link, a.section:visited { |
||||||
|
color: #fff; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
a.section:focus, a.section:hover { |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
/* GLOBAL DEFAULTS */ |
||||||
|
|
||||||
|
p, ol, ul, dl { |
||||||
|
margin: .2em 0 .8em 0; |
||||||
|
} |
||||||
|
|
||||||
|
p { |
||||||
|
padding: 0; |
||||||
|
line-height: 140%; |
||||||
|
} |
||||||
|
|
||||||
|
h1,h2,h3,h4,h5 { |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
h1 { |
||||||
|
margin: 0 0 20px; |
||||||
|
font-weight: 300; |
||||||
|
font-size: 20px; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
h2 { |
||||||
|
font-size: 16px; |
||||||
|
margin: 1em 0 .5em 0; |
||||||
|
} |
||||||
|
|
||||||
|
h2.subhead { |
||||||
|
font-weight: normal; |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
h3 { |
||||||
|
font-size: 14px; |
||||||
|
margin: .8em 0 .3em 0; |
||||||
|
color: #666; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
h4 { |
||||||
|
font-size: 12px; |
||||||
|
margin: 1em 0 .8em 0; |
||||||
|
padding-bottom: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
h5 { |
||||||
|
font-size: 10px; |
||||||
|
margin: 1.5em 0 .5em 0; |
||||||
|
color: #666; |
||||||
|
text-transform: uppercase; |
||||||
|
letter-spacing: 1px; |
||||||
|
} |
||||||
|
|
||||||
|
ul li { |
||||||
|
list-style-type: square; |
||||||
|
padding: 1px 0; |
||||||
|
} |
||||||
|
|
||||||
|
li ul { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
li, dt, dd { |
||||||
|
font-size: 13px; |
||||||
|
line-height: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
dt { |
||||||
|
font-weight: bold; |
||||||
|
margin-top: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
dd { |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
border: none; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
blockquote { |
||||||
|
font-size: 11px; |
||||||
|
color: #777; |
||||||
|
margin-left: 2px; |
||||||
|
padding-left: 10px; |
||||||
|
border-left: 5px solid #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
code, pre { |
||||||
|
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; |
||||||
|
color: #666; |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
pre.literal-block { |
||||||
|
margin: 10px; |
||||||
|
background: #eee; |
||||||
|
padding: 6px 8px; |
||||||
|
} |
||||||
|
|
||||||
|
code strong { |
||||||
|
color: #930; |
||||||
|
} |
||||||
|
|
||||||
|
hr { |
||||||
|
clear: both; |
||||||
|
color: #eee; |
||||||
|
background-color: #eee; |
||||||
|
height: 1px; |
||||||
|
border: none; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
font-size: 1px; |
||||||
|
line-height: 1px; |
||||||
|
} |
||||||
|
|
||||||
|
/* TEXT STYLES & MODIFIERS */ |
||||||
|
|
||||||
|
.small { |
||||||
|
font-size: 11px; |
||||||
|
} |
||||||
|
|
||||||
|
.tiny { |
||||||
|
font-size: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
p.tiny { |
||||||
|
margin-top: -2px; |
||||||
|
} |
||||||
|
|
||||||
|
.mini { |
||||||
|
font-size: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
p.mini { |
||||||
|
margin-top: -3px; |
||||||
|
} |
||||||
|
|
||||||
|
.help, p.help, form p.help { |
||||||
|
font-size: 11px; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
.help-tooltip { |
||||||
|
cursor: help; |
||||||
|
} |
||||||
|
|
||||||
|
p img, h1 img, h2 img, h3 img, h4 img, td img { |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
|
||||||
|
.quiet, a.quiet:link, a.quiet:visited { |
||||||
|
color: #999; |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
|
|
||||||
|
.float-right { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.float-left { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
.clear { |
||||||
|
clear: both; |
||||||
|
} |
||||||
|
|
||||||
|
.align-left { |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.align-right { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.example { |
||||||
|
margin: 10px 0; |
||||||
|
padding: 5px 10px; |
||||||
|
background: #efefef; |
||||||
|
} |
||||||
|
|
||||||
|
.nowrap { |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
|
||||||
|
/* TABLES */ |
||||||
|
|
||||||
|
table { |
||||||
|
border-collapse: collapse; |
||||||
|
border-color: #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
td, th { |
||||||
|
font-size: 13px; |
||||||
|
line-height: 16px; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
vertical-align: top; |
||||||
|
padding: 8px; |
||||||
|
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; |
||||||
|
} |
||||||
|
|
||||||
|
th { |
||||||
|
font-weight: 600; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
thead th, |
||||||
|
tfoot td { |
||||||
|
color: #666; |
||||||
|
padding: 5px 10px; |
||||||
|
font-size: 11px; |
||||||
|
background: #fff; |
||||||
|
border: none; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
tfoot td { |
||||||
|
border-bottom: none; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
tr.alt { |
||||||
|
background: #f6f6f6; |
||||||
|
} |
||||||
|
|
||||||
|
.row1 { |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.row2 { |
||||||
|
background: #f9f9f9; |
||||||
|
} |
||||||
|
|
||||||
|
/* SORTABLE TABLES */ |
||||||
|
|
||||||
|
thead th { |
||||||
|
padding: 5px 10px; |
||||||
|
line-height: normal; |
||||||
|
text-transform: uppercase; |
||||||
|
background: #f6f6f6; |
||||||
|
} |
||||||
|
|
||||||
|
thead th a:link, thead th a:visited { |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
thead th.sorted { |
||||||
|
background: #eee; |
||||||
|
} |
||||||
|
|
||||||
|
thead th.sorted .text { |
||||||
|
padding-right: 42px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th .text span { |
||||||
|
padding: 8px 10px; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th .text a { |
||||||
|
display: block; |
||||||
|
cursor: pointer; |
||||||
|
padding: 8px 10px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th .text a:focus, table thead th .text a:hover { |
||||||
|
background: #eee; |
||||||
|
} |
||||||
|
|
||||||
|
thead th.sorted a.sortremove { |
||||||
|
visibility: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted:hover a.sortremove { |
||||||
|
visibility: visible; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions { |
||||||
|
display: block; |
||||||
|
padding: 9px 5px 0 5px; |
||||||
|
float: right; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortpriority { |
||||||
|
font-size: .8em; |
||||||
|
min-width: 12px; |
||||||
|
text-align: center; |
||||||
|
vertical-align: 3px; |
||||||
|
margin-left: 2px; |
||||||
|
margin-right: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a { |
||||||
|
position: relative; |
||||||
|
width: 14px; |
||||||
|
height: 14px; |
||||||
|
display: inline-block; |
||||||
|
background: url(../img/sorting-icons.svg) 0 0 no-repeat; |
||||||
|
background-size: 14px auto; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.sortremove { |
||||||
|
background-position: 0 0; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.sortremove:after { |
||||||
|
content: '\\'; |
||||||
|
position: absolute; |
||||||
|
top: -6px; |
||||||
|
left: 3px; |
||||||
|
font-weight: 200; |
||||||
|
font-size: 18px; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.sortremove:focus:after, |
||||||
|
table thead th.sorted .sortoptions a.sortremove:hover:after { |
||||||
|
color: #447e9b; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.sortremove:focus, |
||||||
|
table thead th.sorted .sortoptions a.sortremove:hover { |
||||||
|
background-position: 0 -14px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.ascending { |
||||||
|
background-position: 0 -28px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.ascending:focus, |
||||||
|
table thead th.sorted .sortoptions a.ascending:hover { |
||||||
|
background-position: 0 -42px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.descending { |
||||||
|
top: 1px; |
||||||
|
background-position: 0 -56px; |
||||||
|
} |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions a.descending:focus, |
||||||
|
table thead th.sorted .sortoptions a.descending:hover { |
||||||
|
background-position: 0 -70px; |
||||||
|
} |
||||||
|
|
||||||
|
/* FORM DEFAULTS */ |
||||||
|
|
||||||
|
input, textarea, select, .form-row p, form .button { |
||||||
|
margin: 2px 0; |
||||||
|
padding: 2px 3px; |
||||||
|
vertical-align: middle; |
||||||
|
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; |
||||||
|
font-weight: normal; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
textarea { |
||||||
|
vertical-align: top; |
||||||
|
} |
||||||
|
|
||||||
|
input[type=text], input[type=password], input[type=email], input[type=url], |
||||||
|
input[type=number], textarea, select, .vTextField { |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-radius: 4px; |
||||||
|
padding: 5px 6px; |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, |
||||||
|
input[type=url]:focus, input[type=number]:focus, textarea:focus, select:focus, |
||||||
|
.vTextField:focus { |
||||||
|
border-color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
select { |
||||||
|
height: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
select[multiple] { |
||||||
|
min-height: 150px; |
||||||
|
} |
||||||
|
|
||||||
|
/* FORM BUTTONS */ |
||||||
|
|
||||||
|
.button, input[type=submit], input[type=button], .submit-row input, a.button { |
||||||
|
background: #79aec8; |
||||||
|
padding: 10px 15px; |
||||||
|
border: none; |
||||||
|
border-radius: 4px; |
||||||
|
color: #fff; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
a.button { |
||||||
|
padding: 4px 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.button:active, input[type=submit]:active, input[type=button]:active, |
||||||
|
.button:focus, input[type=submit]:focus, input[type=button]:focus, |
||||||
|
.button:hover, input[type=submit]:hover, input[type=button]:hover { |
||||||
|
background: #609ab6; |
||||||
|
} |
||||||
|
|
||||||
|
.button[disabled], input[type=submit][disabled], input[type=button][disabled] { |
||||||
|
opacity: 0.4; |
||||||
|
} |
||||||
|
|
||||||
|
.button.default, input[type=submit].default, .submit-row input.default { |
||||||
|
float: right; |
||||||
|
border: none; |
||||||
|
font-weight: 400; |
||||||
|
background: #417690; |
||||||
|
} |
||||||
|
|
||||||
|
.button.default:active, input[type=submit].default:active, |
||||||
|
.button.default:focus, input[type=submit].default:focus, |
||||||
|
.button.default:hover, input[type=submit].default:hover { |
||||||
|
background: #205067; |
||||||
|
} |
||||||
|
|
||||||
|
.button[disabled].default, |
||||||
|
input[type=submit][disabled].default, |
||||||
|
input[type=button][disabled].default { |
||||||
|
opacity: 0.4; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* MODULES */ |
||||||
|
|
||||||
|
.module { |
||||||
|
border: none; |
||||||
|
margin-bottom: 30px; |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.module p, .module ul, .module h3, .module h4, .module dl, .module pre { |
||||||
|
padding-left: 10px; |
||||||
|
padding-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.module blockquote { |
||||||
|
margin-left: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.module ul, .module ol { |
||||||
|
margin-left: 1.5em; |
||||||
|
} |
||||||
|
|
||||||
|
.module h3 { |
||||||
|
margin-top: .6em; |
||||||
|
} |
||||||
|
|
||||||
|
.module h2, .module caption, .inline-group h2 { |
||||||
|
margin: 0; |
||||||
|
padding: 8px; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 13px; |
||||||
|
text-align: left; |
||||||
|
background: #79aec8; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.module caption, |
||||||
|
.inline-group h2 { |
||||||
|
font-size: 12px; |
||||||
|
letter-spacing: 0.5px; |
||||||
|
text-transform: uppercase; |
||||||
|
} |
||||||
|
|
||||||
|
.module table { |
||||||
|
border-collapse: collapse; |
||||||
|
} |
||||||
|
|
||||||
|
/* MESSAGES & ERRORS */ |
||||||
|
|
||||||
|
ul.messagelist { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
ul.messagelist li { |
||||||
|
display: block; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 13px; |
||||||
|
padding: 10px 10px 10px 65px; |
||||||
|
margin: 0 0 10px 0; |
||||||
|
background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat; |
||||||
|
background-size: 16px auto; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
ul.messagelist li.warning { |
||||||
|
background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat; |
||||||
|
background-size: 14px auto; |
||||||
|
} |
||||||
|
|
||||||
|
ul.messagelist li.error { |
||||||
|
background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat; |
||||||
|
background-size: 16px auto; |
||||||
|
} |
||||||
|
|
||||||
|
.errornote { |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 700; |
||||||
|
display: block; |
||||||
|
padding: 10px 12px; |
||||||
|
margin: 0 0 10px 0; |
||||||
|
color: #ba2121; |
||||||
|
border: 1px solid #ba2121; |
||||||
|
border-radius: 4px; |
||||||
|
background-color: #fff; |
||||||
|
background-position: 5px 12px; |
||||||
|
} |
||||||
|
|
||||||
|
ul.errorlist { |
||||||
|
margin: 0 0 4px; |
||||||
|
padding: 0; |
||||||
|
color: #ba2121; |
||||||
|
background: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
ul.errorlist li { |
||||||
|
font-size: 13px; |
||||||
|
display: block; |
||||||
|
margin-bottom: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
ul.errorlist li:first-child { |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
ul.errorlist li a { |
||||||
|
color: inherit; |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
td ul.errorlist { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
td ul.errorlist li { |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.form-row.errors { |
||||||
|
margin: 0; |
||||||
|
border: none; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
background: none; |
||||||
|
} |
||||||
|
|
||||||
|
.form-row.errors ul.errorlist li { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.errors input, .errors select, .errors textarea { |
||||||
|
border: 1px solid #ba2121; |
||||||
|
} |
||||||
|
|
||||||
|
div.system-message { |
||||||
|
background: #ffc; |
||||||
|
margin: 10px; |
||||||
|
padding: 6px 8px; |
||||||
|
font-size: .8em; |
||||||
|
} |
||||||
|
|
||||||
|
div.system-message p.system-message-title { |
||||||
|
padding: 4px 5px 4px 25px; |
||||||
|
margin: 0; |
||||||
|
color: #c11; |
||||||
|
background: #ffefef url(../img/icon-no.svg) 5px 5px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.description { |
||||||
|
font-size: 12px; |
||||||
|
padding: 5px 0 0 12px; |
||||||
|
} |
||||||
|
|
||||||
|
/* BREADCRUMBS */ |
||||||
|
|
||||||
|
div.breadcrumbs { |
||||||
|
background: #79aec8; |
||||||
|
padding: 10px 40px; |
||||||
|
border: none; |
||||||
|
font-size: 14px; |
||||||
|
color: #c4dce8; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
div.breadcrumbs a { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
div.breadcrumbs a:focus, div.breadcrumbs a:hover { |
||||||
|
color: #c4dce8; |
||||||
|
} |
||||||
|
|
||||||
|
/* ACTION ICONS */ |
||||||
|
|
||||||
|
.addlink { |
||||||
|
padding-left: 16px; |
||||||
|
background: url(../img/icon-addlink.svg) 0 1px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.changelink, .inlinechangelink { |
||||||
|
padding-left: 16px; |
||||||
|
background: url(../img/icon-changelink.svg) 0 1px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.deletelink { |
||||||
|
padding-left: 16px; |
||||||
|
background: url(../img/icon-deletelink.svg) 0 1px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
a.deletelink:link, a.deletelink:visited { |
||||||
|
color: #CC3434; |
||||||
|
} |
||||||
|
|
||||||
|
a.deletelink:focus, a.deletelink:hover { |
||||||
|
color: #993333; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* OBJECT TOOLS */ |
||||||
|
|
||||||
|
.object-tools { |
||||||
|
font-size: 10px; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0; |
||||||
|
float: right; |
||||||
|
position: relative; |
||||||
|
margin-top: -48px; |
||||||
|
} |
||||||
|
|
||||||
|
.form-row .object-tools { |
||||||
|
margin-top: 5px; |
||||||
|
margin-bottom: 5px; |
||||||
|
float: none; |
||||||
|
height: 2em; |
||||||
|
padding-left: 3.5em; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools li { |
||||||
|
display: block; |
||||||
|
float: left; |
||||||
|
margin-left: 5px; |
||||||
|
height: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a { |
||||||
|
border-radius: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a:link, .object-tools a:visited { |
||||||
|
display: block; |
||||||
|
float: left; |
||||||
|
padding: 3px 12px; |
||||||
|
background: #999; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 11px; |
||||||
|
text-transform: uppercase; |
||||||
|
letter-spacing: 0.5px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a:focus, .object-tools a:hover { |
||||||
|
background-color: #417690; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a:focus{ |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink { |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-position: 93% center; |
||||||
|
padding-right: 26px; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a.viewsitelink, .object-tools a.golink { |
||||||
|
background-image: url(../img/tooltag-arrowright.svg); |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools a.addlink { |
||||||
|
background-image: url(../img/tooltag-add.svg); |
||||||
|
} |
||||||
|
|
||||||
|
/* OBJECT HISTORY */ |
||||||
|
|
||||||
|
table#change-history { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
table#change-history tbody th { |
||||||
|
width: 16em; |
||||||
|
} |
||||||
|
|
||||||
|
/* PAGE STRUCTURE */ |
||||||
|
|
||||||
|
#container { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
min-width: 980px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#content { |
||||||
|
padding: 20px 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.dashboard #content { |
||||||
|
width: 600px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-main { |
||||||
|
float: left; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related { |
||||||
|
float: right; |
||||||
|
width: 260px; |
||||||
|
position: relative; |
||||||
|
margin-right: -300px; |
||||||
|
} |
||||||
|
|
||||||
|
#footer { |
||||||
|
clear: both; |
||||||
|
padding: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
/* COLUMN TYPES */ |
||||||
|
|
||||||
|
.colMS { |
||||||
|
margin-right: 300px; |
||||||
|
} |
||||||
|
|
||||||
|
.colSM { |
||||||
|
margin-left: 300px; |
||||||
|
} |
||||||
|
|
||||||
|
.colSM #content-related { |
||||||
|
float: left; |
||||||
|
margin-right: 0; |
||||||
|
margin-left: -300px; |
||||||
|
} |
||||||
|
|
||||||
|
.colSM #content-main { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.popup .colM { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
/* HEADER */ |
||||||
|
|
||||||
|
#header { |
||||||
|
width: auto; |
||||||
|
height: 40px; |
||||||
|
padding: 10px 40px; |
||||||
|
background: #417690; |
||||||
|
line-height: 40px; |
||||||
|
color: #ffc; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
#header a:link, #header a:visited { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
#header a:focus , #header a:hover { |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
#branding { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
#branding h1 { |
||||||
|
padding: 0; |
||||||
|
margin: 0 20px 0 0; |
||||||
|
font-weight: 300; |
||||||
|
font-size: 24px; |
||||||
|
color: #f5dd5d; |
||||||
|
} |
||||||
|
|
||||||
|
#branding h1, #branding h1 a:link, #branding h1 a:visited { |
||||||
|
color: #f5dd5d; |
||||||
|
} |
||||||
|
|
||||||
|
#branding h2 { |
||||||
|
padding: 0 10px; |
||||||
|
font-size: 14px; |
||||||
|
margin: -8px 0 8px 0; |
||||||
|
font-weight: normal; |
||||||
|
color: #ffc; |
||||||
|
} |
||||||
|
|
||||||
|
#branding a:hover { |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
#user-tools { |
||||||
|
float: right; |
||||||
|
padding: 0; |
||||||
|
margin: 0 0 0 20px; |
||||||
|
font-weight: 300; |
||||||
|
font-size: 11px; |
||||||
|
letter-spacing: 0.5px; |
||||||
|
text-transform: uppercase; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
#user-tools a { |
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.25); |
||||||
|
} |
||||||
|
|
||||||
|
#user-tools a:focus, #user-tools a:hover { |
||||||
|
text-decoration: none; |
||||||
|
border-bottom-color: #79aec8; |
||||||
|
color: #79aec8; |
||||||
|
} |
||||||
|
|
||||||
|
/* SIDEBAR */ |
||||||
|
|
||||||
|
#content-related { |
||||||
|
background: #f8f8f8; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related .module { |
||||||
|
background: none; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related h3 { |
||||||
|
font-size: 14px; |
||||||
|
color: #666; |
||||||
|
padding: 0 16px; |
||||||
|
margin: 0 0 16px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related h4 { |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related p { |
||||||
|
padding-left: 16px; |
||||||
|
padding-right: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related .actionlist { |
||||||
|
padding: 0; |
||||||
|
margin: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related .actionlist li { |
||||||
|
line-height: 1.2; |
||||||
|
margin-bottom: 10px; |
||||||
|
padding-left: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related .module h2 { |
||||||
|
background: none; |
||||||
|
padding: 16px; |
||||||
|
margin-bottom: 16px; |
||||||
|
border-bottom: 1px solid #eaeaea; |
||||||
|
font-size: 18px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.delete-confirmation form input[type="submit"] { |
||||||
|
background: #ba2121; |
||||||
|
border-radius: 4px; |
||||||
|
padding: 10px 15px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.delete-confirmation form input[type="submit"]:active, |
||||||
|
.delete-confirmation form input[type="submit"]:focus, |
||||||
|
.delete-confirmation form input[type="submit"]:hover { |
||||||
|
background: #a41515; |
||||||
|
} |
||||||
|
|
||||||
|
.delete-confirmation form .cancel-link { |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
height: 15px; |
||||||
|
line-height: 15px; |
||||||
|
background: #ddd; |
||||||
|
border-radius: 4px; |
||||||
|
padding: 10px 15px; |
||||||
|
color: #333; |
||||||
|
margin: 0 0 0 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.delete-confirmation form .cancel-link:active, |
||||||
|
.delete-confirmation form .cancel-link:focus, |
||||||
|
.delete-confirmation form .cancel-link:hover { |
||||||
|
background: #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
/* POPUP */ |
||||||
|
.popup #content { |
||||||
|
padding: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.popup #container { |
||||||
|
min-width: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.popup #header { |
||||||
|
padding: 10px 20px; |
||||||
|
} |
||||||
@ -0,0 +1,341 @@ |
|||||||
|
/* CHANGELISTS */ |
||||||
|
|
||||||
|
#changelist { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list .hiddenfields { display:none; } |
||||||
|
|
||||||
|
.change-list .filtered table { |
||||||
|
border-right: none; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list .filtered { |
||||||
|
min-height: 400px; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list .filtered .results, .change-list .filtered .paginator, |
||||||
|
.filtered #toolbar, .filtered div.xfull { |
||||||
|
margin-right: 280px; |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list .filtered table tbody th { |
||||||
|
padding-right: 1em; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-form .results { |
||||||
|
overflow-x: auto; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .toplinks { |
||||||
|
border-bottom: 1px solid #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .paginator { |
||||||
|
color: #666; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
background: #fff; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
/* CHANGELIST TABLES */ |
||||||
|
|
||||||
|
#changelist table thead th { |
||||||
|
padding: 0; |
||||||
|
white-space: nowrap; |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table thead th.action-checkbox-column { |
||||||
|
width: 1.5em; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table tbody td.action-checkbox { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table tfoot { |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
/* TOOLBAR */ |
||||||
|
|
||||||
|
#changelist #toolbar { |
||||||
|
padding: 8px 10px; |
||||||
|
margin-bottom: 15px; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
background: #f8f8f8; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #toolbar form input { |
||||||
|
border-radius: 4px; |
||||||
|
font-size: 14px; |
||||||
|
padding: 5px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #toolbar form #searchbar { |
||||||
|
height: 19px; |
||||||
|
border: 1px solid #ccc; |
||||||
|
padding: 2px 5px; |
||||||
|
margin: 0; |
||||||
|
vertical-align: top; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #toolbar form #searchbar:focus { |
||||||
|
border-color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #toolbar form input[type="submit"] { |
||||||
|
border: 1px solid #ccc; |
||||||
|
padding: 2px 10px; |
||||||
|
margin: 0; |
||||||
|
vertical-align: middle; |
||||||
|
background: #fff; |
||||||
|
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; |
||||||
|
cursor: pointer; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #toolbar form input[type="submit"]:focus, |
||||||
|
#changelist #toolbar form input[type="submit"]:hover { |
||||||
|
border-color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist #changelist-search img { |
||||||
|
vertical-align: middle; |
||||||
|
margin-right: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
/* FILTER COLUMN */ |
||||||
|
|
||||||
|
#changelist-filter { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
z-index: 1000; |
||||||
|
width: 240px; |
||||||
|
background: #f8f8f8; |
||||||
|
border-left: none; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter h2 { |
||||||
|
font-size: 14px; |
||||||
|
text-transform: uppercase; |
||||||
|
letter-spacing: 0.5px; |
||||||
|
padding: 5px 15px; |
||||||
|
margin-bottom: 12px; |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter h3 { |
||||||
|
font-weight: 400; |
||||||
|
font-size: 14px; |
||||||
|
padding: 0 15px; |
||||||
|
margin-bottom: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter ul { |
||||||
|
margin: 5px 0; |
||||||
|
padding: 0 15px 15px; |
||||||
|
border-bottom: 1px solid #eaeaea; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter ul:last-child { |
||||||
|
border-bottom: none; |
||||||
|
padding-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter li { |
||||||
|
list-style-type: none; |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter a { |
||||||
|
display: block; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter li.selected { |
||||||
|
border-left: 5px solid #eaeaea; |
||||||
|
padding-left: 10px; |
||||||
|
margin-left: -15px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter li.selected a { |
||||||
|
color: #5b80b2; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter a:focus, #changelist-filter a:hover, |
||||||
|
#changelist-filter li.selected a:focus, |
||||||
|
#changelist-filter li.selected a:hover { |
||||||
|
color: #036; |
||||||
|
} |
||||||
|
|
||||||
|
/* DATE DRILLDOWN */ |
||||||
|
|
||||||
|
.change-list ul.toplinks { |
||||||
|
display: block; |
||||||
|
float: left; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list ul.toplinks li { |
||||||
|
padding: 3px 6px; |
||||||
|
font-weight: bold; |
||||||
|
list-style-type: none; |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list ul.toplinks .date-back a { |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list ul.toplinks .date-back a:focus, |
||||||
|
.change-list ul.toplinks .date-back a:hover { |
||||||
|
color: #036; |
||||||
|
} |
||||||
|
|
||||||
|
/* PAGINATOR */ |
||||||
|
|
||||||
|
.paginator { |
||||||
|
font-size: 13px; |
||||||
|
padding-top: 10px; |
||||||
|
padding-bottom: 10px; |
||||||
|
line-height: 22px; |
||||||
|
margin: 0; |
||||||
|
border-top: 1px solid #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator a:link, .paginator a:visited { |
||||||
|
padding: 2px 6px; |
||||||
|
background: #79aec8; |
||||||
|
text-decoration: none; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator a.showall { |
||||||
|
padding: 0; |
||||||
|
border: none; |
||||||
|
background: none; |
||||||
|
color: #5b80b2; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator a.showall:focus, .paginator a.showall:hover { |
||||||
|
background: none; |
||||||
|
color: #036; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator .end { |
||||||
|
margin-right: 6px; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator .this-page { |
||||||
|
padding: 2px 6px; |
||||||
|
font-weight: bold; |
||||||
|
font-size: 13px; |
||||||
|
vertical-align: top; |
||||||
|
} |
||||||
|
|
||||||
|
.paginator a:focus, .paginator a:hover { |
||||||
|
color: white; |
||||||
|
background: #036; |
||||||
|
} |
||||||
|
|
||||||
|
/* ACTIONS */ |
||||||
|
|
||||||
|
.filtered .actions { |
||||||
|
margin-right: 280px; |
||||||
|
border-right: none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table input { |
||||||
|
margin: 0; |
||||||
|
vertical-align: baseline; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table tbody tr.selected { |
||||||
|
background-color: #FFFFCC; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions { |
||||||
|
padding: 10px; |
||||||
|
background: #fff; |
||||||
|
border-top: none; |
||||||
|
border-bottom: none; |
||||||
|
line-height: 24px; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions.selected { |
||||||
|
background: #fffccf; |
||||||
|
border-top: 1px solid #fffee8; |
||||||
|
border-bottom: 1px solid #edecd6; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions span.all, |
||||||
|
#changelist .actions span.action-counter, |
||||||
|
#changelist .actions span.clear, |
||||||
|
#changelist .actions span.question { |
||||||
|
font-size: 13px; |
||||||
|
margin: 0 0.5em; |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions:last-child { |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions select { |
||||||
|
vertical-align: top; |
||||||
|
height: 24px; |
||||||
|
background: none; |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-radius: 4px; |
||||||
|
font-size: 14px; |
||||||
|
padding: 0 0 0 4px; |
||||||
|
margin: 0; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions select:focus { |
||||||
|
border-color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions label { |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions .button { |
||||||
|
font-size: 13px; |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-radius: 4px; |
||||||
|
background: #fff; |
||||||
|
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; |
||||||
|
cursor: pointer; |
||||||
|
height: 24px; |
||||||
|
line-height: 1; |
||||||
|
padding: 4px 8px; |
||||||
|
margin: 0; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist .actions .button:focus, #changelist .actions .button:hover { |
||||||
|
border-color: #999; |
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
/* DASHBOARD */ |
||||||
|
|
||||||
|
.dashboard .module table th { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.dashboard .module table td { |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
|
||||||
|
.dashboard .module table td a { |
||||||
|
display: block; |
||||||
|
padding-right: .6em; |
||||||
|
} |
||||||
|
|
||||||
|
/* RECENT ACTIONS MODULE */ |
||||||
|
|
||||||
|
.module ul.actionlist { |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
ul.actionlist li { |
||||||
|
list-style-type: none; |
||||||
|
} |
||||||
|
|
||||||
|
ul.actionlist li { |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
-o-text-overflow: ellipsis; |
||||||
|
} |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
@font-face { |
||||||
|
font-family: 'Roboto'; |
||||||
|
src: url('../fonts/Roboto-Bold-webfont.woff'); |
||||||
|
font-weight: 700; |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
|
|
||||||
|
@font-face { |
||||||
|
font-family: 'Roboto'; |
||||||
|
src: url('../fonts/Roboto-Regular-webfont.woff'); |
||||||
|
font-weight: 400; |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
|
|
||||||
|
@font-face { |
||||||
|
font-family: 'Roboto'; |
||||||
|
src: url('../fonts/Roboto-Light-webfont.woff'); |
||||||
|
font-weight: 300; |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
@ -0,0 +1,499 @@ |
|||||||
|
@import url('widgets.css'); |
||||||
|
|
||||||
|
/* FORM ROWS */ |
||||||
|
|
||||||
|
.form-row { |
||||||
|
overflow: hidden; |
||||||
|
padding: 10px; |
||||||
|
font-size: 13px; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
.form-row img, .form-row input { |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
|
||||||
|
.form-row label input[type="checkbox"] { |
||||||
|
margin-top: 0; |
||||||
|
vertical-align: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form .form-row p { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.hidden { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* FORM LABELS */ |
||||||
|
|
||||||
|
label { |
||||||
|
font-weight: normal; |
||||||
|
color: #666; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
.required label, label.required { |
||||||
|
font-weight: bold; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
/* RADIO BUTTONS */ |
||||||
|
|
||||||
|
form ul.radiolist li { |
||||||
|
list-style-type: none; |
||||||
|
} |
||||||
|
|
||||||
|
form ul.radiolist label { |
||||||
|
float: none; |
||||||
|
display: inline; |
||||||
|
} |
||||||
|
|
||||||
|
form ul.radiolist input[type="radio"] { |
||||||
|
margin: -2px 4px 0 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form ul.inline { |
||||||
|
margin-left: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form ul.inline li { |
||||||
|
float: left; |
||||||
|
padding-right: 7px; |
||||||
|
} |
||||||
|
|
||||||
|
/* ALIGNED FIELDSETS */ |
||||||
|
|
||||||
|
.aligned label { |
||||||
|
display: block; |
||||||
|
padding: 4px 10px 0 0; |
||||||
|
float: left; |
||||||
|
width: 160px; |
||||||
|
word-wrap: break-word; |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned label:not(.vCheckboxLabel):after { |
||||||
|
content: ''; |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
height: 26px; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned label + p { |
||||||
|
padding: 6px 0; |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 0; |
||||||
|
margin-left: 170px; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned ul label { |
||||||
|
display: inline; |
||||||
|
float: none; |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned .form-row input { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { |
||||||
|
width: 350px; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned ul { |
||||||
|
margin-left: 160px; |
||||||
|
padding-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned ul.radiolist { |
||||||
|
display: inline-block; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned p.help { |
||||||
|
clear: left; |
||||||
|
margin-top: 0; |
||||||
|
margin-left: 160px; |
||||||
|
padding-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned label + p.help { |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned p.help:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned input + p.help, |
||||||
|
form .aligned textarea + p.help, |
||||||
|
form .aligned select + p.help { |
||||||
|
margin-left: 160px; |
||||||
|
padding-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned ul li { |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
form .aligned table p { |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned .vCheckboxLabel { |
||||||
|
float: none; |
||||||
|
width: auto; |
||||||
|
display: inline-block; |
||||||
|
vertical-align: -3px; |
||||||
|
padding: 0 0 5px 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned .vCheckboxLabel + p.help { |
||||||
|
margin-top: -4px; |
||||||
|
} |
||||||
|
|
||||||
|
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { |
||||||
|
width: 610px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkbox-row p.help { |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset .field-box { |
||||||
|
float: left; |
||||||
|
margin-right: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
/* WIDE FIELDSETS */ |
||||||
|
|
||||||
|
.wide label { |
||||||
|
width: 200px; |
||||||
|
} |
||||||
|
|
||||||
|
form .wide p, form .wide input + p.help { |
||||||
|
margin-left: 200px; |
||||||
|
} |
||||||
|
|
||||||
|
form .wide p.help { |
||||||
|
padding-left: 38px; |
||||||
|
} |
||||||
|
|
||||||
|
.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { |
||||||
|
width: 450px; |
||||||
|
} |
||||||
|
|
||||||
|
/* COLLAPSED FIELDSETS */ |
||||||
|
|
||||||
|
fieldset.collapsed * { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset.collapsed h2, fieldset.collapsed { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset.collapsed { |
||||||
|
border: 1px solid #eee; |
||||||
|
border-radius: 4px; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset.collapsed h2 { |
||||||
|
background: #f8f8f8; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset .collapse-toggle { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset.collapsed .collapse-toggle { |
||||||
|
background: transparent; |
||||||
|
display: inline; |
||||||
|
color: #447e9b; |
||||||
|
} |
||||||
|
|
||||||
|
/* MONOSPACE TEXTAREAS */ |
||||||
|
|
||||||
|
fieldset.monospace textarea { |
||||||
|
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; |
||||||
|
} |
||||||
|
|
||||||
|
/* SUBMIT ROW */ |
||||||
|
|
||||||
|
.submit-row { |
||||||
|
padding: 12px 14px; |
||||||
|
margin: 0 0 20px; |
||||||
|
background: #f8f8f8; |
||||||
|
border: 1px solid #eee; |
||||||
|
border-radius: 4px; |
||||||
|
text-align: right; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
body.popup .submit-row { |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row input { |
||||||
|
height: 35px; |
||||||
|
line-height: 15px; |
||||||
|
margin: 0 0 0 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row input.default { |
||||||
|
margin: 0 0 0 8px; |
||||||
|
text-transform: uppercase; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row p { |
||||||
|
margin: 0.3em; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row p.deletelink-box { |
||||||
|
float: left; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row a.deletelink { |
||||||
|
display: block; |
||||||
|
background: #ba2121; |
||||||
|
border-radius: 4px; |
||||||
|
padding: 10px 15px; |
||||||
|
height: 15px; |
||||||
|
line-height: 15px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row a.deletelink:focus, |
||||||
|
.submit-row a.deletelink:hover, |
||||||
|
.submit-row a.deletelink:active { |
||||||
|
background: #a41515; |
||||||
|
} |
||||||
|
|
||||||
|
/* CUSTOM FORM FIELDS */ |
||||||
|
|
||||||
|
.vSelectMultipleField { |
||||||
|
vertical-align: top; |
||||||
|
} |
||||||
|
|
||||||
|
.vCheckboxField { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.vDateField, .vTimeField { |
||||||
|
margin-right: 2px; |
||||||
|
margin-bottom: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.vDateField { |
||||||
|
min-width: 6.85em; |
||||||
|
} |
||||||
|
|
||||||
|
.vTimeField { |
||||||
|
min-width: 4.7em; |
||||||
|
} |
||||||
|
|
||||||
|
.vURLField { |
||||||
|
width: 30em; |
||||||
|
} |
||||||
|
|
||||||
|
.vLargeTextField, .vXMLLargeTextField { |
||||||
|
width: 48em; |
||||||
|
} |
||||||
|
|
||||||
|
.flatpages-flatpage #id_content { |
||||||
|
height: 40.2em; |
||||||
|
} |
||||||
|
|
||||||
|
.module table .vPositiveSmallIntegerField { |
||||||
|
width: 2.2em; |
||||||
|
} |
||||||
|
|
||||||
|
.vTextField { |
||||||
|
width: 20em; |
||||||
|
} |
||||||
|
|
||||||
|
.vIntegerField { |
||||||
|
width: 5em; |
||||||
|
} |
||||||
|
|
||||||
|
.vBigIntegerField { |
||||||
|
width: 10em; |
||||||
|
} |
||||||
|
|
||||||
|
.vForeignKeyRawIdAdminField { |
||||||
|
width: 5em; |
||||||
|
} |
||||||
|
|
||||||
|
/* INLINES */ |
||||||
|
|
||||||
|
.inline-group { |
||||||
|
padding: 0; |
||||||
|
margin: 0 0 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group thead th { |
||||||
|
padding: 8px 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .aligned label { |
||||||
|
width: 160px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related h3 { |
||||||
|
margin: 0; |
||||||
|
color: #666; |
||||||
|
padding: 5px; |
||||||
|
font-size: 13px; |
||||||
|
background: #f8f8f8; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related h3 span.delete { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related h3 span.delete label { |
||||||
|
margin-left: 2px; |
||||||
|
font-size: 11px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related fieldset { |
||||||
|
margin: 0; |
||||||
|
background: #fff; |
||||||
|
border: none; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related fieldset.module h3 { |
||||||
|
margin: 0; |
||||||
|
padding: 2px 5px 3px 5px; |
||||||
|
font-size: 11px; |
||||||
|
text-align: left; |
||||||
|
font-weight: bold; |
||||||
|
background: #bcd; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular fieldset.module { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related.tabular fieldset.module table { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.last-related fieldset { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular tr.has_original td { |
||||||
|
padding-top: 2em; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular tr td.original { |
||||||
|
padding: 2px 0 0 0; |
||||||
|
width: 0; |
||||||
|
_position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular th.original { |
||||||
|
width: 0px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular td.original p { |
||||||
|
position: absolute; |
||||||
|
left: 0; |
||||||
|
height: 1.1em; |
||||||
|
padding: 2px 9px; |
||||||
|
overflow: hidden; |
||||||
|
font-size: 9px; |
||||||
|
font-weight: bold; |
||||||
|
color: #666; |
||||||
|
_width: 700px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group ul.tools { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group ul.tools li { |
||||||
|
display: inline; |
||||||
|
padding: 0 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group div.add-row, |
||||||
|
.inline-group .tabular tr.add-row td { |
||||||
|
color: #666; |
||||||
|
background: #f8f8f8; |
||||||
|
padding: 8px 10px; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group .tabular tr.add-row td { |
||||||
|
padding: 8px 10px; |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-group ul.tools a.add, |
||||||
|
.inline-group div.add-row a, |
||||||
|
.inline-group .tabular tr.add-row td a { |
||||||
|
background: url(../img/icon-addlink.svg) 0 1px no-repeat; |
||||||
|
padding-left: 16px; |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.empty-form { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* RELATED FIELD ADD ONE / LOOKUP */ |
||||||
|
|
||||||
|
.add-another, .related-lookup { |
||||||
|
margin-left: 5px; |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-size: 14px; |
||||||
|
} |
||||||
|
|
||||||
|
.add-another { |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
background-image: url(../img/icon-addlink.svg); |
||||||
|
} |
||||||
|
|
||||||
|
.related-lookup { |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
background-image: url(../img/search.svg); |
||||||
|
} |
||||||
|
|
||||||
|
form .related-widget-wrapper ul { |
||||||
|
display: inline-block; |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.clearable-file-input input { |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
/* LOGIN FORM */ |
||||||
|
|
||||||
|
body.login { |
||||||
|
background: #f8f8f8; |
||||||
|
} |
||||||
|
|
||||||
|
.login #header { |
||||||
|
height: auto; |
||||||
|
padding: 5px 16px; |
||||||
|
} |
||||||
|
|
||||||
|
.login #header h1 { |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
.login #header h1 a { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.login #content { |
||||||
|
padding: 20px 20px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.login #container { |
||||||
|
background: #fff; |
||||||
|
border: 1px solid #eaeaea; |
||||||
|
border-radius: 4px; |
||||||
|
overflow: hidden; |
||||||
|
width: 28em; |
||||||
|
min-width: 300px; |
||||||
|
margin: 100px auto; |
||||||
|
} |
||||||
|
|
||||||
|
.login #content-main { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.login .form-row { |
||||||
|
padding: 4px 0; |
||||||
|
float: left; |
||||||
|
width: 100%; |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
.login .form-row label { |
||||||
|
padding-right: 0.5em; |
||||||
|
line-height: 2em; |
||||||
|
font-size: 1em; |
||||||
|
clear: both; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.login .form-row #id_username, .login .form-row #id_password { |
||||||
|
clear: both; |
||||||
|
padding: 8px; |
||||||
|
width: 100%; |
||||||
|
-webkit-box-sizing: border-box; |
||||||
|
-moz-box-sizing: border-box; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
|
||||||
|
.login span.help { |
||||||
|
font-size: 10px; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.login .submit-row { |
||||||
|
clear: both; |
||||||
|
padding: 1em 0 0 9.4em; |
||||||
|
margin: 0; |
||||||
|
border: none; |
||||||
|
background: none; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.login .password-reset-link { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
@ -0,0 +1,256 @@ |
|||||||
|
body { |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
/* LOGIN */ |
||||||
|
|
||||||
|
.login .form-row { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.login .form-row label { |
||||||
|
float: right; |
||||||
|
padding-left: 0.5em; |
||||||
|
padding-right: 0; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.login .submit-row { |
||||||
|
clear: both; |
||||||
|
padding: 1em 9.4em 0 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* GLOBAL */ |
||||||
|
|
||||||
|
th { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.module h2, .module caption { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.module ul, .module ol { |
||||||
|
margin-left: 0; |
||||||
|
margin-right: 1.5em; |
||||||
|
} |
||||||
|
|
||||||
|
.addlink, .changelink { |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 16px; |
||||||
|
background-position: 100% 1px; |
||||||
|
} |
||||||
|
|
||||||
|
.deletelink { |
||||||
|
padding-left: 0; |
||||||
|
padding-right: 16px; |
||||||
|
background-position: 100% 1px; |
||||||
|
} |
||||||
|
|
||||||
|
.object-tools { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
thead th:first-child, |
||||||
|
tfoot td:first-child { |
||||||
|
border-left: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* LAYOUT */ |
||||||
|
|
||||||
|
#user-tools { |
||||||
|
right: auto; |
||||||
|
left: 0; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
div.breadcrumbs { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
#content-main { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
#content-related { |
||||||
|
float: left; |
||||||
|
margin-left: -300px; |
||||||
|
margin-right: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.colMS { |
||||||
|
margin-left: 300px; |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
/* SORTABLE TABLES */ |
||||||
|
|
||||||
|
table thead th.sorted .sortoptions { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
thead th.sorted .text { |
||||||
|
padding-right: 0; |
||||||
|
padding-left: 42px; |
||||||
|
} |
||||||
|
|
||||||
|
/* dashboard styles */ |
||||||
|
|
||||||
|
.dashboard .module table td a { |
||||||
|
padding-left: .6em; |
||||||
|
padding-right: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
/* changelists styles */ |
||||||
|
|
||||||
|
.change-list .filtered table { |
||||||
|
border-left: none; |
||||||
|
border-right: 0px none; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter { |
||||||
|
right: auto; |
||||||
|
left: 0; |
||||||
|
border-left: none; |
||||||
|
border-right: none; |
||||||
|
} |
||||||
|
|
||||||
|
.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { |
||||||
|
margin-right: 0; |
||||||
|
margin-left: 280px; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist-filter li.selected { |
||||||
|
border-left: none; |
||||||
|
padding-left: 10px; |
||||||
|
margin-left: 0; |
||||||
|
border-right: 5px solid #eaeaea; |
||||||
|
padding-right: 10px; |
||||||
|
margin-right: -15px; |
||||||
|
} |
||||||
|
|
||||||
|
.filtered .actions { |
||||||
|
margin-left: 280px; |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#changelist table tbody td:first-child, #changelist table tbody th:first-child { |
||||||
|
border-right: none; |
||||||
|
border-left: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* FORMS */ |
||||||
|
|
||||||
|
.aligned label { |
||||||
|
padding: 0 0 3px 1em; |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row { |
||||||
|
text-align: left |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row p.deletelink-box { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row input.default { |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.vDateField, .vTimeField { |
||||||
|
margin-left: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned .form-row input { |
||||||
|
margin-left: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
form ul.inline li { |
||||||
|
float: right; |
||||||
|
padding-right: 0; |
||||||
|
padding-left: 7px; |
||||||
|
} |
||||||
|
|
||||||
|
input[type=submit].default, .submit-row input.default { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset .field-box { |
||||||
|
float: right; |
||||||
|
margin-left: 20px; |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.errorlist li { |
||||||
|
background-position: 100% 12px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.errornote { |
||||||
|
background-position: 100% 12px; |
||||||
|
padding: 10px 12px; |
||||||
|
} |
||||||
|
|
||||||
|
/* WIDGETS */ |
||||||
|
|
||||||
|
.calendarnav-previous { |
||||||
|
top: 0; |
||||||
|
left: auto; |
||||||
|
right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarnav-next { |
||||||
|
top: 0; |
||||||
|
right: auto; |
||||||
|
left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar caption, .calendarbox h2 { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.selector { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-filter { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-deletelink { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
form .form-row p.datetime { |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
/* MISC */ |
||||||
|
|
||||||
|
.inline-related h2, .inline-group h2 { |
||||||
|
text-align: right |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related h3 span.delete { |
||||||
|
padding-right: 20px; |
||||||
|
padding-left: inherit; |
||||||
|
left: 10px; |
||||||
|
right: inherit; |
||||||
|
float:left; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-related h3 span.delete label { |
||||||
|
margin-left: inherit; |
||||||
|
margin-right: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
/* IE7 specific bug fixes */ |
||||||
|
|
||||||
|
div.colM { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.submit-row input { |
||||||
|
float: left; |
||||||
|
} |
||||||
@ -0,0 +1,565 @@ |
|||||||
|
/* SELECTOR (FILTER INTERFACE) */ |
||||||
|
|
||||||
|
.selector { |
||||||
|
width: 800px; |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
.selector select { |
||||||
|
width: 380px; |
||||||
|
height: 17.2em; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-available, .selector-chosen { |
||||||
|
float: left; |
||||||
|
width: 380px; |
||||||
|
text-align: center; |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-chosen select { |
||||||
|
border-top: none; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-available h2, .selector-chosen h2 { |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-radius: 4px 4px 0 0; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-chosen h2 { |
||||||
|
background: #79aec8; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-available h2 { |
||||||
|
background: #f8f8f8; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-filter { |
||||||
|
background: white; |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-width: 0 1px; |
||||||
|
padding: 8px; |
||||||
|
color: #999; |
||||||
|
font-size: 10px; |
||||||
|
margin: 0; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-filter label, |
||||||
|
.inline-group .aligned .selector .selector-filter label { |
||||||
|
float: left; |
||||||
|
margin: 7px 0 0; |
||||||
|
width: 18px; |
||||||
|
height: 18px; |
||||||
|
padding: 0; |
||||||
|
overflow: hidden; |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-available input { |
||||||
|
width: 320px; |
||||||
|
margin-left: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
.selector ul.selector-chooser { |
||||||
|
float: left; |
||||||
|
width: 22px; |
||||||
|
background-color: #eee; |
||||||
|
border-radius: 10px; |
||||||
|
margin: 10em 5px 0 5px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-chooser li { |
||||||
|
margin: 0; |
||||||
|
padding: 3px; |
||||||
|
list-style-type: none; |
||||||
|
} |
||||||
|
|
||||||
|
.selector select { |
||||||
|
padding: 0 10px; |
||||||
|
margin: 0 0 10px; |
||||||
|
border-radius: 0 0 4px 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-add, .selector-remove { |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
display: block; |
||||||
|
text-indent: -3000px; |
||||||
|
overflow: hidden; |
||||||
|
cursor: default; |
||||||
|
opacity: 0.3; |
||||||
|
} |
||||||
|
|
||||||
|
.active.selector-add, .active.selector-remove { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.active.selector-add:hover, .active.selector-remove:hover { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-add { |
||||||
|
background: url(../img/selector-icons.svg) 0 -96px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.active.selector-add:focus, .active.selector-add:hover { |
||||||
|
background-position: 0 -112px; |
||||||
|
} |
||||||
|
|
||||||
|
.selector-remove { |
||||||
|
background: url(../img/selector-icons.svg) 0 -64px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.active.selector-remove:focus, .active.selector-remove:hover { |
||||||
|
background-position: 0 -80px; |
||||||
|
} |
||||||
|
|
||||||
|
a.selector-chooseall, a.selector-clearall { |
||||||
|
display: inline-block; |
||||||
|
height: 16px; |
||||||
|
text-align: left; |
||||||
|
margin: 1px auto 3px; |
||||||
|
overflow: hidden; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 16px; |
||||||
|
color: #666; |
||||||
|
text-decoration: none; |
||||||
|
opacity: 0.3; |
||||||
|
} |
||||||
|
|
||||||
|
a.active.selector-chooseall:focus, a.active.selector-clearall:focus, |
||||||
|
a.active.selector-chooseall:hover, a.active.selector-clearall:hover { |
||||||
|
color: #447e9b; |
||||||
|
} |
||||||
|
|
||||||
|
a.active.selector-chooseall, a.active.selector-clearall { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
a.active.selector-chooseall:hover, a.active.selector-clearall:hover { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
a.selector-chooseall { |
||||||
|
padding: 0 18px 0 0; |
||||||
|
background: url(../img/selector-icons.svg) right -160px no-repeat; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { |
||||||
|
background-position: 100% -176px; |
||||||
|
} |
||||||
|
|
||||||
|
a.selector-clearall { |
||||||
|
padding: 0 0 0 18px; |
||||||
|
background: url(../img/selector-icons.svg) 0 -128px no-repeat; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
a.active.selector-clearall:focus, a.active.selector-clearall:hover { |
||||||
|
background-position: 0 -144px; |
||||||
|
} |
||||||
|
|
||||||
|
/* STACKED SELECTORS */ |
||||||
|
|
||||||
|
.stacked { |
||||||
|
float: left; |
||||||
|
width: 490px; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked select { |
||||||
|
width: 480px; |
||||||
|
height: 10.1em; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-available, .stacked .selector-chosen { |
||||||
|
width: 480px; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-available { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-available input { |
||||||
|
width: 422px; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked ul.selector-chooser { |
||||||
|
height: 22px; |
||||||
|
width: 50px; |
||||||
|
margin: 0 0 10px 40%; |
||||||
|
background-color: #eee; |
||||||
|
border-radius: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-chooser li { |
||||||
|
float: left; |
||||||
|
padding: 3px 3px 3px 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-chooseall, .stacked .selector-clearall { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-add { |
||||||
|
background: url(../img/selector-icons.svg) 0 -32px no-repeat; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .active.selector-add { |
||||||
|
background-position: 0 -48px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .selector-remove { |
||||||
|
background: url(../img/selector-icons.svg) 0 0 no-repeat; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
.stacked .active.selector-remove { |
||||||
|
background-position: 0 -16px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .help-icon { |
||||||
|
background: url(../img/icon-unknown.svg) 0 0 no-repeat; |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
margin: -2px 0 0 2px; |
||||||
|
width: 13px; |
||||||
|
height: 13px; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .selector-chosen .help-icon { |
||||||
|
background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.selector .search-label-icon { |
||||||
|
background: url(../img/search.svg) 0 0 no-repeat; |
||||||
|
display: inline-block; |
||||||
|
height: 18px; |
||||||
|
width: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
/* DATE AND TIME */ |
||||||
|
|
||||||
|
p.datetime { |
||||||
|
line-height: 20px; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
color: #666; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.datetime span { |
||||||
|
white-space: nowrap; |
||||||
|
font-weight: normal; |
||||||
|
font-size: 11px; |
||||||
|
color: #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { |
||||||
|
min-width: 0; |
||||||
|
margin-left: 5px; |
||||||
|
margin-bottom: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
table p.datetime { |
||||||
|
font-size: 11px; |
||||||
|
margin-left: 0; |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon { |
||||||
|
position: relative; |
||||||
|
display: inline-block; |
||||||
|
vertical-align: middle; |
||||||
|
height: 16px; |
||||||
|
width: 16px; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.datetimeshortcuts .clock-icon { |
||||||
|
background: url(../img/icon-clock.svg) 0 0 no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.datetimeshortcuts a:focus .clock-icon, |
||||||
|
.datetimeshortcuts a:hover .clock-icon { |
||||||
|
background-position: 0 -16px; |
||||||
|
} |
||||||
|
|
||||||
|
.datetimeshortcuts .date-icon { |
||||||
|
background: url(../img/icon-calendar.svg) 0 0 no-repeat; |
||||||
|
top: -1px; |
||||||
|
} |
||||||
|
|
||||||
|
.datetimeshortcuts a:focus .date-icon, |
||||||
|
.datetimeshortcuts a:hover .date-icon { |
||||||
|
background-position: 0 -16px; |
||||||
|
} |
||||||
|
|
||||||
|
.timezonewarning { |
||||||
|
font-size: 11px; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
/* URL */ |
||||||
|
|
||||||
|
p.url { |
||||||
|
line-height: 20px; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
color: #666; |
||||||
|
font-size: 11px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.url a { |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
|
|
||||||
|
/* FILE UPLOADS */ |
||||||
|
|
||||||
|
p.file-upload { |
||||||
|
line-height: 20px; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
color: #666; |
||||||
|
font-size: 11px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.aligned p.file-upload { |
||||||
|
margin-left: 170px; |
||||||
|
} |
||||||
|
|
||||||
|
.file-upload a { |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
|
|
||||||
|
.file-upload .deletelink { |
||||||
|
margin-left: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
span.clearable-file-input label { |
||||||
|
color: #333; |
||||||
|
font-size: 11px; |
||||||
|
display: inline; |
||||||
|
float: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* CALENDARS & CLOCKS */ |
||||||
|
|
||||||
|
.calendarbox, .clockbox { |
||||||
|
margin: 5px auto; |
||||||
|
font-size: 12px; |
||||||
|
width: 19em; |
||||||
|
text-align: center; |
||||||
|
background: white; |
||||||
|
border: 1px solid #ddd; |
||||||
|
border-radius: 4px; |
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); |
||||||
|
overflow: hidden; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.clockbox { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar table { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
border-collapse: collapse; |
||||||
|
background: white; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar caption, .calendarbox h2 { |
||||||
|
margin: 0; |
||||||
|
text-align: center; |
||||||
|
border-top: none; |
||||||
|
background: #f5dd5d; |
||||||
|
font-weight: 700; |
||||||
|
font-size: 12px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar th { |
||||||
|
padding: 8px 5px; |
||||||
|
background: #f8f8f8; |
||||||
|
border-bottom: 1px solid #ddd; |
||||||
|
font-weight: 400; |
||||||
|
font-size: 12px; |
||||||
|
text-align: center; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td { |
||||||
|
font-weight: 400; |
||||||
|
font-size: 12px; |
||||||
|
text-align: center; |
||||||
|
padding: 0; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td.selected a { |
||||||
|
background: #79aec8; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td.nonday { |
||||||
|
background: #f8f8f8; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td.today a { |
||||||
|
font-weight: 700; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td a, .timelist a { |
||||||
|
display: block; |
||||||
|
font-weight: 400; |
||||||
|
padding: 6px; |
||||||
|
text-decoration: none; |
||||||
|
color: #444; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td a:focus, .timelist a:focus, |
||||||
|
.calendar td a:hover, .timelist a:hover { |
||||||
|
background: #79aec8; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar td a:active, .timelist a:active { |
||||||
|
background: #417690; |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarnav { |
||||||
|
font-size: 10px; |
||||||
|
text-align: center; |
||||||
|
color: #ccc; |
||||||
|
margin: 0; |
||||||
|
padding: 1px 3px; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarnav a:link, #calendarnav a:visited, |
||||||
|
#calendarnav a:focus, #calendarnav a:hover { |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-shortcuts { |
||||||
|
background: white; |
||||||
|
font-size: 11px; |
||||||
|
line-height: 11px; |
||||||
|
border-top: 1px solid #eee; |
||||||
|
padding: 8px 0; |
||||||
|
color: #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { |
||||||
|
display: block; |
||||||
|
position: absolute; |
||||||
|
top: 8px; |
||||||
|
width: 15px; |
||||||
|
height: 15px; |
||||||
|
text-indent: -9999px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarnav-previous { |
||||||
|
left: 10px; |
||||||
|
background: url(../img/calendar-icons.svg) 0 0 no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarbox .calendarnav-previous:focus, |
||||||
|
.calendarbox .calendarnav-previous:hover { |
||||||
|
background-position: 0 -15px; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarnav-next { |
||||||
|
right: 10px; |
||||||
|
background: url(../img/calendar-icons.svg) 0 -30px no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
.calendarbox .calendarnav-next:focus, |
||||||
|
.calendarbox .calendarnav-next:hover { |
||||||
|
background-position: 0 -45px; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-cancel { |
||||||
|
margin: 0; |
||||||
|
padding: 4px 0; |
||||||
|
font-size: 12px; |
||||||
|
background: #eee; |
||||||
|
border-top: 1px solid #ddd; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-cancel:focus, .calendar-cancel:hover { |
||||||
|
background: #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-cancel a { |
||||||
|
color: black; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
ul.timelist, .timelist li { |
||||||
|
list-style-type: none; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.timelist a { |
||||||
|
padding: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
/* EDIT INLINE */ |
||||||
|
|
||||||
|
.inline-deletelink { |
||||||
|
float: right; |
||||||
|
text-indent: -9999px; |
||||||
|
background: url(../img/inline-delete.svg) 0 0 no-repeat; |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
border: 0px none; |
||||||
|
} |
||||||
|
|
||||||
|
.inline-deletelink:focus, .inline-deletelink:hover { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
/* RELATED WIDGET WRAPPER */ |
||||||
|
.related-widget-wrapper { |
||||||
|
float: left; /* display properly in form rows with multiple fields */ |
||||||
|
overflow: hidden; /* clear floated contents */ |
||||||
|
} |
||||||
|
|
||||||
|
.related-widget-wrapper-link { |
||||||
|
opacity: 0.3; |
||||||
|
} |
||||||
|
|
||||||
|
.related-widget-wrapper-link:link { |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
|
||||||
|
.related-widget-wrapper-link:link:focus, |
||||||
|
.related-widget-wrapper-link:link:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
select + .related-widget-wrapper-link, |
||||||
|
.related-widget-wrapper-link + .related-widget-wrapper-link { |
||||||
|
margin-left: 7px; |
||||||
|
} |
||||||
@ -0,0 +1,202 @@ |
|||||||
|
|
||||||
|
Apache License |
||||||
|
Version 2.0, January 2004 |
||||||
|
http://www.apache.org/licenses/ |
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||||
|
|
||||||
|
1. Definitions. |
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||||
|
the copyright owner that is granting the License. |
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||||
|
other entities that control, are controlled by, or are under common |
||||||
|
control with that entity. For the purposes of this definition, |
||||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||||
|
direction or management of such entity, whether by contract or |
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||||
|
exercising permissions granted by this License. |
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, |
||||||
|
including but not limited to software source code, documentation |
||||||
|
source, and configuration files. |
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical |
||||||
|
transformation or translation of a Source form, including but |
||||||
|
not limited to compiled object code, generated documentation, |
||||||
|
and conversions to other media types. |
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||||
|
Object form, made available under the License, as indicated by a |
||||||
|
copyright notice that is included in or attached to the work |
||||||
|
(an example is provided in the Appendix below). |
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||||
|
form, that is based on (or derived from) the Work and for which the |
||||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||||
|
of this License, Derivative Works shall not include works that remain |
||||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||||
|
the Work and Derivative Works thereof. |
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including |
||||||
|
the original version of the Work and any modifications or additions |
||||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||||
|
means any form of electronic, verbal, or written communication sent |
||||||
|
to the Licensor or its representatives, including but not limited to |
||||||
|
communication on electronic mailing lists, source code control systems, |
||||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||||
|
excluding communication that is conspicuously marked or otherwise |
||||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||||
|
subsequently incorporated within the Work. |
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||||
|
Work and such Derivative Works in Source or Object form. |
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
(except as stated in this section) patent license to make, have made, |
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||||
|
where such license applies only to those patent claims licensable |
||||||
|
by such Contributor that are necessarily infringed by their |
||||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||||
|
institute patent litigation against any entity (including a |
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||||
|
or a Contribution incorporated within the Work constitutes direct |
||||||
|
or contributory patent infringement, then any patent licenses |
||||||
|
granted to You under this License for that Work shall terminate |
||||||
|
as of the date such litigation is filed. |
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||||
|
Work or Derivative Works thereof in any medium, with or without |
||||||
|
modifications, and in Source or Object form, provided that You |
||||||
|
meet the following conditions: |
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or |
||||||
|
Derivative Works a copy of this License; and |
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices |
||||||
|
stating that You changed the files; and |
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||||
|
that You distribute, all copyright, patent, trademark, and |
||||||
|
attribution notices from the Source form of the Work, |
||||||
|
excluding those notices that do not pertain to any part of |
||||||
|
the Derivative Works; and |
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||||
|
distribution, then any Derivative Works that You distribute must |
||||||
|
include a readable copy of the attribution notices contained |
||||||
|
within such NOTICE file, excluding those notices that do not |
||||||
|
pertain to any part of the Derivative Works, in at least one |
||||||
|
of the following places: within a NOTICE text file distributed |
||||||
|
as part of the Derivative Works; within the Source form or |
||||||
|
documentation, if provided along with the Derivative Works; or, |
||||||
|
within a display generated by the Derivative Works, if and |
||||||
|
wherever such third-party notices normally appear. The contents |
||||||
|
of the NOTICE file are for informational purposes only and |
||||||
|
do not modify the License. You may add Your own attribution |
||||||
|
notices within Derivative Works that You distribute, alongside |
||||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||||
|
that such additional attribution notices cannot be construed |
||||||
|
as modifying the License. |
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and |
||||||
|
may provide additional or different license terms and conditions |
||||||
|
for use, reproduction, or distribution of Your modifications, or |
||||||
|
for any such Derivative Works as a whole, provided Your use, |
||||||
|
reproduction, and distribution of the Work otherwise complies with |
||||||
|
the conditions stated in this License. |
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||||
|
by You to the Licensor shall be under the terms and conditions of |
||||||
|
this License, without any additional terms or conditions. |
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||||
|
the terms of any separate license agreement you may have executed |
||||||
|
with Licensor regarding such Contributions. |
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||||
|
except as required for reasonable and customary use in describing the |
||||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||||
|
agreed to in writing, Licensor provides the Work (and each |
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||||
|
implied, including, without limitation, any warranties or conditions |
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||||
|
appropriateness of using or redistributing the Work and assume any |
||||||
|
risks associated with Your exercise of permissions under this License. |
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||||
|
whether in tort (including negligence), contract, or otherwise, |
||||||
|
unless required by applicable law (such as deliberate and grossly |
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||||
|
liable to You for damages, including any direct, indirect, special, |
||||||
|
incidental, or consequential damages of any character arising as a |
||||||
|
result of this License or out of the use or inability to use the |
||||||
|
Work (including but not limited to damages for loss of goodwill, |
||||||
|
work stoppage, computer failure or malfunction, or any and all |
||||||
|
other commercial damages or losses), even if such Contributor |
||||||
|
has been advised of the possibility of such damages. |
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||||
|
or other liability obligations and/or rights consistent with this |
||||||
|
License. However, in accepting such obligations, You may act only |
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||||
|
of any other Contributor, and only if You agree to indemnify, |
||||||
|
defend, and hold each Contributor harmless for any liability |
||||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||||
|
of your accepting any such warranty or additional liability. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work. |
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following |
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||||
|
replaced with your own identifying information. (Don't include |
||||||
|
the brackets!) The text should be enclosed in the appropriate |
||||||
|
comment syntax for the file format. We also recommend that a |
||||||
|
file or class name and description of purpose be included on the |
||||||
|
same "printed page" as the copyright notice for easier |
||||||
|
identification within third-party archives. |
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] |
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
you may not use this file except in compliance with the License. |
||||||
|
You may obtain a copy of the License at |
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software |
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
See the License for the specific language governing permissions and |
||||||
|
limitations under the License. |
||||||
@ -0,0 +1,2 @@ |
|||||||
|
Roboto webfont source: https://www.google.com/fonts/specimen/Roboto |
||||||
|
Weights used in this project: Light (300), Regular (400), Bold (700) |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
The MIT License (MIT) |
||||||
|
|
||||||
|
Copyright (c) 2014 Code Charm Ltd |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||||
|
this software and associated documentation files (the "Software"), to deal in |
||||||
|
the Software without restriction, including without limitation the rights to |
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so, |
||||||
|
subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
All icons are taken from Font Awesome (http://fontawesome.io/) project. |
||||||
|
The Font Awesome font is licensed under the SIL OFL 1.1: |
||||||
|
- http://scripts.sil.org/OFL |
||||||
|
|
||||||
|
SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG |
||||||
|
Font-Awesome-SVG-PNG is licensed under the MIT license (see file license |
||||||
|
in current folder). |
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 331 B |
|
After Width: | Height: | Size: 504 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 380 B |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 392 B |
|
After Width: | Height: | Size: 560 B |
|
After Width: | Height: | Size: 655 B |
|
After Width: | Height: | Size: 655 B |
|
After Width: | Height: | Size: 436 B |
|
After Width: | Height: | Size: 560 B |
|
After Width: | Height: | Size: 458 B |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 331 B |
|
After Width: | Height: | Size: 280 B |
@ -0,0 +1,135 @@ |
|||||||
|
(function() { |
||||||
|
'use strict'; |
||||||
|
var SelectBox = { |
||||||
|
cache: {}, |
||||||
|
init: function(id) { |
||||||
|
var box = document.getElementById(id); |
||||||
|
var node; |
||||||
|
SelectBox.cache[id] = []; |
||||||
|
var cache = SelectBox.cache[id]; |
||||||
|
for (var i = 0, j = box.options.length; i < j; i++) { |
||||||
|
node = box.options[i]; |
||||||
|
cache.push({value: node.value, text: node.text, displayed: 1}); |
||||||
|
} |
||||||
|
}, |
||||||
|
redisplay: function(id) { |
||||||
|
// Repopulate HTML select box from cache
|
||||||
|
var box = document.getElementById(id); |
||||||
|
var node; |
||||||
|
box.options.length = 0; // clear all options
|
||||||
|
var cache = SelectBox.cache[id]; |
||||||
|
for (var i = 0, j = cache.length; i < j; i++) { |
||||||
|
node = cache[i]; |
||||||
|
if (node.displayed) { |
||||||
|
var new_option = new Option(node.text, node.value, false, false); |
||||||
|
// Shows a tooltip when hovering over the option
|
||||||
|
new_option.setAttribute("title", node.text); |
||||||
|
box.options[box.options.length] = new_option; |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
filter: function(id, text) { |
||||||
|
// Redisplay the HTML select box, displaying only the choices containing ALL
|
||||||
|
// the words in text. (It's an AND search.)
|
||||||
|
var tokens = text.toLowerCase().split(/\s+/); |
||||||
|
var node, token; |
||||||
|
var cache = SelectBox.cache[id]; |
||||||
|
for (var i = 0, j = cache.length; i < j; i++) { |
||||||
|
node = cache[i]; |
||||||
|
node.displayed = 1; |
||||||
|
var numTokens = tokens.length; |
||||||
|
for (var k = 0; k < numTokens; k++) { |
||||||
|
token = tokens[k]; |
||||||
|
if (node.text.toLowerCase().indexOf(token) === -1) { |
||||||
|
node.displayed = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
SelectBox.redisplay(id); |
||||||
|
}, |
||||||
|
delete_from_cache: function(id, value) { |
||||||
|
var node, delete_index = null; |
||||||
|
var cache = SelectBox.cache[id]; |
||||||
|
for (var i = 0, j = cache.length; i < j; i++) { |
||||||
|
node = cache[i]; |
||||||
|
if (node.value === value) { |
||||||
|
delete_index = i; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
var k = cache.length - 1; |
||||||
|
for (i = delete_index; i < k; i++) { |
||||||
|
cache[i] = cache[i + 1]; |
||||||
|
} |
||||||
|
cache.length--; |
||||||
|
}, |
||||||
|
add_to_cache: function(id, option) { |
||||||
|
SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); |
||||||
|
}, |
||||||
|
cache_contains: function(id, value) { |
||||||
|
// Check if an item is contained in the cache
|
||||||
|
var node; |
||||||
|
var cache = SelectBox.cache[id]; |
||||||
|
for (var i = 0, j = cache.length; i < j; i++) { |
||||||
|
node = cache[i]; |
||||||
|
if (node.value === value) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
}, |
||||||
|
move: function(from, to) { |
||||||
|
var from_box = document.getElementById(from); |
||||||
|
var option; |
||||||
|
var boxOptions = from_box.options; |
||||||
|
for (var i = 0, j = boxOptions.length; i < j; i++) { |
||||||
|
option = boxOptions[i]; |
||||||
|
if (option.selected && SelectBox.cache_contains(from, option.value)) { |
||||||
|
SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); |
||||||
|
SelectBox.delete_from_cache(from, option.value); |
||||||
|
} |
||||||
|
} |
||||||
|
SelectBox.redisplay(from); |
||||||
|
SelectBox.redisplay(to); |
||||||
|
}, |
||||||
|
move_all: function(from, to) { |
||||||
|
var from_box = document.getElementById(from); |
||||||
|
var option; |
||||||
|
var boxOptions = from_box.options; |
||||||
|
for (var i = 0, j = boxOptions.length; i < j; i++) { |
||||||
|
option = boxOptions[i]; |
||||||
|
if (SelectBox.cache_contains(from, option.value)) { |
||||||
|
SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); |
||||||
|
SelectBox.delete_from_cache(from, option.value); |
||||||
|
} |
||||||
|
} |
||||||
|
SelectBox.redisplay(from); |
||||||
|
SelectBox.redisplay(to); |
||||||
|
}, |
||||||
|
sort: function(id) { |
||||||
|
SelectBox.cache[id].sort(function(a, b) { |
||||||
|
a = a.text.toLowerCase(); |
||||||
|
b = b.text.toLowerCase(); |
||||||
|
try { |
||||||
|
if (a > b) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
if (a < b) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
} |
||||||
|
catch (e) { |
||||||
|
// silently fail on IE 'unknown' exception
|
||||||
|
} |
||||||
|
return 0; |
||||||
|
} ); |
||||||
|
}, |
||||||
|
select_all: function(id) { |
||||||
|
var box = document.getElementById(id); |
||||||
|
for (var i = 0; i < box.options.length; i++) { |
||||||
|
box.options[i].selected = 'selected'; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
window.SelectBox = SelectBox; |
||||||
|
})(); |
||||||
@ -0,0 +1,198 @@ |
|||||||
|
/*global SelectBox, addEvent, gettext, interpolate, quickElement, SelectFilter*/ |
||||||
|
/* |
||||||
|
SelectFilter2 - Turns a multiple-select box into a filter interface. |
||||||
|
|
||||||
|
Requires core.js, SelectBox.js and addevent.js. |
||||||
|
*/ |
||||||
|
(function($) { |
||||||
|
'use strict'; |
||||||
|
function findForm(node) { |
||||||
|
// returns the node of the form containing the given node
|
||||||
|
if (node.tagName.toLowerCase() !== 'form') { |
||||||
|
return findForm(node.parentNode); |
||||||
|
} |
||||||
|
return node; |
||||||
|
} |
||||||
|
|
||||||
|
window.SelectFilter = { |
||||||
|
init: function(field_id, field_name, is_stacked) { |
||||||
|
if (field_id.match(/__prefix__/)) { |
||||||
|
// Don't initialize on empty forms.
|
||||||
|
return; |
||||||
|
} |
||||||
|
var from_box = document.getElementById(field_id); |
||||||
|
from_box.id += '_from'; // change its ID
|
||||||
|
from_box.className = 'filtered'; |
||||||
|
|
||||||
|
var ps = from_box.parentNode.getElementsByTagName('p'); |
||||||
|
for (var i = 0; i < ps.length; i++) { |
||||||
|
if (ps[i].className.indexOf("info") !== -1) { |
||||||
|
// Remove <p class="info">, because it just gets in the way.
|
||||||
|
from_box.parentNode.removeChild(ps[i]); |
||||||
|
} else if (ps[i].className.indexOf("help") !== -1) { |
||||||
|
// Move help text up to the top so it isn't below the select
|
||||||
|
// boxes or wrapped off on the side to the right of the add
|
||||||
|
// button:
|
||||||
|
from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// <div class="selector"> or <div class="selector stacked">
|
||||||
|
var selector_div = quickElement('div', from_box.parentNode); |
||||||
|
selector_div.className = is_stacked ? 'selector stacked' : 'selector'; |
||||||
|
|
||||||
|
// <div class="selector-available">
|
||||||
|
var selector_available = quickElement('div', selector_div); |
||||||
|
selector_available.className = 'selector-available'; |
||||||
|
var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); |
||||||
|
quickElement( |
||||||
|
'span', title_available, '', |
||||||
|
'class', 'help help-tooltip help-icon', |
||||||
|
'title', interpolate( |
||||||
|
gettext( |
||||||
|
'This is the list of available %s. You may choose some by ' + |
||||||
|
'selecting them in the box below and then clicking the ' + |
||||||
|
'"Choose" arrow between the two boxes.' |
||||||
|
), |
||||||
|
[field_name] |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); |
||||||
|
filter_p.className = 'selector-filter'; |
||||||
|
|
||||||
|
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input'); |
||||||
|
|
||||||
|
quickElement( |
||||||
|
'span', search_filter_label, '', |
||||||
|
'class', 'help-tooltip search-label-icon', |
||||||
|
'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]) |
||||||
|
); |
||||||
|
|
||||||
|
filter_p.appendChild(document.createTextNode(' ')); |
||||||
|
|
||||||
|
var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); |
||||||
|
filter_input.id = field_id + '_input'; |
||||||
|
|
||||||
|
selector_available.appendChild(from_box); |
||||||
|
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_add_all_link'); |
||||||
|
choose_all.className = 'selector-chooseall'; |
||||||
|
|
||||||
|
// <ul class="selector-chooser">
|
||||||
|
var selector_chooser = quickElement('ul', selector_div); |
||||||
|
selector_chooser.className = 'selector-chooser'; |
||||||
|
var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript:void(0);', 'id', field_id + '_add_link'); |
||||||
|
add_link.className = 'selector-add'; |
||||||
|
var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript:void(0);', 'id', field_id + '_remove_link'); |
||||||
|
remove_link.className = 'selector-remove'; |
||||||
|
|
||||||
|
// <div class="selector-chosen">
|
||||||
|
var selector_chosen = quickElement('div', selector_div); |
||||||
|
selector_chosen.className = 'selector-chosen'; |
||||||
|
var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); |
||||||
|
quickElement( |
||||||
|
'span', title_chosen, '', |
||||||
|
'class', 'help help-tooltip help-icon', |
||||||
|
'title', interpolate( |
||||||
|
gettext( |
||||||
|
'This is the list of chosen %s. You may remove some by ' + |
||||||
|
'selecting them in the box below and then clicking the ' + |
||||||
|
'"Remove" arrow between the two boxes.' |
||||||
|
), |
||||||
|
[field_name] |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); |
||||||
|
to_box.className = 'filtered'; |
||||||
|
var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript:void(0);', 'id', field_id + '_remove_all_link'); |
||||||
|
clear_all.className = 'selector-clearall'; |
||||||
|
|
||||||
|
from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); |
||||||
|
|
||||||
|
// Set up the JavaScript event handlers for the select box filter interface
|
||||||
|
addEvent(choose_all, 'click', function() { SelectBox.move_all(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(add_link, 'click', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(remove_link, 'click', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(clear_all, 'click', function() { SelectBox.move_all(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(filter_input, 'keypress', function(e) { SelectFilter.filter_key_press(e, field_id); }); |
||||||
|
addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); |
||||||
|
addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); |
||||||
|
addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); |
||||||
|
addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); |
||||||
|
SelectBox.init(field_id + '_from'); |
||||||
|
SelectBox.init(field_id + '_to'); |
||||||
|
// Move selected from_box options to to_box
|
||||||
|
SelectBox.move(field_id + '_from', field_id + '_to'); |
||||||
|
|
||||||
|
if (!is_stacked) { |
||||||
|
// In horizontal mode, give the same height to the two boxes.
|
||||||
|
var j_from_box = $(from_box); |
||||||
|
var j_to_box = $(to_box); |
||||||
|
var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }; |
||||||
|
if (j_from_box.outerHeight() > 0) { |
||||||
|
resize_filters(); // This fieldset is already open. Resize now.
|
||||||
|
} else { |
||||||
|
// This fieldset is probably collapsed. Wait for its 'show' event.
|
||||||
|
j_to_box.closest('fieldset').one('show.fieldset', resize_filters); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Initial icon refresh
|
||||||
|
SelectFilter.refresh_icons(field_id); |
||||||
|
}, |
||||||
|
refresh_icons: function(field_id) { |
||||||
|
var from = $('#' + field_id + '_from'); |
||||||
|
var to = $('#' + field_id + '_to'); |
||||||
|
var is_from_selected = from.find('option:selected').length > 0; |
||||||
|
var is_to_selected = to.find('option:selected').length > 0; |
||||||
|
// Active if at least one item is selected
|
||||||
|
$('#' + field_id + '_add_link').toggleClass('active', is_from_selected); |
||||||
|
$('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); |
||||||
|
// Active if the corresponding box isn't empty
|
||||||
|
$('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); |
||||||
|
$('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); |
||||||
|
}, |
||||||
|
filter_key_press: function(event, field_id) { |
||||||
|
var from = document.getElementById(field_id + '_from'); |
||||||
|
// don't submit form if user pressed Enter
|
||||||
|
if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { |
||||||
|
from.selectedIndex = 0; |
||||||
|
SelectBox.move(field_id + '_from', field_id + '_to'); |
||||||
|
from.selectedIndex = 0; |
||||||
|
event.preventDefault(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
}, |
||||||
|
filter_key_up: function(event, field_id) { |
||||||
|
var from = document.getElementById(field_id + '_from'); |
||||||
|
var temp = from.selectedIndex; |
||||||
|
SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); |
||||||
|
from.selectedIndex = temp; |
||||||
|
return true; |
||||||
|
}, |
||||||
|
filter_key_down: function(event, field_id) { |
||||||
|
var from = document.getElementById(field_id + '_from'); |
||||||
|
// right arrow -- move across
|
||||||
|
if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) { |
||||||
|
var old_index = from.selectedIndex; |
||||||
|
SelectBox.move(field_id + '_from', field_id + '_to'); |
||||||
|
from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index; |
||||||
|
return false; |
||||||
|
} |
||||||
|
// down arrow -- wrap around
|
||||||
|
if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { |
||||||
|
from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; |
||||||
|
} |
||||||
|
// up arrow -- wrap around
|
||||||
|
if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { |
||||||
|
from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
})(django.jQuery); |
||||||
@ -0,0 +1,146 @@ |
|||||||
|
/*global _actions_icnt, gettext, interpolate, ngettext*/ |
||||||
|
(function($) { |
||||||
|
'use strict'; |
||||||
|
var lastChecked; |
||||||
|
|
||||||
|
$.fn.actions = function(opts) { |
||||||
|
var options = $.extend({}, $.fn.actions.defaults, opts); |
||||||
|
var actionCheckboxes = $(this); |
||||||
|
var list_editable_changed = false; |
||||||
|
var showQuestion = function() { |
||||||
|
$(options.acrossClears).hide(); |
||||||
|
$(options.acrossQuestions).show(); |
||||||
|
$(options.allContainer).hide(); |
||||||
|
}, |
||||||
|
showClear = function() { |
||||||
|
$(options.acrossClears).show(); |
||||||
|
$(options.acrossQuestions).hide(); |
||||||
|
$(options.actionContainer).toggleClass(options.selectedClass); |
||||||
|
$(options.allContainer).show(); |
||||||
|
$(options.counterContainer).hide(); |
||||||
|
}, |
||||||
|
reset = function() { |
||||||
|
$(options.acrossClears).hide(); |
||||||
|
$(options.acrossQuestions).hide(); |
||||||
|
$(options.allContainer).hide(); |
||||||
|
$(options.counterContainer).show(); |
||||||
|
}, |
||||||
|
clearAcross = function() { |
||||||
|
reset(); |
||||||
|
$(options.acrossInput).val(0); |
||||||
|
$(options.actionContainer).removeClass(options.selectedClass); |
||||||
|
}, |
||||||
|
checker = function(checked) { |
||||||
|
if (checked) { |
||||||
|
showQuestion(); |
||||||
|
} else { |
||||||
|
reset(); |
||||||
|
} |
||||||
|
$(actionCheckboxes).prop("checked", checked) |
||||||
|
.parent().parent().toggleClass(options.selectedClass, checked); |
||||||
|
}, |
||||||
|
updateCounter = function() { |
||||||
|
var sel = $(actionCheckboxes).filter(":checked").length; |
||||||
|
// _actions_icnt is defined in the generated HTML
|
||||||
|
// and contains the total amount of objects in the queryset
|
||||||
|
$(options.counterContainer).html(interpolate( |
||||||
|
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { |
||||||
|
sel: sel, |
||||||
|
cnt: _actions_icnt |
||||||
|
}, true)); |
||||||
|
$(options.allToggle).prop("checked", function() { |
||||||
|
var value; |
||||||
|
if (sel === actionCheckboxes.length) { |
||||||
|
value = true; |
||||||
|
showQuestion(); |
||||||
|
} else { |
||||||
|
value = false; |
||||||
|
clearAcross(); |
||||||
|
} |
||||||
|
return value; |
||||||
|
}); |
||||||
|
}; |
||||||
|
// Show counter by default
|
||||||
|
$(options.counterContainer).show(); |
||||||
|
// Check state of checkboxes and reinit state if needed
|
||||||
|
$(this).filter(":checked").each(function(i) { |
||||||
|
$(this).parent().parent().toggleClass(options.selectedClass); |
||||||
|
updateCounter(); |
||||||
|
if ($(options.acrossInput).val() === 1) { |
||||||
|
showClear(); |
||||||
|
} |
||||||
|
}); |
||||||
|
$(options.allToggle).show().click(function() { |
||||||
|
checker($(this).prop("checked")); |
||||||
|
updateCounter(); |
||||||
|
}); |
||||||
|
$("a", options.acrossQuestions).click(function(event) { |
||||||
|
event.preventDefault(); |
||||||
|
$(options.acrossInput).val(1); |
||||||
|
showClear(); |
||||||
|
}); |
||||||
|
$("a", options.acrossClears).click(function(event) { |
||||||
|
event.preventDefault(); |
||||||
|
$(options.allToggle).prop("checked", false); |
||||||
|
clearAcross(); |
||||||
|
checker(0); |
||||||
|
updateCounter(); |
||||||
|
}); |
||||||
|
lastChecked = null; |
||||||
|
$(actionCheckboxes).click(function(event) { |
||||||
|
if (!event) { event = window.event; } |
||||||
|
var target = event.target ? event.target : event.srcElement; |
||||||
|
if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) { |
||||||
|
var inrange = false; |
||||||
|
$(lastChecked).prop("checked", target.checked) |
||||||
|
.parent().parent().toggleClass(options.selectedClass, target.checked); |
||||||
|
$(actionCheckboxes).each(function() { |
||||||
|
if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) { |
||||||
|
inrange = (inrange) ? false : true; |
||||||
|
} |
||||||
|
if (inrange) { |
||||||
|
$(this).prop("checked", target.checked) |
||||||
|
.parent().parent().toggleClass(options.selectedClass, target.checked); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
$(target).parent().parent().toggleClass(options.selectedClass, target.checked); |
||||||
|
lastChecked = target; |
||||||
|
updateCounter(); |
||||||
|
}); |
||||||
|
$('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { |
||||||
|
list_editable_changed = true; |
||||||
|
}); |
||||||
|
$('form#changelist-form button[name="index"]').click(function(event) { |
||||||
|
if (list_editable_changed) { |
||||||
|
return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); |
||||||
|
} |
||||||
|
}); |
||||||
|
$('form#changelist-form input[name="_save"]').click(function(event) { |
||||||
|
var action_changed = false; |
||||||
|
$('select option:selected', options.actionContainer).each(function() { |
||||||
|
if ($(this).val()) { |
||||||
|
action_changed = true; |
||||||
|
} |
||||||
|
}); |
||||||
|
if (action_changed) { |
||||||
|
if (list_editable_changed) { |
||||||
|
return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); |
||||||
|
} else { |
||||||
|
return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
/* Setup plugin defaults */ |
||||||
|
$.fn.actions.defaults = { |
||||||
|
actionContainer: "div.actions", |
||||||
|
counterContainer: "span.action-counter", |
||||||
|
allContainer: "div.actions span.all", |
||||||
|
acrossInput: "div.actions input.select-across", |
||||||
|
acrossQuestions: "div.actions span.question", |
||||||
|
acrossClears: "div.actions span.clear", |
||||||
|
allToggle: "#action-toggle", |
||||||
|
selectedClass: "selected" |
||||||
|
}; |
||||||
|
})(django.jQuery); |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
(function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,k=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},l=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},m=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){m(); |
||||||
|
a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},p=function(c){c?k():m();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c===g.length?(a=!0,k()):(a=!1,n());return a})};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass); |
||||||
|
h();1===a(b.acrossInput).val()&&l()});a(b.allToggle).show().click(function(){p(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);l()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();p(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!==a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass, |
||||||
|
d.checked);a(g).each(function(){if(a.data(this)===a.data(f)||a.data(this)===a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))}); |
||||||
|
a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})}; |
||||||
|
a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery); |
||||||
@ -0,0 +1,364 @@ |
|||||||
|
/*global addEvent, Calendar, cancelEventPropagation, findPosX, findPosY, getStyle, get_format, gettext, interpolate, ngettext, quickElement, removeEvent*/ |
||||||
|
// Inserts shortcut buttons after all of the following:
|
||||||
|
// <input type="text" class="vDateField">
|
||||||
|
// <input type="text" class="vTimeField">
|
||||||
|
(function() { |
||||||
|
'use strict'; |
||||||
|
var DateTimeShortcuts = { |
||||||
|
calendars: [], |
||||||
|
calendarInputs: [], |
||||||
|
clockInputs: [], |
||||||
|
dismissClockFunc: [], |
||||||
|
dismissCalendarFunc: [], |
||||||
|
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
|
||||||
|
calendarDivName2: 'calendarin', // name of <div> that contains calendar
|
||||||
|
calendarLinkName: 'calendarlink',// name of the link that is used to toggle
|
||||||
|
clockDivName: 'clockbox', // name of clock <div> that gets toggled
|
||||||
|
clockLinkName: 'clocklink', // name of the link that is used to toggle
|
||||||
|
shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
|
||||||
|
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
|
||||||
|
timezoneOffset: 0, |
||||||
|
init: function() { |
||||||
|
var body = document.getElementsByTagName('body')[0]; |
||||||
|
var serverOffset = body.getAttribute('data-admin-utc-offset'); |
||||||
|
if (serverOffset) { |
||||||
|
var localOffset = new Date().getTimezoneOffset() * -60; |
||||||
|
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; |
||||||
|
} |
||||||
|
|
||||||
|
var inputs = document.getElementsByTagName('input'); |
||||||
|
for (var i = 0; i < inputs.length; i++) { |
||||||
|
var inp = inputs[i]; |
||||||
|
if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) { |
||||||
|
DateTimeShortcuts.addClock(inp); |
||||||
|
DateTimeShortcuts.addTimezoneWarning(inp); |
||||||
|
} |
||||||
|
else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) { |
||||||
|
DateTimeShortcuts.addCalendar(inp); |
||||||
|
DateTimeShortcuts.addTimezoneWarning(inp); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
// Return the current time while accounting for the server timezone.
|
||||||
|
now: function() { |
||||||
|
var body = document.getElementsByTagName('body')[0]; |
||||||
|
var serverOffset = body.getAttribute('data-admin-utc-offset'); |
||||||
|
if (serverOffset) { |
||||||
|
var localNow = new Date(); |
||||||
|
var localOffset = localNow.getTimezoneOffset() * -60; |
||||||
|
localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset)); |
||||||
|
return localNow; |
||||||
|
} else { |
||||||
|
return new Date(); |
||||||
|
} |
||||||
|
}, |
||||||
|
// Add a warning when the time zone in the browser and backend do not match.
|
||||||
|
addTimezoneWarning: function(inp) { |
||||||
|
var $ = django.jQuery; |
||||||
|
var warningClass = DateTimeShortcuts.timezoneWarningClass; |
||||||
|
var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; |
||||||
|
|
||||||
|
// Only warn if there is a time zone mismatch.
|
||||||
|
if (!timezoneOffset) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Check if warning is already there.
|
||||||
|
if ($(inp).siblings('.' + warningClass).length) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var message; |
||||||
|
if (timezoneOffset > 0) { |
||||||
|
message = ngettext( |
||||||
|
'Note: You are %s hour ahead of server time.', |
||||||
|
'Note: You are %s hours ahead of server time.', |
||||||
|
timezoneOffset |
||||||
|
); |
||||||
|
} |
||||||
|
else { |
||||||
|
timezoneOffset *= -1; |
||||||
|
message = ngettext( |
||||||
|
'Note: You are %s hour behind server time.', |
||||||
|
'Note: You are %s hours behind server time.', |
||||||
|
timezoneOffset |
||||||
|
); |
||||||
|
} |
||||||
|
message = interpolate(message, [timezoneOffset]); |
||||||
|
|
||||||
|
var $warning = $('<span>'); |
||||||
|
$warning.attr('class', warningClass); |
||||||
|
$warning.text(message); |
||||||
|
|
||||||
|
$(inp).parent() |
||||||
|
.append($('<br>')) |
||||||
|
.append($warning); |
||||||
|
}, |
||||||
|
// Add clock widget to a given field
|
||||||
|
addClock: function(inp) { |
||||||
|
var num = DateTimeShortcuts.clockInputs.length; |
||||||
|
DateTimeShortcuts.clockInputs[num] = inp; |
||||||
|
DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; |
||||||
|
|
||||||
|
// Shortcut links (clock icon and "Now" link)
|
||||||
|
var shortcuts_span = document.createElement('span'); |
||||||
|
shortcuts_span.className = DateTimeShortcuts.shortCutsClass; |
||||||
|
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); |
||||||
|
var now_link = document.createElement('a'); |
||||||
|
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); |
||||||
|
now_link.appendChild(document.createTextNode(gettext('Now'))); |
||||||
|
var clock_link = document.createElement('a'); |
||||||
|
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); |
||||||
|
clock_link.id = DateTimeShortcuts.clockLinkName + num; |
||||||
|
quickElement( |
||||||
|
'span', clock_link, '', |
||||||
|
'class', 'clock-icon', |
||||||
|
'title', gettext('Choose a Time') |
||||||
|
); |
||||||
|
shortcuts_span.appendChild(document.createTextNode('\u00A0')); |
||||||
|
shortcuts_span.appendChild(now_link); |
||||||
|
shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); |
||||||
|
shortcuts_span.appendChild(clock_link); |
||||||
|
|
||||||
|
// Create clock link div
|
||||||
|
//
|
||||||
|
// Markup looks like:
|
||||||
|
// <div id="clockbox1" class="clockbox module">
|
||||||
|
// <h2>Choose a time</h2>
|
||||||
|
// <ul class="timelist">
|
||||||
|
// <li><a href="#">Now</a></li>
|
||||||
|
// <li><a href="#">Midnight</a></li>
|
||||||
|
// <li><a href="#">6 a.m.</a></li>
|
||||||
|
// <li><a href="#">Noon</a></li>
|
||||||
|
// <li><a href="#">6 p.m.</a></li>
|
||||||
|
// </ul>
|
||||||
|
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
var clock_box = document.createElement('div'); |
||||||
|
clock_box.style.display = 'none'; |
||||||
|
clock_box.style.position = 'absolute'; |
||||||
|
clock_box.className = 'clockbox module'; |
||||||
|
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num); |
||||||
|
document.body.appendChild(clock_box); |
||||||
|
addEvent(clock_box, 'click', cancelEventPropagation); |
||||||
|
|
||||||
|
quickElement('h2', clock_box, gettext('Choose a time')); |
||||||
|
var time_list = quickElement('ul', clock_box); |
||||||
|
time_list.className = 'timelist'; |
||||||
|
quickElement("a", quickElement("li", time_list), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); |
||||||
|
quickElement("a", quickElement("li", time_list), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 0);"); |
||||||
|
quickElement("a", quickElement("li", time_list), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 6);"); |
||||||
|
quickElement("a", quickElement("li", time_list), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 12);"); |
||||||
|
quickElement("a", quickElement("li", time_list), gettext("6 p.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 18);"); |
||||||
|
|
||||||
|
var cancel_p = quickElement('p', clock_box); |
||||||
|
cancel_p.className = 'calendar-cancel'; |
||||||
|
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');'); |
||||||
|
django.jQuery(document).bind('keyup', function(event) { |
||||||
|
if (event.which === 27) { |
||||||
|
// ESC key closes popup
|
||||||
|
DateTimeShortcuts.dismissClock(num); |
||||||
|
event.preventDefault(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
openClock: function(num) { |
||||||
|
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); |
||||||
|
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); |
||||||
|
|
||||||
|
// Recalculate the clockbox position
|
||||||
|
// is it left-to-right or right-to-left layout ?
|
||||||
|
if (getStyle(document.body, 'direction') !== 'rtl') { |
||||||
|
clock_box.style.left = findPosX(clock_link) + 17 + 'px'; |
||||||
|
} |
||||||
|
else { |
||||||
|
// since style's width is in em, it'd be tough to calculate
|
||||||
|
// px value of it. let's use an estimated px for now
|
||||||
|
// TODO: IE returns wrong value for findPosX when in rtl mode
|
||||||
|
// (it returns as it was left aligned), needs to be fixed.
|
||||||
|
clock_box.style.left = findPosX(clock_link) - 110 + 'px'; |
||||||
|
} |
||||||
|
clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; |
||||||
|
|
||||||
|
// Show the clock box
|
||||||
|
clock_box.style.display = 'block'; |
||||||
|
addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); |
||||||
|
}, |
||||||
|
dismissClock: function(num) { |
||||||
|
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; |
||||||
|
removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); |
||||||
|
}, |
||||||
|
handleClockQuicklink: function(num, val) { |
||||||
|
var d; |
||||||
|
if (val === -1) { |
||||||
|
d = DateTimeShortcuts.now(); |
||||||
|
} |
||||||
|
else { |
||||||
|
d = new Date(1970, 1, 1, val, 0, 0, 0); |
||||||
|
} |
||||||
|
DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); |
||||||
|
DateTimeShortcuts.clockInputs[num].focus(); |
||||||
|
DateTimeShortcuts.dismissClock(num); |
||||||
|
}, |
||||||
|
// Add calendar widget to a given field.
|
||||||
|
addCalendar: function(inp) { |
||||||
|
var num = DateTimeShortcuts.calendars.length; |
||||||
|
|
||||||
|
DateTimeShortcuts.calendarInputs[num] = inp; |
||||||
|
DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; |
||||||
|
|
||||||
|
// Shortcut links (calendar icon and "Today" link)
|
||||||
|
var shortcuts_span = document.createElement('span'); |
||||||
|
shortcuts_span.className = DateTimeShortcuts.shortCutsClass; |
||||||
|
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); |
||||||
|
var today_link = document.createElement('a'); |
||||||
|
today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); |
||||||
|
today_link.appendChild(document.createTextNode(gettext('Today'))); |
||||||
|
var cal_link = document.createElement('a'); |
||||||
|
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); |
||||||
|
cal_link.id = DateTimeShortcuts.calendarLinkName + num; |
||||||
|
quickElement( |
||||||
|
'span', cal_link, '', |
||||||
|
'class', 'date-icon', |
||||||
|
'title', gettext('Choose a Date') |
||||||
|
); |
||||||
|
shortcuts_span.appendChild(document.createTextNode('\u00A0')); |
||||||
|
shortcuts_span.appendChild(today_link); |
||||||
|
shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); |
||||||
|
shortcuts_span.appendChild(cal_link); |
||||||
|
|
||||||
|
// Create calendarbox div.
|
||||||
|
//
|
||||||
|
// Markup looks like:
|
||||||
|
//
|
||||||
|
// <div id="calendarbox3" class="calendarbox module">
|
||||||
|
// <h2>
|
||||||
|
// <a href="#" class="link-previous">‹</a>
|
||||||
|
// <a href="#" class="link-next">›</a> February 2003
|
||||||
|
// </h2>
|
||||||
|
// <div class="calendar" id="calendarin3">
|
||||||
|
// <!-- (cal) -->
|
||||||
|
// </div>
|
||||||
|
// <div class="calendar-shortcuts">
|
||||||
|
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
||||||
|
// </div>
|
||||||
|
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||||
|
// </div>
|
||||||
|
var cal_box = document.createElement('div'); |
||||||
|
cal_box.style.display = 'none'; |
||||||
|
cal_box.style.position = 'absolute'; |
||||||
|
cal_box.className = 'calendarbox module'; |
||||||
|
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num); |
||||||
|
document.body.appendChild(cal_box); |
||||||
|
addEvent(cal_box, 'click', cancelEventPropagation); |
||||||
|
|
||||||
|
// next-prev links
|
||||||
|
var cal_nav = quickElement('div', cal_box); |
||||||
|
var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev(' + num + ');'); |
||||||
|
cal_nav_prev.className = 'calendarnav-previous'; |
||||||
|
var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext(' + num + ');'); |
||||||
|
cal_nav_next.className = 'calendarnav-next'; |
||||||
|
|
||||||
|
// main box
|
||||||
|
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); |
||||||
|
cal_main.className = 'calendar'; |
||||||
|
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); |
||||||
|
DateTimeShortcuts.calendars[num].drawCurrent(); |
||||||
|
|
||||||
|
// calendar shortcuts
|
||||||
|
var shortcuts = quickElement('div', cal_box); |
||||||
|
shortcuts.className = 'calendar-shortcuts'; |
||||||
|
quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);'); |
||||||
|
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); |
||||||
|
quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); |
||||||
|
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); |
||||||
|
quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);'); |
||||||
|
|
||||||
|
// cancel bar
|
||||||
|
var cancel_p = quickElement('p', cal_box); |
||||||
|
cancel_p.className = 'calendar-cancel'; |
||||||
|
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); |
||||||
|
django.jQuery(document).bind('keyup', function(event) { |
||||||
|
if (event.which === 27) { |
||||||
|
// ESC key closes popup
|
||||||
|
DateTimeShortcuts.dismissCalendar(num); |
||||||
|
event.preventDefault(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
openCalendar: function(num) { |
||||||
|
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); |
||||||
|
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); |
||||||
|
var inp = DateTimeShortcuts.calendarInputs[num]; |
||||||
|
|
||||||
|
// Determine if the current value in the input has a valid date.
|
||||||
|
// If so, draw the calendar with that date's year and month.
|
||||||
|
if (inp.value) { |
||||||
|
var format = get_format('DATE_INPUT_FORMATS')[0]; |
||||||
|
var selected = inp.value.strptime(format); |
||||||
|
var year = selected.getUTCFullYear(); |
||||||
|
var month = selected.getUTCMonth() + 1; |
||||||
|
var re = /\d{4}/; |
||||||
|
if (re.test(year.toString()) && month >= 1 && month <= 12) { |
||||||
|
DateTimeShortcuts.calendars[num].drawDate(month, year, selected); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Recalculate the clockbox position
|
||||||
|
// is it left-to-right or right-to-left layout ?
|
||||||
|
if (getStyle(document.body, 'direction') !== 'rtl') { |
||||||
|
cal_box.style.left = findPosX(cal_link) + 17 + 'px'; |
||||||
|
} |
||||||
|
else { |
||||||
|
// since style's width is in em, it'd be tough to calculate
|
||||||
|
// px value of it. let's use an estimated px for now
|
||||||
|
// TODO: IE returns wrong value for findPosX when in rtl mode
|
||||||
|
// (it returns as it was left aligned), needs to be fixed.
|
||||||
|
cal_box.style.left = findPosX(cal_link) - 180 + 'px'; |
||||||
|
} |
||||||
|
cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; |
||||||
|
|
||||||
|
cal_box.style.display = 'block'; |
||||||
|
addEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); |
||||||
|
}, |
||||||
|
dismissCalendar: function(num) { |
||||||
|
document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; |
||||||
|
removeEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); |
||||||
|
}, |
||||||
|
drawPrev: function(num) { |
||||||
|
DateTimeShortcuts.calendars[num].drawPreviousMonth(); |
||||||
|
}, |
||||||
|
drawNext: function(num) { |
||||||
|
DateTimeShortcuts.calendars[num].drawNextMonth(); |
||||||
|
}, |
||||||
|
handleCalendarCallback: function(num) { |
||||||
|
var format = get_format('DATE_INPUT_FORMATS')[0]; |
||||||
|
// the format needs to be escaped a little
|
||||||
|
format = format.replace('\\', '\\\\'); |
||||||
|
format = format.replace('\r', '\\r'); |
||||||
|
format = format.replace('\n', '\\n'); |
||||||
|
format = format.replace('\t', '\\t'); |
||||||
|
format = format.replace("'", "\\'"); |
||||||
|
return ["function(y, m, d) { DateTimeShortcuts.calendarInputs[", |
||||||
|
num, |
||||||
|
"].value = new Date(y, m-1, d).strftime('", |
||||||
|
format, |
||||||
|
"');DateTimeShortcuts.calendarInputs[", |
||||||
|
num, |
||||||
|
"].focus();document.getElementById(DateTimeShortcuts.calendarDivName1+", |
||||||
|
num, |
||||||
|
").style.display='none';}"].join(''); |
||||||
|
}, |
||||||
|
handleCalendarQuickLink: function(num, offset) { |
||||||
|
var d = DateTimeShortcuts.now(); |
||||||
|
d.setDate(d.getDate() + offset); |
||||||
|
DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); |
||||||
|
DateTimeShortcuts.calendarInputs[num].focus(); |
||||||
|
DateTimeShortcuts.dismissCalendar(num); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
addEvent(window, 'load', DateTimeShortcuts.init); |
||||||
|
window.DateTimeShortcuts = DateTimeShortcuts; |
||||||
|
})(); |
||||||
@ -0,0 +1,181 @@ |
|||||||
|
/*global SelectBox, interpolate*/ |
||||||
|
// Handles related-objects functionality: lookup link for raw_id_fields
|
||||||
|
// and Add Another links.
|
||||||
|
|
||||||
|
(function($) { |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
function html_unescape(text) { |
||||||
|
// Unescape a string that was escaped using django.utils.html.escape.
|
||||||
|
text = text.replace(/</g, '<'); |
||||||
|
text = text.replace(/>/g, '>'); |
||||||
|
text = text.replace(/"/g, '"'); |
||||||
|
text = text.replace(/'/g, "'"); |
||||||
|
text = text.replace(/&/g, '&'); |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
// IE doesn't accept periods or dashes in the window name, but the element IDs
|
||||||
|
// we use to generate popup window names may contain them, therefore we map them
|
||||||
|
// to allowed characters in a reversible way so that we can locate the correct
|
||||||
|
// element when the popup window is dismissed.
|
||||||
|
function id_to_windowname(text) { |
||||||
|
text = text.replace(/\./g, '__dot__'); |
||||||
|
text = text.replace(/\-/g, '__dash__'); |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
function windowname_to_id(text) { |
||||||
|
text = text.replace(/__dot__/g, '.'); |
||||||
|
text = text.replace(/__dash__/g, '-'); |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
function showAdminPopup(triggeringLink, name_regexp, add_popup) { |
||||||
|
var name = triggeringLink.id.replace(name_regexp, ''); |
||||||
|
name = id_to_windowname(name); |
||||||
|
var href = triggeringLink.href; |
||||||
|
if (add_popup) { |
||||||
|
if (href.indexOf('?') === -1) { |
||||||
|
href += '?_popup=1'; |
||||||
|
} else { |
||||||
|
href += '&_popup=1'; |
||||||
|
} |
||||||
|
} |
||||||
|
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); |
||||||
|
win.focus(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
function showRelatedObjectLookupPopup(triggeringLink) { |
||||||
|
return showAdminPopup(triggeringLink, /^lookup_/, true); |
||||||
|
} |
||||||
|
|
||||||
|
function dismissRelatedLookupPopup(win, chosenId) { |
||||||
|
var name = windowname_to_id(win.name); |
||||||
|
var elem = document.getElementById(name); |
||||||
|
if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { |
||||||
|
elem.value += ',' + chosenId; |
||||||
|
} else { |
||||||
|
document.getElementById(name).value = chosenId; |
||||||
|
} |
||||||
|
win.close(); |
||||||
|
} |
||||||
|
|
||||||
|
function showRelatedObjectPopup(triggeringLink) { |
||||||
|
return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false); |
||||||
|
} |
||||||
|
|
||||||
|
function updateRelatedObjectLinks(triggeringLink) { |
||||||
|
var $this = django.jQuery(triggeringLink); |
||||||
|
var siblings = $this.nextAll('.change-related, .delete-related'); |
||||||
|
if (!siblings.length) { |
||||||
|
return; |
||||||
|
} |
||||||
|
var value = $this.val(); |
||||||
|
if (value) { |
||||||
|
siblings.each(function() { |
||||||
|
var elm = django.jQuery(this); |
||||||
|
elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
siblings.removeAttr('href'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function dismissAddRelatedObjectPopup(win, newId, newRepr) { |
||||||
|
// newId and newRepr are expected to have previously been escaped by
|
||||||
|
// django.utils.html.escape.
|
||||||
|
newId = html_unescape(newId); |
||||||
|
newRepr = html_unescape(newRepr); |
||||||
|
var name = windowname_to_id(win.name); |
||||||
|
var elem = document.getElementById(name); |
||||||
|
if (elem) { |
||||||
|
var elemName = elem.nodeName.toUpperCase(); |
||||||
|
if (elemName === 'SELECT') { |
||||||
|
elem.options[elem.options.length] = new Option(newRepr, newId, true, true); |
||||||
|
} else if (elemName === 'INPUT') { |
||||||
|
if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) { |
||||||
|
elem.value += ',' + newId; |
||||||
|
} else { |
||||||
|
elem.value = newId; |
||||||
|
} |
||||||
|
} |
||||||
|
// Trigger a change event to update related links if required.
|
||||||
|
django.jQuery(elem).trigger('change'); |
||||||
|
} else { |
||||||
|
var toId = name + "_to"; |
||||||
|
var o = new Option(newRepr, newId); |
||||||
|
SelectBox.add_to_cache(toId, o); |
||||||
|
SelectBox.redisplay(toId); |
||||||
|
} |
||||||
|
win.close(); |
||||||
|
} |
||||||
|
|
||||||
|
function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { |
||||||
|
objId = html_unescape(objId); |
||||||
|
newRepr = html_unescape(newRepr); |
||||||
|
var id = windowname_to_id(win.name).replace(/^edit_/, ''); |
||||||
|
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); |
||||||
|
var selects = django.jQuery(selectsSelector); |
||||||
|
selects.find('option').each(function() { |
||||||
|
if (this.value === objId) { |
||||||
|
this.innerHTML = newRepr; |
||||||
|
this.value = newId; |
||||||
|
} |
||||||
|
}); |
||||||
|
win.close(); |
||||||
|
} |
||||||
|
|
||||||
|
function dismissDeleteRelatedObjectPopup(win, objId) { |
||||||
|
objId = html_unescape(objId); |
||||||
|
var id = windowname_to_id(win.name).replace(/^delete_/, ''); |
||||||
|
var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); |
||||||
|
var selects = django.jQuery(selectsSelector); |
||||||
|
selects.find('option').each(function() { |
||||||
|
if (this.value === objId) { |
||||||
|
django.jQuery(this).remove(); |
||||||
|
} |
||||||
|
}).trigger('change'); |
||||||
|
win.close(); |
||||||
|
} |
||||||
|
|
||||||
|
// Global for testing purposes
|
||||||
|
window.html_unescape = html_unescape; |
||||||
|
window.id_to_windowname = id_to_windowname; |
||||||
|
window.windowname_to_id = windowname_to_id; |
||||||
|
|
||||||
|
window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup; |
||||||
|
window.dismissRelatedLookupPopup = dismissRelatedLookupPopup; |
||||||
|
window.showRelatedObjectPopup = showRelatedObjectPopup; |
||||||
|
window.updateRelatedObjectLinks = updateRelatedObjectLinks; |
||||||
|
window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup; |
||||||
|
window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup; |
||||||
|
window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup; |
||||||
|
|
||||||
|
// Kept for backward compatibility
|
||||||
|
window.showAddAnotherPopup = showRelatedObjectPopup; |
||||||
|
window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup; |
||||||
|
|
||||||
|
$(document).ready(function() { |
||||||
|
$('body').on('click', '.related-widget-wrapper-link', function(e) { |
||||||
|
e.preventDefault(); |
||||||
|
if (this.href) { |
||||||
|
var event = $.Event('django:show-related', {href: this.href}); |
||||||
|
$(this).trigger(event); |
||||||
|
if (!event.isDefaultPrevented()) { |
||||||
|
showRelatedObjectPopup(this); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
$('body').on('change', '.related-widget-wrapper select', function(e) { |
||||||
|
var event = $.Event('django:update-related'); |
||||||
|
$(this).trigger(event); |
||||||
|
if (!event.isDefaultPrevented()) { |
||||||
|
updateRelatedObjectLinks(this); |
||||||
|
} |
||||||
|
}); |
||||||
|
$('.related-widget-wrapper select').trigger('change'); |
||||||
|
}); |
||||||
|
|
||||||
|
})(django.jQuery); |
||||||
@ -0,0 +1,178 @@ |
|||||||
|
/*global gettext, get_format, quickElement, removeChildren*/ |
||||||
|
/* |
||||||
|
calendar.js - Calendar functions by Adrian Holovaty |
||||||
|
depends on core.js for utility functions like removeChildren or quickElement |
||||||
|
*/ |
||||||
|
|
||||||
|
(function() { |
||||||
|
'use strict'; |
||||||
|
// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
|
||||||
|
var CalendarNamespace = { |
||||||
|
monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), |
||||||
|
daysOfWeek: gettext('S M T W T F S').split(' '), |
||||||
|
firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), |
||||||
|
isLeapYear: function(year) { |
||||||
|
return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0)); |
||||||
|
}, |
||||||
|
getDaysInMonth: function(month, year) { |
||||||
|
var days; |
||||||
|
if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { |
||||||
|
days = 31; |
||||||
|
} |
||||||
|
else if (month === 4 || month === 6 || month === 9 || month === 11) { |
||||||
|
days = 30; |
||||||
|
} |
||||||
|
else if (month === 2 && CalendarNamespace.isLeapYear(year)) { |
||||||
|
days = 29; |
||||||
|
} |
||||||
|
else { |
||||||
|
days = 28; |
||||||
|
} |
||||||
|
return days; |
||||||
|
}, |
||||||
|
draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
|
||||||
|
var today = new Date(); |
||||||
|
var todayDay = today.getDate(); |
||||||
|
var todayMonth = today.getMonth() + 1; |
||||||
|
var todayYear = today.getFullYear(); |
||||||
|
var todayClass = ''; |
||||||
|
|
||||||
|
// Use UTC functions here because the date field does not contain time
|
||||||
|
// and using the UTC function variants prevent the local time offset
|
||||||
|
// from altering the date, specifically the day field. For example:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// var x = new Date('2013-10-02');
|
||||||
|
// var day = x.getDate();
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// The day variable above will be 1 instead of 2 in, say, US Pacific time
|
||||||
|
// zone.
|
||||||
|
var isSelectedMonth = false; |
||||||
|
if (typeof selected !== 'undefined') { |
||||||
|
isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); |
||||||
|
} |
||||||
|
|
||||||
|
month = parseInt(month); |
||||||
|
year = parseInt(year); |
||||||
|
var calDiv = document.getElementById(div_id); |
||||||
|
removeChildren(calDiv); |
||||||
|
var calTable = document.createElement('table'); |
||||||
|
quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); |
||||||
|
var tableBody = quickElement('tbody', calTable); |
||||||
|
|
||||||
|
// Draw days-of-week header
|
||||||
|
var tableRow = quickElement('tr', tableBody); |
||||||
|
for (var i = 0; i < 7; i++) { |
||||||
|
quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); |
||||||
|
} |
||||||
|
|
||||||
|
var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); |
||||||
|
var days = CalendarNamespace.getDaysInMonth(month, year); |
||||||
|
|
||||||
|
var nonDayCell; |
||||||
|
|
||||||
|
// Draw blanks before first of month
|
||||||
|
tableRow = quickElement('tr', tableBody); |
||||||
|
for (i = 0; i < startingPos; i++) { |
||||||
|
nonDayCell = quickElement('td', tableRow, ' '); |
||||||
|
nonDayCell.className = "nonday"; |
||||||
|
} |
||||||
|
|
||||||
|
// Draw days of month
|
||||||
|
var currentDay = 1; |
||||||
|
for (i = startingPos; currentDay <= days; i++) { |
||||||
|
if (i % 7 === 0 && currentDay !== 1) { |
||||||
|
tableRow = quickElement('tr', tableBody); |
||||||
|
} |
||||||
|
if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { |
||||||
|
todayClass = 'today'; |
||||||
|
} else { |
||||||
|
todayClass = ''; |
||||||
|
} |
||||||
|
|
||||||
|
// use UTC function; see above for explanation.
|
||||||
|
if (isSelectedMonth && currentDay === selected.getUTCDate()) { |
||||||
|
if (todayClass !== '') { |
||||||
|
todayClass += " "; |
||||||
|
} |
||||||
|
todayClass += "selected"; |
||||||
|
} |
||||||
|
|
||||||
|
var cell = quickElement('td', tableRow, '', 'class', todayClass); |
||||||
|
|
||||||
|
quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '(' + year + ',' + month + ',' + currentDay + '));'); |
||||||
|
currentDay++; |
||||||
|
} |
||||||
|
|
||||||
|
// Draw blanks after end of month (optional, but makes for valid code)
|
||||||
|
while (tableRow.childNodes.length < 7) { |
||||||
|
nonDayCell = quickElement('td', tableRow, ' '); |
||||||
|
nonDayCell.className = "nonday"; |
||||||
|
} |
||||||
|
|
||||||
|
calDiv.appendChild(calTable); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Calendar -- A calendar instance
|
||||||
|
function Calendar(div_id, callback, selected) { |
||||||
|
// div_id (string) is the ID of the element in which the calendar will
|
||||||
|
// be displayed
|
||||||
|
// callback (string) is the name of a JavaScript function that will be
|
||||||
|
// called with the parameters (year, month, day) when a day in the
|
||||||
|
// calendar is clicked
|
||||||
|
this.div_id = div_id; |
||||||
|
this.callback = callback; |
||||||
|
this.today = new Date(); |
||||||
|
this.currentMonth = this.today.getMonth() + 1; |
||||||
|
this.currentYear = this.today.getFullYear(); |
||||||
|
if (typeof selected !== 'undefined') { |
||||||
|
this.selected = selected; |
||||||
|
} |
||||||
|
} |
||||||
|
Calendar.prototype = { |
||||||
|
drawCurrent: function() { |
||||||
|
CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); |
||||||
|
}, |
||||||
|
drawDate: function(month, year, selected) { |
||||||
|
this.currentMonth = month; |
||||||
|
this.currentYear = year; |
||||||
|
|
||||||
|
if(selected) { |
||||||
|
this.selected = selected; |
||||||
|
} |
||||||
|
|
||||||
|
this.drawCurrent(); |
||||||
|
}, |
||||||
|
drawPreviousMonth: function() { |
||||||
|
if (this.currentMonth === 1) { |
||||||
|
this.currentMonth = 12; |
||||||
|
this.currentYear--; |
||||||
|
} |
||||||
|
else { |
||||||
|
this.currentMonth--; |
||||||
|
} |
||||||
|
this.drawCurrent(); |
||||||
|
}, |
||||||
|
drawNextMonth: function() { |
||||||
|
if (this.currentMonth === 12) { |
||||||
|
this.currentMonth = 1; |
||||||
|
this.currentYear++; |
||||||
|
} |
||||||
|
else { |
||||||
|
this.currentMonth++; |
||||||
|
} |
||||||
|
this.drawCurrent(); |
||||||
|
}, |
||||||
|
drawPreviousYear: function() { |
||||||
|
this.currentYear--; |
||||||
|
this.drawCurrent(); |
||||||
|
}, |
||||||
|
drawNextYear: function() { |
||||||
|
this.currentYear++; |
||||||
|
this.drawCurrent(); |
||||||
|
} |
||||||
|
}; |
||||||
|
window.Calendar = Calendar; |
||||||
|
})(); |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
/*global gettext*/ |
||||||
|
(function($) { |
||||||
|
'use strict'; |
||||||
|
$(document).ready(function() { |
||||||
|
// Add anchor tag for Show/Hide link
|
||||||
|
$("fieldset.collapse").each(function(i, elem) { |
||||||
|
// Don't hide if fields in this fieldset have errors
|
||||||
|
if ($(elem).find("div.errors").length === 0) { |
||||||
|
$(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' + |
||||||
|
i + '" class="collapse-toggle" href="#">' + gettext("Show") + |
||||||
|
'</a>)'); |
||||||
|
} |
||||||
|
}); |
||||||
|
// Add toggle to anchor tag
|
||||||
|
$("fieldset.collapse a.collapse-toggle").click(function(ev) { |
||||||
|
if ($(this).closest("fieldset").hasClass("collapsed")) { |
||||||
|
// Show
|
||||||
|
$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); |
||||||
|
} else { |
||||||
|
// Hide
|
||||||
|
$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); |
||||||
|
} |
||||||
|
return false; |
||||||
|
}); |
||||||
|
}); |
||||||
|
})(django.jQuery); |
||||||
@ -0,0 +1,2 @@ |
|||||||
|
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(b,c){0===a(c).find("div.errors").length&&a(c).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser'+b+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")});a("fieldset.collapse a.collapse-toggle").click(function(b){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", |
||||||
|
[a(this).attr("id")]);return!1})})})(django.jQuery); |
||||||
@ -0,0 +1,266 @@ |
|||||||
|
// Core javascript helper functions
|
||||||
|
|
||||||
|
// basic browser identification & version
|
||||||
|
var isOpera = (navigator.userAgent.indexOf("Opera") >= 0) && parseFloat(navigator.appVersion); |
||||||
|
var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); |
||||||
|
|
||||||
|
// Cross-browser event handlers.
|
||||||
|
function addEvent(obj, evType, fn) { |
||||||
|
'use strict'; |
||||||
|
if (obj.addEventListener) { |
||||||
|
obj.addEventListener(evType, fn, false); |
||||||
|
return true; |
||||||
|
} else if (obj.attachEvent) { |
||||||
|
var r = obj.attachEvent("on" + evType, fn); |
||||||
|
return r; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function removeEvent(obj, evType, fn) { |
||||||
|
'use strict'; |
||||||
|
if (obj.removeEventListener) { |
||||||
|
obj.removeEventListener(evType, fn, false); |
||||||
|
return true; |
||||||
|
} else if (obj.detachEvent) { |
||||||
|
obj.detachEvent("on" + evType, fn); |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function cancelEventPropagation(e) { |
||||||
|
'use strict'; |
||||||
|
if (!e) { |
||||||
|
e = window.event; |
||||||
|
} |
||||||
|
e.cancelBubble = true; |
||||||
|
if (e.stopPropagation) { |
||||||
|
e.stopPropagation(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
|
||||||
|
function quickElement() { |
||||||
|
'use strict'; |
||||||
|
var obj = document.createElement(arguments[0]); |
||||||
|
if (arguments[2]) { |
||||||
|
var textNode = document.createTextNode(arguments[2]); |
||||||
|
obj.appendChild(textNode); |
||||||
|
} |
||||||
|
var len = arguments.length; |
||||||
|
for (var i = 3; i < len; i += 2) { |
||||||
|
obj.setAttribute(arguments[i], arguments[i + 1]); |
||||||
|
} |
||||||
|
arguments[1].appendChild(obj); |
||||||
|
return obj; |
||||||
|
} |
||||||
|
|
||||||
|
// "a" is reference to an object
|
||||||
|
function removeChildren(a) { |
||||||
|
'use strict'; |
||||||
|
while (a.hasChildNodes()) { |
||||||
|
a.removeChild(a.lastChild); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Cross-browser xmlhttp object
|
||||||
|
// from http://jibbering.com/2002/4/httprequest.html
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
var xmlhttp; |
||||||
|
/*@cc_on @*/ |
||||||
|
/*@if (@_jscript_version >= 5) |
||||||
|
try { |
||||||
|
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); |
||||||
|
} catch (e) { |
||||||
|
try { |
||||||
|
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); |
||||||
|
} catch (E) { |
||||||
|
xmlhttp = false; |
||||||
|
} |
||||||
|
} |
||||||
|
@else |
||||||
|
xmlhttp = false; |
||||||
|
@end @*/ |
||||||
|
if (!xmlhttp && typeof XMLHttpRequest !== 'undefined') { |
||||||
|
xmlhttp = new XMLHttpRequest(); |
||||||
|
} |
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Find-position functions by PPK
|
||||||
|
// See http://www.quirksmode.org/js/findpos.html
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
function findPosX(obj) { |
||||||
|
'use strict'; |
||||||
|
var curleft = 0; |
||||||
|
if (obj.offsetParent) { |
||||||
|
while (obj.offsetParent) { |
||||||
|
curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); |
||||||
|
obj = obj.offsetParent; |
||||||
|
} |
||||||
|
// IE offsetParent does not include the top-level
|
||||||
|
if (isIE && obj.parentElement) { |
||||||
|
curleft += obj.offsetLeft - obj.scrollLeft; |
||||||
|
} |
||||||
|
} else if (obj.x) { |
||||||
|
curleft += obj.x; |
||||||
|
} |
||||||
|
return curleft; |
||||||
|
} |
||||||
|
|
||||||
|
function findPosY(obj) { |
||||||
|
'use strict'; |
||||||
|
var curtop = 0; |
||||||
|
if (obj.offsetParent) { |
||||||
|
while (obj.offsetParent) { |
||||||
|
curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); |
||||||
|
obj = obj.offsetParent; |
||||||
|
} |
||||||
|
// IE offsetParent does not include the top-level
|
||||||
|
if (isIE && obj.parentElement) { |
||||||
|
curtop += obj.offsetTop - obj.scrollTop; |
||||||
|
} |
||||||
|
} else if (obj.y) { |
||||||
|
curtop += obj.y; |
||||||
|
} |
||||||
|
return curtop; |
||||||
|
} |
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Date object extensions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
(function() { |
||||||
|
'use strict'; |
||||||
|
Date.prototype.getTwelveHours = function() { |
||||||
|
var hours = this.getHours(); |
||||||
|
if (hours === 0) { |
||||||
|
return 12; |
||||||
|
} |
||||||
|
else { |
||||||
|
return hours <= 12 ? hours : hours - 12; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitMonth = function() { |
||||||
|
return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitDate = function() { |
||||||
|
return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitTwelveHour = function() { |
||||||
|
return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitHour = function() { |
||||||
|
return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitMinute = function() { |
||||||
|
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getTwoDigitSecond = function() { |
||||||
|
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getHourMinute = function() { |
||||||
|
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.getHourMinuteSecond = function() { |
||||||
|
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); |
||||||
|
}; |
||||||
|
|
||||||
|
Date.prototype.strftime = function(format) { |
||||||
|
var fields = { |
||||||
|
c: this.toString(), |
||||||
|
d: this.getTwoDigitDate(), |
||||||
|
H: this.getTwoDigitHour(), |
||||||
|
I: this.getTwoDigitTwelveHour(), |
||||||
|
m: this.getTwoDigitMonth(), |
||||||
|
M: this.getTwoDigitMinute(), |
||||||
|
p: (this.getHours() >= 12) ? 'PM' : 'AM', |
||||||
|
S: this.getTwoDigitSecond(), |
||||||
|
w: '0' + this.getDay(), |
||||||
|
x: this.toLocaleDateString(), |
||||||
|
X: this.toLocaleTimeString(), |
||||||
|
y: ('' + this.getFullYear()).substr(2, 4), |
||||||
|
Y: '' + this.getFullYear(), |
||||||
|
'%': '%' |
||||||
|
}; |
||||||
|
var result = '', i = 0; |
||||||
|
while (i < format.length) { |
||||||
|
if (format.charAt(i) === '%') { |
||||||
|
result = result + fields[format.charAt(i + 1)]; |
||||||
|
++i; |
||||||
|
} |
||||||
|
else { |
||||||
|
result = result + format.charAt(i); |
||||||
|
} |
||||||
|
++i; |
||||||
|
} |
||||||
|
return result; |
||||||
|
}; |
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// String object extensions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
String.prototype.pad_left = function(pad_length, pad_string) { |
||||||
|
var new_string = this; |
||||||
|
for (var i = 0; new_string.length < pad_length; i++) { |
||||||
|
new_string = pad_string + new_string; |
||||||
|
} |
||||||
|
return new_string; |
||||||
|
}; |
||||||
|
|
||||||
|
String.prototype.strptime = function(format) { |
||||||
|
var split_format = format.split(/[.\-/]/); |
||||||
|
var date = this.split(/[.\-/]/); |
||||||
|
var i = 0; |
||||||
|
var day, month, year; |
||||||
|
while (i < split_format.length) { |
||||||
|
switch (split_format[i]) { |
||||||
|
case "%d": |
||||||
|
day = date[i]; |
||||||
|
break; |
||||||
|
case "%m": |
||||||
|
month = date[i] - 1; |
||||||
|
break; |
||||||
|
case "%Y": |
||||||
|
year = date[i]; |
||||||
|
break; |
||||||
|
case "%y": |
||||||
|
year = date[i]; |
||||||
|
break; |
||||||
|
} |
||||||
|
++i; |
||||||
|
} |
||||||
|
// Create Date object from UTC since the parsed value is supposed to be
|
||||||
|
// in UTC, not local time. Also, the calendar uses UTC functions for
|
||||||
|
// date extraction.
|
||||||
|
return new Date(Date.UTC(year, month, day)); |
||||||
|
}; |
||||||
|
|
||||||
|
})(); |
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Get the computed style for and element
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
function getStyle(oElm, strCssRule) { |
||||||
|
'use strict'; |
||||||
|
var strValue = ""; |
||||||
|
if(document.defaultView && document.defaultView.getComputedStyle) { |
||||||
|
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); |
||||||
|
} |
||||||
|
else if(oElm.currentStyle) { |
||||||
|
strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { |
||||||
|
return p1.toUpperCase(); |
||||||
|
}); |
||||||
|
strValue = oElm.currentStyle[strCssRule]; |
||||||
|
} |
||||||
|
return strValue; |
||||||
|
} |
||||||
@ -0,0 +1,275 @@ |
|||||||
|
/*global DateTimeShortcuts, SelectFilter*/ |
||||||
|
/** |
||||||
|
* Django admin inlines |
||||||
|
* |
||||||
|
* Based on jQuery Formset 1.1 |
||||||
|
* @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) |
||||||
|
* @requires jQuery 1.2.6 or later |
||||||
|
* |
||||||
|
* Copyright (c) 2009, Stanislaus Madueke |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Spiced up with Code from Zain Memon's GSoC project 2009 |
||||||
|
* and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. |
||||||
|
* |
||||||
|
* Licensed under the New BSD License |
||||||
|
* See: http://www.opensource.org/licenses/bsd-license.php
|
||||||
|
*/ |
||||||
|
(function($) { |
||||||
|
'use strict'; |
||||||
|
$.fn.formset = function(opts) { |
||||||
|
var options = $.extend({}, $.fn.formset.defaults, opts); |
||||||
|
var $this = $(this); |
||||||
|
var $parent = $this.parent(); |
||||||
|
var updateElementIndex = function(el, prefix, ndx) { |
||||||
|
var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); |
||||||
|
var replacement = prefix + "-" + ndx; |
||||||
|
if ($(el).prop("for")) { |
||||||
|
$(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); |
||||||
|
} |
||||||
|
if (el.id) { |
||||||
|
el.id = el.id.replace(id_regex, replacement); |
||||||
|
} |
||||||
|
if (el.name) { |
||||||
|
el.name = el.name.replace(id_regex, replacement); |
||||||
|
} |
||||||
|
}; |
||||||
|
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); |
||||||
|
var nextIndex = parseInt(totalForms.val(), 10); |
||||||
|
var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); |
||||||
|
// only show the add button if we are allowed to add more items,
|
||||||
|
// note that max_num = None translates to a blank string.
|
||||||
|
var showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0; |
||||||
|
$this.each(function(i) { |
||||||
|
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass); |
||||||
|
}); |
||||||
|
if ($this.length && showAddButton) { |
||||||
|
var addButton; |
||||||
|
if ($this.prop("tagName") === "TR") { |
||||||
|
// If forms are laid out as table rows, insert the
|
||||||
|
// "add" button in a new table row:
|
||||||
|
var numCols = this.eq(-1).children().length; |
||||||
|
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>"); |
||||||
|
addButton = $parent.find("tr:last a"); |
||||||
|
} else { |
||||||
|
// Otherwise, insert it immediately after the last form:
|
||||||
|
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>"); |
||||||
|
addButton = $this.filter(":last").next().find("a"); |
||||||
|
} |
||||||
|
addButton.click(function(e) { |
||||||
|
e.preventDefault(); |
||||||
|
var template = $("#" + options.prefix + "-empty"); |
||||||
|
var row = template.clone(true); |
||||||
|
row.removeClass(options.emptyCssClass) |
||||||
|
.addClass(options.formCssClass) |
||||||
|
.attr("id", options.prefix + "-" + nextIndex); |
||||||
|
if (row.is("tr")) { |
||||||
|
// If the forms are laid out in table rows, insert
|
||||||
|
// the remove button into the last table cell:
|
||||||
|
row.children(":last").append('<div><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></div>"); |
||||||
|
} else if (row.is("ul") || row.is("ol")) { |
||||||
|
// If they're laid out as an ordered/unordered list,
|
||||||
|
// insert an <li> after the last list item:
|
||||||
|
row.append('<li><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></li>"); |
||||||
|
} else { |
||||||
|
// Otherwise, just insert the remove button as the
|
||||||
|
// last child element of the form's container:
|
||||||
|
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>"); |
||||||
|
} |
||||||
|
row.find("*").each(function() { |
||||||
|
updateElementIndex(this, options.prefix, totalForms.val()); |
||||||
|
}); |
||||||
|
// Insert the new form when it has been fully edited
|
||||||
|
row.insertBefore($(template)); |
||||||
|
// Update number of total forms
|
||||||
|
$(totalForms).val(parseInt(totalForms.val(), 10) + 1); |
||||||
|
nextIndex += 1; |
||||||
|
// Hide add button in case we've hit the max, except we want to add infinitely
|
||||||
|
if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) { |
||||||
|
addButton.parent().hide(); |
||||||
|
} |
||||||
|
// The delete button of each row triggers a bunch of other things
|
||||||
|
row.find("a." + options.deleteCssClass).click(function(e1) { |
||||||
|
e1.preventDefault(); |
||||||
|
// Remove the parent form containing this button:
|
||||||
|
row.remove(); |
||||||
|
nextIndex -= 1; |
||||||
|
// If a post-delete callback was provided, call it with the deleted form:
|
||||||
|
if (options.removed) { |
||||||
|
options.removed(row); |
||||||
|
} |
||||||
|
$(document).trigger('formset:removed', [row, options.prefix]); |
||||||
|
// Update the TOTAL_FORMS form count.
|
||||||
|
var forms = $("." + options.formCssClass); |
||||||
|
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); |
||||||
|
// Show add button again once we drop below max
|
||||||
|
if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) { |
||||||
|
addButton.parent().show(); |
||||||
|
} |
||||||
|
// Also, update names and ids for all remaining form controls
|
||||||
|
// so they remain in sequence:
|
||||||
|
var i, formCount; |
||||||
|
var updateElementCallback = function() { |
||||||
|
updateElementIndex(this, options.prefix, i); |
||||||
|
}; |
||||||
|
for (i = 0, formCount = forms.length; i < formCount; i++) { |
||||||
|
updateElementIndex($(forms).get(i), options.prefix, i); |
||||||
|
$(forms.get(i)).find("*").each(updateElementCallback); |
||||||
|
} |
||||||
|
}); |
||||||
|
// If a post-add callback was supplied, call it with the added form:
|
||||||
|
if (options.added) { |
||||||
|
options.added(row); |
||||||
|
} |
||||||
|
$(document).trigger('formset:added', [row, options.prefix]); |
||||||
|
}); |
||||||
|
} |
||||||
|
return this; |
||||||
|
}; |
||||||
|
|
||||||
|
/* Setup plugin defaults */ |
||||||
|
$.fn.formset.defaults = { |
||||||
|
prefix: "form", // The form prefix for your django formset
|
||||||
|
addText: "add another", // Text for the add link
|
||||||
|
deleteText: "remove", // Text for the delete link
|
||||||
|
addCssClass: "add-row", // CSS class applied to the add link
|
||||||
|
deleteCssClass: "delete-row", // CSS class applied to the delete link
|
||||||
|
emptyCssClass: "empty-row", // CSS class applied to the empty row
|
||||||
|
formCssClass: "dynamic-form", // CSS class applied to each form in a formset
|
||||||
|
added: null, // Function called each time a new form is added
|
||||||
|
removed: null // Function called each time a form is deleted
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Tabular inlines ---------------------------------------------------------
|
||||||
|
$.fn.tabularFormset = function(options) { |
||||||
|
var $rows = $(this); |
||||||
|
var alternatingRows = function(row) { |
||||||
|
$($rows.selector).not(".add-row").removeClass("row1 row2") |
||||||
|
.filter(":even").addClass("row1").end() |
||||||
|
.filter(":odd").addClass("row2"); |
||||||
|
}; |
||||||
|
|
||||||
|
var reinitDateTimeShortCuts = function() { |
||||||
|
// Reinitialize the calendar and clock widgets by force
|
||||||
|
if (typeof DateTimeShortcuts !== "undefined") { |
||||||
|
$(".datetimeshortcuts").remove(); |
||||||
|
DateTimeShortcuts.init(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var updateSelectFilter = function() { |
||||||
|
// If any SelectFilter widgets are a part of the new form,
|
||||||
|
// instantiate a new SelectFilter instance for it.
|
||||||
|
if (typeof SelectFilter !== 'undefined') { |
||||||
|
$('.selectfilter').each(function(index, value) { |
||||||
|
var namearr = value.name.split('-'); |
||||||
|
SelectFilter.init(value.id, namearr[namearr.length - 1], false); |
||||||
|
}); |
||||||
|
$('.selectfilterstacked').each(function(index, value) { |
||||||
|
var namearr = value.name.split('-'); |
||||||
|
SelectFilter.init(value.id, namearr[namearr.length - 1], true); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var initPrepopulatedFields = function(row) { |
||||||
|
row.find('.prepopulated_field').each(function() { |
||||||
|
var field = $(this), |
||||||
|
input = field.find('input, select, textarea'), |
||||||
|
dependency_list = input.data('dependency_list') || [], |
||||||
|
dependencies = []; |
||||||
|
$.each(dependency_list, function(i, field_name) { |
||||||
|
dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id')); |
||||||
|
}); |
||||||
|
if (dependencies.length) { |
||||||
|
input.prepopulate(dependencies, input.attr('maxlength')); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
$rows.formset({ |
||||||
|
prefix: options.prefix, |
||||||
|
addText: options.addText, |
||||||
|
formCssClass: "dynamic-" + options.prefix, |
||||||
|
deleteCssClass: "inline-deletelink", |
||||||
|
deleteText: options.deleteText, |
||||||
|
emptyCssClass: "empty-form", |
||||||
|
removed: alternatingRows, |
||||||
|
added: function(row) { |
||||||
|
initPrepopulatedFields(row); |
||||||
|
reinitDateTimeShortCuts(); |
||||||
|
updateSelectFilter(); |
||||||
|
alternatingRows(row); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return $rows; |
||||||
|
}; |
||||||
|
|
||||||
|
// Stacked inlines ---------------------------------------------------------
|
||||||
|
$.fn.stackedFormset = function(options) { |
||||||
|
var $rows = $(this); |
||||||
|
var updateInlineLabel = function(row) { |
||||||
|
$($rows.selector).find(".inline_label").each(function(i) { |
||||||
|
var count = i + 1; |
||||||
|
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var reinitDateTimeShortCuts = function() { |
||||||
|
// Reinitialize the calendar and clock widgets by force, yuck.
|
||||||
|
if (typeof DateTimeShortcuts !== "undefined") { |
||||||
|
$(".datetimeshortcuts").remove(); |
||||||
|
DateTimeShortcuts.init(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var updateSelectFilter = function() { |
||||||
|
// If any SelectFilter widgets were added, instantiate a new instance.
|
||||||
|
if (typeof SelectFilter !== "undefined") { |
||||||
|
$(".selectfilter").each(function(index, value) { |
||||||
|
var namearr = value.name.split('-'); |
||||||
|
SelectFilter.init(value.id, namearr[namearr.length - 1], false); |
||||||
|
}); |
||||||
|
$(".selectfilterstacked").each(function(index, value) { |
||||||
|
var namearr = value.name.split('-'); |
||||||
|
SelectFilter.init(value.id, namearr[namearr.length - 1], true); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var initPrepopulatedFields = function(row) { |
||||||
|
row.find('.prepopulated_field').each(function() { |
||||||
|
var field = $(this), |
||||||
|
input = field.find('input, select, textarea'), |
||||||
|
dependency_list = input.data('dependency_list') || [], |
||||||
|
dependencies = []; |
||||||
|
$.each(dependency_list, function(i, field_name) { |
||||||
|
dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id')); |
||||||
|
}); |
||||||
|
if (dependencies.length) { |
||||||
|
input.prepopulate(dependencies, input.attr('maxlength')); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
$rows.formset({ |
||||||
|
prefix: options.prefix, |
||||||
|
addText: options.addText, |
||||||
|
formCssClass: "dynamic-" + options.prefix, |
||||||
|
deleteCssClass: "inline-deletelink", |
||||||
|
deleteText: options.deleteText, |
||||||
|
emptyCssClass: "empty-form", |
||||||
|
removed: updateInlineLabel, |
||||||
|
added: function(row) { |
||||||
|
initPrepopulatedFields(row); |
||||||
|
reinitDateTimeShortCuts(); |
||||||
|
updateSelectFilter(); |
||||||
|
updateInlineLabel(row); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return $rows; |
||||||
|
}; |
||||||
|
})(django.jQuery); |
||||||