mirror of
https://github.com/dkmstr/openuds.git
synced 2025-10-07 15:33:51 +03:00
Compare commits
1088 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
15a76f3b9b | ||
|
a3110d4623 | ||
|
92c3fbd827 | ||
|
ea49e18f80 | ||
|
393819bc94 | ||
|
7ab956fa4a | ||
|
17044d38bd | ||
|
0dc461c30b | ||
|
ced5e06ff0 | ||
|
5e848cbc8c | ||
|
f924604217 | ||
|
efc59c0124 | ||
|
2eaa447155 | ||
|
3528424892 | ||
|
2eef7222d5 | ||
|
0d28a5b5f7 | ||
|
e0e7e26234 | ||
|
2674563535 | ||
|
a864fbac96 | ||
|
51c32a4350 | ||
|
ec95f27ee6 | ||
|
15ce5aa938 | ||
|
39b353fb24 | ||
|
7a0c8aa977 | ||
|
664418d4dc | ||
|
381cf47abf | ||
|
1578c92a88 | ||
|
6827380e99 | ||
|
62f637790c | ||
|
bf5311b5af | ||
|
d0e0418ede | ||
|
243cbbfd4b | ||
|
e7984d5a8e | ||
|
eacce7adda | ||
|
622e8629ff | ||
|
50e368ee7a | ||
|
6766fe41fe | ||
|
ba35968e8d | ||
|
4adfac1c02 | ||
|
437865b278 | ||
|
793b6c9004 | ||
|
96bd117622 | ||
|
8b2df76582 | ||
|
4196883bfb | ||
|
8585d10623 | ||
|
c715b92ed0 | ||
|
a3726399f1 | ||
|
8ce3efc7ee | ||
|
0bd3e1ac72 | ||
|
c2d4e995e7 | ||
|
1b71fef8b4 | ||
|
074a4d525d | ||
|
36e19574e0 | ||
|
ef9165b3a2 | ||
|
14cddbb210 | ||
|
2d14884454 | ||
|
ba4eeffc77 | ||
|
59179b818e | ||
|
dbcdc84b3b | ||
|
c73dae361f | ||
|
ec29371b41 | ||
|
9365f5937b | ||
|
971015d33a | ||
|
7a742c043b | ||
|
c08a0cb0ed | ||
|
b5926dec6f | ||
|
2fdcdb014f | ||
|
bd70a6290e | ||
|
3afa96f1c5 | ||
|
5da12a8091 | ||
|
08eeff5604 | ||
|
169a946a03 | ||
|
94842ce0ef | ||
|
0fb7d5ed1b | ||
|
2021fd69ec | ||
|
813764a100 | ||
|
cbd9330907 | ||
|
a250cf4aef | ||
|
50bc3cd3ef | ||
|
4fb863cfa7 | ||
|
3a1bd1eed3 | ||
|
bce3e429cf | ||
|
b5baea184f | ||
|
42cbad4117 | ||
|
09f329db62 | ||
|
6b5f9d266d | ||
|
242d9b5e6e | ||
|
99b17e573c | ||
|
701edb91f1 | ||
|
f0627db09f | ||
|
56a579e11b | ||
|
4427448eca | ||
|
203e2fcdd0 | ||
|
f7fa92e6c1 | ||
|
425257a464 | ||
|
0acc07ebb3 | ||
|
030078a619 | ||
|
0e6ca4c188 | ||
|
c7d5a1c928 | ||
|
e636a4afcd | ||
|
8b76324ffc | ||
|
8fe1e55770 | ||
|
caae694628 | ||
|
268e9d551a | ||
|
07137c2416 | ||
|
273b2a59c4 | ||
|
63364f4e72 | ||
|
abc9622d53 | ||
|
9cd7e2f67b | ||
|
9277d3b5fb | ||
|
6f46e16be8 | ||
|
0b390e406a | ||
|
f301e4654a | ||
|
62481899a1 | ||
|
869dfc8c06 | ||
|
939d456b9d | ||
|
9c70fb3caf | ||
|
baf4a677dd | ||
|
4c4820f166 | ||
|
2749bfc40c | ||
|
704e0607eb | ||
|
401fbac63e | ||
|
7f1252a70a | ||
|
2df103a348 | ||
|
489bb44c92 | ||
|
c606b6f00e | ||
|
0b4b38abe7 | ||
|
40b71fa983 | ||
|
6116db5147 | ||
|
e979c6e1e2 | ||
|
8f9d042cdd | ||
|
fcf030e693 | ||
|
31e6e01cad | ||
|
1aad0c85a4 | ||
|
e6e16334b3 | ||
|
6544a61f72 | ||
|
8a285fddfa | ||
|
c069f51e8d | ||
|
c9a690fe8c | ||
|
847821c66c | ||
|
b5387d4922 | ||
|
b0a6807ea4 | ||
|
2e96074961 | ||
|
f275a91a43 | ||
|
135392d245 | ||
|
ff622bb9cd | ||
|
608c1317d7 | ||
|
9f4ef20dc1 | ||
|
73bd3cc28e | ||
|
ea9eb04461 | ||
|
c45833c252 | ||
|
e260fc9790 | ||
|
cc6ba2ff41 | ||
|
bec74ddc99 | ||
|
7af7d11c8a | ||
|
8934d978fe | ||
|
8376e81532 | ||
|
6587d9ba2c | ||
|
2654036fd2 | ||
|
f9226e7deb | ||
|
56ac8aece9 | ||
|
12737df530 | ||
|
7b9c835562 | ||
|
cbb809db77 | ||
|
4f9085f0a2 | ||
|
389cf62150 | ||
|
44c367bf8f | ||
|
efb0083161 | ||
|
16c1aba3e7 | ||
|
07ed8b9762 | ||
|
fbd0a59a70 | ||
|
a08fe53383 | ||
|
e1b8c43cca | ||
|
60f20e64f3 | ||
|
6bb1109fe1 | ||
|
134f2059dd | ||
|
ec93e5c9cc | ||
|
1487c21e1e | ||
|
fd6b0c9458 | ||
|
c41648748a | ||
|
de4aef3a5c | ||
|
d024d74529 | ||
|
6eb5a7ccc8 | ||
|
335fd338bd | ||
|
d7ac59f257 | ||
|
1ff09a1a04 | ||
|
ca54c2c099 | ||
|
76d209aa25 | ||
|
491a33421d | ||
|
f1cbcf86e1 | ||
|
e2e0f96d3e | ||
|
4be5d8d6e5 | ||
|
0365376ab0 | ||
|
b9929566f6 | ||
|
f463f586a3 | ||
|
f6492256a8 | ||
|
6fe734f67e | ||
|
66d2c63a20 | ||
|
06f2faff35 | ||
|
57bd5e8149 | ||
|
11b9d07aef | ||
|
b6f582d84e | ||
|
b777919f52 | ||
|
6371a24d23 | ||
|
d94cc70eff | ||
|
7d02f3682d | ||
|
51fb42db10 | ||
|
a352059ddc | ||
|
0187b94768 | ||
|
163245401b | ||
|
7a0f28a227 | ||
|
0add4b4321 | ||
|
19fdcadbcd | ||
|
7b85adaddf | ||
|
d8a0a2f80a | ||
|
8ec6ce7edb | ||
|
0eab8d0f3f | ||
|
ae9a9534fc | ||
|
b56dbcfdfd | ||
|
1c1003eb41 | ||
|
4bc6d88006 | ||
|
fe6c701e44 | ||
|
f08593881f | ||
|
9a59725504 | ||
|
30cf167e5b | ||
|
88b7b365e7 | ||
|
064d881c1e | ||
|
c3f9d673bd | ||
|
bbc2790ce0 | ||
|
64970b57ca | ||
|
4695dcaa0c | ||
|
2b11d1715b | ||
|
e23f22d92d | ||
|
c8492a4c47 | ||
|
962f1fcc1c | ||
|
2d6f4e4f2d | ||
|
6bc70ff4de | ||
|
aaf4b539d5 | ||
|
83efb81966 | ||
|
03d0fc2ba4 | ||
|
41f128c2ad | ||
|
bb09ef2a69 | ||
|
407b0ebf55 | ||
|
98d78d9a2e | ||
|
033ac0d1f6 | ||
|
c9e9f60ed1 | ||
|
162c84e21c | ||
|
9f6d126484 | ||
|
f1e27f1364 | ||
|
06c7a46d2a | ||
|
0877cc01f4 | ||
|
00e85357cf | ||
|
cc72b3742f | ||
|
dff20bd6e1 | ||
|
69b6f7d7d8 | ||
|
02a2800a4b | ||
|
9881df5117 | ||
|
bc2f83c937 | ||
|
fa78b4b295 | ||
|
95230292c3 | ||
|
fdaf974009 | ||
|
26764c4cab | ||
|
52d0e8977c | ||
|
1d7df7814c | ||
|
1551fa8efa | ||
|
7e9a37e768 | ||
|
80bf6d77f1 | ||
|
2d7a2d6049 | ||
|
8363b41a68 | ||
|
9804678a30 | ||
|
1187c0aa5e | ||
|
36adbe387c | ||
|
df2dcf7acd | ||
|
b64fa374d7 | ||
|
3fbb492921 | ||
|
1b97e2015d | ||
|
3814986e41 | ||
|
037a4b523b | ||
|
522d493557 | ||
|
2ac06f7345 | ||
|
0745a7aa9a | ||
|
7e419aed8d | ||
|
baa9565140 | ||
|
069dfb154a | ||
|
eea9db7a0d | ||
|
485ed4d60b | ||
|
44056dda3a | ||
|
4de3e83ade | ||
|
73713eac69 | ||
|
6ed924655d | ||
|
7706262702 | ||
|
d878d522d7 | ||
|
e0843179cd | ||
|
c6683db6e6 | ||
|
063b062913 | ||
|
3dd2521408 | ||
|
f8e61d475a | ||
|
e7cea4ff6e | ||
|
33d37ec0c2 | ||
|
512feaed81 | ||
|
93c6c1c20e | ||
|
d2298f77b9 | ||
|
6979d9bc17 | ||
|
d4135d527a | ||
|
91c678eb72 | ||
|
1ef2c7303f | ||
|
1b232d1113 | ||
|
78652b550b | ||
|
95d0965503 | ||
|
d8f8815137 | ||
|
9bcf7076aa | ||
|
ae71e2b4bd | ||
|
f8934acbe4 | ||
|
abf6d3751b | ||
|
b77fa7dfd6 | ||
|
32a04edbf9 | ||
|
3ff281ffa3 | ||
|
e07f1ae068 | ||
|
119635862b | ||
|
e553b904c5 | ||
|
92db63d01d | ||
|
3584ff189b | ||
|
e8614cbf14 | ||
|
399fc901fc | ||
|
524e234e6d | ||
|
c14186fb4e | ||
|
eeea4a3f39 | ||
|
567f91414f | ||
|
e5710eb74c | ||
|
1733f142be | ||
|
ccebca9748 | ||
|
cb5d6ed771 | ||
|
b9283c6778 | ||
|
5dc2c16cbe | ||
|
8d4f60b0fb | ||
|
b9175be480 | ||
|
884bbe7363 | ||
|
98b9e6b659 | ||
|
1c4339f404 | ||
|
0ffc9964d0 | ||
|
18c9406900 | ||
|
df498dd5bc | ||
|
e7a3c7ebeb | ||
|
724aecd21c | ||
|
b00a023f30 | ||
|
592510f0f3 | ||
|
c96e566ebf | ||
|
78526b3560 | ||
|
04ec90ad61 | ||
|
e69914a9a5 | ||
|
c1c54f38cc | ||
|
dad83c5c50 | ||
|
b592e10126 | ||
|
a235e43c07 | ||
|
eb7185b9e3 | ||
|
776702f971 | ||
|
6fb9b11f1b | ||
|
d3e2ab85b8 | ||
|
35a4dd659c | ||
|
e0d2abbbd6 | ||
|
5db3429b2c | ||
|
dd0c605ff4 | ||
|
54d41c1931 | ||
|
9ee66cf6ed | ||
|
a34de035cb | ||
|
1dac61ea69 | ||
|
15c785d5fe | ||
|
7c7c609ea8 | ||
|
f8b34e1d23 | ||
|
6295e7400d | ||
|
42a3df5c82 | ||
|
54a2a0cb35 | ||
|
ec48f27792 | ||
|
15554ab08f | ||
|
c042ab6b31 | ||
|
40641659a5 | ||
|
f7fbc5a0c4 | ||
|
4a6e21d1ec | ||
|
d6dcd265a4 | ||
|
8fe589fa75 | ||
|
656f10a1ca | ||
|
f39d780a88 | ||
|
134e9c0b61 | ||
|
f411eec5f4 | ||
|
a996562a5e | ||
|
1ea3261b27 | ||
|
a1bd7274f4 | ||
|
3206390c9c | ||
|
4ed20850ae | ||
|
ef302205bc | ||
|
e651d3348d | ||
|
cc3cce6038 | ||
|
5b3e5242d1 | ||
|
60556ad4ec | ||
|
8686741410 | ||
|
199e0d3559 | ||
|
95b8969f5b | ||
|
fc447e3ccf | ||
|
6b19e75ce7 | ||
|
c3316a4745 | ||
|
250441056b | ||
|
bdef8b2e8c | ||
|
aef71ba48c | ||
|
86e5b9fcaa | ||
|
8d01e77a94 | ||
|
d34248b868 | ||
|
c15151a35d | ||
|
b5609a7b0c | ||
|
4067de702c | ||
|
375f574e9e | ||
|
ee59f45838 | ||
|
ae5fafae76 | ||
|
dc1dd977fc | ||
|
f8b95382b0 | ||
|
2f655dce16 | ||
|
c5138dbc9c | ||
|
8a17d5d017 | ||
|
089f62e6f8 | ||
|
e4192e6064 | ||
|
646334ece5 | ||
|
2480a79450 | ||
|
f173146d8f | ||
|
62f50304fe | ||
|
c70d94e866 | ||
|
dc006e7cbc | ||
|
c5444f0df2 | ||
|
c7d3e4022f | ||
|
151623e407 | ||
|
67393e88db | ||
|
2fe783e3ae | ||
|
d87f4de4ff | ||
|
b69f56ecb8 | ||
|
b08fd3d60e | ||
|
7d26463639 | ||
|
4d9d4bdbee | ||
|
523ca37ee8 | ||
|
65c7b34ee0 | ||
|
2303861650 | ||
|
38b7ac892e | ||
|
cfad948660 | ||
|
ccf35fcd49 | ||
|
d6e031e9e6 | ||
|
7b29d698dc | ||
|
989600e639 | ||
|
9fa4bacc74 | ||
|
e02b3ad881 | ||
|
cc4619220a | ||
|
c71d86825c | ||
|
7648e9c655 | ||
|
bb8931e7d4 | ||
|
695a67c2cb | ||
|
011ba37d2a | ||
|
d73c8f49cc | ||
|
3ddf2f91ad | ||
|
809aea2c87 | ||
|
4e2fce147f | ||
|
26e01af696 | ||
|
cb9359f9af | ||
|
bad482b7f1 | ||
|
a94f7b335b | ||
|
41b86509e0 | ||
|
27224fa8a1 | ||
|
9656aab27d | ||
|
cbf68030d3 | ||
|
3e97481af2 | ||
|
705c3d7b76 | ||
|
2470e88d55 | ||
|
f300770b29 | ||
|
63278938c8 | ||
|
5623c65763 | ||
|
5dca92ca5e | ||
|
c1fd898d62 | ||
|
2435f589b9 | ||
|
6387629e7e | ||
|
5bde71b117 | ||
|
b2eb7cc9c1 | ||
|
48df4390bd | ||
|
9920af9c59 | ||
|
681b1333d1 | ||
|
67b8955189 | ||
|
d542503f55 | ||
|
be5ed5a70b | ||
|
f751fff8ca | ||
|
2d942fbac7 | ||
|
4bb4987937 | ||
|
d371e3f7ac | ||
|
033fb6eff2 | ||
|
23819b77ee | ||
|
fbcc2210b3 | ||
|
45b2e61631 | ||
|
4fceb8609f | ||
|
26c6b559a5 | ||
|
90e34029f3 | ||
|
6895f602ab | ||
|
b1b8b613e6 | ||
|
40ba837f70 | ||
|
c075ae5a9c | ||
|
8de49e5e94 | ||
|
7887b7f3cc | ||
|
c81f162b90 | ||
|
35a5a78220 | ||
|
2bc0f64e34 | ||
|
19cb475e2d | ||
|
ae4fc2d51a | ||
|
06e886a366 | ||
|
1497314a46 | ||
|
e6998cb1f3 | ||
|
111782dffd | ||
|
a86fbf83e8 | ||
|
c9f6c17407 | ||
|
c04037a4ea | ||
|
d1adcebe4b | ||
|
3e5cbda861 | ||
|
8a393c6717 | ||
|
f235bc0796 | ||
|
2549510eaa | ||
|
3fbcee60cb | ||
|
20cc73dca8 | ||
|
375fe6551c | ||
|
f74524d947 | ||
|
e1f26d2157 | ||
|
7d44bd7b65 | ||
|
ab5f51a3b1 | ||
|
d1e2e98099 | ||
|
f94bbaad67 | ||
|
7143682062 | ||
|
17a087ed4a | ||
|
762138ca57 | ||
|
1fb46003fc | ||
|
e1bbbece43 | ||
|
e3e652d4e1 | ||
|
b8a1fc31f3 | ||
|
d5034c9971 | ||
|
215c8f8f3e | ||
|
b2bf4bd0db | ||
|
1d2c4c8282 | ||
|
70fc09b21a | ||
|
9a529b8f5b | ||
|
4a2401b622 | ||
|
3feb502fec | ||
|
e75c86ad58 | ||
|
9a95d39156 | ||
|
cc48b50dcb | ||
|
32b1ac71a9 | ||
|
bd98349dc4 | ||
|
cf6602033d | ||
|
2959a878af | ||
|
ea087fce53 | ||
|
9335c73003 | ||
|
e11867a55e | ||
|
c72a8d3950 | ||
|
ddd8df3b26 | ||
|
c491dc78ab | ||
|
fd4fe245c6 | ||
|
cbd8a17cc4 | ||
|
9356fc3559 | ||
|
243e627827 | ||
|
bb408a31a2 | ||
|
3035360ce7 | ||
|
cdaf5a17fa | ||
|
f97e02e867 | ||
|
101aa6fc39 | ||
|
8e7a6af3ad | ||
|
22bf17f080 | ||
|
35b27acee3 | ||
|
722c8b2b61 | ||
|
bc6d500898 | ||
|
c9ec31f258 | ||
|
e9f38b044f | ||
|
06a00d00b9 | ||
|
7c916397e4 | ||
|
903664b7c5 | ||
|
bda104d94e | ||
|
e8b16a7e9d | ||
|
c7d3984289 | ||
|
038e37fe39 | ||
|
ce2250bb2c | ||
|
c32222ec8a | ||
|
9a86682c9d | ||
|
2159e0f29d | ||
|
3057f454dd | ||
|
42e8213442 | ||
|
29aa6be5dc | ||
|
8cf6815e8e | ||
|
d77a56f953 | ||
|
229ed2345b | ||
|
d68f5332d1 | ||
|
8ded065fc5 | ||
|
4c6159e431 | ||
|
d22531da7d | ||
|
0a10f81cb7 | ||
|
b3e2d2264a | ||
|
500347d878 | ||
|
2096ad085a | ||
|
41b40d8458 | ||
|
eb844a0c88 | ||
|
44e6a3b50c | ||
|
531c6d983d | ||
|
8a138f9cd8 | ||
|
1cbb7d1ae3 | ||
|
de0447bbc3 | ||
|
609a982c92 | ||
|
cca8fee453 | ||
|
c72f0dd46e | ||
|
da93da5782 | ||
|
7afa2b8042 | ||
|
0c8a1447bf | ||
|
493792aace | ||
|
2fb06c06f6 | ||
|
66653b0602 | ||
|
58e77aa4f3 | ||
|
818c317724 | ||
|
91a40dcc76 | ||
|
dca366b334 | ||
|
15ef761d47 | ||
|
4b96c7936e | ||
|
3cdce63405 | ||
|
d1a5329780 | ||
|
043f65efdc | ||
|
62fca626b7 | ||
|
d2234a4daa | ||
|
029ae69353 | ||
|
a29dc53956 | ||
|
c7e98fdde9 | ||
|
74781c14c0 | ||
|
7a3692cc43 | ||
|
7f049a80de | ||
|
fe15642254 | ||
|
f3e4e9d267 | ||
|
5bca96a882 | ||
|
47e615b7b2 | ||
|
154533b4cb | ||
|
43796e44ae | ||
|
418fac20e5 | ||
|
85a32cf667 | ||
|
0c0ec581c0 | ||
|
c56ef185b6 | ||
|
449b3df02a | ||
|
1f519308a1 | ||
|
12c93732da | ||
|
a02d9561c3 | ||
|
a3760c0e8a | ||
|
8ccf48564a | ||
|
727f455e99 | ||
|
99038a61f1 | ||
|
102a4b35ee | ||
|
97787b7eba | ||
|
42845e6243 | ||
|
43f17a3945 | ||
|
c0669bc1f2 | ||
|
5f377762b5 | ||
|
df7c27dbf6 | ||
|
5bc650eaa9 | ||
|
638817f98b | ||
|
825e88e1f1 | ||
|
971f56c62a | ||
|
d2d7291c19 | ||
|
7137f151fb | ||
|
f23c68d7bf | ||
|
6b8f8f5211 | ||
|
f4414233f8 | ||
|
c2243b8f48 | ||
|
dd5b35b354 | ||
|
a8bba8da48 | ||
|
a685f78561 | ||
|
5fc6710a45 | ||
|
a4df05e428 | ||
|
d1ccdfa686 | ||
|
f7b3e8853f | ||
|
063f433696 | ||
|
6fbe86b218 | ||
|
550967d6d7 | ||
|
02443aabde | ||
|
2ecb274ed6 | ||
|
ce52ac4acc | ||
|
e6150b0b07 | ||
|
bbbc14f860 | ||
|
a2d81b138d | ||
|
74148210a9 | ||
|
3cec0f94e5 | ||
|
a738f3afbf | ||
|
36ec5a7451 | ||
|
87cec03254 | ||
|
8eec58997a | ||
|
b508c24b7d | ||
|
2b73e0356c | ||
|
d21993ceff | ||
|
42feeacc86 | ||
|
0ba2ccab33 | ||
|
bac8a651b0 | ||
|
97e4eb2394 | ||
|
e0ad0185b7 | ||
|
53f1312537 | ||
|
bdf0d034fa | ||
|
15aeba101e | ||
|
d771039daa | ||
|
35ca143690 | ||
|
7f8aea603f | ||
|
97cde76157 | ||
|
a38921975f | ||
|
01b47d128c | ||
|
4bc8150852 | ||
|
d846db17cf | ||
|
573e6b5d1f | ||
|
1b3d156e6c | ||
|
cd78c6a388 | ||
|
1399767c22 | ||
|
babdd9c925 | ||
|
90b67ae3e6 | ||
|
06d6b9fd24 | ||
|
c9524191b1 | ||
|
a48cb597db | ||
|
cde89f1839 | ||
|
9451803ef7 | ||
|
36b816be69 | ||
|
defe8490b1 | ||
|
10d85df2e1 | ||
|
f1593c0957 | ||
|
4e1af8a33f | ||
|
49a512d274 | ||
|
92d746fed5 | ||
|
722021820b | ||
|
21177736f3 | ||
|
6e173b09f2 | ||
|
310e7c5b53 | ||
|
bd7263307a | ||
|
0689bafa9c | ||
|
cc3cd7999d | ||
|
784845c626 | ||
|
946cb66f33 | ||
|
5424d2b8b7 | ||
|
17ec42fca5 | ||
|
9896197c3c | ||
|
f497a902b5 | ||
|
d6887c26ab | ||
|
9feaad840f | ||
|
507aa23df0 | ||
|
fba0bf8631 | ||
|
bbe2b7d1c2 | ||
|
d085f350e0 | ||
|
adbe1dd8cd | ||
|
bf103d5603 | ||
|
9741decb3b | ||
|
084ad39fc9 | ||
|
3562e4ca56 | ||
|
6dbe561512 | ||
|
9e1efff826 | ||
|
42f8487e75 | ||
|
4f6ff538c2 | ||
|
14b24db532 | ||
|
d3c6312ed5 | ||
|
d0f291c386 | ||
|
341a538503 | ||
|
9a381cd333 | ||
|
1c30a5c46d | ||
|
6dc3f2a4dc | ||
|
bd5b81eccc | ||
|
9c77bb321f | ||
|
cc2d7f1d6b | ||
|
3da574985f | ||
|
7a562ec946 | ||
|
a5158acca1 | ||
|
5bf6f00425 | ||
|
3bc46de0a6 | ||
|
5aa798fe26 | ||
|
7e6890c327 | ||
|
f64987a7b1 | ||
|
2af27b86e8 | ||
|
210c218d36 | ||
|
73d0ff01da | ||
|
65418d4cb2 | ||
|
ac1651dcf3 | ||
|
89f887c68c | ||
|
cf5e25796d | ||
|
04135b14c9 | ||
|
0643e44125 | ||
|
c0c8cbf66d | ||
|
775d59a621 | ||
|
6a841a86df | ||
|
c4958e808e | ||
|
4a8d95eec9 | ||
|
9333077187 | ||
|
a14b5fea59 | ||
|
f9172258a4 | ||
|
ce07adcc0d | ||
|
7b12f3e359 | ||
|
d4c065355c | ||
|
b10a0ac386 | ||
|
60990ad64c | ||
|
acfbb0a3cb | ||
|
fd3930880d | ||
|
4b58ec4345 | ||
|
c76d24c0f2 | ||
|
5fac9c3205 | ||
|
8c09ec9b74 | ||
|
0d6171bc0f | ||
|
75c9313a0f | ||
|
0a3433b2f5 | ||
|
ed602e9354 | ||
|
d7f282cd88 | ||
|
5d83ca29bc | ||
|
0003a5fbf8 | ||
|
33c2cbe666 | ||
|
9712d271e7 | ||
|
3f97533e41 | ||
|
ce1a9b4b2f | ||
|
c1d26fb35e | ||
|
376ed1f231 | ||
|
53fda0af56 | ||
|
03ac4dcaa7 | ||
|
25f97a4b88 | ||
|
4b5f21b30e | ||
|
30fa98216e | ||
|
3181fdbf18 | ||
|
eca08d6350 | ||
|
2108353d1e | ||
|
14a2e0a02d | ||
|
5a80efc852 | ||
|
dc6af051ac | ||
|
b846940635 | ||
|
a10550820b | ||
|
217e681cb4 | ||
|
a2d348962d | ||
|
d535c5619a | ||
|
c479fc3fbd | ||
|
9bdfb4a7eb | ||
|
af2de4881f | ||
|
cf07caa5cb | ||
|
47174aa961 | ||
|
4e7376a7f0 | ||
|
4cdc3d2ff0 | ||
|
6e812b2cce | ||
|
6930509259 | ||
|
018e6d742c | ||
|
a2bf6c5799 | ||
|
49e367871e | ||
|
7d8072ca61 | ||
|
ec46452610 | ||
|
d0f3992e80 | ||
|
212b99b831 | ||
|
5de90f967e | ||
|
f6c67dab96 | ||
|
23694184bd | ||
|
827140dc21 | ||
|
52b78f11a3 | ||
|
692e82f62f | ||
|
c4e2f09dfc | ||
|
462b676353 | ||
|
09d1d646a5 | ||
|
9978993c9b | ||
|
a66d75bdc5 | ||
|
87a795cd8b | ||
|
4c66445998 | ||
|
051bf0358b | ||
|
a7f96d3933 | ||
|
2e31d2ec1e | ||
|
195e47f443 | ||
|
1d0bb1798c | ||
|
15df5b8141 | ||
|
7896dae178 | ||
|
e4beaf4584 | ||
|
5b383bb384 | ||
|
dc78222b88 | ||
|
0ef239a409 | ||
|
d0e6c98d2f | ||
|
e73fac22db | ||
|
de80b26880 | ||
|
78d0baf4af | ||
|
3d8fa98376 | ||
|
244302db58 | ||
|
a52c49ae5e | ||
|
46961c42c1 | ||
|
f9bc653a8f | ||
|
9045989186 | ||
|
49063d4187 | ||
|
922036112e | ||
|
eb93ccde21 | ||
|
90157e4d51 | ||
|
23e3c385fd | ||
|
63fc505bee | ||
|
10201bd976 | ||
|
6bf1b8ad83 | ||
|
79cdf4f68b | ||
|
86f789d3a5 | ||
|
4580e6c60a | ||
|
1c58aa116c | ||
|
1ae23c327e | ||
|
20a05371a3 | ||
|
21733cca17 | ||
|
9a28e53045 | ||
|
86318a66c3 | ||
|
1140f1b4e6 | ||
|
50e04eda7d | ||
|
b20c4c933c | ||
|
978ab5772d | ||
|
87d798c92c | ||
|
c62d30c506 | ||
|
9302c0cd76 | ||
|
7db14ec4b5 | ||
|
cf2051b8f2 | ||
|
5d984fb94e | ||
|
4565f00174 | ||
|
b64928f1e6 | ||
|
944d9957d6 | ||
|
19936f7a84 | ||
|
bf77ccc2ab | ||
|
3afb36678c | ||
|
bf66bb1009 | ||
|
366d340fd4 | ||
|
095f21204d | ||
|
5f329552af | ||
|
3c248428eb | ||
|
7a0465fca5 | ||
|
a1e5a1357a | ||
|
3094000c11 | ||
|
e05ae6e3eb | ||
|
1189554a20 | ||
|
7df74d264c | ||
|
41fba86f93 | ||
|
55ce029b68 | ||
|
44007d311c | ||
|
b2e16bd2e8 | ||
|
d943252a40 | ||
|
e7695f360e | ||
|
72c9d27686 | ||
|
feccd388c4 | ||
|
46af1b57dd | ||
|
ddbcc5aec4 | ||
|
06ff8e32be | ||
|
89addaf585 | ||
|
dab3e26223 | ||
|
72456baa8e | ||
|
6f4eca7da3 | ||
|
26c6ffdc8e | ||
|
2fb857a870 | ||
|
d7219fcafc | ||
|
001cd91bf7 | ||
|
1f737a0f4e | ||
|
4f6071ddf8 | ||
|
c33d469304 | ||
|
e335fa88fa | ||
|
83b8c474bd | ||
|
b0756d8e3e | ||
|
03feee9ebc | ||
|
0304762fce | ||
|
93075e2cc3 | ||
|
3e036adbca | ||
|
81439890e1 | ||
|
dcab2e120b | ||
|
3bc044518f | ||
|
0a477cae68 | ||
|
8a9f32dd03 | ||
|
0d3a724ab8 | ||
|
1e74a82a40 | ||
|
a50e1ecca8 | ||
|
5f99877bf7 | ||
|
3ad2a84d55 | ||
|
f5b4dd2ea6 | ||
|
e639911b38 | ||
|
ba1927b0fc | ||
|
8ed7bd1cc0 | ||
|
cfc2dbb49e | ||
|
3b570f86df | ||
|
edc03f4e7e | ||
|
bf3dd99b63 | ||
|
363f8939d9 | ||
|
e925a2a356 | ||
|
53258f2d7b | ||
|
77127664af | ||
|
2b7ad74f2f | ||
|
3cae37ca5c | ||
|
dbc001ea22 | ||
|
895ef25b77 | ||
|
453be53125 | ||
|
71d0cbaf8c | ||
|
48dcd97f5c | ||
|
3c956e94df | ||
|
49dc0eb0c2 | ||
|
de68a0cada | ||
|
a0ca068f54 | ||
|
fb1a367e93 | ||
|
75a7a787b9 | ||
|
6676c62120 | ||
|
db29667f4c | ||
|
b3c6e46f0b | ||
|
828247831b | ||
|
f3e7ec3be9 | ||
|
b9aff159d8 | ||
|
744515f11f | ||
|
6eccaa9ddf | ||
|
52a8021e9d | ||
|
735175badb | ||
|
e071a1afbc | ||
|
c29e2d4dcb | ||
|
f5e5d88973 | ||
|
64382b5afe | ||
|
732840df42 | ||
|
61c9f4f975 | ||
|
36bdbbfd37 | ||
|
a6b3462748 | ||
|
dcfee55122 | ||
|
3c7a0b82d7 | ||
|
ad69d8fa6c | ||
|
3ec517c90f | ||
|
888f125dc6 | ||
|
043b28cfb4 | ||
|
c98e964bba | ||
|
7ea7086ba9 | ||
|
d46400c1f7 | ||
|
fa2335efd4 | ||
|
63da672f30 | ||
|
8c04c88d86 | ||
|
a52e8dc548 | ||
|
b7bfecf87c | ||
|
ceecb0823d | ||
|
de4a9ff291 | ||
|
004e060aaf | ||
|
127c36f364 | ||
|
dbd4531376 | ||
|
17b20ab684 | ||
|
4b2eae58b1 | ||
|
6144eb2f6a | ||
|
2bf0c3e59a | ||
|
805b225552 | ||
|
dbb4466c46 | ||
|
67a691768e | ||
|
96937a397c | ||
|
47be643eac | ||
|
6bb538d941 | ||
|
d2cf0f6846 | ||
|
2615b5fca4 | ||
|
bf83de2f5e | ||
|
e59ac8078d | ||
|
caf250daa3 | ||
|
841580afda | ||
|
0a0772a7c6 | ||
|
d68822eaf7 | ||
|
6e0511add3 | ||
|
ae9f3c7e78 | ||
|
89d27cbcd5 | ||
|
59e9f65241 | ||
|
81d64162f4 | ||
|
495ab90cc2 | ||
|
47dff34637 | ||
|
918259079a | ||
|
2bda255c2a | ||
|
bfed62d833 | ||
|
2b68a119e1 | ||
|
7bbf86117b | ||
|
aa2e532843 | ||
|
fcc7bffb2e | ||
|
b5aa6cd4b8 | ||
|
9dd35ebf1e | ||
|
aba57d8400 | ||
|
66d56dc6e5 | ||
|
52c69a3521 | ||
|
5fd0436ab6 | ||
|
5cf101d3c8 | ||
|
36429e0443 | ||
|
e6d7944e2f | ||
|
15d7ca7a4b | ||
|
ea784bfeef | ||
|
fb463dee73 | ||
|
15011dea95 | ||
|
012dc2792b | ||
|
a07e784af1 | ||
|
59485e39de | ||
|
b79cbcc4e8 | ||
|
c7941017b5 | ||
|
c5b3656d38 | ||
|
eda93e0be2 | ||
|
53522724b3 | ||
|
a08b114aee | ||
|
79048a4271 | ||
|
efb614ff10 | ||
|
650c13067d | ||
|
f220cf3651 | ||
|
46990f6b64 | ||
|
50b7a55be5 | ||
|
81b1646458 | ||
|
8f70298713 | ||
|
0b2e38a85d | ||
|
eb9993f607 | ||
|
5dbacb629b | ||
|
c61ee0f72c | ||
|
eea75c1736 | ||
|
0303fbf910 | ||
|
2cc81d2b8b |
166
.gitignore
vendored
Normal file
166
.gitignore
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.orig
|
||||
*~
|
||||
*.swp
|
||||
.DS_Store
|
||||
*_enterprise.*
|
||||
.settings/
|
||||
.ipynb_checkpoints
|
||||
|
||||
# Debian buildings
|
||||
*.debhelper*
|
||||
*-stamp
|
||||
*.substvars
|
||||
|
||||
# /client/administration/
|
||||
/client/administration/*.suo
|
||||
|
||||
# /client/administration/UdsAdmin/
|
||||
/client/administration/UdsAdmin/*.user
|
||||
|
||||
# /client/administration/UdsAdmin/bin/
|
||||
/client/administration/UdsAdmin/bin/Debug
|
||||
/client/administration/UdsAdmin/bin/Release
|
||||
|
||||
# /client/administration/UdsAdmin/obj/x86/
|
||||
/client/administration/UdsAdmin/obj/x86/Debug
|
||||
/client/administration/UdsAdmin/obj/x86/Release
|
||||
|
||||
# /client/administration/installer/UDSAdminInstaller/
|
||||
/client/administration/installer/UDSAdminInstaller/MSChart.exe
|
||||
/client/administration/installer/UDSAdminInstaller/UDSAdminSetup.exe
|
||||
|
||||
# /guacamole-tunnel/
|
||||
/guacamole-tunnel/target
|
||||
|
||||
# /linuxActor/
|
||||
/linuxActor/udsactor_*
|
||||
|
||||
# /linuxActor/src/debian/
|
||||
/linuxActor/src/debian/udsactor
|
||||
|
||||
# /linuxActorNX/
|
||||
/linuxActorNX/udsactor-nx_*
|
||||
|
||||
# /linuxActorNX/src/debian/
|
||||
/linuxActorNX/src/debian/udsactor-nx
|
||||
|
||||
# /linuxActorXRDP/
|
||||
/linuxActorXRDP/udsactor-xrdp_*
|
||||
|
||||
# /linuxActorXRDP/src/debian/
|
||||
/linuxActorXRDP/src/debian/udsactor-xrdp
|
||||
|
||||
# /nxtransport/jar/
|
||||
/nxtransport/jar/*.sh
|
||||
/nxtransport/jar/*.jar
|
||||
|
||||
# /nxtuntransport/jar/
|
||||
/nxtuntransport/jar/*.sh
|
||||
/nxtuntransport/jar/*.jar
|
||||
|
||||
# /rdptransport/java/jar/
|
||||
/rdptransport/java/jar/*.sh
|
||||
/rdptransport/java/jar/*.jar
|
||||
|
||||
# /server/
|
||||
*_enterprise
|
||||
/server/openuds.sublime-project
|
||||
/server/openuds.sublime-workspace
|
||||
|
||||
# /server/src/
|
||||
/server/src/taskmanager.pid
|
||||
/server/src/testing
|
||||
/server/src/*_enterprise*
|
||||
|
||||
# /server/src/log/
|
||||
/server/src/log/uds.log.*
|
||||
/server/src/log/sql.log.*
|
||||
/server/src/log/*.log.*
|
||||
|
||||
# /server/src/server/
|
||||
/server/src/server/settings.py
|
||||
/server/src/server/*_enterprise.py
|
||||
/server/src/server/enterprise*
|
||||
|
||||
# /server/src/static/
|
||||
/server/src/static/cache
|
||||
|
||||
# /server/src/uds/
|
||||
/server/src/uds/*_enterprise.py
|
||||
/server/src/uds/fixtures
|
||||
/server/src/uds/tests
|
||||
|
||||
# /server/src/uds/auths/
|
||||
/server/src/uds/auths/*-enterprise
|
||||
/server/src/uds/auths/*_enterprise
|
||||
|
||||
# /server/src/uds/core/util/
|
||||
/server/src/uds/core/util/*enterprise.py
|
||||
|
||||
# /server/src/uds/dispatchers/
|
||||
/server/src/uds/dispatchers/*_enterprise
|
||||
|
||||
# /server/src/uds/locale/
|
||||
/server/src/uds/locale/*.sh
|
||||
|
||||
# /server/src/uds/management/commands/
|
||||
/server/src/uds/management/commands/*_enterprise.py
|
||||
|
||||
# /server/src/uds/models/
|
||||
/server/src/uds/models/enterprise*
|
||||
|
||||
# /server/src/uds/plugins/
|
||||
/server/src/uds/plugins/enterprise*
|
||||
|
||||
# /server/src/uds/services/
|
||||
/server/src/uds/services/*-enterprise
|
||||
/server/src/uds/services/*_enterprise
|
||||
|
||||
# /server/src/uds/static/adm/css/
|
||||
/server/src/uds/static/adm/css/admin.min.css
|
||||
|
||||
# /server/src/uds/static/adm/js/
|
||||
/server/src/uds/static/adm/js/admin.min.js
|
||||
|
||||
# /server/src/uds/templates/uds/admin/
|
||||
/server/src/uds/templates/uds/admin/sample.html
|
||||
|
||||
# /server/src/uds/transports/
|
||||
/server/src/uds/transports/*-enterprise
|
||||
|
||||
# /udsService/
|
||||
/udsService/*.suo
|
||||
|
||||
# /udsService/installer/
|
||||
/udsService/installer/UDSActorSetup.exe
|
||||
|
||||
# /udsService/rpc/bin/
|
||||
/udsService/rpc/bin/Debug
|
||||
/udsService/rpc/bin/Release
|
||||
/udsService/rpc/bin/x86
|
||||
|
||||
# /udsService/rpc/obj/
|
||||
/udsService/rpc/obj/Debug
|
||||
/udsService/rpc/obj/Release
|
||||
/udsService/rpc/obj/x86
|
||||
|
||||
# /udsService/udsService/bin/
|
||||
/udsService/udsService/bin/Debug
|
||||
/udsService/udsService/bin/Release
|
||||
/udsService/udsService/bin/x64
|
||||
|
||||
# /udsService/udsService/obj/
|
||||
/udsService/udsService/obj/x64
|
||||
/udsService/udsService/obj/x86
|
||||
|
||||
# /udsService/udsgui/bin/
|
||||
/udsService/udsgui/bin/Debug
|
||||
/udsService/udsgui/bin/Release
|
||||
/udsService/udsgui/bin/x86
|
||||
|
||||
# /udsService/udsgui/obj/
|
||||
/udsService/udsgui/obj/Debug
|
||||
/udsService/udsgui/obj/Release
|
||||
/udsService/udsgui/obj/x86
|
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
||||

|
||||
|
||||
openuds
|
||||
=======
|
||||
|
||||
OpenUDS Is an Open Source Source project, initiated by Spanish Company Virtualcable and released Open Source with the help of several Spanish Universities.
|
||||
|
6
TODO.txt
Normal file
6
TODO.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
* Add "Scheduler" to manage pools, and posibbly other operations (Expect to release an version 1.7.1??)
|
||||
* Improve stats
|
||||
* Add App Virtualization support
|
||||
* Add "Meta Pools"
|
||||
* Manage to connect several UDS in "tree", so one UDS can be provider o another UDS
|
||||
|
8
actors/.gitignore
vendored
Normal file
8
actors/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
bin
|
||||
*_enterprise*
|
||||
udsactor*.deb
|
||||
udsactor*.build
|
||||
udsactor*.changes
|
||||
/udsactor_1.7.0.dsc
|
||||
/udsactor_1.7.0.tar.xz
|
||||
/udsactor*.rpm
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>linuxActor</name>
|
||||
<name>actors</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python2.6</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/linuxActor/src</path>
|
||||
<path>/${PROJECT_DIR_NAME}/src</path>
|
||||
</pydev_pathproperty>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
</pydev_project>
|
1
actors/linux/.gitignore
vendored
Normal file
1
actors/linux/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/udsactor-*[1-9].*.spec
|
96
actors/linux/Makefile
Normal file
96
actors/linux/Makefile
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
# Directories
|
||||
SOURCEDIR := ../src
|
||||
LIBDIR := $(DESTDIR)/usr/share/UDSActor
|
||||
BINDIR := $(DESTDIR)/usr/bin
|
||||
SBINDIR = $(DESTDIR)/usr/sbin
|
||||
APPSDIR := $(DESTDIR)/usr/share/applications
|
||||
CFGDIR := $(DESTDIR)/etc/udsactor
|
||||
INITDIR := $(DESTDIR)/etc/init.d
|
||||
POLKITDIR := $(DESTDIR)/usr/share/polkit-1/actions/
|
||||
XDGAUTOSTARTDIR := $(DESTDIR)/etc/xdg/autostart
|
||||
KDEAUTOSTARTDIR := $(DESTDIR)/usr/share/autostart
|
||||
|
||||
PYC := $(shell find $(SOURCEDIR) -name '*.py[co]')
|
||||
CACHES := $(shell find $(SOURCEDIR) -name '__pycache__')
|
||||
|
||||
clean:
|
||||
rm -rf $(PYC) $(CACHES) $(DESTDIR)
|
||||
install-udsactor-xrdp:
|
||||
mkdir -p $(BINDIR)
|
||||
cp scripts/uds-sesman.sh $(BINDIR)/uds-sesman
|
||||
cp scripts/uds-wait-session.sh $(BINDIR)/uds-wait-session
|
||||
|
||||
chmod 0755 $(BINDIR)/uds-sesman
|
||||
chmod 0755 $(BINDIR)/uds-wait-session
|
||||
|
||||
install-udsactor-nx:
|
||||
mkdir -p $(BINDIR)
|
||||
cp scripts/udsnxstart.sh $(BINDIR)/udsnxstart
|
||||
cp scripts/udsnxstop.sh $(BINDIR)/udsnxstop
|
||||
|
||||
chmod 0755 $(BINDIR)/udsnxstart
|
||||
chmod 0755 $(BINDIR)/udsnxstop
|
||||
install-udsactor:
|
||||
rm -rf $(DESTDIR)
|
||||
mkdir -p $(LIBDIR)
|
||||
mkdir -p $(BINDIR)
|
||||
mkdir -p $(SBINDIR)
|
||||
mkdir -p $(APPSDIR)
|
||||
mkdir -p $(CFGDIR)
|
||||
mkdir -p $(POLKITDIR)
|
||||
mkdir -p $(XDGAUTOSTARTDIR)
|
||||
mkdir -p $(KDEAUTOSTARTDIR)
|
||||
|
||||
mkdir $(LIBDIR)/img
|
||||
|
||||
# Cleans up .pyc and cache folders
|
||||
rm -f $(PYC) $(CACHES)
|
||||
|
||||
cp -r $(SOURCEDIR)/udsactor $(LIBDIR)/udsactor
|
||||
cp $(SOURCEDIR)/img/uds.png $(LIBDIR)/img
|
||||
|
||||
cp $(SOURCEDIR)/UDSActorConfig.py $(LIBDIR)
|
||||
cp $(SOURCEDIR)/UDSActorUser.py $(LIBDIR)
|
||||
# QT Dialogs & resources
|
||||
cp $(SOURCEDIR)/*_ui.py $(LIBDIR)
|
||||
cp $(SOURCEDIR)/UDSActor_rc.py $(LIBDIR)
|
||||
|
||||
# Menu GUI app
|
||||
cp desktop/UDS_Actor_Configuration.desktop $(APPSDIR)
|
||||
|
||||
# Autostart elements for gnome/kde
|
||||
cp desktop/UDSActorTool.desktop $(XDGAUTOSTARTDIR)
|
||||
cp desktop/UDSActorTool.desktop $(KDEAUTOSTARTDIR)
|
||||
|
||||
# scripts
|
||||
cp scripts/udsactor $(BINDIR)
|
||||
cp scripts/UDSActorConfig-pkexec $(SBINDIR)
|
||||
cp scripts/UDSActorTool-startup $(BINDIR)
|
||||
|
||||
# Policy to run as administrator
|
||||
cp policy/org.openuds.pkexec.UDSActorConfig.policy $(POLKITDIR)
|
||||
|
||||
# Fix permissions
|
||||
chmod 755 $(BINDIR)/udsactor
|
||||
chmod 755 $(BINDIR)/UDSActorTool-startup
|
||||
chmod 755 $(SBINDIR)/UDSActorConfig-pkexec
|
||||
chmod 755 $(LIBDIR)/UDSActorConfig.py
|
||||
chmod 755 $(LIBDIR)/UDSActorUser.py
|
||||
chmod 644 $(POLKITDIR)/org.openuds.pkexec.UDSActorConfig.policy
|
||||
|
||||
# If for red hat based, copy init.d
|
||||
ifeq ($(DISTRO),rh)
|
||||
mkdir -p $(INITDIR)
|
||||
cp debian/udsactor.init $(INITDIR)/udsactor
|
||||
ln -s /usr/share/UDSActor/UDSActorConfig.py $(SBINDIR)/UDSActorConfig
|
||||
ln -s /usr/share/UDSActor/UDSActorUser.py $(BINDIR)/UDSActorTool
|
||||
endif
|
||||
|
||||
# chmod 0755 $(BINDIR)/udsactor
|
||||
uninstall:
|
||||
rm -rf $(LIBDIR)
|
||||
# rm -f $(BINDIR)/udsactor
|
||||
rm -rf $(CFGDIR)
|
34
actors/linux/build-packages.sh
Executable file
34
actors/linux/build-packages.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=`cat ../../VERSION`
|
||||
RELEASE=1
|
||||
|
||||
top=`pwd`
|
||||
|
||||
# Debian based
|
||||
dpkg-buildpackage -b
|
||||
|
||||
cat udsactor-template.spec |
|
||||
sed -e s/"version 0.0.0"/"version ${VERSION}"/g |
|
||||
sed -e s/"release 1"/"release ${RELEASE}"/g > udsactor-$VERSION.spec
|
||||
|
||||
# Now fix dependencies for opensuse
|
||||
cat udsactor-template.spec |
|
||||
sed -e s/"version 0.0.0"/"version ${VERSION}"/g |
|
||||
sed -e s/"name udsactor"/"name udsactor-opensuse"/g |
|
||||
sed -e s/"PyQt4"/"python-qt4"/g |
|
||||
sed -e s/"libXScrnSaver"/"libXss1"/g > udsactor-opensuse-$VERSION.spec
|
||||
|
||||
|
||||
# Right now, udsactor-xrdp-1.7.0.spec is not needed
|
||||
for pkg in udsactor-$VERSION.spec udsactor-opensuse-$VERSION.spec; do
|
||||
|
||||
rm -rf rpm
|
||||
for folder in SOURCES BUILD RPMS SPECS SRPMS; do
|
||||
mkdir -p rpm/$folder
|
||||
done
|
||||
|
||||
rpmbuild -v -bb --clean --buildroot=$top/rpm/BUILD/$pkg-root --target noarch $pkg 2>&1
|
||||
done
|
||||
|
||||
#rm udsactor-$VERSION
|
3
actors/linux/debian/.gitignore
vendored
Normal file
3
actors/linux/debian/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/udsactor/
|
||||
/udsactor-xrdp/
|
||||
/udsactor-nx/
|
29
actors/linux/debian/changelog
Normal file
29
actors/linux/debian/changelog
Normal file
@@ -0,0 +1,29 @@
|
||||
udsactor (2.0.0) stable; urgency=medium
|
||||
|
||||
* Upgrade for 2.0.0
|
||||
|
||||
-- Adolfo Gómez García <agomez@virtualcable.es> Tue, 01 Mar 2016 03:39:21 +0100
|
||||
|
||||
udsactor (1.9.1) stable; urgency=medium
|
||||
|
||||
* Upgrade for 1.9.1
|
||||
|
||||
-- Adolfo Gómez García <agomez@virtualcable.es> Tue, 01 Mar 2016 03:19:21 +0100
|
||||
|
||||
udsactor (1.9.0) stable; urgency=medium
|
||||
|
||||
* Upgrade for 1.9.0 (fixed package version)
|
||||
|
||||
-- Adolfo Gómez García <agomez@virtualcable.es> Tue, 05 May 2015 07:10:27 +0200
|
||||
|
||||
udsactor (1.7.5) stable; urgency=medium
|
||||
|
||||
* Upgrade for 1.7.5
|
||||
|
||||
-- Adolfo Gómez García <agomez@virtualcable.es> Thu, 23 Apr 2015 06:08:53 +0200
|
||||
|
||||
udsactor (1.7.0) stable; urgency=medium
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Adolfo Gómez García <agomez@virtualcable.es> Mon, 17 Nov 2014 05:32:41 +0100
|
1
actors/linux/debian/compat
Normal file
1
actors/linux/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
9
|
31
actors/linux/debian/control
Normal file
31
actors/linux/debian/control
Normal file
@@ -0,0 +1,31 @@
|
||||
Source: udsactor
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Maintainer: Adolfo Gómez García <agomez@virtualcable.es>
|
||||
Build-Depends: debhelper (>= 7), po-debconf
|
||||
Standards-Version: 3.9.2
|
||||
Homepage: http://www.virtualcable.es
|
||||
|
||||
Package: udsactor
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Depends: policykit-1(>=0.100), python-requests (>=0.8.2), python-qt4 (>=4.9), python-six(>=1.1), python-prctl(>=1.1.1), python (>=2.7), libxss1, ${misc:Depends}
|
||||
Description: Actor for Universal Desktop Services (UDS) Broker
|
||||
This package provides the required components to allow this machine to work on an environment managed by UDS Broker.
|
||||
|
||||
Package: udsactor-xrdp
|
||||
Section: x11
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Depends: xrdp (>= 0.5.0), udsactor (>= ${binary:Version}), libpam-modules-bin (>=1.0), ${misc:Depends}
|
||||
Description: UDS Actor component for xrdp
|
||||
This package provides connection between uds actor and xrdp
|
||||
|
||||
Package: udsactor-nx
|
||||
Section: x11
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Depends: nxnode (>= 3.5.0), udsactor (>= ${binary:Version}), ${misc:Depends}
|
||||
Description: UDS Actor component for nx
|
||||
This package provides connection between uds actor and nx
|
@@ -1,10 +1,10 @@
|
||||
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
|
||||
Name: udsactor
|
||||
Maintainer: Adolfo Gómez García
|
||||
Source: http://www.virtualcable.es/
|
||||
Source: http://www.udsenterprise.com/
|
||||
|
||||
Copyright: 2010 Virtual Cable S.L.
|
||||
License: GPL-2+
|
||||
Copyright: 2014 Virtual Cable S.L.U.
|
||||
License: BSD-3-clause
|
||||
|
||||
License: GPL-2+
|
||||
This program is free software; you can redistribute it and/or modify
|
3
actors/linux/debian/files
Normal file
3
actors/linux/debian/files
Normal file
@@ -0,0 +1,3 @@
|
||||
udsactor-nx_2.0.0_all.deb x11 optional
|
||||
udsactor-xrdp_2.0.0_all.deb x11 optional
|
||||
udsactor_2.0.0_all.deb admin optional
|
@@ -21,7 +21,9 @@ install: build
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor-nx install
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor install-udsactor
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor-xrdp install-udsactor-xrdp
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor-nx install-udsactor-nx
|
||||
binary-arch: build install
|
||||
# emptyness
|
||||
binary-indep: build install
|
||||
@@ -29,6 +31,9 @@ binary-indep: build install
|
||||
dh_testroot
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
dh_installdebconf
|
||||
dh_installinit --no-start
|
||||
dh_python2=python
|
||||
dh_compress
|
||||
dh_link
|
||||
dh_fixperms
|
1
actors/linux/debian/source/format
Normal file
1
actors/linux/debian/source/format
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
@@ -10,11 +10,13 @@ case "$1" in
|
||||
purge)
|
||||
;;
|
||||
remove)
|
||||
TMPFILE=$(mktemp /tmp/node.cfg.XXXXX)
|
||||
trap "rm -f $TMPFILE" 0
|
||||
cat $NXNODECFG | sed -e "s/.*udsnxst.*//" > $TMPFILE
|
||||
cp $TMPFILE $NXNODECFG
|
||||
invoke-rc.d nxserver restart
|
||||
if [ -f $NXNODECFG ]; then
|
||||
TMPFILE=$(mktemp /tmp/node.cfg.XXXXX)
|
||||
trap "rm -f $TMPFILE" 0
|
||||
cat $NXNODECFG | sed -e "s/.*udsnxst.*//" > $TMPFILE
|
||||
cp $TMPFILE $NXNODECFG
|
||||
invoke-rc.d nxserver restart
|
||||
fi
|
||||
;;
|
||||
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
39
actors/linux/debian/udsactor-xrdp.postinst
Normal file
39
actors/linux/debian/udsactor-xrdp.postinst
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
SESMANFILE=/etc/pam.d/xrdp-sesman
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
trap "cp $SESMANFILE $SESMANFILE.uds.old" 0
|
||||
|
||||
TMPFILE=$(mktemp /tmp/sesman.XXXXX)
|
||||
trap "rm -f $TMPFILE" 0
|
||||
grep -v uds $SESMANFILE > $TMPFILE # Removes all UDS lines from sesman if they exists
|
||||
|
||||
echo >> $TMPFILE
|
||||
echo "# Added by udsactor-xrdp" >> $TMPFILE
|
||||
echo "session optional pam_exec.so /usr/bin/uds-sesman" >> $TMPFILE
|
||||
cp $TMPFILE $SESMANFILE
|
||||
trap "rm -f $TMPFILE" 0
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
# Don't know why, but descriptors get "weird" when launched daemon, so we tell here to debconf to stop.
|
||||
# Solved not starting the service right now, defered to next reboot
|
||||
|
||||
|
||||
exit 0
|
30
actors/linux/debian/udsactor-xrdp.postrm
Normal file
30
actors/linux/debian/udsactor-xrdp.postrm
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
SESMANFILE=/etc/pam.d/xrdp-sesman
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
;;
|
||||
remove)
|
||||
if [ -f $SESMANFILE ]; then
|
||||
TMPFILE=$(mktemp /tmp/sesman.XXXXX)
|
||||
trap "rm -f $TMPFILE" 0
|
||||
grep -v uds $SESMANFILE > $TMPFILE # Removes all UDS lines from sesman if they exists
|
||||
cp $TMPFILE $SESMANFILE
|
||||
trap "rm -f $TMPFILE" 0
|
||||
fi
|
||||
;;
|
||||
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
45
actors/linux/debian/udsactor.config
Executable file
45
actors/linux/debian/udsactor.config
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
db_version 2.0
|
||||
|
||||
# This conf script is capable of backing up
|
||||
db_capb backup
|
||||
|
||||
if [ -f /etc/udsactor/udsactor.cfg ] && [ "$1" != "reconfigure" ]; then
|
||||
echo "/etc/udsactor/udsactor.cfg already exists, leaving untouched."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
STATE=1
|
||||
while [ "$STATE" != 0 -a "$STATE" != 4 ]; do
|
||||
case "$STATE" in
|
||||
1)
|
||||
db_input high udsactor/host || true
|
||||
;;
|
||||
2)
|
||||
db_input high udsactor/secure || true
|
||||
;;
|
||||
3)
|
||||
db_input high udsactor/masterKey || true
|
||||
;;
|
||||
esac
|
||||
|
||||
if db_go; then
|
||||
STATE=$(($STATE + 1))
|
||||
else
|
||||
STATE=$(($STATE - 1))
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# If "cancelled", exit
|
||||
if [ "$STATE" = 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# If using reconfigure, and already exists an configuration file, move it to a backup
|
||||
if [ -f /etc/udsactor/udsactor.cfg ] && [ "$1" = "reconfigure" ]; then
|
||||
echo "/etc/udsactor.cfg backup to /etc/udsactor.cfg.back"
|
||||
mv /etc/udsactor/udsactor.cfg /etc/udsactor/udsactor.cfg.back
|
||||
fi
|
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh -e
|
||||
### BEGIN INIT INFO
|
||||
# Provides: uds-actor
|
||||
# Provides: udsactor
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog $named
|
||||
# Required-Stop: $local_fs $remote_fs $network $syslog $named
|
||||
# Default-Start: 2 3 4 5
|
||||
@@ -9,12 +9,14 @@
|
||||
### END INIT INFO
|
||||
#
|
||||
|
||||
# . /lib/lsb/init-functions
|
||||
|
||||
case "$1" in
|
||||
start|stop|restart)
|
||||
/usr/bin/udsactor $1
|
||||
;;
|
||||
;;
|
||||
force-reload)
|
||||
./actor restart
|
||||
/usr/bin/udsactor restart
|
||||
;;
|
||||
*) echo "Usage: $0 {start|stop|restart|force-reload}" >&2; exit 1 ;;
|
||||
esac
|
2
actors/linux/debian/udsactor.links
Normal file
2
actors/linux/debian/udsactor.links
Normal file
@@ -0,0 +1,2 @@
|
||||
/usr/share/UDSActor/UDSActorConfig.py /usr/sbin/UDSActorConfig
|
||||
/usr/share/UDSActor/UDSActorUser.py /usr/bin/UDSActorTool
|
53
actors/linux/debian/udsactor.postinst
Executable file
53
actors/linux/debian/udsactor.postinst
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
set -e
|
||||
case "$1" in
|
||||
configure)
|
||||
# If new "fresh" install or if configuration file has disappeared...
|
||||
if [ "$2" = "" ] || [ ! -f /etc/udsactor/udsactor.cfg ]; then
|
||||
db_get udsactor/host
|
||||
host=$RET
|
||||
db_get udsactor/secure
|
||||
ssl=$RET
|
||||
if [ "$ssl" = "true" ]; then
|
||||
ssl=True;
|
||||
else
|
||||
ssl=False;
|
||||
fi
|
||||
db_get udsactor/masterKey
|
||||
masterKey=$RET
|
||||
|
||||
# If already has a config file there
|
||||
if [ -f /etc/udsactor/udsactor.cfg ]; then
|
||||
cp /etc/udsactor/udsactor.cfg /etc/udsactor/udsactor.cfg.dpkg-old
|
||||
fi
|
||||
|
||||
echo "[uds]" > /etc/udsactor/udsactor.cfg
|
||||
echo "host = $host" >> /etc/udsactor/udsactor.cfg
|
||||
echo "logLevel = 30000" >> /etc/udsactor/udsactor.cfg
|
||||
echo "ssl = $ssl" >> /etc/udsactor/udsactor.cfg
|
||||
echo "masterKey = $masterKey" >> /etc/udsactor/udsactor.cfg
|
||||
|
||||
fi
|
||||
|
||||
# Fix perms so only root can access "masterKey"
|
||||
chmod 0700 /etc/udsactor
|
||||
chmod 0600 /etc/udsactor/udsactor.cfg
|
||||
chown root:root /etc/udsactor
|
||||
chown root:root /etc/udsactor/udsactor.cfg
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
14
actors/linux/debian/udsactor.postrm
Executable file
14
actors/linux/debian/udsactor.postrm
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$1" = "purge" ] ; then
|
||||
if [ -f /etc/udsactor/udsactor.cfg ]; then
|
||||
mv /etc/udsactor/udsactor.cfg /etc/udsactor/udsactor.cfg.dpkg-backup
|
||||
# Remove .pyc leaved behind
|
||||
rm -rf /usr/share/UDSActor || true > /dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
1
actors/linux/debian/udsactor.prerm
Executable file
1
actors/linux/debian/udsactor.prerm
Executable file
@@ -0,0 +1 @@
|
||||
#! /bin/bash -e
|
@@ -1,19 +1,20 @@
|
||||
Template: udsactor/server
|
||||
Template: udsactor/host
|
||||
Type: string
|
||||
Default:
|
||||
_Description: UDS Server address:
|
||||
Description: UDS Server address:
|
||||
The actor needs the address of the server in order to communicate with it.
|
||||
Provide here full address (or i) of the UDS server
|
||||
|
||||
Template: udsactor/secure
|
||||
Type: boolean
|
||||
Default: true
|
||||
_Description: Use secure (https) connection to communicate with UDS server?
|
||||
Description: Use secure (https) connection to communicate with UDS server?
|
||||
If selected, the communication will be done using https.
|
||||
If not selected, the communication will be done using http
|
||||
|
||||
Template: udsactor/timeout
|
||||
Template: udsactor/masterKey
|
||||
Type: string
|
||||
Default: 5
|
||||
_Description: Timeout in communications with UDS server:
|
||||
The timeout is expressed in seconds
|
||||
Default:
|
||||
Description: Master Key:
|
||||
This key is available on UDS Administration interface.
|
||||
Look for it under configuration, on Security tab.
|
12
actors/linux/desktop/UDSActorTool.desktop
Normal file
12
actors/linux/desktop/UDSActorTool.desktop
Normal file
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Name=UDS Actor Tool
|
||||
Comment=UDS Actor Userspace tools
|
||||
Exec=/usr/bin/UDSActorTool-startup
|
||||
Icon=/usr/share/UDSActor/img/uds.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
X-KDE-autostart-after=panel
|
||||
X-KDE-StartupNotify=false
|
||||
X-DBUS-StartupType=Unique
|
||||
X-KDE-UniqueApplet=true
|
11
actors/linux/desktop/UDS_Actor_Configuration.desktop
Normal file
11
actors/linux/desktop/UDS_Actor_Configuration.desktop
Normal file
@@ -0,0 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Name=UDS Actor Configuration
|
||||
Version=1.0
|
||||
Exec=/usr/sbin/UDSActorConfig-pkexec
|
||||
Comment=UDS Actor Configuration Application. (Must be executed as root)
|
||||
Icon=/usr/share/UDSActor/img/uds.png
|
||||
Type=Application
|
||||
Terminal=false
|
||||
StartupNotify=true
|
||||
Encoding=UTF-8
|
||||
Categories=Settings;System;
|
20
actors/linux/policy/org.openuds.pkexec.UDSActorConfig.policy
Normal file
20
actors/linux/policy/org.openuds.pkexec.UDSActorConfig.policy
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
|
||||
<policyconfig>
|
||||
|
||||
<action id="org.freedesktop.policykit.pkexec.run-UDSActorConfig">
|
||||
<description>Run UDS Actor Configuration Program</description>
|
||||
<message>Authentication is required to run UDS Actor Configuration</message>
|
||||
<defaults>
|
||||
<allow_any>no</allow_any>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/usr/sbin/UDSActorConfig</annotate>
|
||||
<annotate key="org.freedesktop.policykit.exec.allow_gui">TRUE</annotate>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
3
actors/linux/readme.txt
Normal file
3
actors/linux/readme.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
UDSActor is the client actor needed to get machines managed by UDS Broker.
|
||||
|
||||
Please, visit http://www.udsenterprise.com for more information
|
2
actors/linux/scripts/UDSActorConfig-pkexec
Normal file
2
actors/linux/scripts/UDSActorConfig-pkexec
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
pkexec "/usr/sbin/UDSActorConfig" "$@"
|
10
actors/linux/scripts/UDSActorTool-startup
Normal file
10
actors/linux/scripts/UDSActorTool-startup
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Simple hack to wait for systray to be present
|
||||
# Exec tool if not already runned by session manager
|
||||
ps -ef | grep "$USER" | grep -v grep | grep -v UDSActorTool-startup | grep 'UDSActorTool' -q
|
||||
# If not already running
|
||||
if [ $? -eq 1 ]; then
|
||||
sleep 5
|
||||
exec /usr/bin/UDSActorTool
|
||||
fi
|
13
actors/linux/scripts/uds-sesman.sh
Executable file
13
actors/linux/scripts/uds-sesman.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
env > /tmp/env.txt
|
||||
|
||||
if [ "$PAM_TYPE" = "open_session" ]; then
|
||||
nohup /usr/bin/udsactor login $PAM_USER &
|
||||
# Wait in backgroud to TTY to close (close_session is not being invoked right now)
|
||||
nohup /usr/bin/uds-wait-session &
|
||||
elif [ "$PAM_TYPE" = "close_session" ]; then
|
||||
nohup /usr/bin/udsactor logout $PAM_USER &
|
||||
fi
|
||||
|
||||
return 0
|
12
actors/linux/scripts/uds-wait-session.sh
Executable file
12
actors/linux/scripts/uds-wait-session.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
while :
|
||||
do
|
||||
sleep 5 # Wait 5 seconds between checks
|
||||
found=`ps -f -u$PAM_USER | grep -v grep | grep -v uds-wait-session | grep "$PAM_TTY" | wc -l`
|
||||
|
||||
if [ "$found" = "0" ]; then
|
||||
/usr/bin/udsactor logout $PAM_USER
|
||||
exit 0
|
||||
fi
|
||||
done
|
6
actors/linux/scripts/udsactor
Executable file
6
actors/linux/scripts/udsactor
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
FOLDER=/usr/share/UDSActor
|
||||
|
||||
cd $FOLDER
|
||||
python -m udsactor.linux.UDSActorService $@
|
69
actors/linux/udsactor-template.spec
Normal file
69
actors/linux/udsactor-template.spec
Normal file
@@ -0,0 +1,69 @@
|
||||
%define _topdir %(echo $PWD)/rpm
|
||||
%define name udsactor
|
||||
%define version 0.0.0
|
||||
%define release 1
|
||||
%define buildroot %{_topdir}/%{name}-%{version}-%{release}-root
|
||||
|
||||
BuildRoot: %{buildroot}
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Summary: Actor for Universal Desktop Services (UDS) Broker
|
||||
License: BSD3
|
||||
Group: Admin
|
||||
Requires: python-six python-requests PyQt4 libXScrnSaver
|
||||
Vendor: Virtual Cable S.L.U.
|
||||
URL: http://www.udsenterprise.com
|
||||
Provides: udsactor
|
||||
|
||||
%define _rpmdir ../
|
||||
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
|
||||
|
||||
|
||||
%install
|
||||
curdir=`pwd`
|
||||
cd ../..
|
||||
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh install-udsactor
|
||||
cd $curdir
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
curdir=`pwd`
|
||||
cd ../..
|
||||
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh clean
|
||||
cd $curdir
|
||||
|
||||
|
||||
%post
|
||||
systemctl enable udsactor.service > /dev/null 2>&1
|
||||
|
||||
%preun
|
||||
systemctl disable udsactor.service > /dev/null 2>&1
|
||||
systemctl stop udsactor.service > /dev/null 2>&1
|
||||
|
||||
%postun
|
||||
# $1 == 0 on uninstall, == 1 on upgrade for preun and postun (just a reminder for me... :) )
|
||||
if [ $1 -eq 0 ]; then
|
||||
rm -rf /etc/udsactor
|
||||
rm /var/log/udsactor.log
|
||||
fi
|
||||
# And, posibly, the .pyc leaved behind on /usr/share/UDSActor
|
||||
rm -rf /usr/share/UDSActor > /dev/null 2>&1
|
||||
|
||||
%description
|
||||
This package provides the required components to allow this machine to work on an environment managed by UDS Broker.
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
/etc/udsactor
|
||||
/etc/xdg/autostart/UDSActorTool.desktop
|
||||
/etc/init.d/udsactor
|
||||
/usr/bin/UDSActorTool-startup
|
||||
/usr/bin/udsactor
|
||||
/usr/bin/UDSActorTool
|
||||
/usr/sbin/UDSActorConfig
|
||||
/usr/sbin/UDSActorConfig-pkexec
|
||||
/usr/share/UDSActor/*
|
||||
/usr/share/applications/UDS_Actor_Configuration.desktop
|
||||
/usr/share/autostart/UDSActorTool.desktop
|
||||
/usr/share/polkit-1/actions/org.openuds.pkexec.UDSActorConfig.policy
|
4
actors/src/.gitignore
vendored
Normal file
4
actors/src/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
build
|
||||
.idea
|
||||
*_enterprise*
|
||||
/samples/
|
5
actors/src/UDSActor.qrc
Normal file
5
actors/src/UDSActor.qrc
Normal file
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="images">
|
||||
<file>img/uds.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
17
actors/src/UDSActorConfig.manifest
Normal file
17
actors/src/UDSActorConfig.manifest
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="UDSActorConfig"
|
||||
version="1.6.0.0"
|
||||
processorArchitecture="x86"
|
||||
/>
|
||||
<description>Description</description>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
112
actors/src/UDSActorConfig.py
Normal file
112
actors/src/UDSActorConfig.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import six
|
||||
|
||||
from udsactor import store
|
||||
from udsactor import REST
|
||||
from udsactor import utils
|
||||
from udsactor.log import logger
|
||||
|
||||
from setup_dialog_ui import Ui_UdsActorSetupDialog
|
||||
|
||||
|
||||
class UDSConfigDialog(QtGui.QDialog):
|
||||
|
||||
def __init__(self, data, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.ui = Ui_UdsActorSetupDialog()
|
||||
self.ui.setupUi(self)
|
||||
if data is not None:
|
||||
self.ui.host.setText(data.get('host', ''))
|
||||
self.ui.masterKey.setText(data.get('masterKey', ''))
|
||||
self.ui.useSSl.setCurrentIndex(1 if data.get('ssl', False) is True else 0)
|
||||
self.ui.logLevelComboBox.setCurrentIndex(int(data.get('logLevel', '10000')) / 10000 - 1)
|
||||
|
||||
def _getCfg(self):
|
||||
return {
|
||||
'host': six.text_type(self.ui.host.text()),
|
||||
'masterKey': six.text_type(self.ui.masterKey.text()),
|
||||
'ssl': self.ui.useSSl.currentIndex() == 1,
|
||||
'logLevel': (self.ui.logLevelComboBox.currentIndex() + 1) * 10000
|
||||
}
|
||||
|
||||
def textChanged(self):
|
||||
enableButtons = self.ui.host.text() != '' and self.ui.masterKey.text() != ''
|
||||
self.ui.testButton.setEnabled(enableButtons)
|
||||
self.ui.saveButton.setEnabled(enableButtons)
|
||||
|
||||
def cancelAndDiscard(self):
|
||||
logger.debug('Cancelling changes')
|
||||
self.close()
|
||||
|
||||
def testParameters(self):
|
||||
logger.debug('Testing connection')
|
||||
try:
|
||||
cfg = self._getCfg()
|
||||
api = REST.Api(
|
||||
cfg['host'], cfg['masterKey'], cfg['ssl'])
|
||||
api.test()
|
||||
QtGui.QMessageBox.information(
|
||||
self, 'Test Passed', 'The test was executed successfully', QtGui.QMessageBox.Ok)
|
||||
logger.info('Test was passed successfully')
|
||||
except Exception as e:
|
||||
logger.info('Test error: {}'.format(utils.exceptionToMessage(e)))
|
||||
QtGui.QMessageBox.critical(self, 'Test Error', utils.exceptionToMessage(e), QtGui.QMessageBox.Ok)
|
||||
|
||||
def acceptAndSave(self):
|
||||
cfg = self._getCfg()
|
||||
store.writeConfig(cfg)
|
||||
self.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
|
||||
if store.checkPermissions() is False:
|
||||
QtGui.QMessageBox.critical(None, 'Notice', 'This Program must be executed as administrator', QtGui.QMessageBox.Ok)
|
||||
sys.exit(1)
|
||||
|
||||
# Read configuration
|
||||
cfg = store.readConfig()
|
||||
|
||||
if cfg is not None:
|
||||
logger.setLevel(int(cfg.get('logLevel', 20000)))
|
||||
else:
|
||||
logger.setLevel(20000)
|
||||
|
||||
myapp = UDSConfigDialog(cfg)
|
||||
myapp.show()
|
||||
sys.exit(app.exec_())
|
17
actors/src/UDSActorService.manifest
Normal file
17
actors/src/UDSActorService.manifest
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="UDSActorService"
|
||||
version="1.6.0.0"
|
||||
processorArchitecture="x86"
|
||||
/>
|
||||
<description>Description</description>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
342
actors/src/UDSActorUser.py
Normal file
342
actors/src/UDSActorUser.py
Normal file
@@ -0,0 +1,342 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
from PyQt4 import QtGui # @UnresolvedImport
|
||||
from PyQt4 import QtCore # @UnresolvedImport
|
||||
import pickle
|
||||
import time
|
||||
import datetime
|
||||
import signal
|
||||
from udsactor import ipc
|
||||
from udsactor import utils
|
||||
from udsactor.log import logger
|
||||
from udsactor.service import IPC_PORT
|
||||
from udsactor import operations
|
||||
from about_dialog_ui import Ui_UDSAboutDialog
|
||||
from message_dialog_ui import Ui_UDSMessageDialog
|
||||
from udsactor.scriptThread import ScriptExecutorThread
|
||||
from udsactor import VERSION
|
||||
|
||||
trayIcon = None
|
||||
|
||||
|
||||
def sigTerm(sigNo, stackFrame):
|
||||
if trayIcon:
|
||||
trayIcon.quit()
|
||||
|
||||
|
||||
# About dialog
|
||||
class UDSAboutDialog(QtGui.QDialog):
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.ui = Ui_UDSAboutDialog()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.VersionLabel.setText("Version " + VERSION)
|
||||
|
||||
def closeDialog(self):
|
||||
self.hide()
|
||||
|
||||
|
||||
class UDSMessageDialog(QtGui.QDialog):
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.ui = Ui_UDSMessageDialog()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
def displayMessage(self, message):
|
||||
self.ui.message.setText(message)
|
||||
self.show()
|
||||
|
||||
def closeDialog(self):
|
||||
self.hide()
|
||||
|
||||
|
||||
class MessagesProcessor(QtCore.QThread):
|
||||
|
||||
logoff = QtCore.pyqtSignal(name='logoff')
|
||||
displayMessage = QtCore.pyqtSignal(QtCore.QString, name='displayMessage')
|
||||
script = QtCore.pyqtSignal(QtCore.QString, name='script')
|
||||
exit = QtCore.pyqtSignal(name='exit')
|
||||
information = QtCore.pyqtSignal(dict, name='information')
|
||||
|
||||
def __init__(self):
|
||||
super(self.__class__, self).__init__()
|
||||
# Retries connection for a while
|
||||
for _ in range(10):
|
||||
try:
|
||||
self.ipc = ipc.ClientIPC(IPC_PORT)
|
||||
self.ipc.start()
|
||||
break
|
||||
except Exception:
|
||||
logger.debug('IPC Server is not reachable')
|
||||
self.ipc = None
|
||||
time.sleep(2)
|
||||
|
||||
self.running = False
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
if self.ipc:
|
||||
self.ipc.stop()
|
||||
|
||||
def isAlive(self):
|
||||
return self.ipc is not None
|
||||
|
||||
def requestInformation(self):
|
||||
if self.ipc is not None:
|
||||
info = self.ipc.requestInformation()
|
||||
logger.debug('Request information: {}'.format(info))
|
||||
|
||||
def sendLogin(self, userName):
|
||||
if self.ipc:
|
||||
self.ipc.sendLogin(userName)
|
||||
|
||||
def sendLogout(self, userName):
|
||||
if self.ipc:
|
||||
self.ipc.sendLogout(userName)
|
||||
|
||||
def run(self):
|
||||
if self.ipc is None:
|
||||
return
|
||||
self.running = True
|
||||
|
||||
# Wait a bit so we ensure IPC thread is running...
|
||||
time.sleep(2)
|
||||
|
||||
while self.running and self.ipc.running:
|
||||
try:
|
||||
msg = self.ipc.getMessage()
|
||||
if msg is None:
|
||||
break
|
||||
msgId, data = msg
|
||||
logger.debug('Got Message on User Space: {}:{}'.format(msgId, data))
|
||||
if msgId == ipc.MSG_MESSAGE:
|
||||
self.displayMessage.emit(QtCore.QString.fromUtf8(data))
|
||||
elif msgId == ipc.MSG_LOGOFF:
|
||||
self.logoff.emit()
|
||||
elif msgId == ipc.MSG_SCRIPT:
|
||||
self.script.emit(QtCore.QString.fromUtf8(data))
|
||||
elif msgId == ipc.MSG_INFORMATION:
|
||||
self.information.emit(pickle.loads(data))
|
||||
except Exception as e:
|
||||
try:
|
||||
logger.error('Got error on IPC thread {}'.format(utils.exceptionToMessage(e)))
|
||||
except:
|
||||
logger.error('Got error on IPC thread (an unicode error??)')
|
||||
|
||||
if self.ipc.running is False and self.running is True:
|
||||
logger.warn('Lost connection with Service, closing program')
|
||||
|
||||
self.exit.emit()
|
||||
|
||||
|
||||
class UDSSystemTray(QtGui.QSystemTrayIcon):
|
||||
def __init__(self, app_, parent=None):
|
||||
self.app = app_
|
||||
|
||||
# style = app.style()
|
||||
# icon = QtGui.QIcon(style.standardPixmap(QtGui.QStyle.SP_ComputerIcon))
|
||||
icon = QtGui.QIcon(':/images/img/uds.png')
|
||||
|
||||
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
|
||||
self.menu = QtGui.QMenu(parent)
|
||||
exitAction = self.menu.addAction("About")
|
||||
exitAction.triggered.connect(self.about)
|
||||
self.setContextMenu(self.menu)
|
||||
self.ipc = MessagesProcessor()
|
||||
self.sessionStart = datetime.datetime.now()
|
||||
self.maxIdleTime = None
|
||||
self.showIdleWarn = True
|
||||
self.maxSessionTime = None
|
||||
self.showMaxSessionWarn = True
|
||||
self.timer = QtCore.QTimer()
|
||||
self.timer.timeout.connect(self.checkTimers)
|
||||
|
||||
if self.ipc.isAlive() is False:
|
||||
raise Exception('No connection to service, exiting.')
|
||||
|
||||
self.stopped = False
|
||||
|
||||
self.ipc.displayMessage.connect(self.displayMessage)
|
||||
self.ipc.exit.connect(self.quit)
|
||||
self.ipc.script.connect(self.executeScript)
|
||||
self.ipc.logoff.connect(self.logoff)
|
||||
self.ipc.information.connect(self.information)
|
||||
|
||||
# Pre generate a request for information (general parameters) to daemon/service
|
||||
self.ipc.requestInformation()
|
||||
|
||||
self.aboutDlg = UDSAboutDialog()
|
||||
self.msgDlg = UDSMessageDialog()
|
||||
|
||||
self.counter = 0
|
||||
|
||||
self.timer.start(5000) # Launch idle checking every 5 seconds
|
||||
self.graceTimerShots = 6 # Start counting for idle after 30 seconds after login, got on windows some "instant" logout because of idle timer not being reset??
|
||||
|
||||
self.ipc.start()
|
||||
# If this is running, it's because he have logged in
|
||||
self.ipc.sendLogin(operations.getCurrentUser())
|
||||
|
||||
def checkTimers(self):
|
||||
self.checkIdle()
|
||||
self.checkMaxSession()
|
||||
|
||||
def checkMaxSession(self):
|
||||
if self.maxSessionTime is None or self.maxSessionTime == 0:
|
||||
logger.debug('Returning because maxSessionTime is cero')
|
||||
return
|
||||
|
||||
remainingTime = self.maxSessionTime - (datetime.datetime.now() - self.sessionStart).total_seconds()
|
||||
logger.debug('Remaining time: {}'.format(remainingTime))
|
||||
|
||||
if self.showMaxSessionWarn is True and remainingTime < 300: # With five minutes, show a warning message
|
||||
self.showMaxSessionWarn = False
|
||||
self.msgDlg.displayMessage('Your session will expire in less that 5 minutes. Please, save your work and disconnect.')
|
||||
return
|
||||
|
||||
if remainingTime <= 0:
|
||||
logger.debug('Remaining time is less than cero, exiting')
|
||||
self.quit()
|
||||
|
||||
def checkIdle(self):
|
||||
if self.maxIdleTime is None: # No idle check
|
||||
return
|
||||
|
||||
if self.graceTimerShots > 0:
|
||||
self.graceTimerShots -= 1
|
||||
return
|
||||
|
||||
idleTime = operations.getIdleDuration()
|
||||
remainingTime = self.maxIdleTime - idleTime
|
||||
|
||||
if remainingTime > 120: # Reset show Warning dialog if we have more than 5 minutes left
|
||||
self.showIdleWarn = True
|
||||
|
||||
logger.debug('User has been idle for: {}'.format(idleTime))
|
||||
|
||||
if self.showIdleWarn is True and remainingTime < 120: # With two minutes, show a warning message
|
||||
self.showIdleWarn = False
|
||||
self.msgDlg.displayMessage("You have been idle for too long. The session will end if you don't resume operations")
|
||||
|
||||
if remainingTime <= 0:
|
||||
logger.info('User has been idle for too long, notifying Broker that service can be reclaimed')
|
||||
self.quit()
|
||||
|
||||
def displayMessage(self, message):
|
||||
logger.debug('Displaying message')
|
||||
self.msgDlg.displayMessage(message)
|
||||
|
||||
def executeScript(self, script):
|
||||
logger.debug('Executing script')
|
||||
th = ScriptExecutorThread(script)
|
||||
th.start()
|
||||
|
||||
def logoff(self):
|
||||
self.counter += 1
|
||||
# print("Logofff --", self.counter)
|
||||
|
||||
def information(self, info):
|
||||
'''
|
||||
Invoked when received information from service
|
||||
'''
|
||||
logger.info('Got information message: {}'.format(info))
|
||||
if 'idle' in info:
|
||||
idle = int(info['idle'])
|
||||
operations.initIdleDuration(idle)
|
||||
self.maxIdleTime = idle
|
||||
logger.debug('Set screensaver launching to {}'.format(idle))
|
||||
else:
|
||||
self.maxIdleTime = None
|
||||
|
||||
if 'maxSession' in info:
|
||||
maxSession = int(info['maxSession'])
|
||||
# operations.initMaxSession(maxSession)
|
||||
self.maxSessionTime = maxSession
|
||||
logger.debug('Set maxsession to {}'.format(maxSession))
|
||||
|
||||
def about(self):
|
||||
self.aboutDlg.exec_()
|
||||
|
||||
def quit(self):
|
||||
logger.debug('Quit invoked')
|
||||
if self.stopped is False:
|
||||
self.stopped = True
|
||||
try:
|
||||
# If we close Client, send Logoff to Broker
|
||||
self.ipc.sendLogout(operations.getCurrentUser())
|
||||
self.timer.stop()
|
||||
self.ipc.stop()
|
||||
except Exception:
|
||||
# May we have lost connection with server, simply exit in that case
|
||||
pass
|
||||
|
||||
try:
|
||||
operations.loggoff() # Invoke log off
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.app.quit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
|
||||
if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
|
||||
# QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
|
||||
sys.exit(1)
|
||||
|
||||
# This is important so our app won't close on message windows
|
||||
QtGui.QApplication.setQuitOnLastWindowClosed(False)
|
||||
|
||||
try:
|
||||
trayIcon = UDSSystemTray(app)
|
||||
except Exception:
|
||||
logger.error('UDS Service is not running, or it can\'t contact with UDS Server. User Tools stopped')
|
||||
sys.exit(1)
|
||||
|
||||
# Sets a default idle duration, but will not be used unless idle is notified from server
|
||||
operations.initIdleDuration(3600 * 10)
|
||||
|
||||
trayIcon.show()
|
||||
|
||||
# Catch kill and logout user :)
|
||||
signal.signal(signal.SIGTERM, sigTerm)
|
||||
|
||||
res = app.exec_()
|
||||
|
||||
logger.debug('Exiting')
|
||||
trayIcon.quit()
|
||||
|
||||
sys.exit(res)
|
203
actors/src/UDSActor_rc.py
Normal file
203
actors/src/UDSActor_rc.py
Normal file
@@ -0,0 +1,203 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created: Mon Apr 27 22:05:02 2015
|
||||
# by: The Resource Compiler for PyQt (Qt v4.8.6)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
qt_resource_data = b"\
|
||||
\x00\x00\x09\xd1\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x00\x57\x02\xf9\x87\
|
||||
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
|
||||
\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\
|
||||
\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
|
||||
\xdf\x04\x1b\x12\x2a\x1c\x39\xec\x95\x7d\x00\x00\x09\x5e\x49\x44\
|
||||
\x41\x54\x68\xde\xd5\x9a\x7b\x8c\x54\xd5\x1d\xc7\x3f\xbf\xfb\x9a\
|
||||
\x99\x65\x5f\xc8\x63\x41\x51\x40\x40\xac\xd1\x20\xd1\xc5\x68\x40\
|
||||
\x51\xac\x6b\xb5\xe0\xa3\xb1\x94\xa8\x58\x6b\x2a\xad\xa6\x91\xc6\
|
||||
\xd8\x54\xa5\x16\x9b\xf1\xd1\x2a\xa9\x68\x6b\x35\xd1\x1a\x27\xb6\
|
||||
\x6b\xb5\xad\xb5\x69\x8b\x4b\x5c\xaa\x28\x0a\x2c\x2f\x95\x5d\x1e\
|
||||
\x8b\x40\x61\xdd\x65\x60\xd8\xf7\xee\x9d\xb9\xaf\xd3\x3f\x76\x06\
|
||||
\x76\x61\x76\x65\x67\xc6\x3f\xfc\x25\x37\x33\x39\xf7\xce\xf9\x9d\
|
||||
\xef\xf9\x9e\xdf\x73\xae\x28\xa5\xf8\x3a\x8b\x51\xc8\xc9\x6a\xea\
|
||||
\x2a\x8a\x95\xa2\xa8\xb4\x54\xc2\xe5\x65\x9a\x15\xb6\x24\xec\x78\
|
||||
\x4a\xab\x6f\x70\xb5\xc6\x3d\x2e\x4d\xcd\x01\x89\xa3\x81\x4a\x24\
|
||||
\x7c\x3f\xbd\x6f\x3d\x40\x2b\xd0\x59\x5b\x6d\xe7\xb4\x93\x32\x1c\
|
||||
\x06\x6a\xea\x2a\x42\xc0\x4c\xe0\x7c\xe0\x1c\xe0\x6c\xe0\x2c\x60\
|
||||
\x14\x10\x12\x41\xb7\x2c\xd1\x5a\x0e\xf9\xda\x8e\x9d\xae\x1c\x68\
|
||||
\xf2\xb4\x44\x22\x10\xcf\x03\xa5\x14\x41\x00\x4a\x81\x52\x64\x94\
|
||||
\x06\x80\x97\xbe\x6c\xe0\x20\x50\x0f\x6c\x04\x56\xd7\x56\xdb\xf1\
|
||||
\x9c\x01\xd4\xd4\x55\x14\xa7\x17\x76\x05\x70\x3d\x70\x25\x30\x66\
|
||||
\xa8\xc9\xbe\x68\xf6\x59\xfd\x6e\x92\x2f\x9a\x5d\x74\x5d\x10\xcd\
|
||||
\x02\x31\x40\x04\x85\x96\x7e\x4a\x21\x4a\x01\x01\x22\x0a\x51\x6e\
|
||||
\x7a\xfd\x00\x72\xc2\x27\xfb\x81\x95\xc0\x9b\x40\x4b\x6d\xb5\x1d\
|
||||
\x7c\x29\x80\x9a\xba\x8a\x31\xc0\xf7\x81\xf9\xc0\xec\xfe\xb3\x0d\
|
||||
\xba\x0b\x02\x07\x9b\x7c\x5e\x7f\xa3\x87\xc0\x4b\x62\x5b\x33\xe8\
|
||||
\xd4\x66\x91\xd4\x26\xe3\x4a\x39\x81\x84\x51\x98\x7d\x53\x29\x1f\
|
||||
\x4d\x7c\xcc\xe2\x22\x4c\xd3\x47\xf7\x5b\x31\xbc\x38\xa6\xdb\x84\
|
||||
\xe5\xee\x23\xe4\xec\xc2\x70\x0f\xa1\x44\x50\x62\x65\xd4\xb7\x01\
|
||||
\x2f\x03\xbf\xae\xad\xb6\x13\x83\x02\xa8\xa9\xab\xb8\x00\xf8\x37\
|
||||
\x70\xe6\x70\xce\xa1\xae\xc3\xaa\xd5\x49\x36\x6f\x4e\xd2\x3c\xe2\
|
||||
\x61\xda\x8c\x2b\xf0\x89\x00\x1a\x30\x70\x83\xc4\xb0\x30\x47\x4f\
|
||||
\x40\x8c\xd0\x80\xbd\x11\xe5\x20\x2a\x89\xa6\x6c\x42\xce\x5e\xca\
|
||||
\x3b\xfe\x42\x79\x47\x0c\x94\x8f\x12\x33\xf3\xd8\x27\xc0\xdc\xda\
|
||||
\x6a\xbb\x3d\x33\x90\xe1\x95\x35\x5b\xc7\x45\x80\x2d\xc3\x5d\x3c\
|
||||
\xf4\x9d\xeb\x33\x4e\x17\x12\xc6\x0d\x24\x8c\xaa\xf4\xe2\x33\x47\
|
||||
\x5c\x1d\xbb\xc4\x0c\x61\x8d\x9d\x88\x18\x56\x7a\x2c\x38\x76\x29\
|
||||
\x31\x08\xb4\x62\x3c\x7d\x0c\x3d\x91\x4b\x69\x1a\xff\x7b\x1a\xce\
|
||||
\x69\xa1\xbd\xfc\x8e\x34\x13\x0a\x60\x06\xf0\x5e\x7f\xdd\xc7\x00\
|
||||
\xb4\x75\xf8\x4b\x72\xf5\x4a\x41\x00\xe7\x4e\x33\x99\x32\x7d\x2c\
|
||||
\x0a\x3d\x2b\x42\x2d\x54\x84\x35\x76\x22\xe8\xa7\xa2\x22\x40\x54\
|
||||
\x0a\x25\x16\x4d\xe3\x5f\xa4\x65\xdc\x4a\xe4\x38\x9b\x33\xe6\x2d\
|
||||
\x8a\xac\x38\x09\x40\xed\x47\x5d\xd3\x74\x4d\x72\x76\xa1\xba\xa1\
|
||||
\x71\xc7\xd5\xef\x30\xa6\xf8\xf0\xc9\x36\x62\x58\x18\xa7\x9d\x0e\
|
||||
\xa2\xf5\xd1\x75\xea\xdc\x22\xca\xa6\xad\x6c\x21\x2d\xe3\x56\xa0\
|
||||
\x05\xa9\xcc\x8d\x5b\xe7\x2d\x8a\x9c\x3e\x90\x81\x4e\xdf\xde\x52\
|
||||
\xdf\x8b\xa6\xe5\x1e\x07\x4a\x23\xed\x3c\x32\xff\x21\x4c\xdd\x43\
|
||||
\xa9\xe3\x9b\xa1\x17\x9f\x86\xe8\x66\xce\xf3\x8a\xf2\xe8\x28\x9e\
|
||||
\x8f\x63\x4d\xcb\xb0\x50\x0e\x5c\x3a\x00\x80\x69\xc8\xaa\x86\xc6\
|
||||
\x24\x4d\x2d\x2e\x92\x23\x11\x7e\xa0\x33\x7e\xe4\x01\x1e\xb8\x36\
|
||||
\x8a\x65\xb8\x28\x04\xd1\x74\xb4\x48\x49\xde\x41\x32\xd0\xc2\xd8\
|
||||
\x91\x0b\x33\x00\x42\xc0\x94\x01\x00\x62\x51\xa7\x36\x50\x34\xac\
|
||||
\xdf\xd6\x8b\x9d\x0a\x72\x56\xe4\xf9\x26\x17\x4c\xd8\xcc\xc2\x59\
|
||||
\xaf\xa1\x49\x00\x22\x88\x61\x92\xbf\x18\xf8\xfa\x69\xfd\x07\xca\
|
||||
\x07\x00\x48\xcb\x2d\x3d\xbd\x81\xbf\xe6\xa3\xee\xbc\xd5\xdd\x34\
|
||||
\xf3\x75\x2e\x99\xbc\x1e\x3f\x18\xee\xb9\x1f\xea\x28\xf9\x27\x8d\
|
||||
\x9d\x08\x60\x87\xa6\xf1\x58\xa2\xd5\xe3\x83\x4d\x3d\x27\xba\xf0\
|
||||
\x61\x89\xeb\x1b\x2c\xfd\xe6\xe3\xcc\x9a\xb4\x9e\xa4\x5d\x80\xc5\
|
||||
\xe3\xa2\xfb\x03\x62\x58\xc7\x49\x00\x62\x51\x47\x01\x51\x5d\x97\
|
||||
\x86\x03\x5f\x38\x34\xec\x49\xe6\xac\x50\x21\x80\x62\xc9\xe5\x2b\
|
||||
\x38\x6f\xd4\x7a\x02\xa5\xe5\xb9\xfb\x0e\xa6\xd7\x92\x09\x7e\x2e\
|
||||
\xd0\x9c\x8d\x01\x62\x51\xc7\x05\xaa\x00\x7f\x6b\x83\xcd\x91\x56\
|
||||
\x2f\x67\xa3\x56\x08\x25\x91\x76\xee\x9e\xb5\x9c\xd1\x91\x96\x34\
|
||||
\xa8\x5c\x01\xb8\xe8\xde\x31\x17\x6d\x03\x7b\xb2\x02\x48\x83\x68\
|
||||
\x02\x16\x2a\x05\xff\x5d\xdf\x4d\x47\x97\x9f\xb3\x7b\x55\x4a\xe3\
|
||||
\xcc\xb2\x06\xee\xbb\xf8\xc7\x94\x85\x5a\xf1\x03\x23\x67\x00\xa6\
|
||||
\xd7\x9c\x61\x20\x05\xec\x1e\x14\x40\x5a\xfe\x21\xc2\x8b\x8e\xa3\
|
||||
\x78\x7f\x43\x37\xc9\x94\xca\xc3\x1e\x42\x4c\x2e\xdf\xc6\xcf\x2f\
|
||||
\xb9\x8d\xb2\x70\x6b\x0e\x4c\x08\x96\xd7\x82\x1c\x0f\x64\x89\xda\
|
||||
\x6a\xfb\xe8\x90\x00\x62\x51\xc7\x07\x1e\x16\x61\x5f\x47\x57\xc0\
|
||||
\xe6\xed\xbd\x04\xb9\x7b\x57\x02\xa5\x31\xa1\x74\x07\x3f\xbd\xf8\
|
||||
\x6e\x46\x47\x5a\x00\x49\xa6\xcf\xf2\x97\xb3\x28\x3a\xa1\x64\x7d\
|
||||
\xff\xa1\x0f\x07\xf3\x42\x27\x82\x38\x7a\xb4\xdd\xbd\x51\xd7\x84\
|
||||
\x3d\xfb\x1d\x76\xed\x4b\x62\x18\x92\x17\x88\x73\x47\xad\xe3\xa1\
|
||||
\x4b\x17\x71\xcb\xb9\x4f\xbd\xdb\x91\x2a\xb9\x0d\xb8\x1f\xf8\x6d\
|
||||
\x3a\x0b\x3e\x38\x48\xa2\x42\x24\xf5\x29\xea\xb8\x31\xae\x39\xa5\
|
||||
\x8a\xac\xe1\xc0\xb7\xaf\xd7\x34\x79\xb4\x7e\xcf\xa1\x8b\xfe\xba\
|
||||
\x6a\x0b\x86\xa1\x33\xf7\x92\x62\x26\x4e\xb0\xf0\x7d\x95\x87\x4b\
|
||||
\x54\x20\xaa\x47\x17\xff\xee\x79\x17\xb5\xfe\x79\xfa\x13\xfb\xa5\
|
||||
\x33\x35\x2a\x0c\x8c\x00\xc6\x01\xdf\x03\x7e\x94\x2e\xa8\x08\xb4\
|
||||
\x22\xa6\xed\xbb\x9c\xb0\xbd\x11\x25\x06\xc0\xa8\xda\x6a\xbb\xf5\
|
||||
\x24\x00\xbf\x7b\x63\xba\x5c\x36\x73\x52\x79\x24\x6c\xcd\x57\x4a\
|
||||
\x2d\x07\x26\x83\x22\x50\x8a\xb7\x6b\xf7\xb0\xf3\xf3\xfd\x58\xa6\
|
||||
\xf0\xad\x2b\x4a\x28\x29\xd6\x0b\x11\x9b\x5c\xe0\xca\xaa\xca\xf8\
|
||||
\xba\x6c\x37\xc7\x2f\xef\xba\x13\x58\x11\x68\xc5\x23\x2f\xd8\x59\
|
||||
\x8a\x52\x2e\x20\x87\x6b\xab\xed\x8a\xac\x47\x68\xe7\xde\x43\xa5\
|
||||
\x1f\x6c\xfa\x7c\x75\x7b\x67\xef\xab\x96\xa9\x4f\xb6\x0c\x9b\xce\
|
||||
\xe4\x18\x3e\xde\xfb\x5d\x5a\xb4\x18\x18\x67\xe1\xb8\x01\x1f\x6f\
|
||||
\xeb\xcd\x8b\x81\x7e\x62\x02\xab\x6b\xea\x2a\xae\xca\x76\xb3\x65\
|
||||
\x79\xc9\x2b\x81\x16\x59\x10\x72\x0e\xf4\x88\xdf\x9d\xf1\x40\xff\
|
||||
\x19\xb4\x22\xbb\xfd\x61\xb3\x5c\x44\xde\x0b\x59\xc6\x8c\xf3\xa7\
|
||||
\x4f\x45\x95\x3f\xc6\xb6\x83\x73\xe8\x49\x95\x11\x20\xe8\xee\x27\
|
||||
\x44\x8e\x5c\x88\xaf\x4c\xa6\x4d\xb2\x98\x53\x59\x8c\xeb\x15\x04\
|
||||
\xc8\x61\xe0\xda\xaa\xca\xf8\xd6\x6c\x37\xcf\xbf\xef\xb9\xbf\x8d\
|
||||
\x8b\x2f\xbd\xb9\xaf\xb0\xe1\xe6\xda\x6a\xfb\xad\xac\x0c\x88\x48\
|
||||
\x0a\x38\x90\x72\x3c\x36\x6e\xef\x64\x6d\xe3\x7c\xba\x53\xe5\x7d\
|
||||
\x59\x25\x10\x58\x33\x48\x95\xbf\x80\x26\x2e\xbb\xf6\xa6\x68\xd8\
|
||||
\x93\xcc\x2b\xfd\xee\x27\x63\x81\x97\x6b\xea\x2a\x46\x67\xbd\x79\
|
||||
\xe4\x91\x86\xf4\xe2\x03\x60\xfd\x50\xb9\x50\xf2\x58\x84\x13\x1f\
|
||||
\xbd\x2f\xdd\xe8\x1f\x5a\xf1\x8a\x7e\x88\x1f\x59\x88\x61\xc0\xe6\
|
||||
\xcf\x6c\x0e\x1d\xc9\x3d\x52\x9f\x20\x33\x81\x97\xb2\x07\x31\x7b\
|
||||
\x6a\xfa\xeb\x26\xa0\x6b\x50\x00\xe9\x5c\x68\x7b\x5f\x9f\x23\x85\
|
||||
\xf8\x4d\x59\xa6\xd3\x70\x4a\x9f\x41\x69\x63\xf0\x03\xc5\x86\x6d\
|
||||
\xbd\x85\x3a\x46\x00\x37\xd4\xd4\x55\x3c\x93\x05\xc2\xbd\xc0\x54\
|
||||
\xe0\xa6\x74\x33\x6c\xf0\xb6\xca\xe2\x65\xd6\x37\x80\x75\x48\x68\
|
||||
\xa4\x53\xf6\x2a\x5e\xe4\xe6\x6c\x7e\x10\x3d\xb9\x86\x50\xeb\x35\
|
||||
\xf8\xbe\x70\xf6\x59\x21\xe6\x54\x8e\x28\x54\xd6\x6c\xa7\xed\x61\
|
||||
\xed\xa9\x3c\x9c\x2d\x99\xdb\x01\x34\xa2\x92\x68\xee\xa6\xc1\xb2\
|
||||
\x34\xbc\xf0\x55\xb8\x25\x4f\xa1\x6b\x1e\x9f\xff\x2f\xc5\xa7\x3b\
|
||||
\x93\xe8\x05\xf1\xac\x44\x80\xfb\xd3\x5d\xc0\xe1\x03\x48\xcb\xd3\
|
||||
\x00\xba\x53\x8b\xa8\xce\x41\x92\x2b\x70\x47\xdc\x83\x1f\xb9\x05\
|
||||
\xc3\x50\x34\x34\x26\x39\xd8\xec\x16\xca\x1e\x16\x00\x13\x73\x06\
|
||||
\x10\x8b\x3a\x6f\x82\x34\x6b\xce\x46\x34\xf7\xb3\x21\x42\x6a\x08\
|
||||
\xb7\xf4\x09\x94\x76\x06\xae\x17\xb0\xb5\xde\xc6\x4e\x16\xcc\x1e\
|
||||
\xee\xcc\x87\x01\x80\x9f\x28\x11\xac\x8e\x7b\x87\x6c\x2e\x06\xc6\
|
||||
\x14\x9c\xb2\x17\x11\xf1\x48\xb4\x7b\x6c\xfa\xac\x17\x5d\x2f\x08\
|
||||
\x0d\xf3\xf3\x05\xb0\x1a\x8c\x0f\xc4\xfd\x04\xb3\xfb\xe9\xc1\x41\
|
||||
\x28\xf0\xc3\xd7\xe2\x96\x3e\x8f\xa1\x79\xec\x6b\x72\xd8\xd6\xd0\
|
||||
\x8b\x69\xe4\x0d\x62\x52\x5e\x00\x62\x51\xa7\x1b\x78\x06\x31\x1d\
|
||||
\xa3\xeb\x49\x34\x77\xf7\xd0\x49\x4d\xd1\x0f\xf0\xc3\x37\xa2\x89\
|
||||
\xa2\xa1\x31\x45\xcb\x11\x37\x5f\x00\xad\xf9\x32\x40\x2c\xea\xfc\
|
||||
\x1d\x78\x5b\x54\x07\x66\xe7\x03\x80\x3f\xb4\x3d\x94\x3d\x85\xd2\
|
||||
\x46\xe3\x7a\x8a\x2d\xdb\xed\xbc\xea\x07\x60\x55\xde\x00\x32\x6d\
|
||||
\x3c\x90\x16\x3d\xf9\x4f\xac\xae\x28\x6a\x48\x7b\x98\x8a\x53\xfe\
|
||||
\x1a\x9a\x72\x89\x27\x3c\xea\x1b\x93\xf9\xd8\xc3\xca\x82\x00\x48\
|
||||
\x17\xf9\xf3\x10\x33\x69\x76\x2d\xc7\xec\xad\x1e\xaa\x8a\xc7\x0f\
|
||||
\xcf\xc3\x2d\x7d\x14\x4d\x5c\x36\x6f\xef\x6b\x0a\xe4\xd0\x72\x7d\
|
||||
\x21\x53\xf3\x16\x82\x81\x4c\x70\xbb\x57\x89\x89\xd5\x71\x17\x46\
|
||||
\xf2\xed\x21\x41\x38\x25\x0f\x12\x84\xae\xc1\xd4\x03\xd6\x6d\xea\
|
||||
\x26\xe5\x0e\xcb\xb5\x6e\x04\x7e\x51\x55\x19\xf7\x0a\x06\x20\x0d\
|
||||
\xe2\x8f\xc0\xaf\x50\x2e\x56\xdb\xed\xe8\xce\x87\x43\xb8\x57\x13\
|
||||
\xa7\xf4\x71\xd0\x4a\xe9\xec\x0e\xd8\xb5\x37\x75\xaa\x6a\xb6\x02\
|
||||
\x57\x55\x55\xc6\x13\xa7\xfa\x83\x61\x25\xc3\xb1\xa8\xf3\x4b\x90\
|
||||
\x95\x60\x13\x4e\xcc\x41\x4f\xbe\x33\x78\xa3\xd7\xba\x08\x2f\xbc\
|
||||
\x10\x94\xcb\xee\x7d\x29\xec\xe4\x97\x5a\xf4\xfb\xc0\x65\x55\x95\
|
||||
\xf1\x9e\xe1\xac\x69\xd8\xd9\x7c\x2c\xea\x2c\x05\x79\x52\x89\x49\
|
||||
\xa8\x75\x01\x66\xf7\x8a\xc1\x53\x8d\xb2\xdf\x80\x68\x74\x75\xfb\
|
||||
\xec\xdc\x9b\x62\x88\xff\x1f\x5e\x06\x16\x54\x55\xc6\x87\xdd\x0a\
|
||||
\xcc\xa9\x1c\x89\x45\x9d\x07\x81\xfb\x00\xcc\xae\x07\x09\xb7\x7d\
|
||||
\x27\xbb\x39\x68\x25\x04\xd6\xd5\x18\xba\x47\xfd\xee\x24\x9e\x9f\
|
||||
\x95\x85\x7b\x80\x25\x55\x95\xf1\xce\x5c\xd6\x92\x73\x3d\x15\x8b\
|
||||
\x3a\xcf\xa6\xc3\x7d\x97\x96\x7c\x8b\x48\x7c\x22\xba\xbb\x81\xe3\
|
||||
\x7f\x99\x66\x40\x8c\xea\x3b\x52\x81\xe2\xf0\xd1\x01\x1d\xbe\x36\
|
||||
\xe0\xb6\xaa\xca\xf8\x1f\xaa\x2a\xe3\x7e\xae\xeb\xc8\xab\x20\x8c\
|
||||
\x45\x9d\x7f\x01\x73\xc1\x58\x2b\x41\x13\xa1\xc4\x5c\x42\xed\x4b\
|
||||
\xd0\x53\x35\x48\x70\x18\x3d\xb5\x16\x3d\xb5\x0a\xc4\x40\xa0\x7f\
|
||||
\x23\x60\x03\x70\x5d\x55\x65\xfc\x4f\xf9\xb7\xdc\x0b\x50\x85\x2c\
|
||||
\x5e\x66\x15\x01\x77\x01\xcf\x42\x00\x52\x8c\x92\x11\x88\xea\x01\
|
||||
\xd5\xd3\xd7\x1c\xf7\x14\xb7\xde\x30\x12\xcb\x94\x97\x94\xe2\x67\
|
||||
\x55\x95\xf1\xb6\x42\x64\x7c\x52\xc8\x97\x3d\x16\x2f\xb3\xa6\x00\
|
||||
\xaf\xa4\xeb\xdb\xe2\xe3\x0d\x5e\x38\x67\x72\xa8\x73\x4e\xe5\x88\
|
||||
\x65\x73\x67\x1c\x7a\x8e\x02\x8a\x7c\x15\x6f\xab\x2c\x5e\x66\xcd\
|
||||
\x06\xae\x03\x2e\x04\xcc\xd2\x62\x6d\xfb\x35\xb3\x4b\x9f\x5f\x30\
|
||||
\xfb\x70\x63\xa1\x75\xc9\x57\xf9\xba\xcd\xe2\x65\x56\x91\x08\x32\
|
||||
\xf3\xbc\xb0\xbd\x74\x51\x67\xf0\x55\xe8\xf8\x3f\x66\x47\x07\xd4\
|
||||
\xf8\xcc\x73\x31\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\
|
||||
"
|
||||
|
||||
qt_resource_name = b"\
|
||||
\x00\x06\
|
||||
\x07\x03\x7d\xc3\
|
||||
\x00\x69\
|
||||
\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
|
||||
\x00\x03\
|
||||
\x00\x00\x70\x37\
|
||||
\x00\x69\
|
||||
\x00\x6d\x00\x67\
|
||||
\x00\x07\
|
||||
\x0b\xb6\x57\xa7\
|
||||
\x00\x75\
|
||||
\x00\x64\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
"
|
||||
|
||||
qt_resource_struct = b"\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x12\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
|
||||
\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
"
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
qInitResources()
|
240
actors/src/about-dialog.ui
Normal file
240
actors/src/about-dialog.ui
Normal file
@@ -0,0 +1,240 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UDSAboutDialog</class>
|
||||
<widget class="QDialog" name="UDSAboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>466</width>
|
||||
<height>402</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Verdana</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About UDS Actor</string>
|
||||
</property>
|
||||
<property name="locale">
|
||||
<locale language="English" country="UnitedStates"/>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="LogoLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><img src=":/images/img/uds.png"/> UDS Actor Tools</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TitleLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">UDS Actor</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="VersionLabel">
|
||||
<property name="text">
|
||||
<string>Version 1.7.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="aboutTab">
|
||||
<attribute name="title">
|
||||
<string>&About</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="aboutBrowser">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">(c) 2012-2016, Virtual Cable S.L.U.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-style:italic;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.udsenterprise.com"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.udsenterprise.com</span></a></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.openuds.org"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">http://www.openuds.org</span></a></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="authorsTab">
|
||||
<attribute name="title">
|
||||
<string>A&uthors</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="authorsBrowser">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Adolfo Gómez García &lt;agomez@virtualcable.es&gt;</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="licenseTab">
|
||||
<attribute name="title">
|
||||
<string>&License Agreement</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="licenseBrowser">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Copyright (c) 2012-2016 Virtual Cable S.L.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">All rights reserved.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Redistribution and use in source and binary forms, with or without modification,</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">are permitted provided that the following conditions are met:</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> * Redistributions of source code must retain the above copyright notice,</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> this list of conditions and the following disclaimer.</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> * Redistributions in binary form must reproduce the above copyright notice,</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> this list of conditions and the following disclaimer in the documentation</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> and/or other materials provided with the distribution.</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> * Neither the name of Virtual Cable S.L. nor the names of its contributors</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> may be used to endorse or promote products derived from this software</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> without specific prior written permission.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="UDSActor.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>clicked(QAbstractButton*)</signal>
|
||||
<receiver>UDSAboutDialog</receiver>
|
||||
<slot>closeDialog()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>432</x>
|
||||
<y>381</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>282</x>
|
||||
<y>362</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>closeDialog()</slot>
|
||||
</slots>
|
||||
</ui>
|
164
actors/src/about_dialog_ui.py
Normal file
164
actors/src/about_dialog_ui.py
Normal file
@@ -0,0 +1,164 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'about-dialog.ui'
|
||||
#
|
||||
# Created: Mon Apr 27 22:05:02 2015
|
||||
# by: PyQt4 UI code generator 4.11.2
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class Ui_UDSAboutDialog(object):
|
||||
def setupUi(self, UDSAboutDialog):
|
||||
UDSAboutDialog.setObjectName(_fromUtf8("UDSAboutDialog"))
|
||||
UDSAboutDialog.resize(466, 402)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Verdana"))
|
||||
font.setPointSize(9)
|
||||
UDSAboutDialog.setFont(font)
|
||||
UDSAboutDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
|
||||
UDSAboutDialog.setModal(True)
|
||||
self.vboxlayout = QtGui.QVBoxLayout(UDSAboutDialog)
|
||||
self.vboxlayout.setSpacing(9)
|
||||
self.vboxlayout.setMargin(9)
|
||||
self.vboxlayout.setObjectName(_fromUtf8("vboxlayout"))
|
||||
self.LogoLabel = QtGui.QLabel(UDSAboutDialog)
|
||||
self.LogoLabel.setObjectName(_fromUtf8("LogoLabel"))
|
||||
self.vboxlayout.addWidget(self.LogoLabel)
|
||||
spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
self.vboxlayout.addItem(spacerItem)
|
||||
self.TitleLabel = QtGui.QLabel(UDSAboutDialog)
|
||||
self.TitleLabel.setObjectName(_fromUtf8("TitleLabel"))
|
||||
self.vboxlayout.addWidget(self.TitleLabel)
|
||||
self.VersionLabel = QtGui.QLabel(UDSAboutDialog)
|
||||
self.VersionLabel.setObjectName(_fromUtf8("VersionLabel"))
|
||||
self.vboxlayout.addWidget(self.VersionLabel)
|
||||
spacerItem1 = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
self.vboxlayout.addItem(spacerItem1)
|
||||
self.tabWidget = QtGui.QTabWidget(UDSAboutDialog)
|
||||
self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
|
||||
self.aboutTab = QtGui.QWidget()
|
||||
self.aboutTab.setObjectName(_fromUtf8("aboutTab"))
|
||||
self.vboxlayout1 = QtGui.QVBoxLayout(self.aboutTab)
|
||||
self.vboxlayout1.setSpacing(6)
|
||||
self.vboxlayout1.setMargin(9)
|
||||
self.vboxlayout1.setObjectName(_fromUtf8("vboxlayout1"))
|
||||
self.aboutBrowser = QtGui.QTextBrowser(self.aboutTab)
|
||||
self.aboutBrowser.setOpenExternalLinks(True)
|
||||
self.aboutBrowser.setObjectName(_fromUtf8("aboutBrowser"))
|
||||
self.vboxlayout1.addWidget(self.aboutBrowser)
|
||||
self.tabWidget.addTab(self.aboutTab, _fromUtf8(""))
|
||||
self.authorsTab = QtGui.QWidget()
|
||||
self.authorsTab.setObjectName(_fromUtf8("authorsTab"))
|
||||
self.vboxlayout2 = QtGui.QVBoxLayout(self.authorsTab)
|
||||
self.vboxlayout2.setSpacing(6)
|
||||
self.vboxlayout2.setMargin(9)
|
||||
self.vboxlayout2.setObjectName(_fromUtf8("vboxlayout2"))
|
||||
self.authorsBrowser = QtGui.QTextBrowser(self.authorsTab)
|
||||
self.authorsBrowser.setOpenExternalLinks(True)
|
||||
self.authorsBrowser.setObjectName(_fromUtf8("authorsBrowser"))
|
||||
self.vboxlayout2.addWidget(self.authorsBrowser)
|
||||
self.tabWidget.addTab(self.authorsTab, _fromUtf8(""))
|
||||
self.licenseTab = QtGui.QWidget()
|
||||
self.licenseTab.setObjectName(_fromUtf8("licenseTab"))
|
||||
self.vboxlayout3 = QtGui.QVBoxLayout(self.licenseTab)
|
||||
self.vboxlayout3.setSpacing(6)
|
||||
self.vboxlayout3.setMargin(9)
|
||||
self.vboxlayout3.setObjectName(_fromUtf8("vboxlayout3"))
|
||||
self.licenseBrowser = QtGui.QTextBrowser(self.licenseTab)
|
||||
self.licenseBrowser.setObjectName(_fromUtf8("licenseBrowser"))
|
||||
self.vboxlayout3.addWidget(self.licenseBrowser)
|
||||
self.tabWidget.addTab(self.licenseTab, _fromUtf8(""))
|
||||
self.vboxlayout.addWidget(self.tabWidget)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(UDSAboutDialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
|
||||
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
|
||||
self.vboxlayout.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(UDSAboutDialog)
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("clicked(QAbstractButton*)")), UDSAboutDialog.closeDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(UDSAboutDialog)
|
||||
|
||||
def retranslateUi(self, UDSAboutDialog):
|
||||
UDSAboutDialog.setWindowTitle(_translate("UDSAboutDialog", "About UDS Actor", None))
|
||||
self.LogoLabel.setText(_translate("UDSAboutDialog", "<html><head/><body><p><img src=\":/images/img/uds.png\"/> UDS Actor Tools</p></body></html>", None))
|
||||
self.TitleLabel.setText(_translate("UDSAboutDialog", "<html><head/><body><p><span style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:600;\">UDS Actor</span></p></body></html>", None))
|
||||
self.VersionLabel.setText(_translate("UDSAboutDialog", "Version 1.7.0", None))
|
||||
self.aboutBrowser.setHtml(_translate("UDSAboutDialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\';\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\'; font-weight:600;\">(c) 2014, Virtual Cable S.L.U.</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-style:italic;\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.udsenterprise.com\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.udsenterprise.com</span></a></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.openuds.org\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.openuds.org</span></a></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\';\"><br /></p></body></html>", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.aboutTab), _translate("UDSAboutDialog", "&About", None))
|
||||
self.authorsBrowser.setHtml(_translate("UDSAboutDialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\';\">Adolfo Gómez García <agomez@virtualcable.es></span></p></body></html>", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.authorsTab), _translate("UDSAboutDialog", "A&uthors", None))
|
||||
self.licenseBrowser.setHtml(_translate("UDSAboutDialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">Copyright (c) 2014 Virtual Cable S.L.</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">All rights reserved.</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">Redistribution and use in source and binary forms, with or without modification,</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">are permitted provided that the following conditions are met:</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> * Redistributions of source code must retain the above copyright notice,</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> this list of conditions and the following disclaimer.</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> * Redistributions in binary form must reproduce the above copyright notice,</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> this list of conditions and the following disclaimer in the documentation</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> and/or other materials provided with the distribution.</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> * Neither the name of Virtual Cable S.L. nor the names of its contributors</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> may be used to endorse or promote products derived from this software</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"> without specific prior written permission.</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span></p>\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></p>\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p></body></html>", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.licenseTab), _translate("UDSAboutDialog", "&License Agreement", None))
|
||||
|
||||
import UDSActor_rc
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
UDSAboutDialog = QtGui.QDialog()
|
||||
ui = Ui_UDSAboutDialog()
|
||||
ui.setupUi(UDSAboutDialog)
|
||||
UDSAboutDialog.show()
|
||||
sys.exit(app.exec_())
|
||||
|
BIN
actors/src/img/uds-48x48.ico
Normal file
BIN
actors/src/img/uds-48x48.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
BIN
actors/src/img/uds-512.png
Normal file
BIN
actors/src/img/uds-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
actors/src/img/uds.ico
Normal file
BIN
actors/src/img/uds.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
BIN
actors/src/img/uds.png
Normal file
BIN
actors/src/img/uds.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
89
actors/src/message-dialog.ui
Normal file
89
actors/src/message-dialog.ui
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UDSMessageDialog</class>
|
||||
<widget class="QDialog" name="UDSMessageDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>339</width>
|
||||
<height>188</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Verdana</family>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>UDS Actor</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>321</width>
|
||||
<height>171</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="message"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>clicked(QAbstractButton*)</signal>
|
||||
<receiver>UDSMessageDialog</receiver>
|
||||
<slot>closeDialog()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>203</x>
|
||||
<y>161</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>337</x>
|
||||
<y>125</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>closeDialog()</slot>
|
||||
</slots>
|
||||
</ui>
|
71
actors/src/message_dialog_ui.py
Normal file
71
actors/src/message_dialog_ui.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'message-dialog.ui'
|
||||
#
|
||||
# Created: Mon Apr 27 22:05:02 2015
|
||||
# by: PyQt4 UI code generator 4.11.2
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class Ui_UDSMessageDialog(object):
|
||||
def setupUi(self, UDSMessageDialog):
|
||||
UDSMessageDialog.setObjectName(_fromUtf8("UDSMessageDialog"))
|
||||
UDSMessageDialog.resize(339, 188)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(UDSMessageDialog.sizePolicy().hasHeightForWidth())
|
||||
UDSMessageDialog.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Verdana"))
|
||||
font.setPointSize(10)
|
||||
UDSMessageDialog.setFont(font)
|
||||
self.verticalLayoutWidget = QtGui.QWidget(UDSMessageDialog)
|
||||
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 321, 171))
|
||||
self.verticalLayoutWidget.setObjectName(_fromUtf8("verticalLayoutWidget"))
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget)
|
||||
self.verticalLayout.setMargin(0)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.message = QtGui.QTextBrowser(self.verticalLayoutWidget)
|
||||
self.message.setObjectName(_fromUtf8("message"))
|
||||
self.verticalLayout.addWidget(self.message)
|
||||
spacerItem = QtGui.QSpacerItem(20, 15, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(self.verticalLayoutWidget)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
|
||||
self.verticalLayout.addWidget(self.buttonBox)
|
||||
|
||||
self.retranslateUi(UDSMessageDialog)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("clicked(QAbstractButton*)")), UDSMessageDialog.closeDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(UDSMessageDialog)
|
||||
|
||||
def retranslateUi(self, UDSMessageDialog):
|
||||
UDSMessageDialog.setWindowTitle(_translate("UDSMessageDialog", "UDS Actor", None))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
UDSMessageDialog = QtGui.QDialog()
|
||||
ui = Ui_UDSMessageDialog()
|
||||
ui.setupUi(UDSMessageDialog)
|
||||
UDSMessageDialog.show()
|
||||
sys.exit(app.exec_())
|
||||
|
327
actors/src/setup-dialog.ui
Normal file
327
actors/src/setup-dialog.ui
Normal file
@@ -0,0 +1,327 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UdsActorSetupDialog</class>
|
||||
<widget class="QDialog" name="UdsActorSetupDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>243</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Verdana</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>UDS Actor Configuration</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="locale">
|
||||
<locale language="English" country="UnitedStates"/>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QPushButton" name="testButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>160</y>
|
||||
<width>361</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Click to test the selecter parameters</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Click on this button to test the server host and master key parameters.</p><p>A window will be displayed with results after the test is executed.</p><p><br/></p><p>This button will only be active if all parameters are filled.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Test parameters</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="saveButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>190</y>
|
||||
<width>101</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Accepts changes and saves them</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Clicking on this button will accept all changes and save them, closing the configuration window</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept && Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>260</x>
|
||||
<y>190</y>
|
||||
<width>121</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Cancel all changes and discard them</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Discards all changes and closes the configuration window</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel && Discard</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>361</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>UDS Server Host</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="host">
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Uds Broker Server Addres. Use IP or FQDN</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Enter here the UDS Broker Addres using either its IP address or its FQDN address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>UDS Master Key</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="masterKey">
|
||||
<property name="toolTip">
|
||||
<string>Master key to communicate with UDS Broker</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Enter the Master Key (found on<span style=" font-weight:600;"> UDS Configuration</span> section) of the UDS Broker to allow communication of the Actor with Broker</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Security</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="useSSl">
|
||||
<property name="toolTip">
|
||||
<string>Select communication security with broker</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Select the security for communications with UDS Broker.</p><p>The recommended method of communication is <span style=" font-weight:600;">Use SSL</span>, but selection needs to be acording to your broker configuration.</p></body></html></string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Do not use SSL</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use SSL</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="logLevelLabel">
|
||||
<property name="text">
|
||||
<string>Log Level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="logLevelComboBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">DEBUG</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">INFO</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">ERROR</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">FATAL</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>host</sender>
|
||||
<signal>textChanged(QString)</signal>
|
||||
<receiver>UdsActorSetupDialog</receiver>
|
||||
<slot>textChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>123</x>
|
||||
<y>31</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>143</x>
|
||||
<y>48</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>masterKey</sender>
|
||||
<signal>textChanged(QString)</signal>
|
||||
<receiver>UdsActorSetupDialog</receiver>
|
||||
<slot>textChanged()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>258</x>
|
||||
<y>75</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>299</x>
|
||||
<y>84</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cancelButton</sender>
|
||||
<signal>pressed()</signal>
|
||||
<receiver>UdsActorSetupDialog</receiver>
|
||||
<slot>cancelAndDiscard()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>315</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>231</x>
|
||||
<y>161</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>testButton</sender>
|
||||
<signal>pressed()</signal>
|
||||
<receiver>UdsActorSetupDialog</receiver>
|
||||
<slot>testParameters()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>239</x>
|
||||
<y>132</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>285</x>
|
||||
<y>185</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>saveButton</sender>
|
||||
<signal>pressed()</signal>
|
||||
<receiver>UdsActorSetupDialog</receiver>
|
||||
<slot>acceptAndSave()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>71</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>124</x>
|
||||
<y>181</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>textChanged()</slot>
|
||||
<slot>cancelAndDiscard()</slot>
|
||||
<slot>testParameters()</slot>
|
||||
<slot>acceptAndSave()</slot>
|
||||
</slots>
|
||||
</ui>
|
152
actors/src/setup_dialog_ui.py
Normal file
152
actors/src/setup_dialog_ui.py
Normal file
@@ -0,0 +1,152 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'setup-dialog.ui'
|
||||
#
|
||||
# Created: Mon Apr 27 22:05:03 2015
|
||||
# by: PyQt4 UI code generator 4.11.2
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class Ui_UdsActorSetupDialog(object):
|
||||
def setupUi(self, UdsActorSetupDialog):
|
||||
UdsActorSetupDialog.setObjectName(_fromUtf8("UdsActorSetupDialog"))
|
||||
UdsActorSetupDialog.setWindowModality(QtCore.Qt.WindowModal)
|
||||
UdsActorSetupDialog.resize(400, 243)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(UdsActorSetupDialog.sizePolicy().hasHeightForWidth())
|
||||
UdsActorSetupDialog.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("Verdana"))
|
||||
font.setPointSize(9)
|
||||
UdsActorSetupDialog.setFont(font)
|
||||
UdsActorSetupDialog.setAutoFillBackground(False)
|
||||
UdsActorSetupDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
|
||||
UdsActorSetupDialog.setSizeGripEnabled(False)
|
||||
UdsActorSetupDialog.setModal(True)
|
||||
self.testButton = QtGui.QPushButton(UdsActorSetupDialog)
|
||||
self.testButton.setEnabled(False)
|
||||
self.testButton.setGeometry(QtCore.QRect(20, 160, 361, 23))
|
||||
self.testButton.setObjectName(_fromUtf8("testButton"))
|
||||
self.saveButton = QtGui.QPushButton(UdsActorSetupDialog)
|
||||
self.saveButton.setEnabled(False)
|
||||
self.saveButton.setGeometry(QtCore.QRect(20, 190, 101, 23))
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.saveButton.sizePolicy().hasHeightForWidth())
|
||||
self.saveButton.setSizePolicy(sizePolicy)
|
||||
self.saveButton.setObjectName(_fromUtf8("saveButton"))
|
||||
self.cancelButton = QtGui.QPushButton(UdsActorSetupDialog)
|
||||
self.cancelButton.setGeometry(QtCore.QRect(260, 190, 121, 23))
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.cancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.cancelButton.setSizePolicy(sizePolicy)
|
||||
self.cancelButton.setObjectName(_fromUtf8("cancelButton"))
|
||||
self.layoutWidget = QtGui.QWidget(UdsActorSetupDialog)
|
||||
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 361, 131))
|
||||
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
|
||||
self.formLayout = QtGui.QFormLayout(self.layoutWidget)
|
||||
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
|
||||
self.formLayout.setMargin(0)
|
||||
self.formLayout.setVerticalSpacing(16)
|
||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
||||
self.label = QtGui.QLabel(self.layoutWidget)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label)
|
||||
self.host = QtGui.QLineEdit(self.layoutWidget)
|
||||
self.host.setAcceptDrops(False)
|
||||
self.host.setObjectName(_fromUtf8("host"))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.host)
|
||||
self.label_3 = QtGui.QLabel(self.layoutWidget)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_3)
|
||||
self.masterKey = QtGui.QLineEdit(self.layoutWidget)
|
||||
self.masterKey.setObjectName(_fromUtf8("masterKey"))
|
||||
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.masterKey)
|
||||
self.label_4 = QtGui.QLabel(self.layoutWidget)
|
||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4)
|
||||
self.useSSl = QtGui.QComboBox(self.layoutWidget)
|
||||
self.useSSl.setObjectName(_fromUtf8("useSSl"))
|
||||
self.useSSl.addItem(_fromUtf8(""))
|
||||
self.useSSl.addItem(_fromUtf8(""))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.useSSl)
|
||||
self.logLevelLabel = QtGui.QLabel(self.layoutWidget)
|
||||
self.logLevelLabel.setObjectName(_fromUtf8("logLevelLabel"))
|
||||
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.logLevelLabel)
|
||||
self.logLevelComboBox = QtGui.QComboBox(self.layoutWidget)
|
||||
self.logLevelComboBox.setFrame(True)
|
||||
self.logLevelComboBox.setObjectName(_fromUtf8("logLevelComboBox"))
|
||||
self.logLevelComboBox.addItem(_fromUtf8(""))
|
||||
self.logLevelComboBox.setItemText(0, _fromUtf8("DEBUG"))
|
||||
self.logLevelComboBox.addItem(_fromUtf8(""))
|
||||
self.logLevelComboBox.setItemText(1, _fromUtf8("INFO"))
|
||||
self.logLevelComboBox.addItem(_fromUtf8(""))
|
||||
self.logLevelComboBox.setItemText(2, _fromUtf8("ERROR"))
|
||||
self.logLevelComboBox.addItem(_fromUtf8(""))
|
||||
self.logLevelComboBox.setItemText(3, _fromUtf8("FATAL"))
|
||||
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.logLevelComboBox)
|
||||
|
||||
self.retranslateUi(UdsActorSetupDialog)
|
||||
self.logLevelComboBox.setCurrentIndex(1)
|
||||
QtCore.QObject.connect(self.host, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
|
||||
QtCore.QObject.connect(self.masterKey, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
|
||||
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.cancelAndDiscard)
|
||||
QtCore.QObject.connect(self.testButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.testParameters)
|
||||
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.acceptAndSave)
|
||||
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
|
||||
|
||||
def retranslateUi(self, UdsActorSetupDialog):
|
||||
UdsActorSetupDialog.setWindowTitle(_translate("UdsActorSetupDialog", "UDS Actor Configuration", None))
|
||||
self.testButton.setToolTip(_translate("UdsActorSetupDialog", "Click to test the selecter parameters", None))
|
||||
self.testButton.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Click on this button to test the server host and master key parameters.</p><p>A window will be displayed with results after the test is executed.</p><p><br/></p><p>This button will only be active if all parameters are filled.</p></body></html>", None))
|
||||
self.testButton.setText(_translate("UdsActorSetupDialog", "Test parameters", None))
|
||||
self.saveButton.setToolTip(_translate("UdsActorSetupDialog", "Accepts changes and saves them", None))
|
||||
self.saveButton.setWhatsThis(_translate("UdsActorSetupDialog", "Clicking on this button will accept all changes and save them, closing the configuration window", None))
|
||||
self.saveButton.setText(_translate("UdsActorSetupDialog", "Accept && Save", None))
|
||||
self.cancelButton.setToolTip(_translate("UdsActorSetupDialog", "Cancel all changes and discard them", None))
|
||||
self.cancelButton.setWhatsThis(_translate("UdsActorSetupDialog", "Discards all changes and closes the configuration window", None))
|
||||
self.cancelButton.setText(_translate("UdsActorSetupDialog", "Cancel && Discard", None))
|
||||
self.label.setText(_translate("UdsActorSetupDialog", "UDS Server Host", None))
|
||||
self.host.setToolTip(_translate("UdsActorSetupDialog", "Uds Broker Server Addres. Use IP or FQDN", None))
|
||||
self.host.setWhatsThis(_translate("UdsActorSetupDialog", "Enter here the UDS Broker Addres using either its IP address or its FQDN address", None))
|
||||
self.label_3.setText(_translate("UdsActorSetupDialog", "UDS Master Key", None))
|
||||
self.masterKey.setToolTip(_translate("UdsActorSetupDialog", "Master key to communicate with UDS Broker", None))
|
||||
self.masterKey.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Enter the Master Key (found on<span style=\" font-weight:600;\"> UDS Configuration</span> section) of the UDS Broker to allow communication of the Actor with Broker</p></body></html>", None))
|
||||
self.label_4.setText(_translate("UdsActorSetupDialog", "Security", None))
|
||||
self.useSSl.setToolTip(_translate("UdsActorSetupDialog", "Select communication security with broker", None))
|
||||
self.useSSl.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Select the security for communications with UDS Broker.</p><p>The recommended method of communication is <span style=\" font-weight:600;\">Use SSL</span>, but selection needs to be acording to your broker configuration.</p></body></html>", None))
|
||||
self.useSSl.setItemText(0, _translate("UdsActorSetupDialog", "Do not use SSL", None))
|
||||
self.useSSl.setItemText(1, _translate("UdsActorSetupDialog", "Use SSL", None))
|
||||
self.logLevelLabel.setText(_translate("UdsActorSetupDialog", "Log Level", None))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
UdsActorSetupDialog = QtGui.QDialog()
|
||||
ui = Ui_UdsActorSetupDialog()
|
||||
ui.setupUi(UdsActorSetupDialog)
|
||||
UdsActorSetupDialog.show()
|
||||
sys.exit(app.exec_())
|
||||
|
215
actors/src/test.py
Normal file
215
actors/src/test.py
Normal file
@@ -0,0 +1,215 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import urllib3
|
||||
from udsactor import operations
|
||||
from udsactor import store
|
||||
from udsactor import REST
|
||||
from udsactor import ipc
|
||||
from udsactor import httpserver
|
||||
|
||||
from time import sleep
|
||||
|
||||
import random
|
||||
import requests
|
||||
import json
|
||||
import logging
|
||||
|
||||
|
||||
def testRest():
|
||||
# cfg = store.readConfig()
|
||||
cfg = {'host': '172.27.0.1:8000', 'masterKey': '8f914604ad2c5c558575856299866bbb', 'ssl': False}
|
||||
print(cfg)
|
||||
print("Intefaces: ", list(operations.getNetworkInfo()))
|
||||
print("Joined Domain: ", operations.getDomainName())
|
||||
|
||||
# renameComputer('win7-64')
|
||||
# joinDomain('dom.dkmon.com', 'ou=pruebas_2,dc=dom,dc=dkmon,dc=com', 'administrador@dom.dkmon.com', 'Temporal2012', True)
|
||||
# reboot()
|
||||
r = REST.Api(cfg['host'], cfg['masterKey'], cfg['ssl'], scrambledResponses=True)
|
||||
print("Connected: {}".format(r.isConnected))
|
||||
r.test()
|
||||
try:
|
||||
r.init('02:46:00:00:00:07')
|
||||
except REST.UnmanagedHostError:
|
||||
print('Unmanaged host (confirmed)')
|
||||
|
||||
uuid = r.init('02:46:00:00:00:08')
|
||||
print("Notify comm:", r.notifyComm('http://172.27.0.1:8000/'))
|
||||
|
||||
print("Connected: {}".format(r.isConnected))
|
||||
|
||||
print('uuid = {}'.format(uuid))
|
||||
|
||||
# print 'Login: {}'.format(r.login('test-user'))
|
||||
# print 'Logout: {}'.format(r.logout('test-user'))
|
||||
print("Information: >>{}<<".format(r.information()))
|
||||
print("Login: >>{}<<".format(r.login('Pepito')))
|
||||
|
||||
print(r.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()]))
|
||||
print(r.log(10000, 'Test error message'))
|
||||
|
||||
|
||||
def ipcTest():
|
||||
s = ipc.ServerIPC(39188) # I have got the enterprise number for Virtual Cable. This number is not about ports, but as good as any other selection :)
|
||||
|
||||
s.start()
|
||||
|
||||
sleep(1)
|
||||
|
||||
client = ipc.ClientIPC(39188)
|
||||
client.start()
|
||||
client2 = ipc.ClientIPC(39188)
|
||||
client2.start()
|
||||
|
||||
print("Requesting information")
|
||||
client.requestInformation()
|
||||
print("Sending login info")
|
||||
client.sendLogin('user1')
|
||||
print("Sending logout info")
|
||||
client.sendLogout('mariete' * 1000)
|
||||
|
||||
print('Sending message')
|
||||
s.sendMessage(ipc.MSG_LOGOFF, None)
|
||||
s.sendMessage(ipc.MSG_MESSAGE, 'Cierra la sesión')
|
||||
s.sendMessage(33, 'invalid')
|
||||
s.sendMessage(ipc.MSG_SCRIPT, 'print "hello"')
|
||||
print('Message sent')
|
||||
|
||||
for c in (client, client2):
|
||||
print(c.getMessage())
|
||||
print(c.getMessage())
|
||||
print(c.getMessage())
|
||||
|
||||
client.stop()
|
||||
client.join()
|
||||
|
||||
s.sendMessage(ipc.MSG_LOGOFF, None)
|
||||
s.sendMessage(ipc.MSG_MESSAGE, 'Cierra la sesión')
|
||||
s.sendMessage(33, 'invalid')
|
||||
s.sendMessage(ipc.MSG_SCRIPT, 'print "hello"')
|
||||
|
||||
print(client2.getMessage())
|
||||
print(client2.getMessage())
|
||||
print(client2.getMessage())
|
||||
|
||||
client2.stop()
|
||||
s.stop()
|
||||
client2.join()
|
||||
s.join()
|
||||
|
||||
|
||||
def ipcServer():
|
||||
s = ipc.ServerIPC(39188, {'idle': 180}) # I have got the enterprise number for Virtual Cable. This number is not about ports, but as good as any other selection :)
|
||||
|
||||
s.start()
|
||||
|
||||
counter = 0
|
||||
while True:
|
||||
try:
|
||||
counter += 1
|
||||
print("Sending new message {}".format(counter))
|
||||
s.sendMessage(ipc.MSG_MESSAGE, 'This is a test message ñöitó 33.3€ {}'.format(counter))
|
||||
counter += 1
|
||||
s.sendMessage(ipc.MSG_SCRIPT, 'print "This is a test message ñöitó 33.3€ {}"'.format(counter))
|
||||
counter += 1
|
||||
s.sendMessage(ipc.MSG_LOGOFF, None)
|
||||
sleep(1)
|
||||
except:
|
||||
break
|
||||
|
||||
s.stop()
|
||||
|
||||
|
||||
def testIdle():
|
||||
for _ in range(1, 10):
|
||||
print(operations.getIdleDuration())
|
||||
sleep(1)
|
||||
|
||||
|
||||
def testServer():
|
||||
|
||||
# Disable verify warinings
|
||||
logging.getLogger("requests").setLevel(logging.ERROR)
|
||||
urllib3.disable_warnings() # @UndefinedVariable
|
||||
|
||||
s = ipc.ServerIPC(39188) # I have got the enterprise number for Virtual Cable. This number is not about ports, but as good as any other selection :)
|
||||
|
||||
s.start()
|
||||
|
||||
client = ipc.ClientIPC(39188)
|
||||
client.start()
|
||||
|
||||
while True:
|
||||
try:
|
||||
port = random.randrange(32000, 64000)
|
||||
server = httpserver.HTTPServerThread(('172.27.0.8', port), s)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
serverUrl = server.getServerUrl()
|
||||
server.start()
|
||||
|
||||
print(serverUrl)
|
||||
|
||||
res = requests.post(serverUrl + '/message', data=json.dumps({'message': 'Test message'}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.post(serverUrl + '/script', data=json.dumps({'script': 'import time\ntime.sleep(1)\nfor v in xrange(10): print "Hello world, this is an script"'}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.post(serverUrl + '/script', data=json.dumps({'script': 'print "Hello world, this is an script"', 'user': True}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.get(serverUrl + '/information?param1=1¶m2=2', headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
print("Messages:")
|
||||
print(client.getMessage())
|
||||
print(client.getMessage())
|
||||
|
||||
# try:
|
||||
# while True:
|
||||
# Sleep(1000)
|
||||
# except:
|
||||
# pass
|
||||
|
||||
server.stop()
|
||||
s.stop()
|
||||
client.stop()
|
||||
|
||||
|
||||
def testRemote():
|
||||
serverUrl = "https://172.27.0.208:52562/633a1245873848b7b4017c23283bc195"
|
||||
print(serverUrl)
|
||||
|
||||
res = requests.post(serverUrl + '/message', data=json.dumps({'message': 'Test message'}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.post(serverUrl + '/script', data=json.dumps({'script': 'import time\ntime.sleep(1)\nfor v in xrange(10): print "Hello world, this is an script"'}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.post(serverUrl + '/script', data=json.dumps({'script': 'print "Hello world, this is an script"', 'user': True}), headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
res = requests.get(serverUrl + '/information?param1=1¶m2=2', headers={'content-type': 'application/json'}, verify=False)
|
||||
print(res)
|
||||
print(res.json())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# ipcServer()
|
||||
# ipcTest()
|
||||
testRest()
|
||||
# testIdle()
|
||||
# testServer()
|
||||
# testRemote()
|
||||
|
237
actors/src/udsactor/REST.py
Normal file
237
actors/src/udsactor/REST.py
Normal file
@@ -0,0 +1,237 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 201 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
|
||||
# pylint: disable-msg=E1101,W0703
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import requests
|
||||
import logging
|
||||
import json
|
||||
import uuid
|
||||
import six
|
||||
import warnings
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
from udsactor import VERSION
|
||||
from .utils import exceptionToMessage
|
||||
|
||||
VERIFY_CERT = False
|
||||
|
||||
|
||||
class RESTError(Exception):
|
||||
ERRCODE = 0
|
||||
|
||||
|
||||
class ConnectionError(RESTError):
|
||||
ERRCODE = -1
|
||||
|
||||
|
||||
# Errors ""raised"" from broker
|
||||
class InvalidKeyError(RESTError):
|
||||
ERRCODE = 1
|
||||
|
||||
|
||||
class UnmanagedHostError(RESTError):
|
||||
ERRCODE = 2
|
||||
|
||||
|
||||
class UserServiceNotFoundError(RESTError):
|
||||
ERRCODE = 3
|
||||
|
||||
|
||||
class OsManagerError(RESTError):
|
||||
ERRCODE = 4
|
||||
|
||||
|
||||
# Disable warnings log messages
|
||||
try:
|
||||
import urllib3 # @UnusedImport
|
||||
except Exception:
|
||||
from requests.packages import urllib3 # @Reimport
|
||||
|
||||
try:
|
||||
urllib3.disable_warnings() # @UndefinedVariable
|
||||
warnings.simplefilter("ignore")
|
||||
except Exception:
|
||||
pass # In fact, isn't too important, but wil log warns to logging file
|
||||
|
||||
|
||||
def ensureResultIsOk(result):
|
||||
if 'error' not in result:
|
||||
return
|
||||
|
||||
for i in (InvalidKeyError, UnmanagedHostError, UserServiceNotFoundError, OsManagerError):
|
||||
if result['error'] == i.ERRCODE:
|
||||
raise i(result['result'])
|
||||
|
||||
err = RESTError(result['result'])
|
||||
err.ERRCODE = result['error']
|
||||
raise err
|
||||
|
||||
|
||||
class Api(object):
|
||||
def __init__(self, host, masterKey, ssl):
|
||||
self.host = host
|
||||
self.masterKey = masterKey
|
||||
self.useSSL = True if ssl else False
|
||||
self.uuid = None
|
||||
self.mac = None
|
||||
self.url = "{}://{}/rest/actor/".format(('http', 'https')[self.useSSL], self.host)
|
||||
self.idle = None
|
||||
self.maxSession = None
|
||||
self.secretKey = six.text_type(uuid.uuid4())
|
||||
try:
|
||||
self.newerRequestLib = requests.__version__.split('.')[0] >= '1'
|
||||
except Exception:
|
||||
self.newerRequestLib = False # I no version, guess this must be an old requests
|
||||
|
||||
# Disable logging requests messages except for errors, ...
|
||||
logging.getLogger("requests").setLevel(logging.CRITICAL)
|
||||
# Tries to disable all warnings
|
||||
try:
|
||||
warnings.simplefilter("ignore") # Disables all warnings
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _getUrl(self, method, key=None, ids=None):
|
||||
url = self.url + method
|
||||
params = []
|
||||
if key is not None:
|
||||
params.append('key=' + key)
|
||||
if ids is not None:
|
||||
params.append('id=' + ids)
|
||||
params.append('version=' + VERSION)
|
||||
|
||||
if len(params) > 0:
|
||||
url += '?' + '&'.join(params)
|
||||
|
||||
return url
|
||||
|
||||
def _request(self, url, data=None):
|
||||
try:
|
||||
if data is None:
|
||||
# Old requests version does not support verify, but they do not checks ssl certificate by default
|
||||
if self.newerRequestLib:
|
||||
r = requests.get(url, verify=VERIFY_CERT)
|
||||
else:
|
||||
logger.debug('Requesting with old')
|
||||
r = requests.get(url) # Always ignore certs??
|
||||
else:
|
||||
if self.newerRequestLib:
|
||||
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, verify=VERIFY_CERT)
|
||||
else:
|
||||
logger.debug('Requesting with old')
|
||||
r = requests.post(url, data=data, headers={'content-type': 'application/json'})
|
||||
|
||||
r = json.loads(r.content) # Using instead of r.json() to make compatible with oooold rquests lib versions
|
||||
except requests.exceptions.RequestException as e:
|
||||
raise ConnectionError(e)
|
||||
except Exception as e:
|
||||
raise ConnectionError(exceptionToMessage(e))
|
||||
|
||||
ensureResultIsOk(r)
|
||||
|
||||
return r
|
||||
|
||||
@property
|
||||
def isConnected(self):
|
||||
return self.uuid is not None
|
||||
|
||||
def test(self):
|
||||
url = self._getUrl('test', self.masterKey)
|
||||
return self._request(url)['result']
|
||||
|
||||
def init(self, ids):
|
||||
'''
|
||||
Ids is a comma separated values indicating MAC=ip
|
||||
Server returns:
|
||||
uuid, mac
|
||||
Optionally can return an third parameter, that is max "idle" request time
|
||||
'''
|
||||
logger.debug('Invoking init')
|
||||
url = self._getUrl('init', key=self.masterKey, ids=ids)
|
||||
res = self._request(url)['result']
|
||||
logger.debug('Got response parameters: {}'.format(res))
|
||||
self.uuid, self.mac = res[0:2]
|
||||
# Optional idle parameter
|
||||
try:
|
||||
self.idle = int(res[2])
|
||||
if self.idle < 30:
|
||||
self.idle = None # No values under 30 seconds are allowed :)
|
||||
except Exception:
|
||||
self.idle = None
|
||||
|
||||
return self.uuid
|
||||
|
||||
def postMessage(self, msg, data, processData=True):
|
||||
logger.debug('Invoking post message {} with data {}'.format(msg, data))
|
||||
|
||||
if self.uuid is None:
|
||||
raise ConnectionError('REST api has not been initialized')
|
||||
|
||||
if processData:
|
||||
data = json.dumps({'data': data})
|
||||
url = self._getUrl('/'.join([self.uuid, msg]))
|
||||
return self._request(url, data)['result']
|
||||
|
||||
def notifyComm(self, url):
|
||||
logger.debug('Notifying comms {}'.format(url))
|
||||
return self.postMessage('notifyComms', url)
|
||||
|
||||
def login(self, username):
|
||||
logger.debug('Notifying login {}'.format(username))
|
||||
return self.postMessage('login', username)
|
||||
|
||||
def logout(self, username):
|
||||
logger.debug('Notifying logout {}'.format(username))
|
||||
return self.postMessage('logout', username)
|
||||
|
||||
def information(self):
|
||||
logger.debug('Requesting information'.format())
|
||||
return self.postMessage('information', '')
|
||||
|
||||
def setReady(self, ipsInfo):
|
||||
logger.debug('Notifying readyness: {}'.format(ipsInfo))
|
||||
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
|
||||
return self.postMessage('ready', data)
|
||||
|
||||
def notifyIpChanges(self, ipsInfo):
|
||||
logger.debug('Notifying ip changes: {}'.format(ipsInfo))
|
||||
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
|
||||
return self.postMessage('ip', data)
|
||||
|
||||
def log(self, logLevel, message):
|
||||
data = json.dumps({'message': message, 'level': logLevel})
|
||||
return self.postMessage('log', data, processData=False)
|
||||
|
54
actors/src/udsactor/__init__.py
Normal file
54
actors/src/udsactor/__init__.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# On centos, old six release does not includes byte2int, nor six.PY2
|
||||
import six
|
||||
|
||||
VERSION = '2.0.0'
|
||||
|
||||
__title__ = 'udsactor'
|
||||
__version__ = VERSION
|
||||
__build__ = 0x010750
|
||||
__author__ = 'Adolfo Gómez <dkmaster@dkmon.com>'
|
||||
__license__ = "BSD 3-clause"
|
||||
__copyright__ = "Copyright 2014-2016 VirtualCable S.L.U."
|
||||
|
||||
|
||||
if not hasattr(six, 'byte2int'):
|
||||
if six.PY3:
|
||||
import operator
|
||||
six.byte2int = operator.itemgetter(0)
|
||||
else:
|
||||
def _byte2int(bs):
|
||||
return ord(bs[0])
|
||||
six.byte2int = _byte2int
|
101
actors/src/udsactor/certs.py
Normal file
101
actors/src/udsactor/certs.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
|
||||
from tempfile import gettempdir
|
||||
from os.path import exists, join
|
||||
|
||||
CERTFILE = 'UDSActor.pem'
|
||||
|
||||
|
||||
def createSelfSignedCert(force=False):
|
||||
|
||||
certFile = join(gettempdir(), CERTFILE)
|
||||
|
||||
if exists(certFile) and not force:
|
||||
return certFile
|
||||
|
||||
certData = '''-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCb50K3mIznNklz
|
||||
yVAD7xSQOSJQ6+NPXj7U9/4zLZ+TvmbQ7RqUUsxbfxHbeRnoYTWV2nKk4+tHqmvz
|
||||
ujLSS/loFhTSMqtrLn7rowSYJoQhKOUkAiQlWkqCfItWgL5pJopDpNHFul9Rn3ds
|
||||
PMWQTiGeUNR4Y3RnBhr1Q1BsqAzf4m6zFUmgLPPmVLdF4uJ3Tuz8TSy2gWLs5aSr
|
||||
5do4WamwUfYjRSVMJECmwjUM4rQ8SQgg0sHBeBuDUGNBvBQFac1G7qUcMReeu8Zr
|
||||
DUtMsXma/l4rA8NB5CRmTrQbTBF4l+jb2BDFebDqDUK1Oqs9X35yOQfDOAFYHiix
|
||||
PX0IsXOZAgMBAAECggEBAJi3000RrIUZUp6Ph0gzPMuCjDEEwWiQA7CPNX1gpb8O
|
||||
dp0WhkDhUroWIaICYPSXtOwUTtVjRqivMoxPy1Thg3EIoGC/rdeSdlXRHMEGicwJ
|
||||
yVyalFnatr5Xzg5wkxVh4XMd0zeDt7e3JD7s0QLo5lm1CEzd77qz6lhzFic5/1KX
|
||||
bzdULtTlq60dazg2hEbcS4OmM1UMCtRVDAsOIUIZPL0M9j1C1d1iEdYnh2xshKeG
|
||||
/GOfo95xsgdMlGjtv3hUT5ryKVoEsu+36rGb4VfhPfUvvoVbRx5QZpW+QvxaYh5E
|
||||
Fi0JEROozFwG31Y++8El7J3yQko8cFBa1lYYUwwpNAECgYEAykT+GiM2YxJ4uVF1
|
||||
OoKiE9BD53i0IG5j87lGPnWqzEwYBwnqjEKDTou+uzMGz3MDV56UEFNho7wUWh28
|
||||
LpEkjJB9QgbsugjxIBr4JoL/rYk036e/6+U8I95lvYWrzb+rBMIkRDYI7kbQD/mQ
|
||||
piYUpuCkTymNAu2RisK6bBzJslkCgYEAxVE23OQvkCeOV8hJNPZGpJ1mDS+TiOow
|
||||
oOScMZmZpail181eYbAfMsCr7ri812lSj98NvA2GNVLpddil6LtS1cQ5p36lFBtV
|
||||
xQUMZiFz4qVbEak+izL+vPaev/mXXsOcibAIQ+qI/0txFpNhJjpaaSy6vRCBYFmc
|
||||
8pgSoBnBI0ECgYAUKCn2atnpp5aWSTLYgNosBU4vDA1PShD14dnJMaqyr0aZtPhF
|
||||
v/8b3btFJoGgPMLxgWEZ+2U4ju6sSFhPf7FXvLJu2QfQRkHZRDbEh7t5DLpTK4Fp
|
||||
va9vl6Ml7uM/HsGpOLuqfIQJUs87OFCc7iCSvMJDDU37I7ekT2GKkpfbCQKBgBrE
|
||||
0NeY0WcSJrp7/oqD2sOcYurpCG/rrZs2SIZmGzUhMxaa0vIXzbO59dlWELB8pmnE
|
||||
Tf20K//x9qA5OxDe0PcVPukdQlH+/1zSOYNliG44FqnHtyd1TJ/gKVtMBiAiE4uO
|
||||
aSClod5Yosf4SJbCFd/s5Iyfv52NqsAyp1w3Aj/BAoGAVCnEiGUfyHlIR+UH4zZW
|
||||
GXJMeqdZLfcEIszMxLePkml4gUQhoq9oIs/Kw+L1DDxUwzkXN4BNTlFbOSu9gzK1
|
||||
dhuIUGfS6RPL88U+ivC3A0y2jT43oUMqe3hiRt360UQ1GXzp2dMnR9odSRB1wHoO
|
||||
IOjEBZ8341/c9ZHc5PCGAG8=
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID7zCCAtegAwIBAgIJAIrEIthCfxUCMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
|
||||
VQQGEwJFUzEPMA0GA1UECAwGTWFkcmlkMREwDwYDVQQHDAhBbGNvcmNvbjEMMAoG
|
||||
A1UECgwDVURTMQ4wDAYDVQQLDAVBY3RvcjESMBAGA1UEAwwJVURTIEFjdG9yMSgw
|
||||
JgYJKoZIhvcNAQkBFhlzdXBwb3J0QHVkc2VudGVycHJpc2UuY29tMB4XDTE0MTAy
|
||||
NjIzNDEyNFoXDTI0MTAyMzIzNDEyNFowgY0xCzAJBgNVBAYTAkVTMQ8wDQYDVQQI
|
||||
DAZNYWRyaWQxETAPBgNVBAcMCEFsY29yY29uMQwwCgYDVQQKDANVRFMxDjAMBgNV
|
||||
BAsMBUFjdG9yMRIwEAYDVQQDDAlVRFMgQWN0b3IxKDAmBgkqhkiG9w0BCQEWGXN1
|
||||
cHBvcnRAdWRzZW50ZXJwcmlzZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQCb50K3mIznNklzyVAD7xSQOSJQ6+NPXj7U9/4zLZ+TvmbQ7RqUUsxb
|
||||
fxHbeRnoYTWV2nKk4+tHqmvzujLSS/loFhTSMqtrLn7rowSYJoQhKOUkAiQlWkqC
|
||||
fItWgL5pJopDpNHFul9Rn3dsPMWQTiGeUNR4Y3RnBhr1Q1BsqAzf4m6zFUmgLPPm
|
||||
VLdF4uJ3Tuz8TSy2gWLs5aSr5do4WamwUfYjRSVMJECmwjUM4rQ8SQgg0sHBeBuD
|
||||
UGNBvBQFac1G7qUcMReeu8ZrDUtMsXma/l4rA8NB5CRmTrQbTBF4l+jb2BDFebDq
|
||||
DUK1Oqs9X35yOQfDOAFYHiixPX0IsXOZAgMBAAGjUDBOMB0GA1UdDgQWBBRShS90
|
||||
5lJTNvYPIEqP3GxWwG5iiDAfBgNVHSMEGDAWgBRShS905lJTNvYPIEqP3GxWwG5i
|
||||
iDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAU0Sp4gXhQmRVzq+7+
|
||||
vRFUkQuPj4Ga/d9r5Wrbg3hck3+5pwe9/7APoq0P/M0DBhQpiJKjrD6ydUevC+Y/
|
||||
43ZOJPhMlNw0o6TdQxOkX6FDwQanLLs7sfvJvqtVzYn3nuRFKT3dvl7Zg44QMw2M
|
||||
ay42q59fAcpB4LaDx/i7gOYSS5eca3lYW7j7YSr/+ozXK2KlgUkuCUHN95lOq+dF
|
||||
trmV9mjzM4CNPZqKSE7kpHRywgrXGPCO000NvEGSYf82AtgRSFKiU8NWLQSEPdcB
|
||||
k//2dsQZw2cRZ8DrC2B6Tb3M+3+CA6wVyqfqZh1SZva3LfGvq/C+u+ItguzPqNpI
|
||||
xtvM
|
||||
-----END CERTIFICATE-----'''
|
||||
with open(certFile, "wt") as f:
|
||||
f.write(certData)
|
||||
|
||||
return certFile
|
221
actors/src/udsactor/httpserver.py
Normal file
221
actors/src/udsactor/httpserver.py
Normal file
@@ -0,0 +1,221 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.log import logger
|
||||
from udsactor import utils
|
||||
from udsactor.certs import createSelfSignedCert
|
||||
from udsactor.scriptThread import ScriptExecutorThread
|
||||
|
||||
import threading
|
||||
import string
|
||||
import random
|
||||
import json
|
||||
import six
|
||||
from six.moves import socketserver # @UnresolvedImport, pylint: disable=import-error
|
||||
from six.moves import BaseHTTPServer # @UnresolvedImport, pylint: disable=import-error
|
||||
import time
|
||||
|
||||
import ssl
|
||||
|
||||
startTime = time.time()
|
||||
|
||||
|
||||
class HTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
protocol_version = 'HTTP/1.0'
|
||||
server_version = 'UDS Actor Server'
|
||||
sys_version = ''
|
||||
|
||||
uuid = None
|
||||
service = None
|
||||
lock = threading.Lock()
|
||||
|
||||
def sendJsonError(self, code, message):
|
||||
self.send_response(code)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({'error': message}))
|
||||
return
|
||||
|
||||
def sendJsonResponse(self, data):
|
||||
self.send_response(200)
|
||||
data = json.dumps(data)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.send_header('Content-Length', len(data))
|
||||
self.end_headers()
|
||||
# Send the html message
|
||||
self.wfile.write(data)
|
||||
|
||||
def do_GET(self):
|
||||
# Very simple path & params splitter
|
||||
path = self.path.split('?')[0][1:].split('/')
|
||||
try:
|
||||
params = dict((v.split('=') for v in self.path.split('?')[1].split('&')))
|
||||
except Exception:
|
||||
params = {}
|
||||
|
||||
if path[0] != HTTPServerHandler.uuid:
|
||||
self.sendJsonError(403, 'Forbidden')
|
||||
return
|
||||
|
||||
if len(path) != 2:
|
||||
self.sendJsonResponse("UDS Actor has been running for {} seconds".format(time.time() - startTime))
|
||||
return
|
||||
|
||||
try:
|
||||
operation = getattr(self, 'get_' + path[1])
|
||||
result = operation(params) # Protect not POST methods
|
||||
except AttributeError:
|
||||
self.sendJsonError(404, 'Method not found')
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing GET {}: {}'.format(path[1], utils.toUnicode(e.message)))
|
||||
self.sendJsonError(500, str(e))
|
||||
return
|
||||
|
||||
self.sendJsonResponse(result)
|
||||
|
||||
def do_POST(self):
|
||||
path = self.path.split('?')[0][1:].split('/')
|
||||
if path[0] != HTTPServerHandler.uuid:
|
||||
self.sendJsonError(403, 'Forbidden')
|
||||
return
|
||||
|
||||
if len(path) != 2:
|
||||
self.sendJsonError(400, 'Invalid request')
|
||||
return
|
||||
|
||||
try:
|
||||
HTTPServerHandler.lock.acquire()
|
||||
length = int(self.headers.getheader('content-length'))
|
||||
content = self.rfile.read(length)
|
||||
logger.debug('length: {}, content >>{}<<'.format(length, content))
|
||||
params = json.loads(content)
|
||||
|
||||
operation = getattr(self, 'post_' + path[1])
|
||||
result = operation(params) # Protect not POST methods
|
||||
except AttributeError:
|
||||
self.sendJsonError(404, 'Method not found')
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing POST {}: {}'.format(path[1], utils.toUnicode(e.message)))
|
||||
self.sendJsonError(500, str(e))
|
||||
return
|
||||
finally:
|
||||
HTTPServerHandler.lock.release()
|
||||
|
||||
self.sendJsonResponse(result)
|
||||
|
||||
def post_logoff(self, params):
|
||||
logger.debug('Sending LOGOFF to clients')
|
||||
HTTPServerHandler.service.ipc.sendLoggofMessage()
|
||||
return 'ok'
|
||||
|
||||
# Alias
|
||||
post_logout = post_logoff
|
||||
|
||||
def post_message(self, params):
|
||||
logger.debug('Sending MESSAGE to clients')
|
||||
if 'message' not in params:
|
||||
raise Exception('Invalid message parameters')
|
||||
HTTPServerHandler.service.ipc.sendMessageMessage(params['message'])
|
||||
return 'ok'
|
||||
|
||||
def post_script(self, params):
|
||||
logger.debug('Received script: {}'.format(params))
|
||||
if 'script' not in params:
|
||||
raise Exception('Invalid script parameters')
|
||||
if 'user' in params:
|
||||
logger.debug('Sending SCRIPT to clients')
|
||||
HTTPServerHandler.service.ipc.sendScriptMessage(params['script'])
|
||||
else:
|
||||
# Execute script at server space, that is, here
|
||||
# as a secondary thread
|
||||
th = ScriptExecutorThread(params['script'])
|
||||
th.start()
|
||||
return 'ok'
|
||||
|
||||
def post_preConnect(self, params):
|
||||
logger.debug('Received Pre connection')
|
||||
if 'user' not in params or 'protocol' not in params:
|
||||
raise Exception('Invalid preConnect parameters')
|
||||
return HTTPServerHandler.service.preConnect(params.get('user'), params.get('protocol'))
|
||||
|
||||
def get_information(self, params):
|
||||
# TODO: Return something useful? :)
|
||||
return 'Up and running'
|
||||
|
||||
def get_uuid(self, params):
|
||||
return self.service.api.uuid
|
||||
|
||||
def log_error(self, fmt, *args):
|
||||
logger.error('HTTP ' + fmt % args)
|
||||
|
||||
def log_message(self, fmt, *args):
|
||||
logger.info('HTTP ' + fmt % args)
|
||||
|
||||
|
||||
class HTTPServerThread(threading.Thread):
|
||||
def __init__(self, address, service):
|
||||
super(self.__class__, self).__init__()
|
||||
|
||||
if HTTPServerHandler.uuid is None:
|
||||
HTTPServerHandler.uuid = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(48))
|
||||
|
||||
self.certFile = createSelfSignedCert()
|
||||
HTTPServerHandler.service = service
|
||||
|
||||
self.initiateServer(address)
|
||||
|
||||
|
||||
def initiateServer(self, address):
|
||||
self.server = socketserver.TCPServer(address, HTTPServerHandler)
|
||||
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.certFile, server_side=True)
|
||||
|
||||
def getServerUrl(self):
|
||||
return 'https://{}:{}/{}'.format(self.server.server_address[0], self.server.server_address[1], HTTPServerHandler.uuid)
|
||||
|
||||
def stop(self):
|
||||
logger.debug('Stopping REST Service')
|
||||
self.server.shutdown()
|
||||
|
||||
def restart(self, address=None):
|
||||
|
||||
if address is None:
|
||||
address = self.server.server_address
|
||||
|
||||
self.stop()
|
||||
|
||||
self.initiateServer(address)
|
||||
|
||||
def run(self):
|
||||
self.server.serve_forever()
|
421
actors/src/udsactor/ipc.py
Normal file
421
actors/src/udsactor/ipc.py
Normal file
@@ -0,0 +1,421 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import socket
|
||||
import threading
|
||||
import sys
|
||||
import six
|
||||
import traceback
|
||||
import pickle
|
||||
|
||||
from udsactor.utils import toUnicode
|
||||
from udsactor.log import logger
|
||||
|
||||
# The IPC Server will wait for connections from clients
|
||||
# Clients will open socket, and wait for data from server
|
||||
# The messages sent (from server) will be the following (subject to future changes):
|
||||
# Message_id Data Action
|
||||
# ------------ -------- --------------------------
|
||||
# MSG_LOGOFF None Logout user from session
|
||||
# MSG_MESSAGE message,level Display a message with level (INFO, WARN, ERROR, FATAL) # TODO: Include level, right now only has message
|
||||
# MSG_SCRIPT python script Execute an specific python script INSIDE CLIENT environment (this messages is not sent right now)
|
||||
# The messages received (sent from client) will be the following:
|
||||
# Message_id Data Action
|
||||
# ------------ -------- --------------------------
|
||||
# REQ_LOGOUT Logout user from session
|
||||
# REQ_INFORMATION None Request information from ipc server (maybe configuration parameters in a near future)
|
||||
# REQ_LOGIN python script Execute an specific python script INSIDE CLIENT environment (this messages is not sent right now)
|
||||
#
|
||||
# All messages are in the form:
|
||||
# BYTE
|
||||
# 0 1-2 3 4 ...
|
||||
# MSG_ID DATA_LENGTH (little endian) Data (can be 0 length)
|
||||
# With a previos "MAGIC" header in fron of each message
|
||||
|
||||
MSG_LOGOFF = 0xA1
|
||||
MSG_MESSAGE = 0xB2
|
||||
MSG_SCRIPT = 0xC3
|
||||
MSG_INFORMATION = 0xD4
|
||||
|
||||
# Request messages
|
||||
REQ_INFORMATION = MSG_INFORMATION
|
||||
REQ_LOGIN = 0xE5
|
||||
REQ_LOGOUT = MSG_LOGOFF
|
||||
|
||||
VALID_MESSAGES = (MSG_LOGOFF, MSG_MESSAGE, MSG_SCRIPT, MSG_INFORMATION)
|
||||
|
||||
REQ_INFORMATION = 0xAA
|
||||
|
||||
# Reverse msgs dict for debugging
|
||||
REV_DICT = {
|
||||
MSG_LOGOFF: 'MSG_LOGOFF',
|
||||
MSG_MESSAGE: 'MSG_MESSAGE',
|
||||
MSG_SCRIPT: 'MSG_SCRIPT',
|
||||
MSG_INFORMATION: 'MSG_INFORMATION',
|
||||
REQ_LOGIN: 'REQ_LOGIN',
|
||||
REQ_LOGOUT: 'REQ_LOGOUT'
|
||||
}
|
||||
|
||||
MAGIC = b'\x55\x44\x53\x00' # UDS in hexa with a padded 0 to the right
|
||||
|
||||
|
||||
# Allows notifying login/logout from client for linux platform
|
||||
ALLOW_LOG_METHODS = sys.platform != 'win32'
|
||||
|
||||
|
||||
# States for client processor
|
||||
ST_SECOND_BYTE = 0x01
|
||||
ST_RECEIVING = 0x02
|
||||
ST_PROCESS_MESSAGE = 0x02
|
||||
|
||||
|
||||
class ClientProcessor(threading.Thread):
|
||||
def __init__(self, parent, clientSocket):
|
||||
super(self.__class__, self).__init__()
|
||||
self.parent = parent
|
||||
self.clientSocket = clientSocket
|
||||
self.running = False
|
||||
self.messages = six.moves.queue.Queue(32) # @UndefinedVariable
|
||||
|
||||
def stop(self):
|
||||
logger.debug('Stoping client processor')
|
||||
self.running = False
|
||||
|
||||
def processRequest(self, msg, data):
|
||||
logger.debug('Got Client message {}={}'.format(msg, REV_DICT.get(msg)))
|
||||
if self.parent.clientMessageProcessor is not None:
|
||||
self.parent.clientMessageProcessor(msg, data)
|
||||
|
||||
def run(self):
|
||||
self.running = True
|
||||
self.clientSocket.setblocking(0)
|
||||
|
||||
state = None
|
||||
recv_msg = None
|
||||
recv_data = None
|
||||
while self.running:
|
||||
try:
|
||||
counter = 1024
|
||||
while counter > 0: # So we process at least the incoming queue every XX bytes readed
|
||||
counter -= 1
|
||||
b = self.clientSocket.recv(1)
|
||||
if b == b'':
|
||||
# Client disconnected
|
||||
self.running = False
|
||||
break
|
||||
buf = six.byte2int(b) # Empty buffer, this is set as non-blocking
|
||||
if state is None:
|
||||
if buf in (REQ_INFORMATION, REQ_LOGIN, REQ_LOGOUT):
|
||||
logger.debug('State set to {}'.format(buf))
|
||||
state = buf
|
||||
recv_msg = buf
|
||||
continue # Get next byte
|
||||
else:
|
||||
logger.debug('Got unexpected data {}'.format(buf))
|
||||
elif state in (REQ_INFORMATION, REQ_LOGIN, REQ_LOGOUT):
|
||||
logger.debug('First length byte is {}'.format(buf))
|
||||
msg_len = buf
|
||||
state = ST_SECOND_BYTE
|
||||
continue
|
||||
elif state == ST_SECOND_BYTE:
|
||||
msg_len += buf << 8
|
||||
logger.debug('Second length byte is {}, len is {}'.format(buf, msg_len))
|
||||
if msg_len == 0:
|
||||
self.processRequest(recv_msg, None)
|
||||
state = None
|
||||
break
|
||||
state = ST_RECEIVING
|
||||
recv_data = b''
|
||||
continue
|
||||
elif state == ST_RECEIVING:
|
||||
recv_data += six.int2byte(buf)
|
||||
msg_len -= 1
|
||||
if msg_len == 0:
|
||||
self.processRequest(recv_msg, recv_data)
|
||||
recv_data = None
|
||||
state = None
|
||||
break
|
||||
else:
|
||||
logger.debug('Got invalid message from request: {}, state: {}'.format(buf, state))
|
||||
except socket.error as e:
|
||||
# If no data is present, no problem at all, pass to check messages
|
||||
pass
|
||||
except Exception as e:
|
||||
tb = traceback.format_exc()
|
||||
logger.error('Error: {}, trace: {}'.format(e, tb))
|
||||
|
||||
if self.running is False:
|
||||
break
|
||||
|
||||
try:
|
||||
msg = self.messages.get(block=True, timeout=1)
|
||||
except six.moves.queue.Empty: # No message got in time @UndefinedVariable
|
||||
continue
|
||||
|
||||
logger.debug('Got message {}={}'.format(msg, REV_DICT.get(msg)))
|
||||
|
||||
try:
|
||||
m = msg[1] if msg[1] is not None else b''
|
||||
l = len(m)
|
||||
data = MAGIC + six.int2byte(msg[0]) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + m
|
||||
try:
|
||||
self.clientSocket.sendall(data)
|
||||
except socket.error as e:
|
||||
# Send data error
|
||||
logger.debug('Socket connection is no more available: {}'.format(e.args))
|
||||
self.running = False
|
||||
except Exception as e:
|
||||
logger.error('Invalid message in queue: {}'.format(e))
|
||||
|
||||
logger.debug('Client processor stopped')
|
||||
try:
|
||||
self.clientSocket.close()
|
||||
except Exception:
|
||||
pass # If can't close, nothing happens, just end thread
|
||||
|
||||
|
||||
class ServerIPC(threading.Thread):
|
||||
|
||||
def __init__(self, listenPort, clientMessageProcessor=None):
|
||||
super(self.__class__, self).__init__()
|
||||
self.port = listenPort
|
||||
self.running = False
|
||||
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.threads = []
|
||||
self.clientMessageProcessor = clientMessageProcessor
|
||||
|
||||
def stop(self):
|
||||
logger.debug('Stopping Server IPC')
|
||||
self.running = False
|
||||
for t in self.threads:
|
||||
t.stop()
|
||||
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(('localhost', self.port))
|
||||
self.serverSocket.close()
|
||||
|
||||
for t in self.threads:
|
||||
t.join()
|
||||
|
||||
def sendMessage(self, msgId, msgData):
|
||||
'''
|
||||
Notify message to all listening threads
|
||||
'''
|
||||
logger.debug('Sending message {}({}),{} to all clients'.format(msgId, REV_DICT.get(msgId), msgData))
|
||||
|
||||
# Convert to bytes so length is correctly calculated
|
||||
if isinstance(msgData, six.text_type):
|
||||
msgData = msgData.encode('utf8')
|
||||
|
||||
for t in self.threads:
|
||||
if t.isAlive():
|
||||
logger.debug('Sending to {}'.format(t))
|
||||
t.messages.put((msgId, msgData))
|
||||
|
||||
def sendLoggofMessage(self):
|
||||
self.sendMessage(MSG_LOGOFF, '')
|
||||
|
||||
def sendMessageMessage(self, message):
|
||||
self.sendMessage(MSG_MESSAGE, message)
|
||||
|
||||
def sendScriptMessage(self, script):
|
||||
self.sendMessage(MSG_SCRIPT, script)
|
||||
|
||||
def sendInformationMessage(self, info):
|
||||
self.sendMessage(MSG_INFORMATION, pickle.dumps(info))
|
||||
|
||||
def cleanupFinishedThreads(self):
|
||||
'''
|
||||
Cleans up current threads list
|
||||
'''
|
||||
aliveThreads = []
|
||||
for t in self.threads:
|
||||
if t.isAlive():
|
||||
logger.debug('Thread {} is alive'.format(t))
|
||||
aliveThreads.append(t)
|
||||
self.threads[:] = aliveThreads
|
||||
|
||||
def run(self):
|
||||
self.running = True
|
||||
|
||||
self.serverSocket.bind(('localhost', self.port))
|
||||
self.serverSocket.setblocking(1)
|
||||
self.serverSocket.listen(4)
|
||||
|
||||
while True:
|
||||
try:
|
||||
(clientSocket, address) = self.serverSocket.accept()
|
||||
# Stop processing if thread is mean to stop
|
||||
if self.running is False:
|
||||
break
|
||||
logger.debug('Got connection from {}'.format(address))
|
||||
|
||||
self.cleanupFinishedThreads() # House keeping
|
||||
|
||||
logger.debug('Starting new thread, current: {}'.format(self.threads))
|
||||
t = ClientProcessor(self, clientSocket)
|
||||
self.threads.append(t)
|
||||
t.start()
|
||||
except Exception as e:
|
||||
logger.error('Got an exception on Server ipc thread: {}'.format(e))
|
||||
|
||||
|
||||
class ClientIPC(threading.Thread):
|
||||
def __init__(self, listenPort):
|
||||
super(ClientIPC, self).__init__()
|
||||
self.port = listenPort
|
||||
self.running = False
|
||||
self.clientSocket = None
|
||||
self.messages = six.moves.queue.Queue(32) # @UndefinedVariable
|
||||
|
||||
self.connect()
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
def getMessage(self):
|
||||
while self.running:
|
||||
try:
|
||||
return self.messages.get(timeout=1)
|
||||
except six.moves.queue.Empty: # @UndefinedVariable
|
||||
continue
|
||||
|
||||
return None
|
||||
|
||||
def sendRequestMessage(self, msg, data=None):
|
||||
logger.debug('Sending request for msg: {}({}), {}'.format(msg, REV_DICT.get(msg), data))
|
||||
if data is None:
|
||||
data = b''
|
||||
|
||||
if isinstance(data, six.text_type): # Convert to bytes if necessary
|
||||
data = data.encode('utf-8')
|
||||
|
||||
l = len(data)
|
||||
msg = six.int2byte(msg) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + data
|
||||
self.clientSocket.sendall(msg)
|
||||
|
||||
def requestInformation(self):
|
||||
self.sendRequestMessage(REQ_INFORMATION)
|
||||
|
||||
def sendLogin(self, username):
|
||||
self.sendRequestMessage(REQ_LOGIN, username)
|
||||
|
||||
def sendLogout(self, username):
|
||||
self.sendRequestMessage(REQ_LOGOUT, username)
|
||||
|
||||
def messageReceived(self):
|
||||
'''
|
||||
Override this method to automatically get notified on new message
|
||||
received. Message is at self.messages queue
|
||||
'''
|
||||
pass # Messa
|
||||
|
||||
def receiveBytes(self, number):
|
||||
msg = b''
|
||||
while self.running and len(msg) < number:
|
||||
try:
|
||||
buf = self.clientSocket.recv(number - len(msg))
|
||||
if buf == b'':
|
||||
logger.debug('Buf {}, msg {}({})'.format(buf, msg, REV_DICT.get(msg)))
|
||||
self.running = False
|
||||
break
|
||||
msg += buf
|
||||
except socket.timeout:
|
||||
pass
|
||||
|
||||
if self.running is False:
|
||||
logger.debug('Not running, returning None')
|
||||
return None
|
||||
return msg
|
||||
|
||||
def connect(self):
|
||||
self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.clientSocket.connect(('localhost', self.port))
|
||||
self.clientSocket.settimeout(2) # 2 seconds timeout
|
||||
|
||||
def run(self):
|
||||
self.running = True
|
||||
|
||||
while self.running:
|
||||
try:
|
||||
msg = b''
|
||||
# We look for magic message header
|
||||
while self.running: # Wait for MAGIC
|
||||
try:
|
||||
buf = self.clientSocket.recv(len(MAGIC) - len(msg))
|
||||
if buf == b'':
|
||||
self.running = False
|
||||
break
|
||||
msg += buf
|
||||
if len(msg) != len(MAGIC):
|
||||
continue # Do not have message
|
||||
if msg != MAGIC: # Skip first byte an continue searchong
|
||||
msg = msg[1:]
|
||||
continue
|
||||
break
|
||||
except socket.timeout: # Timeout is here so we can get stop thread
|
||||
continue
|
||||
|
||||
if self.running is False:
|
||||
break
|
||||
|
||||
# Now we get message basic data (msg + datalen)
|
||||
msg = bytearray(self.receiveBytes(3))
|
||||
|
||||
# We have the magic header, here comes the message itself
|
||||
if msg is None:
|
||||
continue
|
||||
|
||||
msgId = msg[0]
|
||||
dataLen = msg[1] + (msg[2] << 8)
|
||||
if msgId not in VALID_MESSAGES:
|
||||
raise Exception('Invalid message id: {}'.format(msgId))
|
||||
|
||||
data = self.receiveBytes(dataLen)
|
||||
if data is None:
|
||||
continue
|
||||
|
||||
self.messages.put((msgId, data))
|
||||
self.messageReceived()
|
||||
|
||||
except socket.error as e:
|
||||
logger.error('Communication with server got an error: {}'.format(toUnicode(e.strerror)))
|
||||
self.running = False
|
||||
return
|
||||
except Exception as e:
|
||||
tb = traceback.format_exc()
|
||||
logger.error('Error: {}, trace: {}'.format(e, tb))
|
||||
|
||||
try:
|
||||
self.clientSocket.close()
|
||||
except Exception:
|
||||
pass # If can't close, nothing happens, just end thread
|
||||
|
168
actors/src/udsactor/linux/UDSActorService.py
Normal file
168
actors/src/udsactor/linux/UDSActorService.py
Normal file
@@ -0,0 +1,168 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor import operations
|
||||
|
||||
from udsactor.service import CommonService
|
||||
from udsactor.service import initCfg
|
||||
from udsactor.service import IPC_PORT
|
||||
from udsactor import ipc
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
from udsactor.linux.daemon import Daemon
|
||||
from udsactor.linux import renamer
|
||||
|
||||
import sys
|
||||
import time
|
||||
try:
|
||||
from prctl import set_proctitle
|
||||
except Exception: # Platform may not include prctl, so in case it's not available, we let the "name" as is
|
||||
def set_proctitle(_):
|
||||
pass
|
||||
|
||||
|
||||
class UDSActorSvc(Daemon, CommonService):
|
||||
def __init__(self, args=None):
|
||||
Daemon.__init__(self, '/var/run/udsa.pid')
|
||||
CommonService.__init__(self)
|
||||
|
||||
def rename(self, name, user=None, oldPassword=None, newPassword=None):
|
||||
'''
|
||||
Renames the computer, and optionally sets a password for an user
|
||||
before this
|
||||
'''
|
||||
|
||||
# Check for password change request for an user
|
||||
if user is not None:
|
||||
logger.info('Setting password for user {}'.format(user))
|
||||
try:
|
||||
operations.changeUserPassword(user, oldPassword, newPassword)
|
||||
except Exception as e:
|
||||
# We stop here without even renaming computer, because the
|
||||
# process has failed
|
||||
raise Exception(
|
||||
'Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(user, unicode(e)))
|
||||
|
||||
renamer.rename(name)
|
||||
self.setReady()
|
||||
|
||||
def joinDomain(self, name, domain, ou, account, password):
|
||||
logger.fatal('Join domain is not supported on linux platforms right now')
|
||||
|
||||
def run(self):
|
||||
initCfg()
|
||||
|
||||
logger.debug('Running Daemon')
|
||||
set_proctitle('UDSActorDaemon')
|
||||
|
||||
# Linux daemon will continue running unless something is requested to
|
||||
while True:
|
||||
brokerConnected = self.interactWithBroker()
|
||||
if brokerConnected is False:
|
||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
||||
return
|
||||
elif brokerConnected is True:
|
||||
break
|
||||
|
||||
# If brokerConnected returns None, repeat the cycle
|
||||
self.doWait(16000) # Wait for a looong while
|
||||
|
||||
if self.isAlive is False:
|
||||
logger.debug('The service is not alive after broker interaction, stopping it')
|
||||
return
|
||||
|
||||
if self.rebootRequested is True:
|
||||
logger.debug('Reboot has been requested, stopping service')
|
||||
return
|
||||
|
||||
self.initIPC()
|
||||
|
||||
# *********************
|
||||
# * Main Service loop *
|
||||
# *********************
|
||||
# Counter used to check ip changes only once every 10 seconds, for
|
||||
# example
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
counter += 1
|
||||
if counter % 10 == 0:
|
||||
self.checkIpsChanged()
|
||||
# In milliseconds, will break
|
||||
self.doWait(1000)
|
||||
|
||||
self.endIPC()
|
||||
self.endAPI()
|
||||
|
||||
self.notifyStop()
|
||||
|
||||
|
||||
def usage():
|
||||
sys.stderr.write("usage: {} start|stop|restart|login 'username'|logout 'username'\n".format(sys.argv[0]))
|
||||
sys.exit(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.setLevel(20000)
|
||||
|
||||
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
||||
logger.debug('Running client udsactor')
|
||||
client = None
|
||||
try:
|
||||
client = ipc.ClientIPC(IPC_PORT)
|
||||
if 'login' == sys.argv[1]:
|
||||
client.sendLogin(sys.argv[2])
|
||||
sys.exit(0)
|
||||
elif 'logout' == sys.argv[1]:
|
||||
client.sendLogout(sys.argv[2])
|
||||
sys.exit(0)
|
||||
else:
|
||||
usage()
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
elif len(sys.argv) != 2:
|
||||
usage()
|
||||
|
||||
logger.debug('Executing actor')
|
||||
daemon = UDSActorSvc()
|
||||
if len(sys.argv) == 2:
|
||||
if 'start' == sys.argv[1]:
|
||||
daemon.start()
|
||||
elif 'stop' == sys.argv[1]:
|
||||
daemon.stop()
|
||||
elif 'restart' == sys.argv[1]:
|
||||
daemon.restart()
|
||||
else:
|
||||
usage()
|
||||
sys.exit(0)
|
||||
else:
|
||||
usage()
|
32
actors/src/udsactor/linux/__init__.py
Normal file
32
actors/src/udsactor/linux/__init__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
182
actors/src/udsactor/linux/daemon.py
Normal file
182
actors/src/udsactor/linux/daemon.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: : http://www.jejik.com/authors/sander_marechal/
|
||||
@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
|
||||
'''
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import atexit
|
||||
from udsactor.log import logger
|
||||
|
||||
from signal import SIGTERM
|
||||
|
||||
|
||||
class Daemon:
|
||||
"""
|
||||
A generic daemon class.
|
||||
|
||||
Usage: subclass the Daemon class and override the run() method
|
||||
"""
|
||||
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||
self.stdin = stdin
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
self.pidfile = pidfile
|
||||
|
||||
def daemonize(self):
|
||||
"""
|
||||
do the UNIX double-fork magic, see Stevens' "Advanced
|
||||
Programming in the UNIX Environment" for details (ISBN 0201563177)
|
||||
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
|
||||
"""
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit first parent
|
||||
sys.exit(0)
|
||||
except OSError as e:
|
||||
logger.error("fork #1 error: {}".format(e))
|
||||
sys.stderr.write("fork #1 failed: {}\n".format(e))
|
||||
sys.exit(1)
|
||||
|
||||
# decouple from parent environment
|
||||
os.chdir("/")
|
||||
os.setsid()
|
||||
os.umask(0)
|
||||
|
||||
# do second fork
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
# exit from second parent
|
||||
sys.exit(0)
|
||||
except OSError as e:
|
||||
logger.error("fork #2 error: {}".format(e))
|
||||
sys.stderr.write("fork #2 failed: {}\n".format(e))
|
||||
sys.exit(1)
|
||||
|
||||
# redirect standard file descriptors
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
si = open(self.stdin, 'r')
|
||||
so = open(self.stdout, 'a+')
|
||||
se = open(self.stderr, 'a+', 0)
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
|
||||
# write pidfile
|
||||
atexit.register(self.delpid)
|
||||
pid = str(os.getpid())
|
||||
with open(self.pidfile, 'w+') as f:
|
||||
f.write("{}\n".format(pid))
|
||||
|
||||
def delpid(self):
|
||||
try:
|
||||
os.remove(self.pidfile)
|
||||
except Exception:
|
||||
# Not found/not permissions or whatever...
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Start the daemon
|
||||
"""
|
||||
logger.debug('Starting daemon')
|
||||
# Check for a pidfile to see if the daemon already runs
|
||||
try:
|
||||
pf = open(self.pidfile, 'r')
|
||||
pid = int(pf.read().strip())
|
||||
pf.close()
|
||||
except IOError:
|
||||
pid = None
|
||||
|
||||
if pid:
|
||||
message = "pidfile {} already exist. Daemon already running?\n".format(pid)
|
||||
logger.error(message)
|
||||
sys.stderr.write(message)
|
||||
sys.exit(1)
|
||||
|
||||
# Start the daemon
|
||||
self.daemonize()
|
||||
try:
|
||||
self.run()
|
||||
except Exception as e:
|
||||
logger.error('Exception running process: {}'.format(e))
|
||||
|
||||
if os.path.exists(self.pidfile):
|
||||
os.remove(self.pidfile)
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stop the daemon
|
||||
"""
|
||||
# Get the pid from the pidfile
|
||||
try:
|
||||
pf = open(self.pidfile, 'r')
|
||||
pid = int(pf.read().strip())
|
||||
pf.close()
|
||||
except IOError:
|
||||
pid = None
|
||||
|
||||
if pid is None:
|
||||
message = "pidfile {} does not exist. Daemon not running?\n".format(self.pidfile)
|
||||
logger.info(message)
|
||||
# sys.stderr.write(message)
|
||||
return # not an error in a restart
|
||||
|
||||
# Try killing the daemon process
|
||||
try:
|
||||
while True:
|
||||
os.kill(pid, SIGTERM)
|
||||
time.sleep(1)
|
||||
except OSError as err:
|
||||
if err.errno == 3: # No such process
|
||||
if os.path.exists(self.pidfile):
|
||||
os.remove(self.pidfile)
|
||||
else:
|
||||
sys.stderr.write(err)
|
||||
sys.exit(1)
|
||||
|
||||
def restart(self):
|
||||
"""
|
||||
Restart the daemon
|
||||
"""
|
||||
self.stop()
|
||||
self.start()
|
||||
|
||||
# Overridables
|
||||
def run(self):
|
||||
"""
|
||||
You should override this method when you subclass Daemon. It will be called after the process has been
|
||||
daemonized by start() or restart().
|
||||
"""
|
80
actors/src/udsactor/linux/log.py
Normal file
80
actors/src/udsactor/linux/log.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import six
|
||||
|
||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable
|
||||
|
||||
|
||||
class LocalLogger(object):
|
||||
def __init__(self):
|
||||
# tempdir is different for "user application" and "service"
|
||||
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
|
||||
# Try to open logger at /var/log path
|
||||
# If it fails (access denied normally), will try to open one at user's home folder, and if
|
||||
# agaim it fails, open it at the tmpPath
|
||||
|
||||
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
||||
try:
|
||||
fname = os.path.join(logDir, 'udsactor.log')
|
||||
logging.basicConfig(
|
||||
filename=fname,
|
||||
filemode='a',
|
||||
format='%(levelname)s %(asctime)s %(message)s',
|
||||
level=logging.DEBUG
|
||||
)
|
||||
self.logger = logging.getLogger('udsactor')
|
||||
os.chmod(fname, 0o0600)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Logger can't be set
|
||||
self.logger = None
|
||||
|
||||
def log(self, level, message):
|
||||
# Debug messages are logged to a file
|
||||
# our loglevels are 10000 (other), 20000 (debug), ....
|
||||
# logging levels are 10 (debug), 20 (info)
|
||||
# OTHER = logging.NOTSET
|
||||
self.logger.log(int(level / 1000) - 10, message)
|
||||
|
||||
def isWindows(self):
|
||||
return False
|
||||
|
||||
def isLinux(self):
|
||||
return True
|
245
actors/src/udsactor/linux/operations.py
Normal file
245
actors/src/udsactor/linux/operations.py
Normal file
@@ -0,0 +1,245 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import socket
|
||||
import platform
|
||||
import fcntl
|
||||
import os
|
||||
import ctypes # @UnusedImport
|
||||
import ctypes.util
|
||||
import subprocess
|
||||
import struct
|
||||
import array
|
||||
import six
|
||||
from udsactor import utils
|
||||
from .renamer import rename
|
||||
|
||||
|
||||
def _getMacAddr(ifname):
|
||||
'''
|
||||
Returns the mac address of an interface
|
||||
Mac is returned as unicode utf-8 encoded
|
||||
'''
|
||||
if isinstance(ifname, list):
|
||||
return dict([(name, _getMacAddr(name)) for name in ifname])
|
||||
if isinstance(ifname, six.text_type):
|
||||
ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
info = bytearray(fcntl.ioctl(s.fileno(), 0x8927, struct.pack(str('256s'), ifname[:15])))
|
||||
return six.text_type(''.join(['%02x:' % char for char in info[18:24]])[:-1]).upper()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _getIpAddr(ifname):
|
||||
'''
|
||||
Returns the ip address of an interface
|
||||
Ip is returned as unicode utf-8 encoded
|
||||
'''
|
||||
if isinstance(ifname, list):
|
||||
return dict([(name, _getIpAddr(name)) for name in ifname])
|
||||
if isinstance(ifname, six.text_type):
|
||||
ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
return six.text_type(socket.inet_ntoa(fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8915, # SIOCGIFADDR
|
||||
struct.pack(str('256s'), ifname[:15])
|
||||
)[20:24]))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _getInterfaces():
|
||||
'''
|
||||
Returns a list of interfaces names coded in utf-8
|
||||
'''
|
||||
max_possible = 128 # arbitrary. raise if needed.
|
||||
space = max_possible * 16
|
||||
if platform.architecture()[0] == '32bit':
|
||||
offset, length = 32, 32
|
||||
elif platform.architecture()[0] == '64bit':
|
||||
offset, length = 16, 40
|
||||
else:
|
||||
raise OSError('Unknown arquitecture {0}'.format(platform.architecture()[0]))
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
names = array.array(str('B'), b'\0' * space)
|
||||
outbytes = struct.unpack(str('iL'), fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8912, # SIOCGIFCONF
|
||||
struct.pack(str('iL'), space, names.buffer_info()[0])
|
||||
))[0]
|
||||
namestr = names.tostring()
|
||||
# return namestr, outbytes
|
||||
return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
|
||||
|
||||
|
||||
def _getIpAndMac(ifname):
|
||||
ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
|
||||
return (ip, mac)
|
||||
|
||||
|
||||
def getComputerName():
|
||||
'''
|
||||
Returns computer name, with no domain
|
||||
'''
|
||||
return socket.gethostname().split('.')[0]
|
||||
|
||||
|
||||
def getNetworkInfo():
|
||||
for ifname in _getInterfaces():
|
||||
ip, mac = _getIpAndMac(ifname)
|
||||
if mac != '00:00:00:00:00:00': # Skips local interfaces
|
||||
yield utils.Bunch(name=ifname, mac=mac, ip=ip)
|
||||
|
||||
|
||||
def getDomainName():
|
||||
return ''
|
||||
|
||||
|
||||
def getLinuxVersion():
|
||||
lv = platform.linux_distribution()
|
||||
return lv[0] + ', ' + lv[1]
|
||||
|
||||
|
||||
def reboot(flags=0):
|
||||
'''
|
||||
Simple reboot using os command
|
||||
'''
|
||||
# Workaround for dummy thread
|
||||
if six.PY3 is False:
|
||||
import threading
|
||||
threading._DummyThread._Thread__stop = lambda x: 42
|
||||
|
||||
subprocess.call(['/sbin/shutdown', 'now', '-r'])
|
||||
|
||||
|
||||
def loggoff():
|
||||
'''
|
||||
Right now restarts the machine...
|
||||
'''
|
||||
# Workaround for dummy thread
|
||||
if six.PY3 is False:
|
||||
import threading
|
||||
threading._DummyThread._Thread__stop = lambda x: 42
|
||||
|
||||
subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']])
|
||||
# subprocess.call(['/sbin/shutdown', 'now', '-r'])
|
||||
# subprocess.call(['/usr/bin/systemctl', 'reboot', '-i'])
|
||||
|
||||
|
||||
def renameComputer(newName):
|
||||
rename(newName)
|
||||
|
||||
|
||||
def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
pass
|
||||
|
||||
|
||||
def changeUserPassword(user, oldPassword, newPassword):
|
||||
'''
|
||||
Simple password change for user using command line
|
||||
'''
|
||||
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(user, newPassword))
|
||||
|
||||
|
||||
class XScreenSaverInfo(ctypes.Structure):
|
||||
_fields_ = [('window', ctypes.c_long),
|
||||
('state', ctypes.c_int),
|
||||
('kind', ctypes.c_int),
|
||||
('til_or_since', ctypes.c_ulong),
|
||||
('idle', ctypes.c_ulong),
|
||||
('eventMask', ctypes.c_ulong)]
|
||||
|
||||
# Initialize xlib & xss
|
||||
try:
|
||||
xlibPath = ctypes.util.find_library('X11')
|
||||
xssPath = ctypes.util.find_library('Xss')
|
||||
xlib = ctypes.cdll.LoadLibrary(xlibPath)
|
||||
xss = ctypes.cdll.LoadLibrary(xssPath)
|
||||
|
||||
# Fix result type to XScreenSaverInfo Structure
|
||||
xss.XScreenSaverQueryExtension.restype = ctypes.c_int
|
||||
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) # Result in a XScreenSaverInfo structure
|
||||
display = xlib.XOpenDisplay(None)
|
||||
info = xss.XScreenSaverAllocInfo()
|
||||
except Exception: # Libraries not accesible, not found or whatever..
|
||||
xlib = xss = display = info = None
|
||||
|
||||
|
||||
def initIdleDuration(atLeastSeconds):
|
||||
'''
|
||||
On linux we set the screensaver to at least required seconds, or we never will get "idle"
|
||||
'''
|
||||
# Workaround for dummy thread
|
||||
if six.PY3 is False:
|
||||
import threading
|
||||
threading._DummyThread._Thread__stop = lambda x: 42
|
||||
|
||||
subprocess.call(['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)])
|
||||
# And now reset it
|
||||
subprocess.call(['/usr/bin/xset', 's', 'reset'])
|
||||
|
||||
|
||||
def getIdleDuration():
|
||||
'''
|
||||
Returns idle duration, in seconds
|
||||
'''
|
||||
if xlib is None or xss is None:
|
||||
return 0 # Libraries not available
|
||||
|
||||
event_base = ctypes.c_int()
|
||||
error_base = ctypes.c_int()
|
||||
|
||||
available = xss.XScreenSaverQueryExtension(display, ctypes.byref(event_base), ctypes.byref(error_base))
|
||||
|
||||
if available != 1:
|
||||
return 0 # No screen saver is available, no way of getting idle
|
||||
|
||||
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), info)
|
||||
|
||||
# Centos seems to set state to 1?? (weird, but it's happening don't know why... will try this way)
|
||||
if info.contents.state != 0 and 'centos' not in platform.linux_distribution()[0].lower().strip():
|
||||
return 3600 * 100 * 1000 # If screen saver is active, return a high enough value
|
||||
|
||||
return info.contents.idle / 1000.0
|
||||
|
||||
|
||||
def getCurrentUser():
|
||||
'''
|
||||
Returns current logged in user
|
||||
'''
|
||||
return os.environ['USER']
|
61
actors/src/udsactor/linux/renamer/__init__.py
Normal file
61
actors/src/udsactor/linux/renamer/__init__.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import platform
|
||||
import os
|
||||
import sys
|
||||
import pkgutil
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
renamers = {}
|
||||
|
||||
|
||||
# Renamers now are for IPv4 only addresses
|
||||
def rename(newName):
|
||||
distribution = platform.linux_distribution()[0].lower().strip()
|
||||
if distribution in renamers:
|
||||
return renamers[distribution](newName)
|
||||
|
||||
# Try Debian renamer, simplest one
|
||||
logger.info('Renamer for platform "{0}" not found, tryin debian renamer'.format(distribution))
|
||||
return renamers['debian'](newName)
|
||||
|
||||
|
||||
# Do load of packages
|
||||
def _init():
|
||||
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
|
||||
for _, name, _ in pkgutil.iter_modules([pkgpath]):
|
||||
__import__(__name__ + '.' + name, globals(), locals())
|
||||
|
||||
_init()
|
68
actors/src/udsactor/linux/renamer/debian.py
Normal file
68
actors/src/udsactor/linux/renamer/debian.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.linux.renamer import renamers
|
||||
from udsactor.log import logger
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def rename(newName):
|
||||
'''
|
||||
Debian renamer
|
||||
Expects new host name on newName
|
||||
Host does not needs to be rebooted after renaming
|
||||
'''
|
||||
logger.debug('using Debian renamer')
|
||||
|
||||
with open('/etc/hostname', 'w') as hostname:
|
||||
hostname.write(newName)
|
||||
|
||||
# Force system new name
|
||||
os.system('/bin/hostname %s' % newName)
|
||||
|
||||
# add name to "hosts"
|
||||
with open('/etc/hosts', 'r') as hosts:
|
||||
lines = hosts.readlines()
|
||||
with open('/etc/hosts', 'w') as hosts:
|
||||
hosts.write("127.0.1.1\t%s\n" % newName)
|
||||
for l in lines:
|
||||
if l[:9] == '127.0.1.1': # Skips existing 127.0.1.1. if it already exists
|
||||
continue
|
||||
hosts.write(l)
|
||||
|
||||
return True
|
||||
|
||||
# All names in lower case
|
||||
renamers['debian'] = rename
|
||||
renamers['ubuntu'] = rename
|
66
actors/src/udsactor/linux/renamer/opensuse.py
Normal file
66
actors/src/udsactor/linux/renamer/opensuse.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.linux.renamer import renamers
|
||||
from udsactor.log import logger
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def rename(newName):
|
||||
'''
|
||||
RH, Centos, Fedora Renamer
|
||||
Expects new host name on newName
|
||||
Host does not needs to be rebooted after renaming
|
||||
'''
|
||||
logger.debug('using SUSE renamer')
|
||||
|
||||
with open('/etc/hostname', 'w') as hostname:
|
||||
hostname.write(newName)
|
||||
|
||||
# Force system new name
|
||||
os.system('/bin/hostname %s' % newName)
|
||||
|
||||
# add name to "hosts"
|
||||
with open('/etc/hosts', 'r') as hosts:
|
||||
lines = hosts.readlines()
|
||||
with open('/etc/hosts', 'w') as hosts:
|
||||
hosts.write("127.0.1.1\t{}\n".format(newName))
|
||||
for l in lines:
|
||||
if l[:9] != '127.0.1.1': # Skips existing 127.0.1.1. if it already exists
|
||||
hosts.write(l)
|
||||
|
||||
return True
|
||||
|
||||
# All names in lower case
|
||||
renamers['opensuse'] = rename
|
||||
renamers['suse'] = rename
|
74
actors/src/udsactor/linux/renamer/redhat.py
Normal file
74
actors/src/udsactor/linux/renamer/redhat.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.linux.renamer import renamers
|
||||
from udsactor.log import logger
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def rename(newName):
|
||||
'''
|
||||
RH, Centos, Fedora Renamer
|
||||
Expects new host name on newName
|
||||
Host does not needs to be rebooted after renaming
|
||||
'''
|
||||
logger.debug('using RH renamer')
|
||||
|
||||
with open('/etc/hostname', 'w') as hostname:
|
||||
hostname.write(newName)
|
||||
|
||||
# Force system new name
|
||||
os.system('/bin/hostname %s' % newName)
|
||||
|
||||
# add name to "hosts"
|
||||
with open('/etc/hosts', 'r') as hosts:
|
||||
lines = hosts.readlines()
|
||||
with open('/etc/hosts', 'w') as hosts:
|
||||
hosts.write("127.0.1.1\t{}\n".format(newName))
|
||||
for l in lines:
|
||||
if l[:9] != '127.0.1.1': # Skips existing 127.0.1.1. if it already exists
|
||||
hosts.write(l)
|
||||
|
||||
with open('/etc/sysconfig/network', 'r') as net:
|
||||
lines = net.readlines()
|
||||
with open('/etc/sysconfig/network', 'w') as net:
|
||||
net.write('HOSTNAME={}\n'.format(newName))
|
||||
for l in lines:
|
||||
if l[:8] != 'HOSTNAME':
|
||||
net.write(l)
|
||||
|
||||
return True
|
||||
|
||||
# All names in lower case
|
||||
renamers['centos linux'] = rename
|
||||
renamers['fedora'] = rename
|
80
actors/src/udsactor/linux/store.py
Normal file
80
actors/src/udsactor/linux/store.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
|
||||
|
||||
import six
|
||||
import os
|
||||
|
||||
DEBUG = False
|
||||
|
||||
CONFIGFILE = '/etc/udsactor/udsactor.cfg' if DEBUG is False else '/tmp/udsactor.cfg'
|
||||
|
||||
|
||||
def checkPermissions():
|
||||
return True if DEBUG else os.getuid() == 0
|
||||
|
||||
|
||||
def readConfig():
|
||||
res = {}
|
||||
try:
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
cfg.read(CONFIGFILE)
|
||||
# Just reads 'uds' section
|
||||
for key in cfg.options('uds'):
|
||||
res[key] = cfg.get('uds', key)
|
||||
if res[key].lower() in ('true', 'yes', 'si'):
|
||||
res[key] = True
|
||||
elif res[key].lower() in ('false', 'no'):
|
||||
res[key] = False
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def writeConfig(data):
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
cfg.add_section('uds')
|
||||
for key, val in data.items():
|
||||
cfg.set('uds', key, str(val))
|
||||
|
||||
# Ensures exists destination folder
|
||||
dirname = os.path.dirname(CONFIGFILE)
|
||||
if not os.path.exists(dirname):
|
||||
os.mkdir(dirname, mode=0o700) # Will create only if route to path already exists, for example, /etc (that must... :-))
|
||||
|
||||
with open(CONFIGFILE, 'w') as f:
|
||||
cfg.write(f)
|
||||
|
||||
os.chmod(CONFIGFILE, 0o0600)
|
103
actors/src/udsactor/log.py
Normal file
103
actors/src/udsactor/log.py
Normal file
@@ -0,0 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import six
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from udsactor.windows.log import LocalLogger # @UnusedImport
|
||||
else:
|
||||
from udsactor.linux.log import LocalLogger # @Reimport
|
||||
|
||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable
|
||||
|
||||
|
||||
class Logger(object):
|
||||
def __init__(self):
|
||||
self.logLevel = INFO
|
||||
self.logger = LocalLogger()
|
||||
self.remoteLogger = None
|
||||
|
||||
def setLevel(self, level):
|
||||
'''
|
||||
Sets log level filter (minimum level required for a log message to be processed)
|
||||
:param level: Any message with a level below this will be filtered out
|
||||
'''
|
||||
self.logLevel = int(level) # Ensures level is an integer or fails
|
||||
|
||||
def setRemoteLogger(self, remoteLogger):
|
||||
self.remoteLogger = remoteLogger
|
||||
|
||||
def log(self, level, message):
|
||||
if level < self.logLevel: # Skip not wanted messages
|
||||
return
|
||||
|
||||
# If remote logger is available, notify message to it
|
||||
try:
|
||||
if self.remoteLogger is not None and self.remoteLogger.isConnected and level >= INFO:
|
||||
self.remoteLogger.log(level, message)
|
||||
except Exception as e:
|
||||
self.logger.log(FATAL, 'Error notifying log to broker: {}'.format(e.message))
|
||||
|
||||
self.logger.log(level, message)
|
||||
|
||||
def debug(self, message):
|
||||
self.log(DEBUG, message)
|
||||
|
||||
def warn(self, message):
|
||||
self.log(WARN, message)
|
||||
|
||||
def info(self, message):
|
||||
self.log(INFO, message)
|
||||
|
||||
def error(self, message):
|
||||
self.log(ERROR, message)
|
||||
|
||||
def fatal(self, message):
|
||||
self.log(FATAL, message)
|
||||
|
||||
def exception(self):
|
||||
try:
|
||||
tb = traceback.format_exc()
|
||||
except Exception:
|
||||
tb = '(could not get traceback!)'
|
||||
|
||||
self.log(DEBUG, tb)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
|
||||
logger = Logger()
|
40
actors/src/udsactor/operations.py
Normal file
40
actors/src/udsactor/operations.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from .windows.operations import * # @UnusedWildImport
|
||||
else:
|
||||
from .linux.operations import * # @UnusedWildImport
|
@@ -1,51 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 201 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
|
||||
# pylint: disable-msg=E1101,W0703
|
||||
|
||||
from ..auths.AdminAuth import needs_credentials
|
||||
from udsactor.log import logger
|
||||
|
||||
import threading
|
||||
import six
|
||||
|
||||
|
||||
from uds.core.ui.UserInterface import gui
|
||||
class ScriptExecutorThread(threading.Thread):
|
||||
def __init__(self, script):
|
||||
super(ScriptExecutorThread, self).__init__()
|
||||
self.script = script
|
||||
|
||||
@needs_credentials
|
||||
def chooseCallback(credentials, name, parameters):
|
||||
res = {}
|
||||
params = {}
|
||||
for p in parameters:
|
||||
params[p['name']] = p['value']
|
||||
if gui.callbacks.has_key(name):
|
||||
res = gui.callbacks[name](params)
|
||||
return res
|
||||
|
||||
def registerCallbackFunctions(dispatcher):
|
||||
dispatcher.register_function(chooseCallback, 'chooseCallback')
|
||||
def run(self):
|
||||
try:
|
||||
logger.debug('Executing script: {}'.format(self.script))
|
||||
six.exec_(self.script, globals(), None)
|
||||
except Exception as e:
|
||||
logger.error('Error executing script: {}'.format(e))
|
325
actors/src/udsactor/service.py
Normal file
325
actors/src/udsactor/service.py
Normal file
@@ -0,0 +1,325 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
from . import operations
|
||||
from . import store
|
||||
from . import REST
|
||||
from . import ipc
|
||||
from . import httpserver
|
||||
from .scriptThread import ScriptExecutorThread
|
||||
from .utils import exceptionToMessage
|
||||
|
||||
import socket
|
||||
import time
|
||||
import random
|
||||
|
||||
IPC_PORT = 39188
|
||||
|
||||
cfg = None
|
||||
|
||||
|
||||
def initCfg():
|
||||
global cfg # pylint: disable=global-statement
|
||||
cfg = store.readConfig()
|
||||
|
||||
if logger.logger.isWindows():
|
||||
# Logs will also go to windows event log for services
|
||||
logger.logger.serviceLogger = True
|
||||
|
||||
if cfg is not None:
|
||||
logger.setLevel(cfg.get('logLevel', 20000))
|
||||
else:
|
||||
logger.setLevel(20000)
|
||||
cfg = {}
|
||||
|
||||
# If ANY var is missing, reset cfg
|
||||
for v in ('host', 'ssl', 'masterKey'):
|
||||
if v not in cfg:
|
||||
cfg = None
|
||||
break
|
||||
|
||||
|
||||
class CommonService(object):
|
||||
def __init__(self):
|
||||
self.isAlive = True
|
||||
self.api = None
|
||||
self.ipc = None
|
||||
self.httpServer = None
|
||||
self.rebootRequested = False
|
||||
self.knownIps = []
|
||||
socket.setdefaulttimeout(20)
|
||||
|
||||
def reboot(self):
|
||||
self.rebootRequested = True
|
||||
|
||||
def setReady(self):
|
||||
self.api.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()])
|
||||
|
||||
def interactWithBroker(self):
|
||||
'''
|
||||
Returns True to continue to main loop, false to stop & exit service
|
||||
'''
|
||||
# If no configuration is found, stop service
|
||||
if cfg is None:
|
||||
logger.fatal('No configuration found, stopping service')
|
||||
return False
|
||||
|
||||
self.api = REST.Api(cfg['host'], cfg['masterKey'], cfg['ssl'])
|
||||
|
||||
# Wait for Broker to be ready
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
try:
|
||||
# getNetworkInfo is a generator function
|
||||
netInfo = tuple(operations.getNetworkInfo())
|
||||
self.knownIps = dict(((i.mac, i.ip) for i in netInfo))
|
||||
ids = ','.join([i.mac for i in netInfo])
|
||||
if ids == '':
|
||||
# Wait for any network interface to be ready
|
||||
logger.debug('No valid network interfaces found, retrying in a while...')
|
||||
raise Exception()
|
||||
logger.debug('Ids: {}'.format(ids))
|
||||
self.api.init(ids)
|
||||
# Set remote logger to notify log info to broker
|
||||
logger.setRemoteLogger(self.api)
|
||||
|
||||
break
|
||||
except REST.InvalidKeyError:
|
||||
logger.fatal('Can\'t sync with broker: Invalid broker Master Key')
|
||||
return False
|
||||
except REST.UnmanagedHostError:
|
||||
# Maybe interface that is registered with broker is not enabled already?
|
||||
# Right now, we thing that the interface connected to broker is
|
||||
# the interface that broker will know, let's see how this works
|
||||
logger.fatal('This host is not managed by UDS Broker (ids: {})'.format(ids))
|
||||
return False # On unmanaged hosts, there is no reason right now to continue running
|
||||
except Exception as e:
|
||||
logger.debug('Exception on network info: retrying')
|
||||
# Any other error is expectable and recoverable, so let's wait a bit and retry again
|
||||
# but, if too many errors, will log it (one every minute, for
|
||||
# example)
|
||||
counter += 1
|
||||
if counter % 60 == 0: # Every 5 minutes, raise a log
|
||||
logger.info('Trying to inititialize connection with broker (last error: {})'.format(exceptionToMessage(e)))
|
||||
# Wait a bit before next check
|
||||
self.doWait(5000)
|
||||
|
||||
# Broker connection is initialized, now get information about what to
|
||||
# do
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
try:
|
||||
logger.debug('Requesting information of what to do now')
|
||||
info = self.api.information()
|
||||
data = info.split('\r')
|
||||
if len(data) != 2:
|
||||
logger.error('The format of the information message is not correct (got {})'.format(info))
|
||||
raise Exception
|
||||
params = data[1].split('\t')
|
||||
if data[0] == 'rename':
|
||||
try:
|
||||
if len(params) == 1: # Simple rename
|
||||
logger.debug('Renaming computer to {}'.format(params[0]))
|
||||
self.rename(params[0])
|
||||
# Rename with change password for an user
|
||||
elif len(params) == 4:
|
||||
logger.debug('Renaming computer to {}'.format(params))
|
||||
self.rename(params[0], params[1], params[2], params[3])
|
||||
else:
|
||||
logger.error('Got invalid parameter for rename operation: {}'.format(params))
|
||||
return False
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error('Error at computer renaming stage: {}'.format(e.message))
|
||||
return None # Will retry complete broker connection if this point is reached
|
||||
elif data[0] == 'domain':
|
||||
if len(params) != 5:
|
||||
logger.error('Got invalid parameters for domain message: {}'.format(params))
|
||||
return False # Stop running service
|
||||
self.joinDomain(params[0], params[1], params[2], params[3], params[4])
|
||||
break
|
||||
else:
|
||||
logger.error('Unrecognized action sent from broker: {}'.format(data[0]))
|
||||
return False # Stop running service
|
||||
except REST.UserServiceNotFoundError:
|
||||
logger.error('The host has lost the sync state with broker! (host uuid changed?)')
|
||||
return False
|
||||
except Exception as err:
|
||||
if counter % 60 == 0:
|
||||
logger.warn('Too many retries in progress, though still trying (last error: {})'.format(exceptionToMessage(err)))
|
||||
counter += 1
|
||||
# Any other error is expectable and recoverable, so let's wait
|
||||
# a bit and retry again
|
||||
# Wait a bit before next check
|
||||
self.doWait(5000)
|
||||
|
||||
if self.rebootRequested:
|
||||
try:
|
||||
operations.reboot()
|
||||
except Exception as e:
|
||||
logger.error('Exception on reboot: {}'.format(e.message))
|
||||
return False # Stops service
|
||||
|
||||
return True
|
||||
|
||||
def checkIpsChanged(self):
|
||||
if self.api is None or self.api.uuid is None:
|
||||
return # Not connected
|
||||
netInfo = tuple(operations.getNetworkInfo())
|
||||
for i in netInfo:
|
||||
# If at least one ip has changed
|
||||
if i.mac in self.knownIps and self.knownIps[i.mac] != i.ip:
|
||||
logger.info('Notifying ip change to broker (mac {}, from {} to {})'.format(i.mac, self.knownIps[i.mac], i.ip))
|
||||
try:
|
||||
# Notifies all interfaces IPs
|
||||
self.api.notifyIpChanges(((v.mac, v.ip) for v in netInfo))
|
||||
|
||||
# Regenerates Known ips
|
||||
self.knownIps = dict(((v.mac, v.ip) for v in netInfo))
|
||||
|
||||
# And notify new listening address to broker
|
||||
address = (self.knownIps[self.api.mac], random.randrange(43900, 44000))
|
||||
# And new listening address
|
||||
self.httpServer.restart(address)
|
||||
# sends notification
|
||||
self.api.notifyComm(self.httpServer.getServerUrl())
|
||||
|
||||
except Exception as e:
|
||||
logger.warn('Got an error notifiying IPs to broker: {} (will retry in a bit)'.format(e.message.decode('windows-1250', 'ignore')))
|
||||
|
||||
def clientMessageProcessor(self, msg, data):
|
||||
logger.debug('Got message {}'.format(msg))
|
||||
if self.api is None:
|
||||
logger.info('Rest api not ready')
|
||||
return
|
||||
|
||||
if msg == ipc.REQ_LOGIN:
|
||||
res = self.api.login(data).split('\t')
|
||||
# third parameter, if exists, sets maxSession duration to this.
|
||||
# First & second parameters are ip & hostname of connection source
|
||||
if len(res) >= 3:
|
||||
self.api.maxSession = int(res[2]) # Third parameter is max session duration
|
||||
msg = ipc.REQ_INFORMATION # Senf information, requested or not, to client on login notification
|
||||
if msg == ipc.REQ_LOGOUT:
|
||||
self.api.logout(data)
|
||||
self.onLogout(data)
|
||||
if msg == ipc.REQ_INFORMATION:
|
||||
info = {}
|
||||
if self.api.idle is not None:
|
||||
info['idle'] = self.api.idle
|
||||
if self.api.maxSession is not None:
|
||||
info['maxSession'] = self.api.maxSession
|
||||
self.ipc.sendInformationMessage(info)
|
||||
|
||||
def initIPC(self):
|
||||
# ******************************************
|
||||
# * Initialize listener IPC & REST threads *
|
||||
# ******************************************
|
||||
logger.debug('Starting IPC listener at {}'.format(IPC_PORT))
|
||||
self.ipc = ipc.ServerIPC(IPC_PORT, clientMessageProcessor=self.clientMessageProcessor)
|
||||
self.ipc.start()
|
||||
|
||||
if self.api.mac in self.knownIps:
|
||||
address = (self.knownIps[self.api.mac], random.randrange(43900, 44000))
|
||||
logger.info('Starting REST listener at {}'.format(address))
|
||||
self.httpServer = httpserver.HTTPServerThread(address, self)
|
||||
self.httpServer.start()
|
||||
# And notify it to broker
|
||||
self.api.notifyComm(self.httpServer.getServerUrl())
|
||||
|
||||
def endIPC(self):
|
||||
# Remove IPC threads
|
||||
if self.ipc is not None:
|
||||
try:
|
||||
self.ipc.stop()
|
||||
except Exception:
|
||||
logger.error('Couln\'t stop ipc server')
|
||||
if self.httpServer is not None:
|
||||
try:
|
||||
self.httpServer.stop()
|
||||
except Exception:
|
||||
logger.error('Couln\'t stop REST server')
|
||||
|
||||
def endAPI(self):
|
||||
if self.api is not None:
|
||||
try:
|
||||
self.api.notifyComm(None)
|
||||
except Exception:
|
||||
logger.error('Couln\'t remove comms url from broker')
|
||||
|
||||
self.notifyStop()
|
||||
|
||||
# ***************************************************
|
||||
# Methods that ARE overriden by linux & windows Actor
|
||||
# ***************************************************
|
||||
def rename(self, name, user=None, oldPassword=None, newPassword=None):
|
||||
'''
|
||||
Invoked when broker requests a rename action
|
||||
MUST BE OVERRIDEN
|
||||
'''
|
||||
raise NotImplementedError('Method renamed has not been implemented!')
|
||||
|
||||
def joinDomain(self, name, domain, ou, account, password):
|
||||
'''
|
||||
Invoked when broker requests a "domain" action
|
||||
MUST BE OVERRIDEN
|
||||
'''
|
||||
raise NotImplementedError('Method renamed has not been implemented!')
|
||||
|
||||
# ****************************************
|
||||
# Methods that CAN BE overriden by actors
|
||||
# ****************************************
|
||||
def doWait(self, miliseconds):
|
||||
'''
|
||||
Invoked to wait a bit
|
||||
CAN be OVERRIDEN
|
||||
'''
|
||||
time.sleep(float(miliseconds) / 1000)
|
||||
|
||||
def notifyStop(self):
|
||||
'''
|
||||
Overriden to log stop
|
||||
'''
|
||||
logger.info('Service is being stopped')
|
||||
|
||||
def preConnect(self, user, protocol):
|
||||
'''
|
||||
Invoked when received a PRE Connection request via REST
|
||||
'''
|
||||
logger.debug('Pre-connect does nothing')
|
||||
return 'ok'
|
||||
|
||||
def onLogout(self, user):
|
||||
logger.debug('On logout invoked for {}'.format(user))
|
39
actors/src/udsactor/store.py
Normal file
39
actors/src/udsactor/store.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=unused-wildcard-import, wildcard-import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from udsactor.windows.store import * # @UnusedWildImport
|
||||
else:
|
||||
from udsactor.linux.store import * # @UnusedWildImport
|
@@ -1,60 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import cStringIO
|
||||
import sys
|
||||
import six
|
||||
|
||||
from xmlrpclib import Transport, ServerProxy
|
||||
from django.test.client import Client
|
||||
if sys.platform == 'win32':
|
||||
_fromEncoding = 'windows-1250'
|
||||
else:
|
||||
_fromEncoding = 'utf-8'
|
||||
|
||||
class TestTransport(Transport,object):
|
||||
|
||||
""" Handles connections to XML-RPC server through Django test client."""
|
||||
def toUnicode(msg):
|
||||
try:
|
||||
if not isinstance(msg, six.text_type):
|
||||
if isinstance(msg, six.binary_type):
|
||||
return msg.decode(_fromEncoding, 'ignore')
|
||||
return six.text_type(msg)
|
||||
else:
|
||||
return msg
|
||||
except Exception:
|
||||
try:
|
||||
return six.text_type(msg)
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestTransport, self).__init__(*args, **kwargs)
|
||||
self.client = Client()
|
||||
|
||||
def request(self, host, handler, request_body, verbose=0):
|
||||
def exceptionToMessage(e):
|
||||
msg = ''
|
||||
for arg in e.args:
|
||||
if isinstance(arg, Exception):
|
||||
msg = msg + exceptionToMessage(arg)
|
||||
else:
|
||||
msg = msg + toUnicode(arg) + '. '
|
||||
return msg
|
||||
|
||||
self.verbose = verbose
|
||||
|
||||
response = self.client.post(handler,
|
||||
request_body,
|
||||
content_type="text/xml")
|
||||
class Bunch(dict):
|
||||
def __init__(self, **kw):
|
||||
dict.__init__(self, kw)
|
||||
self.__dict__ = self
|
||||
|
||||
res = cStringIO.StringIO(response.content)
|
||||
res.seek(0)
|
||||
|
||||
return self.parse_response(res)
|
||||
|
||||
rpcServer = ServerProxy("http://test:test@172.27.0.1:8000/xmlrpc", verbose = 1, transport=TestTransport())
|
148
actors/src/udsactor/windows/SENS.py
Normal file
148
actors/src/udsactor/windows/SENS.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# _*_ coding: iso-8859-1 _*_
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import win32com.client # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32com.server.policy # @UnresolvedImport, pylint: disable=import-error
|
||||
import os
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
# based on python SENS example from
|
||||
# http://timgolden.me.uk/python/win32_how_do_i/track-session-events.html
|
||||
|
||||
# from Sens.h
|
||||
SENSGUID_PUBLISHER = "{5fee1bd6-5b9b-11d1-8dd2-00aa004abd5e}"
|
||||
SENSGUID_EVENTCLASS_LOGON = "{d5978630-5b9f-11d1-8dd2-00aa004abd5e}"
|
||||
|
||||
# from EventSys.h
|
||||
PROGID_EventSystem = "EventSystem.EventSystem"
|
||||
PROGID_EventSubscription = "EventSystem.EventSubscription"
|
||||
|
||||
IID_ISensLogon = "{d597bab3-5b9f-11d1-8dd2-00aa004abd5e}"
|
||||
|
||||
|
||||
class SensLogon(win32com.server.policy.DesignatedWrapPolicy):
|
||||
_com_interfaces_ = [IID_ISensLogon]
|
||||
_public_methods_ = [
|
||||
'Logon',
|
||||
'Logoff',
|
||||
'StartShell',
|
||||
'DisplayLock',
|
||||
'DisplayUnlock',
|
||||
'StartScreenSaver',
|
||||
'StopScreenSaver'
|
||||
]
|
||||
|
||||
def __init__(self, service):
|
||||
self._wrap_(self)
|
||||
self.service = service
|
||||
|
||||
def Logon(self, *args):
|
||||
logger.debug('Logon event: {}'.format(args))
|
||||
if self.service.api is not None and self.service.api.isConnected:
|
||||
try:
|
||||
data = self.service.api.login(args[0])
|
||||
logger.debug('Data received for login: {}'.format(data))
|
||||
data = data.split('\t')
|
||||
if len(data) >= 2:
|
||||
logger.debug('Data is valid: {}'.format(data))
|
||||
windir = os.environ['windir']
|
||||
with open(os.path.join(windir, 'remoteip.txt'), 'w') as f:
|
||||
f.write(data[0])
|
||||
with open(os.path.join(windir, 'remoteh.txt'), 'w') as f:
|
||||
f.write(data[1])
|
||||
except Exception as e:
|
||||
logger.fatal('Error notifying logon to server: {}'.format(e))
|
||||
|
||||
def Logoff(self, *args):
|
||||
logger.debug('Logoff event: arguments: {}'.format(args))
|
||||
if self.service is not None and self.service.api is not None and self.service.api.isConnected:
|
||||
try:
|
||||
self.service.api.logout(args[0])
|
||||
except Exception as e:
|
||||
logger.fatal('Error notifying logoff to server: {}'.format(e))
|
||||
|
||||
logger.debug('Invoking onLogout: {}'.format(self.service))
|
||||
self.service.onLogout(args[0])
|
||||
logger.debug('Invoked!!')
|
||||
|
||||
def StartShell(self, *args):
|
||||
# logevent('StartShell : %s' % [args])
|
||||
pass
|
||||
|
||||
def DisplayLock(self, *args):
|
||||
# logevent('DisplayLock : %s' % [args])
|
||||
pass
|
||||
|
||||
def DisplayUnlock(self, *args):
|
||||
# logevent('DisplayUnlock : %s' % [args])
|
||||
pass
|
||||
|
||||
def StartScreenSaver(self, *args):
|
||||
# When finished basic actor, we will use this to provide a new parameter: logout on screensaver
|
||||
# This will allow to easily close sessions of idle users
|
||||
# logevent('StartScreenSaver : %s' % [args])
|
||||
pass
|
||||
|
||||
def StopScreenSaver(self, *args):
|
||||
# logevent('StopScreenSaver : %s' % [args])
|
||||
pass
|
||||
|
||||
|
||||
def logevent(msg):
|
||||
logger.info(msg)
|
||||
|
||||
# def register():
|
||||
# call the CoInitialize to allow the registration to run in an other
|
||||
# thread
|
||||
# pythoncom.CoInitialize()
|
||||
|
||||
# logevent('Registring ISensLogon')
|
||||
|
||||
# sl=SensLogon()
|
||||
# subscription_interface=pythoncom.WrapObject(sl)
|
||||
|
||||
# event_system=win32com.client.Dispatch(PROGID_EventSystem)
|
||||
|
||||
# event_subscription=win32com.client.Dispatch(PROGID_EventSubscription)
|
||||
# event_subscription.EventClassID=SENSGUID_EVENTCLASS_LOGON
|
||||
# event_subscription.PublisherID=SENSGUID_PUBLISHER
|
||||
# event_subscription.SubscriptionName='Python subscription'
|
||||
# event_subscription.SubscriberInterface=subscription_interface
|
||||
|
||||
# event_system.Store(PROGID_EventSubscription, event_subscription)
|
||||
|
||||
# pythoncom.PumpMessages()
|
||||
# #logevent('ISensLogon stopped')
|
331
actors/src/udsactor/windows/UDSActorService.py
Normal file
331
actors/src/udsactor/windows/UDSActorService.py
Normal file
@@ -0,0 +1,331 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
# pylint: disable=unused-wildcard-import, wildcard-import
|
||||
|
||||
import win32serviceutil # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32service # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32net # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32event # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32com.client # @UnresolvedImport, @UnusedImport, pylint: disable=import-error
|
||||
import pythoncom # @UnresolvedImport, pylint: disable=import-error
|
||||
import servicemanager # @UnresolvedImport, pylint: disable=import-error
|
||||
import os
|
||||
|
||||
from udsactor import operations
|
||||
from udsactor.service import CommonService
|
||||
from udsactor.service import initCfg
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
from .SENS import SensLogon
|
||||
from .SENS import logevent
|
||||
from .SENS import SENSGUID_EVENTCLASS_LOGON
|
||||
from .SENS import SENSGUID_PUBLISHER
|
||||
from .SENS import PROGID_EventSubscription
|
||||
from .SENS import PROGID_EventSystem
|
||||
|
||||
|
||||
class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
'''
|
||||
This class represents a Windows Service for managing actor interactions
|
||||
with UDS Broker and Machine
|
||||
'''
|
||||
_svc_name_ = "UDSActor"
|
||||
_svc_display_name_ = "UDS Actor Service"
|
||||
_svc_description_ = "UDS Actor for machines managed by UDS Broker"
|
||||
# 'System Event Notification' is the SENS service
|
||||
_svc_deps_ = ['EventLog', 'SENS']
|
||||
|
||||
def __init__(self, args):
|
||||
win32serviceutil.ServiceFramework.__init__(self, args)
|
||||
CommonService.__init__(self)
|
||||
self.hWaitStop = win32event.CreateEvent(None, 1, 0, None)
|
||||
self._user = None
|
||||
|
||||
def SvcStop(self):
|
||||
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
|
||||
self.isAlive = False
|
||||
win32event.SetEvent(self.hWaitStop)
|
||||
|
||||
SvcShutdown = SvcStop
|
||||
|
||||
def notifyStop(self):
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STOPPED,
|
||||
(self._svc_name_, ''))
|
||||
|
||||
def doWait(self, miliseconds):
|
||||
win32event.WaitForSingleObject(self.hWaitStop, miliseconds)
|
||||
|
||||
def rename(self, name, user=None, oldPassword=None, newPassword=None):
|
||||
'''
|
||||
Renames the computer, and optionally sets a password for an user
|
||||
before this
|
||||
'''
|
||||
hostName = operations.getComputerName()
|
||||
|
||||
if hostName.lower() == name.lower():
|
||||
logger.info('Computer name is now {}'.format(hostName))
|
||||
self.setReady()
|
||||
return
|
||||
|
||||
# Check for password change request for an user
|
||||
if user is not None:
|
||||
logger.info('Setting password for user {}'.format(user))
|
||||
try:
|
||||
operations.changeUserPassword(user, oldPassword, newPassword)
|
||||
except Exception as e:
|
||||
# We stop here without even renaming computer, because the
|
||||
# process has failed
|
||||
raise Exception(
|
||||
'Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(user, unicode(e)))
|
||||
|
||||
operations.renameComputer(name)
|
||||
# Reboot just after renaming
|
||||
logger.info('Rebooting computer got activate new name {}'.format(name))
|
||||
self.reboot()
|
||||
|
||||
def oneStepJoin(self, name, domain, ou, account, password):
|
||||
'''
|
||||
Ejecutes the join domain in exactly one step
|
||||
'''
|
||||
currName = operations.getComputerName()
|
||||
# If name is desired, simply execute multiStepJoin, because computer
|
||||
# name will not change
|
||||
if currName.lower() == name.lower():
|
||||
self.multiStepJoin(name, domain, ou, account, password)
|
||||
else:
|
||||
operations.renameComputer(name)
|
||||
logger.debug('Computer renamed to {} without reboot'.format(name))
|
||||
operations.joinDomain(
|
||||
domain, ou, account, password, executeInOneStep=True)
|
||||
logger.debug(
|
||||
'Requested join domain {} without errors'.format(domain))
|
||||
self.reboot()
|
||||
|
||||
def multiStepJoin(self, name, domain, ou, account, password):
|
||||
currName = operations.getComputerName()
|
||||
if currName.lower() == name.lower():
|
||||
currDomain = operations.getDomainName()
|
||||
if currDomain is not None:
|
||||
# logger.debug('Name: "{}" vs "{}", Domain: "{}" vs "{}"'.format(currName.lower(), name.lower(), currDomain.lower(), domain.lower()))
|
||||
logger.info(
|
||||
'Machine {} is part of domain {}'.format(name, domain))
|
||||
self.setReady()
|
||||
else:
|
||||
operations.joinDomain(
|
||||
domain, ou, account, password, executeInOneStep=False)
|
||||
self.reboot()
|
||||
else:
|
||||
operations.renameComputer(name)
|
||||
logger.info(
|
||||
'Rebooting computer got activate new name {}'.format(name))
|
||||
self.reboot()
|
||||
|
||||
def joinDomain(self, name, domain, ou, account, password):
|
||||
ver = operations.getWindowsVersion()
|
||||
ver = ver[0] * 10 + ver[1]
|
||||
logger.debug('Starting joining domain {} with name {} (detected operating version: {})'.format(
|
||||
domain, name, ver))
|
||||
# Accepts one step joinDomain, also remember XP is no more supported by
|
||||
# microsoft, but this also must works with it because will do a "multi
|
||||
# step" join
|
||||
if ver >= 60:
|
||||
self.oneStepJoin(name, domain, ou, account, password)
|
||||
else:
|
||||
self.multiStepJoin(name, domain, ou, account, password)
|
||||
|
||||
def preConnect(self, user, protocol):
|
||||
logger.debug('Pre connect invoked')
|
||||
if protocol != 'rdp': # If connection is not using rdp, skip adding user
|
||||
return 'ok'
|
||||
# Well known SSID for Remote Desktop Users
|
||||
REMOTE_USERS_SID = 'S-1-5-32-555'
|
||||
|
||||
p = win32security.GetBinarySid(REMOTE_USERS_SID)
|
||||
groupName = win32security.LookupAccountSid(None, p)[0]
|
||||
|
||||
useraAlreadyInGroup = False
|
||||
resumeHandle = 0
|
||||
while True:
|
||||
users, _, resumeHandle = win32net.NetLocalGroupGetMembers(None, groupName, 1, resumeHandle, 32768)
|
||||
if user in [u['name'] for u in users]:
|
||||
useraAlreadyInGroup = True
|
||||
break
|
||||
if resumeHandle == 0:
|
||||
break
|
||||
|
||||
if useraAlreadyInGroup is False:
|
||||
logger.debug('User not in group, adding it')
|
||||
self._user = user
|
||||
try:
|
||||
userSSID = win32security.LookupAccountName(None, user)[0]
|
||||
win32net.NetLocalGroupAddMembers(None, groupName, 0, [{'sid': userSSID}])
|
||||
except Exception as e:
|
||||
logger.error('Exception adding user to Remote Desktop Users: {}'.format(e))
|
||||
else:
|
||||
self._user = None
|
||||
logger.debug('User {} already in group'.format(user))
|
||||
|
||||
return 'ok'
|
||||
|
||||
def onLogout(self, user):
|
||||
logger.debug('Windows onLogout invoked: {}, {}'.format(user, self._user))
|
||||
try:
|
||||
REMOTE_USERS_SID = 'S-1-5-32-555'
|
||||
p = win32security.GetBinarySid(REMOTE_USERS_SID)
|
||||
groupName = win32security.LookupAccountSid(None, p)[0]
|
||||
except Exception:
|
||||
logger.error('Exception getting Windows Group')
|
||||
return
|
||||
|
||||
if self._user is not None:
|
||||
try:
|
||||
win32net.NetLocalGroupDelMembers(None, groupName, [self._user])
|
||||
except Exception as e:
|
||||
logger.error('Exception removing user from Remote Desktop Users: {}'.format(e))
|
||||
|
||||
def SvcDoRun(self):
|
||||
'''
|
||||
Main service loop
|
||||
'''
|
||||
try:
|
||||
initCfg()
|
||||
|
||||
logger.debug('running SvcDoRun')
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STARTED,
|
||||
(self._svc_name_, ''))
|
||||
|
||||
# call the CoInitialize to allow the registration to run in an other
|
||||
# thread
|
||||
logger.debug('Initializing com...')
|
||||
pythoncom.CoInitialize()
|
||||
|
||||
# ********************************************************
|
||||
# * Ask brokers what to do before proceding to main loop *
|
||||
# ********************************************************
|
||||
while True:
|
||||
brokerConnected = self.interactWithBroker()
|
||||
if brokerConnected is False:
|
||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
||||
self.notifyStop()
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
||||
return
|
||||
elif brokerConnected is True:
|
||||
break
|
||||
|
||||
# If brokerConnected returns None, repeat the cycle
|
||||
self.doWait(16000) # Wait for a looong while
|
||||
|
||||
if self.interactWithBroker() is False:
|
||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
||||
self.notifyStop()
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
||||
return
|
||||
|
||||
if self.isAlive is False:
|
||||
logger.debug('The service is not alive after broker interaction, stopping it')
|
||||
self.notifyStop()
|
||||
return
|
||||
|
||||
if self.rebootRequested is True:
|
||||
logger.debug('Reboot has been requested, stopping service')
|
||||
self.notifyStop()
|
||||
return
|
||||
|
||||
self.initIPC()
|
||||
except Exception: # Any init exception wil be caught, service must be then restarted
|
||||
logger.exception()
|
||||
logger.debug('Exiting service with failure status')
|
||||
os._exit(-1) # pylint: disable=protected-access
|
||||
|
||||
# ********************************
|
||||
# * Registers SENS subscriptions *
|
||||
# ********************************
|
||||
logevent('Registering ISensLogon')
|
||||
subscription_guid = '{41099152-498E-11E4-8FD3-10FEED05884B}'
|
||||
sl = SensLogon(self)
|
||||
subscription_interface = pythoncom.WrapObject(sl)
|
||||
|
||||
event_system = win32com.client.Dispatch(PROGID_EventSystem)
|
||||
|
||||
event_subscription = win32com.client.Dispatch(PROGID_EventSubscription)
|
||||
event_subscription.EventClassID = SENSGUID_EVENTCLASS_LOGON
|
||||
event_subscription.PublisherID = SENSGUID_PUBLISHER
|
||||
event_subscription.SubscriptionName = 'UDS Actor subscription'
|
||||
event_subscription.SubscriptionID = subscription_guid
|
||||
event_subscription.SubscriberInterface = subscription_interface
|
||||
|
||||
event_system.Store(PROGID_EventSubscription, event_subscription)
|
||||
|
||||
logger.debug('Registered SENS, running main loop')
|
||||
|
||||
# *********************
|
||||
# * Main Service loop *
|
||||
# *********************
|
||||
# Counter used to check ip changes only once every 10 seconds, for
|
||||
# example
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
counter += 1
|
||||
# Process SENS messages, This will be a bit asyncronous (1 second
|
||||
# delay)
|
||||
pythoncom.PumpWaitingMessages()
|
||||
if counter >= 15: # Once every 15 seconds
|
||||
counter = 0
|
||||
try:
|
||||
self.checkIpsChanged()
|
||||
except Exception as e:
|
||||
logger.error('Error checking ip change: {}'.format(e))
|
||||
# In milliseconds, will break
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 1000)
|
||||
|
||||
logger.debug('Exited main loop, deregistering SENS')
|
||||
|
||||
# *******************************************
|
||||
# * Remove SENS subscription before exiting *
|
||||
# *******************************************
|
||||
event_system.Remove(
|
||||
PROGID_EventSubscription, "SubscriptionID == " + subscription_guid)
|
||||
|
||||
self.endIPC() # Ends IPC servers
|
||||
self.endAPI() # And deinitializes REST api if needed
|
||||
|
||||
self.notifyStop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
initCfg()
|
||||
win32serviceutil.HandleCommandLine(UDSActorSvc)
|
32
actors/src/udsactor/windows/__init__.py
Normal file
32
actors/src/udsactor/windows/__init__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
77
actors/src/udsactor/windows/log.py
Normal file
77
actors/src/udsactor/windows/log.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import servicemanager # @UnresolvedImport, pylint: disable=import-error
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6))
|
||||
|
||||
|
||||
class LocalLogger(object):
|
||||
def __init__(self):
|
||||
# tempdir is different for "user application" and "service"
|
||||
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
|
||||
logging.basicConfig(
|
||||
filename=os.path.join(tempfile.gettempdir(), 'udsactor.log'),
|
||||
filemode='a',
|
||||
format='%(levelname)s %(asctime)s %(message)s',
|
||||
level=logging.INFO
|
||||
)
|
||||
self.logger = logging.getLogger('udsactor')
|
||||
self.serviceLogger = False
|
||||
|
||||
def log(self, level, message):
|
||||
# Debug messages are logged to a file
|
||||
# our loglevels are 10000 (other), 20000 (debug), ....
|
||||
# logging levels are 10 (debug), 20 (info)
|
||||
# OTHER = logging.NOTSET
|
||||
self.logger.log(level / 1000 - 10, message)
|
||||
|
||||
if level < INFO or self.serviceLogger is False: # Only information and above will be on event log
|
||||
return
|
||||
|
||||
if level < WARN: # Info
|
||||
servicemanager.LogInfoMsg(message)
|
||||
elif level < ERROR: # WARN
|
||||
servicemanager.LogWarningMsg(message)
|
||||
else: # Error & Fatal
|
||||
servicemanager.LogErrorMsg(message)
|
||||
|
||||
def isWindows(self):
|
||||
return True
|
||||
|
||||
def isLinux(self):
|
||||
return False
|
220
actors/src/udsactor/windows/operations.py
Normal file
220
actors/src/udsactor/windows/operations.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import win32com.client # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32net # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32api # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32con # @UnresolvedImport, pylint: disable=import-error
|
||||
import ctypes
|
||||
from ctypes.wintypes import DWORD, LPCWSTR
|
||||
import os
|
||||
|
||||
from udsactor import utils
|
||||
from udsactor.log import logger
|
||||
|
||||
|
||||
def getErrorMessage(res=0):
|
||||
# sys_fs_enc = sys.getfilesystemencoding() or 'mbcs'
|
||||
msg = win32api.FormatMessage(res)
|
||||
return msg.decode('windows-1250', 'ignore')
|
||||
|
||||
|
||||
def getComputerName():
|
||||
return win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
|
||||
|
||||
|
||||
def getNetworkInfo():
|
||||
obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
|
||||
wmobj = obj.ConnectServer("localhost", "root\cimv2")
|
||||
adapters = wmobj.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IpEnabled=True")
|
||||
try:
|
||||
for obj in adapters:
|
||||
for ip in obj.IPAddress:
|
||||
if ':' in ip: # Is IPV6, skip this
|
||||
continue
|
||||
if ip is None or ip == '' or ip.startswith('169.254') or ip.startswith('0.'): # If single link ip, or no ip
|
||||
continue
|
||||
# logger.debug('Net config found: {}=({}, {})'.format(obj.Caption, obj.MACAddress, ip))
|
||||
yield utils.Bunch(name=obj.Caption, mac=obj.MACAddress, ip=ip)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
def getDomainName():
|
||||
'''
|
||||
Will return the domain name if we belong a domain, else None
|
||||
(if part of a network group, will also return None)
|
||||
'''
|
||||
# Status:
|
||||
# 0 = Unknown
|
||||
# 1 = Unjoined
|
||||
# 2 = Workgroup
|
||||
# 3 = Domain
|
||||
domain, status = win32net.NetGetJoinInformation()
|
||||
if status != 3:
|
||||
domain = None
|
||||
|
||||
return domain
|
||||
|
||||
|
||||
def getWindowsVersion():
|
||||
return win32api.GetVersionEx()
|
||||
|
||||
EWX_LOGOFF = 0x00000000
|
||||
EWX_SHUTDOWN = 0x00000001
|
||||
EWX_REBOOT = 0x00000002
|
||||
EWX_FORCE = 0x00000004
|
||||
EWX_POWEROFF = 0x00000008
|
||||
EWX_FORCEIFHUNG = 0x00000010
|
||||
|
||||
|
||||
def reboot(flags=EWX_FORCEIFHUNG | EWX_REBOOT):
|
||||
hproc = win32api.GetCurrentProcess()
|
||||
htok = win32security.OpenProcessToken(hproc, win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY)
|
||||
privs = ((win32security.LookupPrivilegeValue(None, win32security.SE_SHUTDOWN_NAME), win32security.SE_PRIVILEGE_ENABLED),)
|
||||
win32security.AdjustTokenPrivileges(htok, 0, privs)
|
||||
win32api.ExitWindowsEx(flags, 0)
|
||||
|
||||
|
||||
def loggoff():
|
||||
win32api.ExitWindowsEx(EWX_LOGOFF)
|
||||
|
||||
|
||||
def renameComputer(newName):
|
||||
# Needs admin privileges to work
|
||||
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0: # @UndefinedVariable
|
||||
# win32api.FormatMessage -> returns error string
|
||||
# win32api.GetLastError -> returns error code
|
||||
# (just put this comment here to remember to log this when logger is available)
|
||||
error = getErrorMessage()
|
||||
computerName = win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
|
||||
raise Exception('Error renaming computer from {} to {}: {}'.format(computerName, newName, error))
|
||||
|
||||
NETSETUP_JOIN_DOMAIN = 0x00000001
|
||||
NETSETUP_ACCT_CREATE = 0x00000002
|
||||
NETSETUP_ACCT_DELETE = 0x00000004
|
||||
NETSETUP_WIN9X_UPGRADE = 0x00000010
|
||||
NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020
|
||||
NETSETUP_JOIN_UNSECURE = 0x00000040
|
||||
NETSETUP_MACHINE_PWD_PASSED = 0x00000080
|
||||
NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400
|
||||
NETSETUP_DEFER_SPN_SET = 0x1000000
|
||||
|
||||
|
||||
def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
'''
|
||||
Joins machine to a windows domain
|
||||
:param domain: Domain to join to
|
||||
:param ou: Ou that will hold machine
|
||||
:param account: Account used to join domain
|
||||
:param password: Password of account used to join domain
|
||||
:param executeInOneStep: If true, means that this machine has been renamed and wants to add NETSETUP_JOIN_WITH_NEW_NAME to request so we can do rename/join in one step.
|
||||
'''
|
||||
# If account do not have domain, include it
|
||||
if '@' not in account and '\\' not in account:
|
||||
if '.' in domain:
|
||||
account = account + '@' + domain
|
||||
else:
|
||||
account = domain + '\\' + account
|
||||
|
||||
# Do log
|
||||
flags = NETSETUP_ACCT_CREATE | NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN
|
||||
|
||||
if executeInOneStep:
|
||||
flags |= NETSETUP_JOIN_WITH_NEW_NAME
|
||||
|
||||
flags = DWORD(flags)
|
||||
|
||||
domain = LPCWSTR(domain)
|
||||
|
||||
# Must be in format "ou=.., ..., dc=...,"
|
||||
ou = LPCWSTR(ou) if ou is not None and ou != '' else None
|
||||
account = LPCWSTR(account)
|
||||
password = LPCWSTR(password)
|
||||
|
||||
res = ctypes.windll.netapi32.NetJoinDomain(None, domain, ou, account, password, flags)
|
||||
# Machine found in another ou, use it and warn this on log
|
||||
if res == 2224:
|
||||
flags = DWORD(NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN)
|
||||
res = ctypes.windll.netapi32.NetJoinDomain(None, domain, None, account, password, flags)
|
||||
if res != 0:
|
||||
# Log the error
|
||||
error = getErrorMessage(res)
|
||||
if res == 1355:
|
||||
error = "DC Is not reachable"
|
||||
logger.error('Error joining domain: {}, {}'.format(error, res))
|
||||
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain, account, ', under OU {}'.format(ou) if ou is not None else '', res, error))
|
||||
|
||||
|
||||
def changeUserPassword(user, oldPassword, newPassword):
|
||||
computerName = LPCWSTR(getComputerName())
|
||||
user = LPCWSTR(user)
|
||||
oldPassword = LPCWSTR(oldPassword)
|
||||
newPassword = LPCWSTR(newPassword)
|
||||
|
||||
res = ctypes.windll.netapi32.NetUserChangePassword(computerName, user, oldPassword, newPassword)
|
||||
|
||||
if res != 0:
|
||||
# Log the error, and raise exception to parent
|
||||
error = getErrorMessage()
|
||||
raise Exception('Error changing password for user {}: {}'.format(user.value, error))
|
||||
|
||||
|
||||
class LASTINPUTINFO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('cbSize', ctypes.c_uint),
|
||||
('dwTime', ctypes.c_uint),
|
||||
]
|
||||
|
||||
|
||||
def initIdleDuration(atLeastSeconds):
|
||||
'''
|
||||
In windows, there is no need to set screensaver
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def getIdleDuration():
|
||||
lastInputInfo = LASTINPUTINFO()
|
||||
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
|
||||
ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lastInputInfo))
|
||||
millis = ctypes.windll.kernel32.GetTickCount() - lastInputInfo.dwTime # @UndefinedVariable
|
||||
return millis / 1000.0
|
||||
|
||||
|
||||
def getCurrentUser():
|
||||
'''
|
||||
Returns current logged in username
|
||||
'''
|
||||
return os.environ['USERNAME']
|
95
actors/src/udsactor/windows/store.py
Normal file
95
actors/src/udsactor/windows/store.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from win32com.shell import shell # @UnresolvedImport, pylint: disable=import-error
|
||||
import _winreg as wreg # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security # @UnresolvedImport, pylint: disable=import-error
|
||||
import cPickle
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
# Can be changed to whatever we want, but registry key is protected by permissions
|
||||
def encoder(data):
|
||||
return data.encode('bz2')
|
||||
|
||||
|
||||
def decoder(data):
|
||||
return data.decode('bz2')
|
||||
|
||||
path = 'Software\\UDSActor'
|
||||
baseKey = wreg.HKEY_CURRENT_USER if DEBUG is True else wreg.HKEY_LOCAL_MACHINE # @UndefinedVariable
|
||||
|
||||
|
||||
def checkPermissions():
|
||||
return True if DEBUG else shell.IsUserAnAdmin()
|
||||
|
||||
|
||||
def fixRegistryPermissions(handle):
|
||||
if DEBUG:
|
||||
return
|
||||
# Fix permissions so users can't read this key
|
||||
v = win32security.GetSecurityInfo(handle, win32security.SE_REGISTRY_KEY, win32security.DACL_SECURITY_INFORMATION)
|
||||
dacl = v.GetSecurityDescriptorDacl()
|
||||
n = 0
|
||||
# Remove all normal users access permissions to the registry key
|
||||
while n < dacl.GetAceCount():
|
||||
if unicode(dacl.GetAce(n)[2]) == u'PySID:S-1-5-32-545': # Whell known Users SID
|
||||
dacl.DeleteAce(n)
|
||||
else:
|
||||
n += 1
|
||||
win32security.SetSecurityInfo(handle, win32security.SE_REGISTRY_KEY,
|
||||
win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION,
|
||||
None, None, dacl, None)
|
||||
|
||||
|
||||
def readConfig():
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
||||
data, _ = wreg.QueryValueEx(key, '') # @UndefinedVariable
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
||||
return cPickle.loads(decoder(data))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def writeConfig(data, fixPermissions=True):
|
||||
try:
|
||||
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
except Exception:
|
||||
key = wreg.CreateKeyEx(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||
if fixPermissions is True:
|
||||
fixRegistryPermissions(key.handle)
|
||||
|
||||
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(cPickle.dumps(data))) # @UndefinedVariable
|
||||
wreg.CloseKey(key) # @UndefinedVariable
|
15
actors/src/update.sh
Executable file
15
actors/src/update.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
function process {
|
||||
pyuic4 about-dialog.ui -o about_dialog_ui.py -x
|
||||
pyuic4 message-dialog.ui -o message_dialog_ui.py -x
|
||||
pyuic4 setup-dialog.ui -o setup_dialog_ui.py -x
|
||||
}
|
||||
|
||||
pyrcc4 -py3 UDSActor.qrc -o UDSActor_rc.py
|
||||
|
||||
|
||||
# process current directory ui's
|
||||
process
|
||||
|
4
client/.gitignore
vendored
Normal file
4
client/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/bin
|
||||
/udsclient_*
|
||||
/udsclient-*.tar.gz
|
||||
/*.rpm
|
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tunnelLaucher</name>
|
||||
<name>UDSclient</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
8
client/.pydevproject
Normal file
8
client/.pydevproject
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/${PROJECT_DIR_NAME}/src</path>
|
||||
</pydev_pathproperty>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
</pydev_project>
|
@@ -1,30 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UdsAdmin", "UdsAdmin\UdsAdmin.csproj", "{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Debug|x86.Build.0 = Debug|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Release|x86.ActiveCfg = Release|x86
|
||||
{F8DBFEC2-6B52-4A89-AD0B-1886B2ABC11D}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
224
client/administration/UdsAdmin/Images.Designer.cs
generated
224
client/administration/UdsAdmin/Images.Designer.cs
generated
@@ -1,224 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Este código fue generado por una herramienta.
|
||||
// Versión de runtime:4.0.30319.239
|
||||
//
|
||||
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||
// se vuelve a generar el código.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UdsAdmin {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clase de recurso con establecimiento inflexible de tipos, para buscar cadenas traducidas, etc.
|
||||
/// </summary>
|
||||
// StronglyTypedResourceBuilder generó automáticamente esta clase
|
||||
// a través de una herramienta como ResGen o Visual Studio.
|
||||
// Para agregar o quitar un miembro, edite el archivo .ResX y, a continuación, vuelva a ejecutar ResGen
|
||||
// con la opción /str o vuelva a generar su proyecto de VS.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Images {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Images() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve la instancia de ResourceManager almacenada en caché utilizada por esta clase.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UdsAdmin.Images", typeof(Images).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reemplaza la propiedad CurrentUICulture del subproceso actual para todas las
|
||||
/// búsquedas de recursos mediante esta clase de recurso con establecimiento inflexible de tipos.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap apply16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("apply16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap assignedServices16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("assignedServices16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap authenticators16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("authenticators16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap cache16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("cache16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap cancel16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("cancel16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap connectivity16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("connectivity16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap delete16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("delete16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap deployedService16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("deployedService16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap deployedServices16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("deployedServices16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap downarrow16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("downarrow16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap empty16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("empty16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap find16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("find16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap groups16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("groups16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon iconDeployedServices16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("iconDeployedServices16", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap networks16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("networks16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap new16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("new16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap osmanagers16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("osmanagers16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap publications16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("publications16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap serviceProviders16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("serviceProviders16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap services16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("services16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap transports16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("transports16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap uparrow16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("uparrow16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap users16 {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("users16", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,191 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="apply16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\apply16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="assignedServices16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\assignedServices16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="authenticators16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\authenticators16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="cache16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\cache16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="cancel16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\cancel16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="connectivity16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\connectivity16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="delete16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\delete16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="deployedService16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\deployedService16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="deployedServices16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\deployedServices16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="downarrow16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\downarrow16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="empty16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\empty16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="find16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\find16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="groups16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\groups16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="iconDeployedServices16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\deployedServices16.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="networks16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\networks16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="new16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\new16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="osmanagers16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\osmanagers16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="publications16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\publications16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="serviceProviders16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\serviceProviders16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="services16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\services16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="transports16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\transports16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="uparrow16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\uparrow16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="users16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>Resources\users16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
@@ -1,72 +0,0 @@
|
||||
// Copyright (c) 2012 Virtual Cable S.L.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace UdsAdmin
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Punto de entrada principal para la aplicación.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
string[] args = Environment.GetCommandLineArgs();
|
||||
|
||||
foreach (string arg in args)
|
||||
{
|
||||
if (arg == "--enabledebug" || arg == "--enabledevel")
|
||||
UdsAdmin.Properties.Settings.Default.debug = true;
|
||||
else if (arg == "--disabledebug" || arg == "--disabledevel")
|
||||
UdsAdmin.Properties.Settings.Default.debug = false;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
CultureInfo culture = new CultureInfo(UdsAdmin.Properties.Settings.Default.Locale);
|
||||
Thread.CurrentThread.CurrentCulture = culture;
|
||||
Thread.CurrentThread.CurrentUICulture = culture;
|
||||
forms.LoginForm logForm = new forms.LoginForm();
|
||||
DialogResult res = logForm.ShowDialog();
|
||||
if (res == DialogResult.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Application.Run(new forms.MainForm());
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Resources;
|
||||
|
||||
// La información general sobre un ensamblado se controla mediante el siguiente
|
||||
// conjunto de atributos. Cambie estos atributos para modificar la información
|
||||
// asociada con un ensamblado.
|
||||
[assembly: AssemblyTitle("UDS Administration Client")]
|
||||
[assembly: AssemblyDescription("(c) 2012 Virtual Cable S.L.\nXML-RPC.NET Copyright (c) 2006 Charles Cook")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Virtual Cable S.L.")]
|
||||
[assembly: AssemblyProduct("UDS Administration Client")]
|
||||
[assembly: AssemblyCopyright("Copyright © Virtual Cable 2012")]
|
||||
[assembly: AssemblyTrademark("UDS Admin")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Si establece ComVisible como false, los tipos de este ensamblado no estarán visibles
|
||||
// para los componentes COM. Si necesita obtener acceso a un tipo de este ensamblado desde
|
||||
// COM, establezca el atributo ComVisible como true en este tipo.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// El siguiente GUID sirve como identificador de typelib si este proyecto se expone a COM
|
||||
[assembly: Guid("203d7325-5e07-455f-a27c-09d2c31d00a2")]
|
||||
|
||||
// La información de versión de un ensamblado consta de los cuatro valores siguientes:
|
||||
//
|
||||
// Versión principal
|
||||
// Versión secundaria
|
||||
// Número de compilación
|
||||
// Revisión
|
||||
//
|
||||
// Puede especificar todos los valores o establecer como predeterminados los números de versión de compilación y de revisión
|
||||
// mediante el asterisco ('*'), como se muestra a continuación:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.2.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.2.0.0")]
|
||||
[assembly: NeutralResourcesLanguageAttribute("en")]
|
@@ -1,63 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Este código fue generado por una herramienta.
|
||||
// Versión de runtime:4.0.30319.225
|
||||
//
|
||||
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||
// se vuelve a generar el código.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UdsAdmin.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clase de recurso con establecimiento inflexible de tipos, para buscar cadenas traducidas, etc.
|
||||
/// </summary>
|
||||
// StronglyTypedResourceBuilder generó automáticamente esta clase
|
||||
// a través de una herramienta como ResGen o Visual Studio.
|
||||
// Para agregar o quitar un miembro, edite el archivo .ResX y, a continuación, vuelva a ejecutar ResGen
|
||||
// con la opción /str o vuelva a generar su proyecto de VS.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve la instancia de ResourceManager almacenada en caché utilizada por esta clase.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UdsAdmin.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reemplaza la propiedad CurrentUICulture del subproceso actual para todas las
|
||||
/// búsquedas de recursos mediante esta clase de recurso con establecimiento inflexible de tipos.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
@@ -1,143 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.296
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UdsAdmin.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("en-US")]
|
||||
public string Locale {
|
||||
get {
|
||||
return ((string)(this["Locale"]));
|
||||
}
|
||||
set {
|
||||
this["Locale"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("20000")]
|
||||
public int TimeOut {
|
||||
get {
|
||||
return ((int)(this["TimeOut"]));
|
||||
}
|
||||
set {
|
||||
this["TimeOut"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("93")]
|
||||
public int wUsernameCol {
|
||||
get {
|
||||
return ((int)(this["wUsernameCol"]));
|
||||
}
|
||||
set {
|
||||
this["wUsernameCol"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("220")]
|
||||
public int wNameCol {
|
||||
get {
|
||||
return ((int)(this["wNameCol"]));
|
||||
}
|
||||
set {
|
||||
this["wNameCol"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("81")]
|
||||
public int wStateCol {
|
||||
get {
|
||||
return ((int)(this["wStateCol"]));
|
||||
}
|
||||
set {
|
||||
this["wStateCol"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("93")]
|
||||
public int wLastAccessCol {
|
||||
get {
|
||||
return ((int)(this["wLastAccessCol"]));
|
||||
}
|
||||
set {
|
||||
this["wLastAccessCol"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("250")]
|
||||
public int wCommentsCol {
|
||||
get {
|
||||
return ((int)(this["wCommentsCol"]));
|
||||
}
|
||||
set {
|
||||
this["wCommentsCol"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("320")]
|
||||
public int MaxControlWidth {
|
||||
get {
|
||||
return ((int)(this["MaxControlWidth"]));
|
||||
}
|
||||
set {
|
||||
this["MaxControlWidth"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("200")]
|
||||
public int StatsItems {
|
||||
get {
|
||||
return ((int)(this["StatsItems"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool debug {
|
||||
get {
|
||||
return ((bool)(this["debug"]));
|
||||
}
|
||||
set {
|
||||
this["debug"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="UdsAdmin.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Locale" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">en-US</Value>
|
||||
</Setting>
|
||||
<Setting Name="TimeOut" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">20000</Value>
|
||||
</Setting>
|
||||
<Setting Name="wUsernameCol" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">93</Value>
|
||||
</Setting>
|
||||
<Setting Name="wNameCol" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">220</Value>
|
||||
</Setting>
|
||||
<Setting Name="wStateCol" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">81</Value>
|
||||
</Setting>
|
||||
<Setting Name="wLastAccessCol" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">93</Value>
|
||||
</Setting>
|
||||
<Setting Name="wCommentsCol" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">250</Value>
|
||||
</Setting>
|
||||
<Setting Name="MaxControlWidth" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">320</Value>
|
||||
</Setting>
|
||||
<Setting Name="StatsItems" Type="System.Int32" Scope="Application">
|
||||
<Value Profile="(Default)">200</Value>
|
||||
</Setting>
|
||||
<Setting Name="debug" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user