Compare commits
811 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60505e1638 | ||
|
|
b52c67848c | ||
|
|
a0a7055583 | ||
|
|
83163c2b9b | ||
|
|
fb499570aa | ||
|
|
536d6a65db | ||
|
|
82d0c934ff | ||
|
|
75bb28f376 | ||
|
|
21c7bf604a | ||
|
|
a3de7fc47b | ||
|
|
e3d9c68f5a | ||
|
|
3b27a04590 | ||
|
|
4b9ff6a6f8 | ||
|
|
a2185bf957 | ||
|
|
02f0dd8c59 | ||
|
|
3848a0bcd6 | ||
|
|
e2cc72589a | ||
|
|
4216136d42 | ||
|
|
e9f18fb93e | ||
|
|
395ac68c32 | ||
|
|
461fdc43e9 | ||
|
|
f9888d7ffb | ||
|
|
ec75dedc57 | ||
|
|
a26db3a772 | ||
|
|
ae559bc482 | ||
|
|
b9c3c95129 | ||
|
|
1fbe024e53 | ||
|
|
8948cc56a9 | ||
|
|
af2cfd5a2c | ||
|
|
054ef1b66f | ||
|
|
1f47546846 | ||
|
|
4b3adbcb2f | ||
|
|
8e8488a939 | ||
|
|
8252a2884d | ||
|
|
d766cdcf0c | ||
|
|
4955d8c71d | ||
|
|
566a83bb98 | ||
|
|
785d00a1e0 | ||
|
|
6e6e89463c | ||
|
|
24ccd16311 | ||
|
|
a67dd5dc6a | ||
|
|
144bb40707 | ||
|
|
ed82e34d10 | ||
|
|
0b1c9751e5 | ||
|
|
05f82c66b0 | ||
|
|
32dd7293d0 | ||
|
|
a923563357 | ||
|
|
5e4022cc43 | ||
|
|
5e35072a39 | ||
|
|
bfb88e60e0 | ||
|
|
35df096333 | ||
|
|
c2328ae72c | ||
|
|
02b12dc8e4 | ||
|
|
9a5f0de726 | ||
|
|
4504d45f0c | ||
|
|
b53a30a267 | ||
|
|
3ce6296a58 | ||
|
|
1556dc46c1 | ||
|
|
15bf794f9e | ||
|
|
1c13158e79 | ||
|
|
940863a1a4 | ||
|
|
ccf6780e6d | ||
|
|
abb644eeb8 | ||
|
|
5bfa6ff736 | ||
|
|
da51c070d0 | ||
|
|
6d09f67adc | ||
|
|
ea0c155c27 | ||
|
|
60fb7bc3d5 | ||
|
|
ba59cbd1b3 | ||
|
|
a433eb564b | ||
|
|
9215ae44ba | ||
|
|
ad4aa891cf | ||
|
|
1c03172211 | ||
|
|
92263c6e04 | ||
|
|
0b208008cf | ||
|
|
7db24cc4a0 | ||
|
|
5558136b51 | ||
|
|
d49666835f | ||
|
|
7f5612d0dc | ||
|
|
7253a09531 | ||
|
|
f56e53255e | ||
|
|
27286a1b71 | ||
|
|
a5d4fadca5 | ||
|
|
1165d5ff9c | ||
|
|
c65a4dbe12 | ||
|
|
c335ae6eb4 | ||
|
|
6ffb9dc9ef | ||
|
|
08ce9b903b | ||
|
|
156f6f6cce | ||
|
|
3f681060b2 | ||
|
|
6a4a9a09f5 | ||
|
|
6dae7cd11d | ||
|
|
85f522b055 | ||
|
|
5eb63005ad | ||
|
|
2fb3d52b44 | ||
|
|
7c1fbdd44b | ||
|
|
fdeacaa554 | ||
|
|
d81b00616a | ||
|
|
2af5e0c37b | ||
|
|
7c657796aa | ||
|
|
c8c62354f4 | ||
|
|
62e9f712a0 | ||
|
|
c60ae71bd9 | ||
|
|
99b27fa084 | ||
|
|
52ff0a6a1d | ||
|
|
2a224785c3 | ||
|
|
54ee2a1e97 | ||
|
|
8eace1b1e9 | ||
|
|
eb658ab421 | ||
|
|
53f33b0fc1 | ||
|
|
871966166b | ||
|
|
69e71bbe87 | ||
|
|
ac9274c540 | ||
|
|
bcd9836088 | ||
|
|
4fef4f872e | ||
|
|
d578f585b3 | ||
|
|
42b9e2a406 | ||
|
|
de2f6eeabf | ||
|
|
3fcaf3926a | ||
|
|
b396818c52 | ||
|
|
f89c9769be | ||
|
|
dd9a6c1c7b | ||
|
|
98b92ddc76 | ||
|
|
8e9b144cff | ||
|
|
9cc4021cb3 | ||
|
|
c63c615dc3 | ||
|
|
4055c205da | ||
|
|
dc892cd95b | ||
|
|
f609f1cc9c | ||
|
|
ebad07fde5 | ||
|
|
d44dc77511 | ||
|
|
2a9e0d4c73 | ||
|
|
6ecc500dde | ||
|
|
f452f20189 | ||
|
|
f25719fd9e | ||
|
|
8f0c5e478e | ||
|
|
bbcff986f9 | ||
|
|
1bc3413660 | ||
|
|
bd6f1ec538 | ||
|
|
6c487e159b | ||
|
|
57f9be98b8 | ||
|
|
6a0bebad3b | ||
|
|
4d7e170dcc | ||
|
|
7dad79d5a5 | ||
|
|
2a2298dcec | ||
|
|
31118e222b | ||
|
|
8a02403f83 | ||
|
|
26933d9286 | ||
|
|
a33c9eea0a | ||
|
|
93eae3fdbf | ||
|
|
becfabfc79 | ||
|
|
946c8bd5bf | ||
|
|
5f01a62292 | ||
|
|
739708edb4 | ||
|
|
f21cb39d38 | ||
|
|
05a9e96bbb | ||
|
|
b639c27883 | ||
|
|
9e1bec1ea4 | ||
|
|
3c4ae55407 | ||
|
|
70ca19c6d9 | ||
|
|
92c11b8320 | ||
|
|
7f59ae0b6f | ||
|
|
232819b6bd | ||
|
|
29b83757e3 | ||
|
|
efc4600918 | ||
|
|
e92b87e4dd | ||
|
|
5ef4e2f0dd | ||
|
|
ae2264f344 | ||
|
|
8c32b8ccb1 | ||
|
|
80fb235b06 | ||
|
|
f07e603826 | ||
|
|
bcdf1cc781 | ||
|
|
e9bbaf7075 | ||
|
|
d71a8798dc | ||
|
|
15a9eee66e | ||
|
|
cacafcff58 | ||
|
|
7193d6d28f | ||
|
|
ceaeb02105 | ||
|
|
4942d429f0 | ||
|
|
67093c96bc | ||
|
|
78daa5012d | ||
|
|
748565b6dc | ||
|
|
33581ce5b0 | ||
|
|
7309e6a694 | ||
|
|
61d1c02961 | ||
|
|
87584668dd | ||
|
|
8773022f10 | ||
|
|
1a803fb182 | ||
|
|
e2b23b6ebc | ||
|
|
a5f845625f | ||
|
|
f949291cdc | ||
|
|
2ab1c3a63e | ||
|
|
55805e251c | ||
|
|
844d2ba1ad | ||
|
|
4059815811 | ||
|
|
caac781651 | ||
|
|
ff1e19dbc7 | ||
|
|
95adced183 | ||
|
|
44dbdf2f10 | ||
|
|
68cbd6e6be | ||
|
|
2e8196b753 | ||
|
|
cf9677ec38 | ||
|
|
d7c25cb94b | ||
|
|
c08b4f4fcd | ||
|
|
dd8ecd1380 | ||
|
|
e923be03cc | ||
|
|
c040cf3a3a | ||
|
|
5c0dadcb3a | ||
|
|
6f7f50c82f | ||
|
|
8c90b8ed02 | ||
|
|
121c7bc686 | ||
|
|
743de0fae7 | ||
|
|
9b3b140fad | ||
|
|
ed41d383a3 | ||
|
|
4692cd60ee | ||
|
|
14d3a9eb0a | ||
|
|
20b4d93686 | ||
|
|
80960665ec | ||
|
|
97a5d58f13 | ||
|
|
26258f2768 | ||
|
|
be2514f3c0 | ||
|
|
74535a54ee | ||
|
|
fea5e454fc | ||
|
|
a54c089e6d | ||
|
|
dafe618494 | ||
|
|
cab46874f7 | ||
|
|
cce2cb01f9 | ||
|
|
f31e0d1c13 | ||
|
|
2c029f7532 | ||
|
|
e6f8109749 | ||
|
|
b4f4ed5fe0 | ||
|
|
7fb6fd4fd9 | ||
|
|
38384bd1df | ||
|
|
3a5db7e813 | ||
|
|
df068d6e4d | ||
|
|
318cc86c6b | ||
|
|
2c83038ea8 | ||
|
|
29f111aec4 | ||
|
|
6a24c55f06 | ||
|
|
11ff114a61 | ||
|
|
f7fb87f62b | ||
|
|
3ba8dda800 | ||
|
|
54c1acb669 | ||
|
|
ad5a949d60 | ||
|
|
6901b128d0 | ||
|
|
aa002d1ee4 | ||
|
|
a4edb62743 | ||
|
|
eee8d1d8ff | ||
|
|
2934bfb3e7 | ||
|
|
105bd85441 | ||
|
|
d49cb02d2f | ||
|
|
bc4bbbb7fb | ||
|
|
70a47c80b5 | ||
|
|
ed8deaa1ba | ||
|
|
9b7dfdc01d | ||
|
|
f6e37d0b83 | ||
|
|
4dc07fbc26 | ||
|
|
4d2adf4325 | ||
|
|
bed9b9d54b | ||
|
|
35191c913d | ||
|
|
4f93f1efc6 | ||
|
|
0f5937b387 | ||
|
|
4eda11f79e | ||
|
|
7f7496d64e | ||
|
|
57aa438e64 | ||
|
|
bffe1e3796 | ||
|
|
acc8a24c21 | ||
|
|
74cdd16bc6 | ||
|
|
eed9745c67 | ||
|
|
5fbe1ce66e | ||
|
|
492816ab35 | ||
|
|
16f255745f | ||
|
|
570553f7d6 | ||
|
|
254b918a08 | ||
|
|
f49a960f5e | ||
|
|
b8507c71b6 | ||
|
|
e4698309a4 | ||
|
|
20c57bcac6 | ||
|
|
36c5ec25ab | ||
|
|
3d5c22b640 | ||
|
|
4697e53d7c | ||
|
|
f7d5bc0ab5 | ||
|
|
d7945eed8c | ||
|
|
1d060af852 | ||
|
|
670141aef7 | ||
|
|
93330fc56e | ||
|
|
72df2c1545 | ||
|
|
fc3a1e21d3 | ||
|
|
c20688837f | ||
|
|
1db57a746b | ||
|
|
d9178dd053 | ||
|
|
e163e6f8cf | ||
|
|
4b11007393 | ||
|
|
3929ff2662 | ||
|
|
76b088b5ec | ||
|
|
59388a8f80 | ||
|
|
01dec12909 | ||
|
|
dda27ef45f | ||
|
|
968a7729c3 | ||
|
|
afe64a1b8f | ||
|
|
83ab3c8b07 | ||
|
|
baf20927e4 | ||
|
|
3a126f07c4 | ||
|
|
c1e495b212 | ||
|
|
9a50a378cb | ||
|
|
4cf9dc6eb9 | ||
|
|
86c5c61e84 | ||
|
|
d12888f611 | ||
|
|
1c8bce2935 | ||
|
|
075092857b | ||
|
|
dd09daf28f | ||
|
|
798dc9bf4b | ||
|
|
0a82f950c3 | ||
|
|
dc46dd48b1 | ||
|
|
280be17c3a | ||
|
|
fb6c7d2b64 | ||
|
|
7b80d3c07e | ||
|
|
b2a27591e6 | ||
|
|
fb63d22666 | ||
|
|
dcb171a655 | ||
|
|
b2bc982c1c | ||
|
|
255a0f0ffa | ||
|
|
80ea816bc7 | ||
|
|
b1371aae2b | ||
|
|
c66984cd3b | ||
|
|
27a455ad00 | ||
|
|
69e7c7def3 | ||
|
|
21882c81d8 | ||
|
|
47f53ab47f | ||
|
|
30ac099653 | ||
|
|
1a85927e44 | ||
|
|
b1d55fdf00 | ||
|
|
1c62504b22 | ||
|
|
fe504ed660 | ||
|
|
9507369293 | ||
|
|
84571f05fc | ||
|
|
a6ba9040d9 | ||
|
|
29e61feede | ||
|
|
d055cf789f | ||
|
|
15412c2508 | ||
|
|
c216727735 | ||
|
|
a38b13608e | ||
|
|
0b302915d6 | ||
|
|
009cc28415 | ||
|
|
7007f2e650 | ||
|
|
05b1895205 | ||
|
|
955aa2c9ec | ||
|
|
7b8f6ccd7f | ||
|
|
a6b5401c0b | ||
|
|
6d53e486c5 | ||
|
|
aa35280ca9 | ||
|
|
b5d846442d | ||
|
|
b040187c3f | ||
|
|
804dc12a47 | ||
|
|
5095c543d0 | ||
|
|
3ae850e69b | ||
|
|
4cd01433b7 | ||
|
|
06c47ec10a | ||
|
|
e90bf47d8a | ||
|
|
52c0179e8e | ||
|
|
2209ab226c | ||
|
|
ed0dbf4f18 | ||
|
|
81b2eed342 | ||
|
|
5a555427ee | ||
|
|
9c98465b21 | ||
|
|
8c053797ce | ||
|
|
210085b854 | ||
|
|
e72298ad42 | ||
|
|
3b447b697c | ||
|
|
a3c685388e | ||
|
|
2363793d29 | ||
|
|
969c365a64 | ||
|
|
1d1259e8eb | ||
|
|
55ce1394c6 | ||
|
|
8499d06a14 | ||
|
|
1739ac3935 | ||
|
|
1a802f3e32 | ||
|
|
51d2c2148a | ||
|
|
25d0ec6ddb | ||
|
|
b9d12aec9b | ||
|
|
44f241a4eb | ||
|
|
27e314088e | ||
|
|
be2a041a71 | ||
|
|
38d5394a48 | ||
|
|
2b32fb358c | ||
|
|
7ce1c4acfb | ||
|
|
571c52a0f2 | ||
|
|
47a2ffa313 | ||
|
|
1026d0a290 | ||
|
|
f02dad054b | ||
|
|
36bd2c032f | ||
|
|
5c35ada012 | ||
|
|
e0833ba719 | ||
|
|
7039bbdb51 | ||
|
|
bc4d69ffd8 | ||
|
|
a319838029 | ||
|
|
570ea5bb51 | ||
|
|
7638d9bc39 | ||
|
|
46c993d608 | ||
|
|
0838174622 | ||
|
|
75849ecceb | ||
|
|
9139e64762 | ||
|
|
4d9ca394f4 | ||
|
|
1c88cf96df | ||
|
|
8a6b9d4de7 | ||
|
|
7829643104 | ||
|
|
84ccd323e0 | ||
|
|
e93d8f0f7c | ||
|
|
132a04d9b9 | ||
|
|
332a434499 | ||
|
|
4dc8055830 | ||
|
|
ea7421ea93 | ||
|
|
959f66ad78 | ||
|
|
f9d128994d | ||
|
|
9bf7d5b92a | ||
|
|
445f19dcd2 | ||
|
|
ccffdaa5ee | ||
|
|
804c771cbe | ||
|
|
0ab6734dec | ||
|
|
23ae126026 | ||
|
|
963b7aa78f | ||
|
|
3eb7534ddd | ||
|
|
8dad840f3f | ||
|
|
be128ed1d5 | ||
|
|
fb904840b8 | ||
|
|
b4e81301a3 | ||
|
|
0ada1871ba | ||
|
|
6200eba45d | ||
|
|
7f7c6eb1c4 | ||
|
|
92fb27e188 | ||
|
|
82eebf82d3 | ||
|
|
5607458f60 | ||
|
|
16654d46df | ||
|
|
c8bfd73c8d | ||
|
|
e6a2646a98 | ||
|
|
6dc12f0d3c | ||
|
|
0846ca40cd | ||
|
|
dae55ad500 | ||
|
|
5e361c2087 | ||
|
|
3d7ecd197b | ||
|
|
c0524db98d | ||
|
|
fa8021c048 | ||
|
|
246a761eb7 | ||
|
|
28260afdd9 | ||
|
|
4c42995ebc | ||
|
|
bdc2843b40 | ||
|
|
6e61f38644 | ||
|
|
8ff186d716 | ||
|
|
c58b9d58a9 | ||
|
|
1603516666 | ||
|
|
46e841fc13 | ||
|
|
d4ff5d3022 | ||
|
|
935416cf0d | ||
|
|
7ca75f51e3 | ||
|
|
9b592259aa | ||
|
|
281678892d | ||
|
|
9aace8ae16 | ||
|
|
adcfade7f2 | ||
|
|
d0d51a907e | ||
|
|
0a4e003bde | ||
|
|
7230507f5a | ||
|
|
07744ab88f | ||
|
|
a8f80ca60e | ||
|
|
3011f22101 | ||
|
|
f3098bd6d9 | ||
|
|
b9d3592f3a | ||
|
|
f299cf3ac3 | ||
|
|
48118d5691 | ||
|
|
5d6b71b7a7 | ||
|
|
e5982b49a2 | ||
|
|
bb80da9b19 | ||
|
|
d027901257 | ||
|
|
8b8629ef19 | ||
|
|
3cdab54f5c | ||
|
|
d0342019bc | ||
|
|
3c61cb6f06 | ||
|
|
3863008846 | ||
|
|
22ca2d9552 | ||
|
|
e6029c41a7 | ||
|
|
63cf687f02 | ||
|
|
d30bde715c | ||
|
|
12b9d6ca7d | ||
|
|
0933d913dc | ||
|
|
8aa82a22f4 | ||
|
|
91817a10ff | ||
|
|
8f10d27d0f | ||
|
|
49a7c8df7a | ||
|
|
34780f91be | ||
|
|
851a4d30e1 | ||
|
|
2ab6d13493 | ||
|
|
fd79b317ea | ||
|
|
0e0d53fa00 | ||
|
|
034edbd32a | ||
|
|
ecc438b21e | ||
|
|
d2d3dfbe77 | ||
|
|
addd6ae226 | ||
|
|
5818548dbf | ||
|
|
38e039ac34 | ||
|
|
4c3f45fd8c | ||
|
|
1b7e8a9edf | ||
|
|
af4df90832 | ||
|
|
c99fdfe641 | ||
|
|
211e80cb17 | ||
|
|
d687dfc3e1 | ||
|
|
1ea5b21956 | ||
|
|
aff3af0214 | ||
|
|
f9b2875470 | ||
|
|
606c82921b | ||
|
|
4463fc0550 | ||
|
|
2bdb1ee0ff | ||
|
|
2af27c0a87 | ||
|
|
db9fb73b4d | ||
|
|
aee64183fc | ||
|
|
9cabf72829 | ||
|
|
ec7a2d049c | ||
|
|
11ebe34f55 | ||
|
|
db476951fe | ||
|
|
a49e0d5667 | ||
|
|
605c6bcada | ||
|
|
9c2e5b4219 | ||
|
|
2e1ce6f202 | ||
|
|
650435aaef | ||
|
|
f2248200af | ||
|
|
6a9777895c | ||
|
|
47a8c977d9 | ||
|
|
b138e243ee | ||
|
|
fbab796e76 | ||
|
|
8126fc3c85 | ||
|
|
27a7b2d711 | ||
|
|
86ecacffcb | ||
|
|
8b5d3d0170 | ||
|
|
4c3cb9f295 | ||
|
|
c9f945a08e | ||
|
|
46c6bd74a2 | ||
|
|
61e2add89a | ||
|
|
24fe395cf0 | ||
|
|
aab8968a14 | ||
|
|
de98438102 | ||
|
|
108213f098 | ||
|
|
861271ac04 | ||
|
|
b378f74202 | ||
|
|
866e1df174 | ||
|
|
0bb231eeca | ||
|
|
fb5c82ff85 | ||
|
|
d9f57b4e13 | ||
|
|
4676972493 | ||
|
|
1d3ac34011 | ||
|
|
634a860f5c | ||
|
|
eb00665df1 | ||
|
|
5e77d27021 | ||
|
|
8fec3ede4e | ||
|
|
ae6d5ccfc6 | ||
|
|
e309d96c51 | ||
|
|
2a3b42f83a | ||
|
|
4819a3c8ed | ||
|
|
34d091942a | ||
|
|
ee2abe6751 | ||
|
|
27f0448caf | ||
|
|
6493037251 | ||
|
|
0cd11e1882 | ||
|
|
cfdafa01c9 | ||
|
|
e3852bcb1b | ||
|
|
e33e95c1b2 | ||
|
|
3d0e777d22 | ||
|
|
aeb3d49c06 | ||
|
|
c2cf5adeb2 | ||
|
|
40ab7280ca | ||
|
|
0c37a191fd | ||
|
|
19547bc58f | ||
|
|
bcbe18214b | ||
|
|
eb60a6854c | ||
|
|
11406697be | ||
|
|
b2b576a72d | ||
|
|
e537e4976e | ||
|
|
490254d16b | ||
|
|
a5cc7d973f | ||
|
|
3e000453a5 | ||
|
|
8f090fabef | ||
|
|
91eb4c37cb | ||
|
|
da43f17558 | ||
|
|
3b3c3b0947 | ||
|
|
06e386c253 | ||
|
|
a2ae2d3384 | ||
|
|
3532a73d59 | ||
|
|
b7daffea87 | ||
|
|
e7b9f8c5ec | ||
|
|
9ada58a6e3 | ||
|
|
c8d974cf52 | ||
|
|
c544de8fed | ||
|
|
93ec102a86 | ||
|
|
92bda2b09b | ||
|
|
1cd0358531 | ||
|
|
222fec2fd0 | ||
|
|
3790cbb894 | ||
|
|
05d5798046 | ||
|
|
9e9deb17c7 | ||
|
|
2aedc4f335 | ||
|
|
dfa708e355 | ||
|
|
6d1997ef96 | ||
|
|
db479d8de8 | ||
|
|
741e6407ce | ||
|
|
141f3e57e5 | ||
|
|
00027a41c1 | ||
|
|
e754d3da9f | ||
|
|
bf54a2f171 | ||
|
|
7b7d0082b6 | ||
|
|
3614b1b3da | ||
|
|
39b0670a29 | ||
|
|
1689c46c91 | ||
|
|
0143bdfe14 | ||
|
|
93a9568a77 | ||
|
|
40079b0365 | ||
|
|
168f04e786 | ||
|
|
861a33f4af | ||
|
|
57c52d9eb2 | ||
|
|
f574dedbe8 | ||
|
|
a6d2ecffbb | ||
|
|
300354ef13 | ||
|
|
4a519226f5 | ||
|
|
6a4f6e3638 | ||
|
|
157b042c0a | ||
|
|
9385218c9d | ||
|
|
7482e8d9c4 | ||
|
|
5501d282de | ||
|
|
123bb4af5f | ||
|
|
4d36dae634 | ||
|
|
eac11ab807 | ||
|
|
b6892f1dc6 | ||
|
|
0695b8f84e | ||
|
|
04995f1a10 | ||
|
|
44d9b3ecc8 | ||
|
|
a311509b7c | ||
|
|
0db4229bd4 | ||
|
|
441aad5a18 | ||
|
|
d8d911abf8 | ||
|
|
7423e3f5bc | ||
|
|
48fea35645 | ||
|
|
cef72f11d0 | ||
|
|
ad3039b70f | ||
|
|
73d590cebd | ||
|
|
1d0790471f | ||
|
|
3b3048aa01 | ||
|
|
183fb56b0a | ||
|
|
466be31e6f | ||
|
|
db42bc944b | ||
|
|
102e7338f9 | ||
|
|
01b30b0743 | ||
|
|
947dbac485 | ||
|
|
0d29e85c80 | ||
|
|
89a28e2e95 | ||
|
|
66b2c20b42 | ||
|
|
e6035bcaa5 | ||
|
|
68aac78360 | ||
|
|
4b02141250 | ||
|
|
8e1d321817 | ||
|
|
3354d37aa3 | ||
|
|
7675214092 | ||
|
|
7af8e1916e | ||
|
|
6d4720e58f | ||
|
|
9928815777 | ||
|
|
a7d65fedfb | ||
|
|
464b142130 | ||
|
|
e1bcdce019 | ||
|
|
ced9bad4f8 | ||
|
|
c6140d7eef | ||
|
|
97f4a9de5d | ||
|
|
be1f6a43a7 | ||
|
|
c8d96990d5 | ||
|
|
e9db6edce8 | ||
|
|
eee7f2999f | ||
|
|
01e5ad792e | ||
|
|
aa02644e05 | ||
|
|
26dd740a53 | ||
|
|
952b6d7f95 | ||
|
|
e8742554c2 | ||
|
|
7229da2fbb | ||
|
|
39db77eb7c | ||
|
|
d866758a0d | ||
|
|
4d72d08e26 | ||
|
|
2e169a8c3a | ||
|
|
978ce0827f | ||
|
|
fe94e4833d | ||
|
|
592f04389f | ||
|
|
5992e6d701 | ||
|
|
d44ebb7d43 | ||
|
|
852142e9ae | ||
|
|
3ba52f15dd | ||
|
|
502a4dc763 | ||
|
|
d336a761a7 | ||
|
|
9240f9d72b | ||
|
|
cab91ff346 | ||
|
|
2a327549f5 | ||
|
|
5748881a29 | ||
|
|
69aa38c1ff | ||
|
|
aa157cfcb9 | ||
|
|
f963f8d173 | ||
|
|
1d75164aaf | ||
|
|
f503f0543e | ||
|
|
333f7297fa | ||
|
|
3fdfc4a142 | ||
|
|
0ac58224f9 | ||
|
|
3d08fcb4b9 | ||
|
|
c2f11306b1 | ||
|
|
07a0c2c828 | ||
|
|
28eaa637df | ||
|
|
8707e6b2e9 | ||
|
|
7a8d83b693 | ||
|
|
403c0ef7e4 | ||
|
|
3374c14311 | ||
|
|
9eade51d89 | ||
|
|
bc9e4a30cb | ||
|
|
0103c48c97 | ||
|
|
29ecf8a584 | ||
|
|
eec07bc5b8 | ||
|
|
bf23878477 | ||
|
|
043085e8f3 | ||
|
|
39e612d60c | ||
|
|
6f8b1b749d | ||
|
|
439e9296f9 | ||
|
|
1332b49370 | ||
|
|
33a7db5ec4 | ||
|
|
2075e914eb | ||
|
|
758ad91a55 | ||
|
|
e9b604d3c4 | ||
|
|
51aa4f35bd | ||
|
|
fc55882f16 | ||
|
|
d03cbefa57 | ||
|
|
e079c90535 | ||
|
|
8591add0bf | ||
|
|
fbbe4f9c45 | ||
|
|
289c5cd24f | ||
|
|
84a45737d3 | ||
|
|
d083cf774a | ||
|
|
f2ce167bbf | ||
|
|
4e04bbbcf4 | ||
|
|
7f5d00e89f | ||
|
|
f777114644 | ||
|
|
7c63a6b8f2 | ||
|
|
f0140999bf | ||
|
|
6f0a249503 | ||
|
|
2e79500f50 | ||
|
|
720b5971d3 | ||
|
|
dba63857e4 | ||
|
|
b05ee653d3 | ||
|
|
84df60368c | ||
|
|
76102ac171 | ||
|
|
3c6e77a2ca | ||
|
|
f6272032a6 | ||
|
|
41fb5e89b4 | ||
|
|
42c9967844 | ||
|
|
e740e2434d | ||
|
|
057df28d1b | ||
|
|
6fbc4b6904 | ||
|
|
cab608f0ec | ||
|
|
f5592d04e2 | ||
|
|
5138496436 | ||
|
|
bcc1e5ff6c | ||
|
|
7eb57d8e9a | ||
|
|
929c12ccc6 | ||
|
|
1ba1b91b8e | ||
|
|
d90a2613fc | ||
|
|
0d25ed2921 | ||
|
|
a07bffa773 | ||
|
|
f0da6ce247 | ||
|
|
32d0a8d703 | ||
|
|
6e2087d5dc | ||
|
|
82f330f4af | ||
|
|
14f86107e1 | ||
|
|
845faf9066 | ||
|
|
7c2b801ee9 | ||
|
|
f96dca5653 | ||
|
|
0e4e9f4253 | ||
|
|
dc38f8c041 | ||
|
|
17f544be36 | ||
|
|
fb59e84def | ||
|
|
de8e33e647 | ||
|
|
cf1bbc603e | ||
|
|
ecc60e59d8 | ||
|
|
e7be6faf2f | ||
|
|
9e3076dde6 | ||
|
|
35103206cf | ||
|
|
29cf00560f | ||
|
|
9ef9302808 | ||
|
|
616b436648 | ||
|
|
702e975d57 | ||
|
|
6c90016c0c | ||
|
|
90152a7eed | ||
|
|
dabd95655b | ||
|
|
4f938e3ea8 | ||
|
|
f21a721ddb | ||
|
|
7d65e60750 | ||
|
|
c87f1b3949 | ||
|
|
08b471fd1e | ||
|
|
4a0d2dcc57 | ||
|
|
91eae526f9 | ||
|
|
11fd2db5a5 | ||
|
|
75e7ce81c2 | ||
|
|
345602926e | ||
|
|
780ea4c631 | ||
|
|
cf9d87a7d8 | ||
|
|
3f2d6f0cee | ||
|
|
22cf450d07 | ||
|
|
8bd7233756 | ||
|
|
2807a71e0e | ||
|
|
b60bcda109 | ||
|
|
4d36165cdf | ||
|
|
44de6e5459 | ||
|
|
d31c593d4b | ||
|
|
0473029277 | ||
|
|
3bef19cbfe | ||
|
|
79fc4850ed |
4
.github/ISSUE_TEMPLATE.md
vendored
@@ -3,7 +3,7 @@
|
||||
Provide a description of the feature request or bug, the more details the better.
|
||||
If you are experiencing an issue with a tracker, a **full log must be included**. Instructions for obtaining logs are here: https://github.com/Jackett/Jackett#troubleshooting
|
||||
|
||||
Jackett version:
|
||||
Mono version (if not using Windows):
|
||||
**Jackett version**:
|
||||
**Mono version** (if not using Windows):
|
||||
|
||||
-------------------------------
|
||||
|
||||
100
.github/appveyor.yml
vendored
@@ -1,100 +0,0 @@
|
||||
version: 0.7.{build}
|
||||
skip_tags: true
|
||||
image: Visual Studio 2015
|
||||
configuration: Release
|
||||
assembly_info:
|
||||
patch: true
|
||||
file: '**\AssemblyInfo.*'
|
||||
assembly_version: '{version}'
|
||||
assembly_file_version: '{version}'
|
||||
assembly_informational_version: '{version}'
|
||||
install:
|
||||
- cmd: choco install InnoSetup
|
||||
before_build:
|
||||
- cmd: nuget restore src\Jackett.sln
|
||||
build:
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
xcopy src\Jackett.Console\bin\Release build.windows\ /e /y
|
||||
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y LICENSE build.windows\LICENSE
|
||||
|
||||
copy /Y README.md build.windows\README.md
|
||||
|
||||
|
||||
xcopy build.windows WindowsBuild\Jackett\ /e /y
|
||||
|
||||
|
||||
msbuild src\Jackett.sln /t:Clean /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
"C:\Program Files (x86)\Mono\bin\xbuild.bat" src\Jackett.sln /t:Build /p:Configuration=Release /verbosity:minimal /tv:12.0
|
||||
|
||||
|
||||
xcopy src\Jackett.Console\bin\Release build.mono\ /e /y
|
||||
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y LICENSE build.mono\LICENSE
|
||||
|
||||
copy /Y README.md build.mono\README.md
|
||||
|
||||
copy /Y Upstart.config build.mono\Upstart.config
|
||||
|
||||
|
||||
xcopy build.mono MonoBuild\Jackett\ /e /y
|
||||
|
||||
|
||||
"C:\Program Files (x86)\Inno Setup 5\ISCC.exe" Installer.iss
|
||||
|
||||
RENAME Output\setup.exe Jackett.Installer.Windows.exe
|
||||
|
||||
MOVE Output\Jackett.Installer.Windows.exe %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
|
||||
cd WindowsBuild
|
||||
|
||||
7z a -tzip -r "%APPVEYOR_BUILD_FOLDER%\Jackett.Binaries.Windows.zip" "Jackett\"
|
||||
|
||||
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
cd MonoBuild
|
||||
|
||||
7z a -ttar "%APPVEYOR_BUILD_FOLDER%\Jackett.Binaries.Mono.tar" "Jackett\"
|
||||
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
7z a -tgzip "Jackett.Binaries.Mono.tar.gz" "Jackett.Binaries.Mono.tar"
|
||||
|
||||
|
||||
appveyor PushArtifact Jackett.Installer.Windows.exe
|
||||
|
||||
appveyor PushArtifact Jackett.Binaries.Windows.zip
|
||||
|
||||
appveyor PushArtifact Jackett.Binaries.Mono.tar.gz
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
tag: v$(appveyor_build_version)
|
||||
auth_token:
|
||||
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
|
||||
draft: true
|
||||
on:
|
||||
branch: master
|
||||
notifications:
|
||||
- provider: GitHubPullRequest
|
||||
auth_token:
|
||||
secure: k6ZZACPbKcvAFiXe/uOmY6Ofs4aw2rgKEWMNA8EilQpdJ6o7ef31we4DPn3SXZzx
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
||||
8
.gitignore
vendored
@@ -194,6 +194,8 @@ FakesAssemblies/
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
/Build.mono
|
||||
/Build.windows
|
||||
/Output
|
||||
/tools
|
||||
/BuildOutput
|
||||
/Artifacts
|
||||
/TestResults
|
||||
*.DS_Store
|
||||
|
||||
37
Build.bat
@@ -1,37 +0,0 @@
|
||||
|
||||
rmdir /s /q build.windows
|
||||
rmdir /s /q build.mono
|
||||
rmdir /s /q Output
|
||||
cd src
|
||||
Msbuild Jackett.sln /t:Clean,Build /p:Configuration=Release /verbosity:minimal
|
||||
cd ..
|
||||
|
||||
xcopy src\Jackett.Console\bin\Release build.windows\ /e /y
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.windows\JackettService.exe
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe.config build.windows\JackettService.exe.config
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe build.windows\JackettTray.exe
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe.config build.windows\JackettTray.exe.config
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe build.windows\JackettUpdater.exe
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe.config build.windows\JackettUpdater.exe.config
|
||||
copy /Y LICENSE build.windows\LICENSE
|
||||
copy /Y README.md build.windows\README.md
|
||||
|
||||
|
||||
cd src
|
||||
Msbuild Jackett.sln /t:Clean
|
||||
call "C:\Program Files (x86)\Mono\bin\xbuild.bat" Jackett.sln /t:Build /p:Configuration=Release /verbosity:minimal
|
||||
cd ..
|
||||
|
||||
xcopy src\Jackett.Console\bin\Release build.mono\ /e /y
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.mono\JackettService.exe
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe.config build.mono\JackettService.exe.config
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe build.mono\JackettTray.exe
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe.config build.mono\JackettTray.exe.config
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe build.mono\JackettUpdater.exe
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe.config build.mono\JackettUpdater.exe.config
|
||||
copy /Y LICENSE build.mono\LICENSE
|
||||
copy /Y README.md build.mono\README.md
|
||||
copy /Y Upstart.config build.mono\Upstart.config
|
||||
|
||||
iscc Installer.iss
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define MyAppName "Jackett"
|
||||
#define MyAppVersion GetFileVersion("build.windows/Jackett.dll")
|
||||
#define MyAppVersion GetFileVersion("BuildOutput\FullFramework\Windows\Jackett\Jackett.Common.dll")
|
||||
#define MyAppPublisher "Jackett Inc."
|
||||
#define MyAppURL "https://github.com/Jackett/Jackett"
|
||||
#define MyAppExeName "JackettTray.exe"
|
||||
@@ -22,7 +22,7 @@ AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={pf}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
DisableProgramGroupPage=yes
|
||||
OutputBaseFilename=setup
|
||||
OutputBaseFilename=Jackett.Installer.Windows
|
||||
SetupIconFile=src\Jackett.Console\jackett.ico
|
||||
UninstallDisplayIcon={commonappdata}\Jackett\JackettConsole.exe
|
||||
Compression=lzma
|
||||
@@ -37,9 +37,9 @@ Name: "windowsService"; Description: "Install as a Windows Service"
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
Source: "build.windows\JackettTray.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
|
||||
Source: "build.windows\JackettUpdater.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
|
||||
Source: "build.windows\*"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "BuildOutput\FullFramework\Windows\Jackett\JackettTray.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
|
||||
Source: "BuildOutput\FullFramework\Windows\Jackett\JackettUpdater.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
|
||||
Source: "BuildOutput\FullFramework\Windows\Jackett\*"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[Icons]
|
||||
|
||||
207
README.md
@@ -1,48 +1,92 @@
|
||||
# Jackett
|
||||
# Jackett
|
||||
|
||||
[](https://github.com/Jackett/Jackett/issues)
|
||||
[](https://github.com/Jackett/Jackett/pulls)
|
||||
[](https://ci.appveyor.com/project/camjac251/jackett)
|
||||
[](https://www.bountysource.com/teams/jackett)
|
||||
[](https://ci.appveyor.com/project/Jackett/jackett)
|
||||
[](https://github.com/Jackett/Jackett/releases/latest)
|
||||
[](https://hub.docker.com/r/linuxserver/jackett/)
|
||||
[](https://discord.gg/J865QuA)
|
||||
|
||||
This project is a new fork and is recruiting development help. If you are able to help out please contact us.
|
||||
|
||||
Jackett works as a proxy server: it translates queries from apps ([Sonarr](https://github.com/Sonarr/Sonarr), [Radarr](https://github.com/Radarr/Radarr), [SickRage](https://sickrage.github.io/), [CouchPotato](https://couchpota.to/), [Mylar](https://github.com/evilhero/mylar), etc) into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
|
||||
Jackett works as a proxy server: it translates queries from apps ([Sonarr](https://github.com/Sonarr/Sonarr), [Radarr](https://github.com/Radarr/Radarr), [SickRage](https://sickrage.github.io/), [CouchPotato](https://couchpota.to/), [Mylar](https://github.com/evilhero/mylar), [DuckieTV](https://github.com/SchizoDuckie/DuckieTV), etc) into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
|
||||
|
||||
Developer note: The software implements the [Torznab](https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer) (with [nZEDb](https://github.com/nZEDb/nZEDb/blob/dev/docs/newznab_api_specification.txt) category numbering) and [TorrentPotato](https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider) APIs.
|
||||
|
||||
|
||||
|
||||
#### Supported Systems
|
||||
* Windows using .NET 4.5
|
||||
* Linux and OSX using Mono 4 (mono 3 is no longer supported).
|
||||
* Windows using .NET 4.5.2 [Download here](https://www.microsoft.com/net/framework/versions/net452).
|
||||
* Linux and macOS using Mono 4.6.0 and above. [Download here](http://www.mono-project.com/download/). Earlier versions of mono may work but some trackers may fail to negotiate SSL correctly, and others may cause Jackett to crash when used.
|
||||
|
||||
### Supported Public Trackers
|
||||
* 1337x
|
||||
* Anidex
|
||||
* Anime Tosho
|
||||
* AniRena
|
||||
* btbit
|
||||
* BTDB
|
||||
* BT-Scene
|
||||
* cpasbien
|
||||
* ETTV
|
||||
* ExtraTorrent.ag
|
||||
* EZTV
|
||||
* Frozen Layer
|
||||
* GkTorrent
|
||||
* Horrible Subs
|
||||
* Idope
|
||||
* Il Corsaro Nero <!-- maintained by bonny1992 -->
|
||||
* Isohunt
|
||||
* Isohunt2
|
||||
* KickAssTorrent
|
||||
* KickAssTorrent (kat.how clone)
|
||||
* KickAssTorrent (thekat.se clone)
|
||||
* LimeTorrents
|
||||
* MagnetDL
|
||||
* NextTorrent
|
||||
* Nyaa.si
|
||||
* Nyaa-Pantsu
|
||||
* Nyoo
|
||||
* OxTorrent
|
||||
* RARBG
|
||||
* RuTor
|
||||
* ShowRSS
|
||||
* Sky torrents
|
||||
* The Pirate Bay
|
||||
* TNTVillage <!-- maintained by bonny1992 -->
|
||||
* Tokyo Toshokan
|
||||
* TorrentProject
|
||||
* Torlock
|
||||
* Torrent Downloads
|
||||
* Torrent9
|
||||
* TorrentKim
|
||||
* Torrentz2
|
||||
|
||||
* World Wide Torrents
|
||||
* YIFY (YTS)
|
||||
* YTS.ag
|
||||
* Zooqle
|
||||
|
||||
### Supported Semi-Private Trackers
|
||||
* 7tor
|
||||
* CzTorrent
|
||||
* Deildu
|
||||
* Gay-Torrents.net
|
||||
* Kinozal
|
||||
* LostFilm.tv
|
||||
* Mega-Bliz
|
||||
* Metal Tracker
|
||||
* MVGroup Forum
|
||||
* MVGroup Main
|
||||
* Newstudio
|
||||
* NetHD
|
||||
* NoName Club
|
||||
* RuTracker
|
||||
* SkTorrent
|
||||
* Union Fansub
|
||||
* Xtreme Zone
|
||||
* YggTorrent
|
||||
* Ztracker
|
||||
|
||||
### Supported Private Trackers
|
||||
* 2 Fast 4 You
|
||||
* 3D Torrents
|
||||
* 7tor
|
||||
* Abnormal
|
||||
* Acid-Lounge
|
||||
* AlphaRatio
|
||||
@@ -54,92 +98,104 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* ArabaFenice
|
||||
* Arche Torrent
|
||||
* AsianDVDClub
|
||||
* AST4u
|
||||
* Audiobook Torrents
|
||||
* Awesome-HD
|
||||
* Avistaz
|
||||
* B2S-Share
|
||||
* Back-ups
|
||||
* BakaBT [![(invite needed)][inviteneeded]](#)
|
||||
* bB
|
||||
* Best Friends
|
||||
* BeyondHD
|
||||
* BIGTorrent
|
||||
* Bit-City Reloaded
|
||||
* BIT-HDTV
|
||||
* BitHQ
|
||||
* Bithorlo
|
||||
* BitHUmen
|
||||
* BitMe
|
||||
* BitMeTV
|
||||
* BitSoup [![(invite needed)][inviteneeded]](#)
|
||||
* Bitspyder
|
||||
* Blu-bits
|
||||
* BitTorrentFiles [![(invite needed)][inviteneeded]](#)
|
||||
* BJ-Share
|
||||
* BlueBird
|
||||
* BroadcastTheNet [![(invite needed)][inviteneeded]](#)
|
||||
* Blutopia
|
||||
* BroadcastTheNet
|
||||
* BrokenStones
|
||||
* BTNext
|
||||
* Carpathians
|
||||
* CCFBits
|
||||
* CGPeers
|
||||
* CHDBits
|
||||
* Cinematik
|
||||
* Cinemageddon
|
||||
* CinemaZ
|
||||
* Classix
|
||||
* CZTeam
|
||||
* DanishBits
|
||||
* DataScene
|
||||
* Deildu
|
||||
* Demonoid
|
||||
* Diablo Torrent
|
||||
* DigitalHive
|
||||
* Dragon World (DTW)
|
||||
* Downloadville
|
||||
* Dragonworld Reloaded
|
||||
* Dream Team
|
||||
* EliteHD [![(invite needed)][inviteneeded]](#)
|
||||
* Elit Tracker
|
||||
* Elite-Tracker
|
||||
* Empornium
|
||||
* EoT-Forum
|
||||
* eStone
|
||||
* Ethor.net (Thor's Land)
|
||||
* FANO.IN
|
||||
* FileList
|
||||
* Femdomcult
|
||||
* Freedom-HD
|
||||
* FullMixMusic
|
||||
* FunFile
|
||||
* FunkyTorrents
|
||||
* Fuzer
|
||||
* GayTorrent.ru
|
||||
* GazelleGames
|
||||
* GFTracker
|
||||
* Gfxnews
|
||||
* GFXPeers
|
||||
* Ghost City
|
||||
* GigaTorrents [![(invite needed)][inviteneeded]](#)
|
||||
* GigaTorrents
|
||||
* GimmePeers <!-- maintained by jamesb2147 -->
|
||||
* GODS [![(invite needed)][inviteneeded]](#)
|
||||
* Gormogon
|
||||
* Greek Team
|
||||
* HacheDe
|
||||
* Hardbay
|
||||
* HD-Forever
|
||||
* HD-Only
|
||||
* HD-Space
|
||||
* HD-Torrents
|
||||
* HD-Bits.com
|
||||
* HD4Free
|
||||
* HDBits
|
||||
* HDChina
|
||||
* HDClub
|
||||
* HDCity
|
||||
* HDHome
|
||||
* HDME
|
||||
* HDSky
|
||||
* HDTorrents.it
|
||||
* Hebits
|
||||
* Hon3y HD
|
||||
* Hounddawgs
|
||||
* House-of-Torrents
|
||||
* Hyperay
|
||||
* ICE Torrent
|
||||
* I Love Classics
|
||||
* Immortalseed
|
||||
* Infinity-T
|
||||
* inPeril
|
||||
* Insane Tracker
|
||||
* IPTorrents
|
||||
* JPopsuki
|
||||
* Kapaki
|
||||
* Karagarga
|
||||
* Le Paradis Du Net
|
||||
* LinkoManija
|
||||
* LosslessClub
|
||||
* M-Team - TP
|
||||
* Magico
|
||||
* Majomparádé
|
||||
* Majomparádé
|
||||
* Manicomio Share
|
||||
* Mononoké-BT
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
@@ -147,10 +203,8 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* MySpleen
|
||||
* NCore
|
||||
* Nebulance
|
||||
* NetHD
|
||||
* New Real World
|
||||
* NextGen
|
||||
* Norbits [![(invite needed)][inviteneeded]](#) <!-- added by DiseaseNO but no longer maintained? -->
|
||||
* Norbits <!-- added by DiseaseNO but no longer maintained? -->
|
||||
* notwhat.cd
|
||||
* Ourbits
|
||||
* Passione Torrent <!-- maintained by bonny1992 -->
|
||||
@@ -163,14 +217,12 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* PrivateHD
|
||||
* Psytorrents
|
||||
* PTFiles
|
||||
* QcTorrent
|
||||
* PuntoTorrent
|
||||
* Redacted (PassTheHeadphones)
|
||||
* RevolutionTT
|
||||
* Rockhard Lossless
|
||||
* RoDVD
|
||||
* RuTracker
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneReactor
|
||||
* SceneTime
|
||||
* SDBits
|
||||
* Secret Cinema
|
||||
@@ -178,11 +230,15 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* ShareSpaceDB
|
||||
* Shazbat
|
||||
* Shellife
|
||||
* Speed-Share
|
||||
* SpeedCD
|
||||
* SpeedTorrent Reloaded
|
||||
* SportsCult
|
||||
* SportHD
|
||||
* Superbits
|
||||
* Synthesiz3r
|
||||
* Tasmanit
|
||||
* TBPlus
|
||||
* The Empire
|
||||
* The Geeks
|
||||
* The Horror Charnel
|
||||
@@ -193,42 +249,45 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* The Show
|
||||
* The Vault
|
||||
* The-Torrents
|
||||
* TehConnection
|
||||
* TenYardTracker
|
||||
* Torrent Network
|
||||
* Torrent Sector Crew
|
||||
* Torrent411
|
||||
* Torrent9
|
||||
* Torrent.LT
|
||||
* TorrentBD
|
||||
* TorrentBytes
|
||||
* TorrentCCF [![(invite needed)][inviteneeded]](#)
|
||||
* TorrentDay
|
||||
* Torrentech
|
||||
* TorrentHeaven
|
||||
* TorrentHR
|
||||
* Torrenting
|
||||
* Torrentland
|
||||
* TorrentLeech
|
||||
* Torrents.Md
|
||||
* TorrentSeeds
|
||||
* Torrent-Syndikat
|
||||
* TorrentWTF
|
||||
* TorViet
|
||||
* ToTheGlory
|
||||
* TranceTraffic
|
||||
* Trezzor
|
||||
* TV Chaos UK
|
||||
* TV-Vault
|
||||
* u-Torrent
|
||||
* u-torrents (SceneFZ)
|
||||
* UHDBits
|
||||
* Ultimate Gamer Club
|
||||
* ULTRAHDCLUB
|
||||
* Waffles
|
||||
* World-In-HD [![(invite needed)][inviteneeded]](#)
|
||||
* World-In-HD
|
||||
* WorldOfP2P
|
||||
* x264
|
||||
* XSpeeds
|
||||
* Xthor
|
||||
* Xtreme Zone
|
||||
* Ztracker
|
||||
* Your Exotic Torrents
|
||||
* Zamunda.net
|
||||
* Zelka.org
|
||||
|
||||
Trackers marked with [![(invite needed)][inviteneeded]](#) have no active maintainer and are missing features or are broken. If you have an invite for them please send it to kaso1717 -at- gmail.com to get them fixed/improved.
|
||||
|
||||
|
||||
## Installation on Windows
|
||||
|
||||
We recommend you install Jackett as a Windows service using the supplied installer. You may also download the zipped version if you would like to configure everything manually.
|
||||
@@ -244,10 +303,10 @@ To get started with using the installer for Jackett, follow the steps below:
|
||||
|
||||
When installed as a service the tray icon acts as a way to open/start/stop Jackett. If you opted to not install it as a service then Jackett will run its web server from the tray tool.
|
||||
|
||||
Jackett can also be run from the command line if you would like to see log messages (Ensure the server isn't already running from the tray/service). This can be done by using "JackettConsole.exe" (for Command Prompt), found in the Jackett data folder: "%ProgramData%\Jackett".
|
||||
Jackett can also be run from the command line if you would like to see log messages (Ensure the server isn't already running from the tray/service). This can be done by using "JackettConsole.exe" (for Command Prompt), found in the Jackett data folder: "%ProgramData%\Jackett".
|
||||
|
||||
## Installation on Linux
|
||||
1. Install [Mono 4](http://www.mono-project.com/download/#download-lin) or better (version 4.8 is recommended)
|
||||
1. Install [Mono 4.6](http://www.mono-project.com/download/#download-lin) or better (using the latest stable release for your distribution is recommended)
|
||||
* Follow the instructions on the mono website and install the `mono-devel` and the `ca-certificates-mono` packages.
|
||||
* On Red Hat/CentOS/openSUSE/Fedora the `mono-locale-extras` package is also required.
|
||||
2. Install libcurl:
|
||||
@@ -258,20 +317,43 @@ Jackett can also be run from the command line if you would like to see log messa
|
||||
|
||||
Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jackett-on-ubuntu-14-x-for-custom-torrents-in-sonarr/) and [Ubuntu 15.x](http://www.htpcguides.com/install-jackett-ubuntu-15-x-for-custom-torrents-in-sonarr/)
|
||||
|
||||
## Installation on OSX
|
||||
1. Install [Mono 4](http://www.mono-project.com/download/#download-mac) or better (version 4.8 is recommended)
|
||||
* Setup ssl support by running
|
||||
```
|
||||
https://curl.haxx.se/ca/cacert.pem
|
||||
cert-sync --user ~/Downloads/cacert.pem
|
||||
```
|
||||
1. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
|
||||
If you want to run it with a user without a /home directory you need to add `Environment=XDG_CONFIG_HOME=/path/to/folder` to your systemd file, this folder will be used to store your config files.
|
||||
|
||||
## Installation on macOS
|
||||
|
||||
### Prerequisites
|
||||
Install [Mono 4.6](http://www.mono-project.com/download/#download-mac) or better (using the latest pkg installer is recommended).
|
||||
* Setup ssl support by running `curl -sS https://curl.haxx.se/ca/cacert.pem | cert-sync --user /dev/stdin`
|
||||
|
||||
### Install as service
|
||||
1. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases).
|
||||
2. Open the extracted folder and double-click on `install_service_macos`.
|
||||
3. If the installation was a success, you can close the Terminal window.
|
||||
|
||||
The service will start on each logon. You can always stop it by running `launchctl unload ~/Library/LaunchAgents/org.user.Jackett.plist` from Terminal. You can start it again it using `launchctl load ~/Library/LaunchAgents/org.user.Jackett.plist`.
|
||||
Logs are stored as usual under `~/.config/Jackett/log.txt`.
|
||||
|
||||
### Run without installing as a service
|
||||
Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
|
||||
|
||||
## Installation using Docker
|
||||
Detailed instructions are available at [LinuxServer.io Jackett Docker](https://hub.docker.com/r/linuxserver/jackett/). The Jackett Docker is highly recommended, especially if you are having Mono stability issues or having issues running Mono on your system eg. QNAP, Synology. Thanks to [LinuxServer.io](https://linuxserver.io)
|
||||
|
||||
## Installation on Synology
|
||||
Jackett is available as beta package from [SynoCommuniy](https://synocommunity.com/)
|
||||
Jackett is available as beta package from [SynoCommunity](https://synocommunity.com/)
|
||||
|
||||
## Running Jackett behind a reverse proxy
|
||||
When running jackett behind a reverse proxy make sure that the original hostname of the request is passed to Jackett. If HTTPS is used also set the X-Forwarded-Proto header to "https". Don't forget to adjust the "Base Path Override" Jackett option accordingly.
|
||||
|
||||
Example config for apache:
|
||||
```
|
||||
<Location /jackett>
|
||||
ProxyPreserveHost On
|
||||
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
|
||||
ProxyPass http://127.0.0.1:9117
|
||||
ProxyPassReverse http://127.0.0.1:9117
|
||||
</Location>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -279,27 +361,24 @@ Jackett is available as beta package from [SynoCommuniy](https://synocommunity.c
|
||||
|
||||
You can pass various options when running via the command line, see --help for details.
|
||||
|
||||
* __Unable to connect to trackers with invalid SSL certificates__
|
||||
* __Error "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."__
|
||||
|
||||
If you're using mono this is often caused by missing ca-certificates.
|
||||
This is often caused by missing CA certificates.
|
||||
Try reimporting the certificates in this case:
|
||||
|
||||
`wget -O - https://curl.haxx.se/ca/cacert.pem | cert-sync /dev/stdin`
|
||||
|
||||
As a option of last resort you can disable certificate validation using the `--IgnoreSslErrors true` option but it's not recommended to use it as it enables Man-in-the-middle attacks on your connections.
|
||||
- On Linux (as user root): `wget -O - https://curl.haxx.se/ca/cacert.pem | cert-sync /dev/stdin`
|
||||
- On macOS: `curl -sS https://curl.haxx.se/ca/cacert.pem | cert-sync --user /dev/stdin`
|
||||
|
||||
* __Enable logging__
|
||||
|
||||
You can get additional logging with the command line switches `-t -l` or by enabeling `Enhanced logging` via the web interface.
|
||||
You can get additional logging with the command line switches `-t -l` or by enabling `Enhanced logging` via the web interface (followed by clicking on the `Apply Server Settings` button).
|
||||
Please post logs if you are unable to resolve your issue with these switches ensuring to remove your username/password/cookies.
|
||||
The logfiles (log.txt/updater.txt) are stored in `%ProgramData%\Jackett` on Windows and `~/.config/Jackett/` on Linux/OSX.
|
||||
The logfiles (log.txt/updater.txt) are stored in `%ProgramData%\Jackett` on Windows and `~/.config/Jackett/` on Linux/macOS.
|
||||
|
||||
## Creating an issue
|
||||
Please supply as much information about the problem you are experiencing as possible. Your issue has a much greater chance of being resolved if logs are supplied so that we can see what is going on. Creating an issue with '### isn't working' doesn't help anyone to fix the problem.
|
||||
|
||||
## Contributing
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/Jackett/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project.
|
||||
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/Jackett/Jackett/issues). It is recommended to use Visual Studio 2017 when making code changes in this project. You can download the community version for free [here](https://www.visualstudio.com/downloads/).
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
39
appveyor.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
version: 0.8.{build}
|
||||
skip_tags: true
|
||||
image: Visual Studio 2017
|
||||
configuration: Release
|
||||
assembly_info:
|
||||
patch: true
|
||||
file: '**\AssemblyInfo.*'
|
||||
assembly_version: '{version}'
|
||||
assembly_file_version: '{version}'
|
||||
assembly_informational_version: '{version}'
|
||||
dotnet_csproj:
|
||||
patch: true
|
||||
file: '**\*.csproj'
|
||||
version: '{version}'
|
||||
package_version: '{version}'
|
||||
assembly_version: '{version}'
|
||||
file_version: '{version}'
|
||||
informational_version: '{version}'
|
||||
build_script:
|
||||
- ps: .\build.ps1
|
||||
test: off
|
||||
before_deploy:
|
||||
- ps: ${env:release_description} = ( Get-Content -LiteralPath BuildOutput/ReleaseNotes.txt -Encoding UTF8 ) -join "`n";
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
tag: v$(appveyor_build_version)
|
||||
description: $(release_description)
|
||||
auth_token:
|
||||
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
|
||||
draft: true
|
||||
on:
|
||||
branch: master
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://skyhook.glitch.me/api/webhooks/346588605843767297/_VWi5abKliaWsBmQO7AX69tD28FhqSLjKyLBwkSwwT13uyWJQHx5TSWK_iAs-0RzmyvZ/appveyor
|
||||
method: POST
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
||||
286
build.cake
Normal file
@@ -0,0 +1,286 @@
|
||||
#tool nuget:?package=NUnit.ConsoleRunner
|
||||
#addin nuget:?package=Cake.FileHelpers
|
||||
#addin nuget:?package=Cake.Git
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ARGUMENTS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var target = Argument("target", "Default");
|
||||
var configuration = Argument("configuration", "Release");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// PREPARATION
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Define directories.
|
||||
var workingDir = MakeAbsolute(Directory("./"));
|
||||
var artifactsDirName = "Artifacts";
|
||||
var testResultsDirName = "TestResults";
|
||||
|
||||
var windowsBuildFullFramework = "./BuildOutput/FullFramework/Windows";
|
||||
var monoBuildFullFramework = "./BuildOutput/FullFramework/Mono";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TASKS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Task("Info")
|
||||
.Does(() =>
|
||||
{
|
||||
Information(@"Jackett Cake build script starting...");
|
||||
Information(@"Requires InnoSetup and C:\cygwin to be present for packaging (Pre-installed on AppVeyor)");
|
||||
Information(@"Working directory is: " + workingDir);
|
||||
});
|
||||
|
||||
Task("Clean")
|
||||
.IsDependentOn("Info")
|
||||
.Does(() =>
|
||||
{
|
||||
CleanDirectories("./src/**/obj" + configuration);
|
||||
CleanDirectories("./src/**/bin" + configuration);
|
||||
CleanDirectories("./BuildOutput");
|
||||
CleanDirectories("./" + artifactsDirName);
|
||||
CleanDirectories("./" + testResultsDirName);
|
||||
|
||||
Information("Clean completed");
|
||||
});
|
||||
|
||||
Task("Restore-NuGet-Packages")
|
||||
.IsDependentOn("Clean")
|
||||
.Does(() =>
|
||||
{
|
||||
NuGetRestore("./src/Jackett.sln");
|
||||
});
|
||||
|
||||
Task("Build")
|
||||
.IsDependentOn("Restore-NuGet-Packages")
|
||||
.Does(() =>
|
||||
{
|
||||
MSBuild("./src/Jackett.sln", settings => settings.SetConfiguration(configuration));
|
||||
});
|
||||
|
||||
Task("Run-Unit-Tests")
|
||||
.IsDependentOn("Build")
|
||||
.Does(() =>
|
||||
{
|
||||
CreateDirectory("./" + testResultsDirName);
|
||||
var resultsFile = $"./{testResultsDirName}/JackettTestResult.xml";
|
||||
|
||||
NUnit3("./src/**/bin/" + configuration + "/**/*.Test.dll", new NUnit3Settings
|
||||
{
|
||||
Results = new[] { new NUnit3Result { FileName = resultsFile } }
|
||||
});
|
||||
|
||||
if(AppVeyor.IsRunningOnAppVeyor)
|
||||
{
|
||||
AppVeyor.UploadTestResults(resultsFile, AppVeyorTestResultsType.NUnit3);
|
||||
}
|
||||
});
|
||||
|
||||
Task("Copy-Files-Full-Framework")
|
||||
.IsDependentOn("Run-Unit-Tests")
|
||||
.Does(() =>
|
||||
{
|
||||
var windowsOutput = windowsBuildFullFramework + "/Jackett";
|
||||
|
||||
CopyDirectory("./src/Jackett.Console/bin/" + configuration, windowsOutput);
|
||||
CopyFiles("./src/Jackett.Service/bin/" + configuration + "/JackettService.*", windowsOutput);
|
||||
CopyFiles("./src/Jackett.Tray/bin/" + configuration + "/JackettTray.*", windowsOutput);
|
||||
CopyFiles("./src/Jackett.Updater/bin/" + configuration + "/JackettUpdater.*", windowsOutput);
|
||||
CopyFiles("./Upstart.config", windowsOutput);
|
||||
CopyFiles("./LICENSE", windowsOutput);
|
||||
CopyFiles("./README.md", windowsOutput);
|
||||
|
||||
var monoOutput = monoBuildFullFramework + "/Jackett";
|
||||
|
||||
CopyDirectory(windowsBuildFullFramework, monoBuildFullFramework);
|
||||
DeleteFiles(monoOutput + "/JackettService.*");
|
||||
DeleteFiles(monoOutput + "/JackettTray.*");
|
||||
|
||||
Information("Full framework file copy completed");
|
||||
});
|
||||
|
||||
Task("Check-Packaging-Platform")
|
||||
.IsDependentOn("Copy-Files-Full-Framework")
|
||||
.Does(() =>
|
||||
{
|
||||
if (IsRunningOnWindows())
|
||||
{
|
||||
CreateDirectory("./" + artifactsDirName);
|
||||
Information("Platform is Windows");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Packaging is currently only implemented for a Windows environment");
|
||||
}
|
||||
});
|
||||
|
||||
Task("Package-Windows-Installer-Full-Framework")
|
||||
.IsDependentOn("Check-Packaging-Platform")
|
||||
.Does(() =>
|
||||
{
|
||||
InnoSetup("./Installer.iss", new InnoSetupSettings {
|
||||
OutputDirectory = workingDir + "/" + artifactsDirName
|
||||
});
|
||||
});
|
||||
|
||||
Task("Package-Files-Full-Framework-Windows")
|
||||
.IsDependentOn("Check-Packaging-Platform")
|
||||
.Does(() =>
|
||||
{
|
||||
Zip(windowsBuildFullFramework, $"./{artifactsDirName}/Jackett.Binaries.Windows.zip");
|
||||
Information(@"Full Framework Windows Binaries Zipping Completed");
|
||||
});
|
||||
|
||||
Task("Package-Files-Full-Framework-Mono")
|
||||
.IsDependentOn("Check-Packaging-Platform")
|
||||
.Does(() =>
|
||||
{
|
||||
var cygMonoBuildPath = RelativeWinPathToCygPath(monoBuildFullFramework);
|
||||
var tarFileName = "Jackett.Binaries.Mono.tar";
|
||||
var tarArguments = @"-cvf " + cygMonoBuildPath + "/" + tarFileName + " -C " + cygMonoBuildPath + " Jackett --mode ='755'";
|
||||
var gzipArguments = @"-k " + cygMonoBuildPath + "/" + tarFileName;
|
||||
|
||||
RunCygwinCommand("Tar", tarArguments);
|
||||
RunCygwinCommand("Gzip", gzipArguments);
|
||||
|
||||
MoveFile($"{monoBuildFullFramework}/{tarFileName}.gz", $"./{artifactsDirName}/{tarFileName}.gz");
|
||||
});
|
||||
|
||||
Task("Package-Full-Framework")
|
||||
.IsDependentOn("Package-Windows-Installer-Full-Framework")
|
||||
.IsDependentOn("Package-Files-Full-Framework-Windows")
|
||||
.IsDependentOn("Package-Files-Full-Framework-Mono")
|
||||
.Does(() =>
|
||||
{
|
||||
Information("Full Framwork Packaging Completed");
|
||||
});
|
||||
|
||||
Task("Appveyor-Push-Artifacts")
|
||||
.IsDependentOn("Package-Full-Framework")
|
||||
.Does(() =>
|
||||
{
|
||||
if (AppVeyor.IsRunningOnAppVeyor)
|
||||
{
|
||||
foreach (var file in GetFiles(workingDir + $"/{artifactsDirName}/*"))
|
||||
{
|
||||
AppVeyor.UploadArtifact(file.FullPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Information(@"Skipping as not running in AppVeyor Environment");
|
||||
}
|
||||
});
|
||||
|
||||
Task("Potential-Release-Notes")
|
||||
.IsDependentOn("Appveyor-Push-Artifacts")
|
||||
.Does(() =>
|
||||
{
|
||||
string latestTag = GitDescribe(".", false, GitDescribeStrategy.Tags, 0);
|
||||
Information($"Latest tag is: {latestTag}" + Environment.NewLine);
|
||||
|
||||
List<GitCommit> relevantCommits = new List<GitCommit>();
|
||||
|
||||
var commitCollection = GitLog("./", 50);
|
||||
|
||||
foreach(GitCommit commit in commitCollection)
|
||||
{
|
||||
var commitTag = GitDescribe(".", commit.Sha, false, GitDescribeStrategy.Tags, 0);
|
||||
|
||||
if (commitTag == latestTag)
|
||||
{
|
||||
relevantCommits.Add(commit);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
relevantCommits = relevantCommits.AsEnumerable().Reverse().Skip(1).ToList();
|
||||
|
||||
if (relevantCommits.Count() > 0)
|
||||
{
|
||||
List<string> notesList = new List<string>();
|
||||
|
||||
foreach(GitCommit commit in relevantCommits)
|
||||
{
|
||||
notesList.Add($"{commit.MessageShort} (Thank you @{commit.Author.Name})");
|
||||
}
|
||||
|
||||
string buildNote = String.Join(Environment.NewLine, notesList);
|
||||
Information(buildNote);
|
||||
|
||||
FileAppendLines(workingDir + "\\BuildOutput\\ReleaseNotes.txt", notesList.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
Information($"No commit messages found to create release notes");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
private void RunCygwinCommand(string utility, string utilityArguments)
|
||||
{
|
||||
var cygwinDir = @"C:\cygwin\bin\";
|
||||
var utilityProcess = cygwinDir + utility + ".exe";
|
||||
|
||||
Information("CygWin Utility: " + utility);
|
||||
Information("CygWin Directory: " + cygwinDir);
|
||||
Information("Utility Location: " + utilityProcess);
|
||||
Information("Utility Arguments: " + utilityArguments);
|
||||
|
||||
IEnumerable<string> redirectedStandardOutput;
|
||||
IEnumerable<string> redirectedErrorOutput;
|
||||
var exitCodeWithArgument =
|
||||
StartProcess(
|
||||
utilityProcess,
|
||||
new ProcessSettings {
|
||||
Arguments = utilityArguments,
|
||||
WorkingDirectory = cygwinDir,
|
||||
RedirectStandardOutput = true
|
||||
},
|
||||
out redirectedStandardOutput,
|
||||
out redirectedErrorOutput
|
||||
);
|
||||
|
||||
Information(utility + " output:" + Environment.NewLine + string.Join(Environment.NewLine, redirectedStandardOutput.ToArray()));
|
||||
|
||||
// Throw exception if anything was written to the standard error.
|
||||
if (redirectedErrorOutput != null && redirectedErrorOutput.Any())
|
||||
{
|
||||
throw new Exception(
|
||||
string.Format(
|
||||
utility + " Errors ocurred: {0}",
|
||||
string.Join(", ", redirectedErrorOutput)));
|
||||
}
|
||||
|
||||
Information(utility + " Exit code: {0}", exitCodeWithArgument);
|
||||
}
|
||||
|
||||
private string RelativeWinPathToCygPath(string relativePath)
|
||||
{
|
||||
var cygdriveBase = "/cygdrive/" + workingDir.ToString().Replace(":", "").Replace("\\", "/");
|
||||
var cygPath = cygdriveBase + relativePath.Replace(".", "");
|
||||
return cygPath;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TASK TARGETS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Task("Default")
|
||||
.IsDependentOn("Potential-Release-Notes")
|
||||
.Does(() =>
|
||||
{
|
||||
Information("Default Task Completed");
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// EXECUTION
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
RunTarget(target);
|
||||
234
build.ps1
Normal file
@@ -0,0 +1,234 @@
|
||||
##########################################################################
|
||||
# This is the Cake bootstrapper script for PowerShell.
|
||||
# This file was downloaded from https://github.com/cake-build/resources
|
||||
# Feel free to change this file to fit your needs.
|
||||
##########################################################################
|
||||
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
This is a Powershell script to bootstrap a Cake build.
|
||||
|
||||
.DESCRIPTION
|
||||
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
|
||||
and execute your Cake build script with the parameters you provide.
|
||||
|
||||
.PARAMETER Script
|
||||
The build script to execute.
|
||||
.PARAMETER Target
|
||||
The build script target to run.
|
||||
.PARAMETER Configuration
|
||||
The build configuration to use.
|
||||
.PARAMETER Verbosity
|
||||
Specifies the amount of information to be displayed.
|
||||
.PARAMETER ShowDescription
|
||||
Shows description about tasks.
|
||||
.PARAMETER DryRun
|
||||
Performs a dry run.
|
||||
.PARAMETER Experimental
|
||||
Uses the nightly builds of the Roslyn script engine.
|
||||
.PARAMETER Mono
|
||||
Uses the Mono Compiler rather than the Roslyn script engine.
|
||||
.PARAMETER SkipToolPackageRestore
|
||||
Skips restoring of packages.
|
||||
.PARAMETER ScriptArgs
|
||||
Remaining arguments are added here.
|
||||
|
||||
.LINK
|
||||
https://cakebuild.net
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[string]$Script = "build.cake",
|
||||
[string]$Target,
|
||||
[string]$Configuration,
|
||||
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
||||
[string]$Verbosity,
|
||||
[switch]$ShowDescription,
|
||||
[Alias("WhatIf", "Noop")]
|
||||
[switch]$DryRun,
|
||||
[switch]$Experimental,
|
||||
[switch]$Mono,
|
||||
[switch]$SkipToolPackageRestore,
|
||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
||||
[string[]]$ScriptArgs
|
||||
)
|
||||
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
|
||||
function MD5HashFile([string] $filePath)
|
||||
{
|
||||
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
|
||||
{
|
||||
return $null
|
||||
}
|
||||
|
||||
[System.IO.Stream] $file = $null;
|
||||
[System.Security.Cryptography.MD5] $md5 = $null;
|
||||
try
|
||||
{
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create()
|
||||
$file = [System.IO.File]::OpenRead($filePath)
|
||||
return [System.BitConverter]::ToString($md5.ComputeHash($file))
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($file -ne $null)
|
||||
{
|
||||
$file.Dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetProxyEnabledWebClient
|
||||
{
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
||||
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||
$wc.Proxy = $proxy
|
||||
return $wc
|
||||
}
|
||||
|
||||
Write-Host "Preparing to run build script..."
|
||||
|
||||
if(!$PSScriptRoot){
|
||||
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
|
||||
}
|
||||
|
||||
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
|
||||
$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
|
||||
$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
|
||||
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
|
||||
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
|
||||
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
|
||||
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
|
||||
$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
|
||||
$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
|
||||
|
||||
# Make sure tools folder exists
|
||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
||||
Write-Verbose -Message "Creating tools directory..."
|
||||
New-Item -Path $TOOLS_DIR -Type directory | out-null
|
||||
}
|
||||
|
||||
# Make sure that packages.config exist.
|
||||
if (!(Test-Path $PACKAGES_CONFIG)) {
|
||||
Write-Verbose -Message "Downloading packages.config..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
|
||||
Throw "Could not download packages.config."
|
||||
}
|
||||
}
|
||||
|
||||
# Try find NuGet.exe in path if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
|
||||
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
|
||||
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
|
||||
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
|
||||
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
|
||||
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
|
||||
}
|
||||
}
|
||||
|
||||
# Try download NuGet.exe if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Downloading NuGet.exe..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile($NUGET_URL, $NUGET_EXE)
|
||||
} catch {
|
||||
Throw "Could not download NuGet.exe."
|
||||
}
|
||||
}
|
||||
|
||||
# Save nuget.exe path to environment to be available to child processed
|
||||
$ENV:NUGET_EXE = $NUGET_EXE
|
||||
|
||||
# Restore tools from NuGet?
|
||||
if(-Not $SkipToolPackageRestore.IsPresent) {
|
||||
Push-Location
|
||||
Set-Location $TOOLS_DIR
|
||||
|
||||
# Check for changes in packages.config and remove installed tools if true.
|
||||
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
|
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
|
||||
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
|
||||
Write-Verbose -Message "Missing or changed package.config hash..."
|
||||
Remove-Item * -Recurse -Exclude packages.config,nuget.exe
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Restoring tools from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occured while restoring NuGet tools."
|
||||
}
|
||||
else
|
||||
{
|
||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
||||
}
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore addins from NuGet
|
||||
if (Test-Path $ADDINS_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $ADDINS_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring addins from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occured while restoring NuGet addins."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore modules from NuGet
|
||||
if (Test-Path $MODULES_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $MODULES_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring modules from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occured while restoring NuGet modules."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Make sure that Cake has been installed.
|
||||
if (!(Test-Path $CAKE_EXE)) {
|
||||
Throw "Could not find Cake.exe at $CAKE_EXE"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Build Cake arguments
|
||||
$cakeArguments = @("$Script");
|
||||
if ($Target) { $cakeArguments += "-target=$Target" }
|
||||
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
||||
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
||||
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
||||
if ($DryRun) { $cakeArguments += "-dryrun" }
|
||||
if ($Experimental) { $cakeArguments += "-experimental" }
|
||||
if ($Mono) { $cakeArguments += "-mono" }
|
||||
$cakeArguments += $ScriptArgs
|
||||
|
||||
# Start Cake
|
||||
Write-Host "Running build script..."
|
||||
&$CAKE_EXE $cakeArguments
|
||||
exit $LASTEXITCODE
|
||||
@@ -26,12 +26,16 @@ namespace CurlSharp
|
||||
/// <description>Debug information as a string.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>size</term>
|
||||
/// <description>The size in bytes.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>extraData</term>
|
||||
/// <description>Client-provided extra data.</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
public delegate void CurlDebugCallback(CurlInfoType infoType, String message, Object extraData);
|
||||
public delegate void CurlDebugCallback(CurlInfoType infoType, String message, int size, Object extraData);
|
||||
|
||||
/// <summary>
|
||||
/// Called when cURL has header data for the client.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2013 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -72,7 +72,7 @@ namespace CurlSharp
|
||||
/// </returns>
|
||||
public static CurlCode GlobalInit(CurlInitFlag flags)
|
||||
{
|
||||
_initCode = NativeMethods.curl_global_init((int)flags);
|
||||
_initCode = NativeMethods.curl_global_init((int) flags);
|
||||
#if USE_LIBCURLSHIM
|
||||
if (_initCode == CurlCode.Ok)
|
||||
NativeMethods.curl_shim_initialize();
|
||||
@@ -99,48 +99,6 @@ namespace CurlSharp
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL encode a String.
|
||||
/// </summary>
|
||||
/// <param name="url">The string to URL encode.</param>
|
||||
/// <param name="length">
|
||||
/// Input string length;
|
||||
/// use 0 for cURL to determine.
|
||||
/// </param>
|
||||
/// <returns>A new URL encoded string.</returns>
|
||||
/// <exception cref="System.InvalidOperationException">
|
||||
/// Thrown if cURL isn't properly initialized.
|
||||
/// </exception>
|
||||
public static string Escape(string url, int length)
|
||||
{
|
||||
EnsureCurl();
|
||||
var p = NativeMethods.curl_escape(url, length);
|
||||
var s = Marshal.PtrToStringAnsi(p);
|
||||
NativeMethods.curl_free(p);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL decode a String.
|
||||
/// </summary>
|
||||
/// <param name="url">The string to URL decode.</param>
|
||||
/// <param name="length">
|
||||
/// Input string length;
|
||||
/// use 0 for cURL to determine.
|
||||
/// </param>
|
||||
/// <returns>A new URL decoded string.</returns>
|
||||
/// <exception cref="System.InvalidOperationException">
|
||||
/// Thrown if cURL isn't properly initialized.
|
||||
/// </exception>
|
||||
public static string Unescape(string url, int length)
|
||||
{
|
||||
EnsureCurl();
|
||||
var p = NativeMethods.curl_unescape(url, length);
|
||||
var s = Marshal.PtrToStringAnsi(p);
|
||||
NativeMethods.curl_free(p);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="CurlVersionInfoData" /> object.
|
||||
/// </summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2014 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -56,7 +56,7 @@ namespace CurlSharp
|
||||
private bool _cookieSession;
|
||||
private CurlShare _curlShare;
|
||||
private string _customRequest;
|
||||
private Object _debugData;
|
||||
private object _debugData;
|
||||
private int _dnsCacheTimeout;
|
||||
private bool _dnsUseGlobalCache;
|
||||
private string _egdSocket;
|
||||
@@ -79,7 +79,7 @@ namespace CurlSharp
|
||||
private bool _ftpUseEprt;
|
||||
private bool _ftpUseEpsv;
|
||||
private GCHandle _hThis;
|
||||
private Object _headerData;
|
||||
private object _headerData;
|
||||
private CurlHttpAuth _httpAuth;
|
||||
private bool _httpGet;
|
||||
private CurlHttpMultiPartForm _httpMultiPartForm;
|
||||
@@ -88,10 +88,8 @@ namespace CurlSharp
|
||||
private bool _ignoreContentLength;
|
||||
private long _infileSize;
|
||||
private string _interface;
|
||||
private Object _ioctlData;
|
||||
private object _ioctlData;
|
||||
private string _krb4Level;
|
||||
private CurlCode _lastErrorCode;
|
||||
private string _lastErrorDescription;
|
||||
private int _lowSpeedLimit;
|
||||
private int _lowSpeedTime;
|
||||
private int _maxConnects;
|
||||
@@ -118,6 +116,7 @@ namespace CurlSharp
|
||||
private NativeMethods._CurlDebugCallback _pcbDebug;
|
||||
private NativeMethods._CurlIoctlCallback _pcbIoctl;
|
||||
private NativeMethods._CurlProgressCallback _pcbProgress;
|
||||
private NativeMethods._CurlSslCtxCallback _pcbSslCtx;
|
||||
#endif
|
||||
private CurlDebugCallback _pfCurlDebug;
|
||||
private CurlHeaderCallback _pfCurlHeader;
|
||||
@@ -130,27 +129,27 @@ namespace CurlSharp
|
||||
private bool _post;
|
||||
private int _postFieldSize;
|
||||
private string _postFields;
|
||||
private Object _privateData;
|
||||
private Object _progressData;
|
||||
private object _progressData;
|
||||
private string _proxy;
|
||||
private int _proxyPort;
|
||||
private string _proxyUserPwd;
|
||||
private bool _put;
|
||||
private string _randomFile;
|
||||
private string _range;
|
||||
private Object _readData;
|
||||
private object _readData;
|
||||
private string _referer;
|
||||
private int _resumeFrom;
|
||||
private string _sourceUrl;
|
||||
private string _sslCert;
|
||||
private string _sslCertPasswd;
|
||||
private string _sslCipherList;
|
||||
private Object _sslContextData;
|
||||
private object _sslContextData;
|
||||
private string _sslEngine;
|
||||
private bool _sslEngineDefault;
|
||||
private string _sslKey;
|
||||
private string _sslKeyPasswd;
|
||||
private bool _sslVerifyPeer;
|
||||
private bool _sslVerifyHost;
|
||||
private bool _tcpNoDelay;
|
||||
private int _timeValue;
|
||||
private int _timeout;
|
||||
@@ -161,7 +160,7 @@ namespace CurlSharp
|
||||
private string _userAgent;
|
||||
private string _userPwd;
|
||||
private bool _verbose;
|
||||
private Object _writeData;
|
||||
private object _writeData;
|
||||
private string _writeInfo;
|
||||
|
||||
/// <summary>
|
||||
@@ -180,6 +179,7 @@ namespace CurlSharp
|
||||
Curl.EnsureCurl();
|
||||
_pCurl = NativeMethods.curl_easy_init();
|
||||
ensureHandle();
|
||||
NativeMethods.curl_easy_setopt(_pCurl, CurlOption.NoSignal, 1L);
|
||||
NativeMethods.curl_easy_setopt(_pCurl, CurlOption.NoProgress, IntPtr.Zero);
|
||||
#if USE_LIBCURLSHIM
|
||||
_pMyStrings = NativeMethods.curl_shim_alloc_strings();
|
||||
@@ -199,11 +199,7 @@ namespace CurlSharp
|
||||
installDelegates();
|
||||
}
|
||||
|
||||
public object Private
|
||||
{
|
||||
get { return _privateData; }
|
||||
set { _privateData = value; }
|
||||
}
|
||||
public object Private { get; set; }
|
||||
|
||||
public object WriteData
|
||||
{
|
||||
@@ -227,6 +223,8 @@ namespace CurlSharp
|
||||
/// <returns></returns>
|
||||
private CurlCode setWriteData(object data)
|
||||
{
|
||||
freeHandle(ref _curlWriteData);
|
||||
|
||||
_curlWriteData = getHandle(data);
|
||||
return setCurlOpt(_curlWriteData, CurlOption.WriteData);
|
||||
}
|
||||
@@ -292,6 +290,18 @@ namespace CurlSharp
|
||||
return setCurlOpt(_curlDebugData, CurlOption.DebugData);
|
||||
}
|
||||
|
||||
private IntPtr _curlSslCtxData = IntPtr.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Object to pass to OnSslCtxCallback.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
private CurlCode setSslCtxData(object data)
|
||||
{
|
||||
_curlSslCtxData = getHandle(data);
|
||||
return setCurlOpt(_curlSslCtxData, CurlOption.SslCtxData);
|
||||
}
|
||||
|
||||
private IntPtr _curlIoctlData = IntPtr.Zero;
|
||||
|
||||
@@ -355,6 +365,17 @@ namespace CurlSharp
|
||||
}
|
||||
}
|
||||
|
||||
public object SslCtxData
|
||||
{
|
||||
get { return _sslContextData; }
|
||||
set
|
||||
{
|
||||
_sslContextData = value;
|
||||
#if !USE_LIBCURLSHIM
|
||||
setSslCtxData(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public object IoctlData
|
||||
{
|
||||
@@ -426,7 +447,7 @@ namespace CurlSharp
|
||||
_ftpAuth = value;
|
||||
var l = Convert.ToInt32(value);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.FtpSslAuth, (IntPtr) l),
|
||||
CurlOption.FtpSslAuth);
|
||||
CurlOption.FtpSslAuth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +459,7 @@ namespace CurlSharp
|
||||
_httpVersion = value;
|
||||
var l = Convert.ToInt32(value);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.HttpVersion, (IntPtr) l),
|
||||
CurlOption.HttpVersion);
|
||||
CurlOption.HttpVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +471,7 @@ namespace CurlSharp
|
||||
_httpAuth = value;
|
||||
var l = Convert.ToInt32(value);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.HttpAuth, (IntPtr) l),
|
||||
CurlOption.HttpAuth);
|
||||
CurlOption.HttpAuth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +483,7 @@ namespace CurlSharp
|
||||
_ftpSsl = value;
|
||||
var l = Convert.ToInt32(value);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.FtpSsl, (IntPtr) l),
|
||||
CurlOption.FtpSsl);
|
||||
CurlOption.FtpSsl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +495,7 @@ namespace CurlSharp
|
||||
_closePolicy = value;
|
||||
var l = Convert.ToInt32(value);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.ClosePolicy, (IntPtr) l),
|
||||
CurlOption.ClosePolicy);
|
||||
CurlOption.ClosePolicy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,12 +535,14 @@ namespace CurlSharp
|
||||
set { setFunctionOptions(CurlOption.IoctlFunction, value); }
|
||||
}
|
||||
|
||||
|
||||
public string LastErrorDescription
|
||||
public CurlSslContextCallback SslContextFunction
|
||||
{
|
||||
get { return _lastErrorDescription; }
|
||||
get { return _pfCurlSslContext; }
|
||||
set { setFunctionOptions(CurlOption.SslCtxFunction, value); }
|
||||
}
|
||||
|
||||
public string LastErrorDescription { get; private set; }
|
||||
|
||||
public bool NoProgress
|
||||
{
|
||||
get { return _noProgress; }
|
||||
@@ -592,6 +615,12 @@ namespace CurlSharp
|
||||
set { setBoolOption(CurlOption.SslVerifyPeer, ref _sslVerifyPeer, value); }
|
||||
}
|
||||
|
||||
public bool SslVerifyhost
|
||||
{
|
||||
get { return _sslVerifyHost; }
|
||||
set { setBoolOption(CurlOption.SslVerifyhost, ref _sslVerifyHost, value); }
|
||||
}
|
||||
|
||||
public bool FreshConnect
|
||||
{
|
||||
get { return _freshConnect; }
|
||||
@@ -1106,10 +1135,7 @@ namespace CurlSharp
|
||||
get { return getSlistInfo(CurlInfo.SslEngines); }
|
||||
}
|
||||
|
||||
public CurlCode LastErrorCode
|
||||
{
|
||||
get { return _lastErrorCode; }
|
||||
}
|
||||
public CurlCode LastErrorCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup unmanaged resources.
|
||||
@@ -1122,7 +1148,7 @@ namespace CurlSharp
|
||||
|
||||
private void resetPrivateVariables()
|
||||
{
|
||||
_privateData = null;
|
||||
Private = null;
|
||||
|
||||
_pfCurlWrite = null;
|
||||
_writeData = null;
|
||||
@@ -1179,10 +1205,10 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
private void setLastError(CurlCode code, CurlOption opt)
|
||||
{
|
||||
if (LastErrorCode == CurlCode.Ok && code != CurlCode.Ok)
|
||||
if ((LastErrorCode == CurlCode.Ok) && (code != CurlCode.Ok))
|
||||
{
|
||||
_lastErrorCode = code;
|
||||
_lastErrorDescription = string.Format("Error: {0} setting option {1}", StrError(code), opt);
|
||||
LastErrorCode = code;
|
||||
LastErrorDescription = string.Format("Error: {0} setting option {1}", StrError(code), opt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1191,10 +1217,10 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
private void setLastError(CurlCode code, CurlInfo info)
|
||||
{
|
||||
if (LastErrorCode == CurlCode.Ok && code != CurlCode.Ok)
|
||||
if ((LastErrorCode == CurlCode.Ok) && (code != CurlCode.Ok))
|
||||
{
|
||||
_lastErrorCode = code;
|
||||
_lastErrorDescription = string.Format("Error: {0} getting info {1}", StrError(code), info);
|
||||
LastErrorCode = code;
|
||||
LastErrorDescription = string.Format("Error: {0} getting info {1}", StrError(code), info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,6 +1259,7 @@ namespace CurlSharp
|
||||
freeHandle(ref _curlProgressData);
|
||||
freeHandle(ref _curlHeaderData);
|
||||
freeHandle(ref _curlIoctlData);
|
||||
freeHandle(ref _curlSslCtxData);
|
||||
#endif
|
||||
NativeMethods.curl_easy_cleanup(_pCurl);
|
||||
|
||||
@@ -1293,6 +1320,12 @@ namespace CurlSharp
|
||||
|
||||
private void setStringOption(CurlOption option, out string field, string value)
|
||||
{
|
||||
// all string options are copied by the library, the only exception to this rule is PostFields option
|
||||
if (option == CurlOption.PostFields)
|
||||
option = CurlOption.CopyPostFields;
|
||||
if ((option == CurlOption.CopyPostFields) && (PostFieldSize == 0))
|
||||
PostFieldSize = System.Text.Encoding.UTF8.GetByteCount(value);
|
||||
|
||||
setStringOption(option, value);
|
||||
field = value;
|
||||
}
|
||||
@@ -1313,7 +1346,13 @@ namespace CurlSharp
|
||||
#else
|
||||
// convert the string to a null-terminated one
|
||||
var buffer = System.Text.Encoding.UTF8.GetBytes(value + "\0");
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, option, buffer), option);
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bufPtr = &buffer[0])
|
||||
{
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, option, buffer), option);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1337,7 +1376,7 @@ namespace CurlSharp
|
||||
/// <see cref="CurlCode.BadFunctionArgument" />
|
||||
/// will be returned if the type of value of <c>parameter</c> is invalid.
|
||||
/// </returns>
|
||||
public CurlCode SetOpt(CurlOption option, Object parameter)
|
||||
public CurlCode SetOpt(CurlOption option, object parameter)
|
||||
{
|
||||
ensureHandle();
|
||||
var retCode = CurlCode.Ok;
|
||||
@@ -1346,10 +1385,8 @@ namespace CurlSharp
|
||||
if ((int) option < CURLOPTTYPE_OBJECTPOINT)
|
||||
{
|
||||
var i = 0;
|
||||
if (option == CurlOption.DnsUseGlobalCache || option == CurlOption.SourcePort)
|
||||
{
|
||||
if ((option == CurlOption.DnsUseGlobalCache) || (option == CurlOption.SourcePort))
|
||||
return CurlCode.BadFunctionArgument;
|
||||
}
|
||||
|
||||
if (option == CurlOption.TimeValue)
|
||||
{
|
||||
@@ -1365,17 +1402,17 @@ namespace CurlSharp
|
||||
retCode = NativeMethods.curl_easy_setopt(_pCurl, option, (IntPtr) i);
|
||||
}
|
||||
|
||||
// object cases: the majority
|
||||
// object cases: the majority
|
||||
else if ((int) option < CURLOPTTYPE_FUNCTIONPOINT)
|
||||
{
|
||||
return setObjectOptions(option, parameter);
|
||||
}
|
||||
// FUNCTIONPOINT args, for delegates
|
||||
// FUNCTIONPOINT args, for delegates
|
||||
else if ((int) option < CURLOPTTYPE_OFF_T)
|
||||
{
|
||||
return setFunctionOptions(option, parameter);
|
||||
}
|
||||
// otherwise, it's one of those 64-bit off_t guys!
|
||||
// otherwise, it's one of those 64-bit off_t guys!
|
||||
else
|
||||
{
|
||||
var i = Convert.ToInt64(parameter);
|
||||
@@ -1390,9 +1427,9 @@ namespace CurlSharp
|
||||
var retCode = CurlCode.Ok;
|
||||
switch (option)
|
||||
{
|
||||
// various data items
|
||||
// various data items
|
||||
case CurlOption.Private:
|
||||
_privateData = parameter;
|
||||
Private = parameter;
|
||||
break;
|
||||
case CurlOption.WriteData:
|
||||
_writeData = parameter;
|
||||
@@ -1409,12 +1446,15 @@ namespace CurlSharp
|
||||
case CurlOption.HeaderData:
|
||||
_headerData = parameter;
|
||||
break;
|
||||
case CurlOption.SslCtxData:
|
||||
_sslContextData = parameter;
|
||||
break;
|
||||
case CurlOption.IoctlData:
|
||||
_ioctlData = parameter;
|
||||
break;
|
||||
|
||||
// items that can't be set externally or
|
||||
// obsolete items
|
||||
// items that can't be set externally or
|
||||
// obsolete items
|
||||
case CurlOption.ErrorBuffer:
|
||||
case CurlOption.Stderr:
|
||||
case CurlOption.SourceHost:
|
||||
@@ -1422,7 +1462,7 @@ namespace CurlSharp
|
||||
case CurlOption.PasvHost:
|
||||
return CurlCode.BadFunctionArgument;
|
||||
|
||||
// singular case for share
|
||||
// singular case for share
|
||||
case CurlOption.Share:
|
||||
{
|
||||
_curlShare = parameter as CurlShare;
|
||||
@@ -1430,7 +1470,7 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// multipart HTTP post
|
||||
// multipart HTTP post
|
||||
case CurlOption.HttpPost:
|
||||
{
|
||||
_httpMultiPartForm = parameter as CurlHttpMultiPartForm;
|
||||
@@ -1438,7 +1478,7 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// items curl wants as a curl_slist
|
||||
// items curl wants as a curl_slist
|
||||
case CurlOption.HttpHeader:
|
||||
case CurlOption.Prequote:
|
||||
case CurlOption.Quote:
|
||||
@@ -1452,12 +1492,12 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// string items
|
||||
// string items
|
||||
default:
|
||||
{
|
||||
var s = parameter as string;
|
||||
setStringOption(option, s);
|
||||
retCode = _lastErrorCode;
|
||||
retCode = LastErrorCode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1560,6 +1600,14 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
case CurlOption.SslCtxFunction:
|
||||
{
|
||||
var sf = pfn as CurlSslContextCallback;
|
||||
if (sf == null)
|
||||
return CurlCode.BadFunctionArgument;
|
||||
_pfCurlSslContext = sf;
|
||||
break;
|
||||
}
|
||||
|
||||
case CurlOption.IoctlFunction:
|
||||
{
|
||||
@@ -1590,7 +1638,13 @@ namespace CurlSharp
|
||||
public CurlCode Perform()
|
||||
{
|
||||
ensureHandle();
|
||||
return NativeMethods.curl_easy_perform(_pCurl);
|
||||
|
||||
var nativeRet = NativeMethods.curl_easy_perform(_pCurl);
|
||||
#if !USE_LIBCURLSHIM
|
||||
freeHandle(ref _curlWriteData);
|
||||
#endif
|
||||
|
||||
return nativeRet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1606,12 +1660,60 @@ namespace CurlSharp
|
||||
return new CurlEasy(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL encode a String.
|
||||
/// </summary>
|
||||
/// <param name="url">The string to URL encode.</param>
|
||||
/// <param name="length">
|
||||
/// Input string length;
|
||||
/// use 0 for cURL to determine.
|
||||
/// </param>
|
||||
/// <returns>A new URL encoded string.</returns>
|
||||
/// <exception cref="NullReferenceException">
|
||||
/// This is thrown if
|
||||
/// the native <c>CURL*</c> handle wasn't created successfully.
|
||||
/// </exception>
|
||||
public string Escape(string url)
|
||||
{
|
||||
ensureHandle();
|
||||
|
||||
var length = System.Text.Encoding.ASCII.GetBytes(url).Length;
|
||||
var p = NativeMethods.curl_easy_escape(_pCurl, url, length);
|
||||
var s = Marshal.PtrToStringAnsi(p);
|
||||
NativeMethods.curl_free(p);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL decode a String.
|
||||
/// </summary>
|
||||
/// <param name="url">The string to URL decode.</param>
|
||||
/// <param name="length">
|
||||
/// Input string length;
|
||||
/// use 0 for cURL to determine.
|
||||
/// </param>
|
||||
/// <returns>A new URL decoded string.</returns>
|
||||
/// <exception cref="NullReferenceException">
|
||||
/// This is thrown if
|
||||
/// the native <c>CURL*</c> handle wasn't created successfully.
|
||||
/// </exception>
|
||||
public string Unescape(string url)
|
||||
{
|
||||
ensureHandle();
|
||||
|
||||
var length = System.Text.Encoding.ASCII.GetBytes(url).Length;
|
||||
var p = NativeMethods.curl_easy_unescape(_pCurl, url, length, out int outLength);
|
||||
var s = Marshal.PtrToStringAnsi(p, outLength);
|
||||
NativeMethods.curl_free(p);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string description of an error code.
|
||||
/// </summary>
|
||||
/// <param name="code">Error code.</param>
|
||||
/// <returns>String description of the error code.</returns>
|
||||
public String StrError(CurlCode code)
|
||||
public string StrError(CurlCode code)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(NativeMethods.curl_easy_strerror(code));
|
||||
}
|
||||
@@ -1635,7 +1737,7 @@ namespace CurlSharp
|
||||
/// This is thrown if
|
||||
/// the native <c>CURL*</c> handle wasn't created successfully.
|
||||
/// </exception>
|
||||
public CurlCode GetInfo(CurlInfo info, ref Object objInfo)
|
||||
public CurlCode GetInfo(CurlInfo info, ref object objInfo)
|
||||
{
|
||||
ensureHandle();
|
||||
var retCode = CurlCode.Ok;
|
||||
@@ -1651,7 +1753,7 @@ namespace CurlSharp
|
||||
// private data
|
||||
if (info == CurlInfo.Private)
|
||||
{
|
||||
objInfo = _privateData;
|
||||
objInfo = Private;
|
||||
return retCode;
|
||||
}
|
||||
|
||||
@@ -1681,7 +1783,7 @@ namespace CurlSharp
|
||||
{
|
||||
ensureHandle();
|
||||
// ensure it's an integral type
|
||||
if ((int) info < CURLINFO_LONG || (int) info >= CURLINFO_DOUBLE)
|
||||
if (((int) info < CURLINFO_LONG) || ((int) info >= CURLINFO_DOUBLE))
|
||||
{
|
||||
setLastError(CurlCode.BadFunctionArgument, info);
|
||||
return -1;
|
||||
@@ -1779,7 +1881,7 @@ namespace CurlSharp
|
||||
var retCode = CurlCode.Ok;
|
||||
var ptr = IntPtr.Zero;
|
||||
|
||||
if ((int) info < CURLINFO_STRING || (int) info >= CURLINFO_LONG)
|
||||
if (((int) info < CURLINFO_STRING) || ((int) info >= CURLINFO_LONG))
|
||||
return CurlCode.BadFunctionArgument;
|
||||
retCode = NativeMethods.curl_easy_getinfo(_pCurl, info, ref ptr);
|
||||
if (retCode == CurlCode.Ok)
|
||||
@@ -1839,7 +1941,7 @@ namespace CurlSharp
|
||||
var ptr = IntPtr.Zero;
|
||||
|
||||
// ensure it's an integral type
|
||||
if ((int) info < CURLINFO_LONG || (int) info >= CURLINFO_DOUBLE)
|
||||
if (((int) info < CURLINFO_LONG) || ((int) info >= CURLINFO_DOUBLE))
|
||||
return CurlCode.BadFunctionArgument;
|
||||
|
||||
retCode = NativeMethods.curl_easy_getinfo(_pCurl, info, ref ptr);
|
||||
@@ -1876,10 +1978,8 @@ namespace CurlSharp
|
||||
|
||||
retCode = NativeMethods.curl_easy_getinfo(_pCurl, info, ref ptr);
|
||||
if (retCode == CurlCode.Ok)
|
||||
{
|
||||
if ((int) ptr < 0)
|
||||
dt = new DateTime(0);
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
@@ -1908,34 +2008,38 @@ namespace CurlSharp
|
||||
_pcbProgress = _curlProgressCallback;
|
||||
_pcbDebug = _curlDebugCallback;
|
||||
_pcbHeader = _curlHeaderCallback;
|
||||
_pcbSslCtx = _curlSslCtxCallback;
|
||||
_pcbIoctl = _curlIoctlCallback;
|
||||
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.WriteFunction, _pcbWrite),
|
||||
CurlOption.WriteFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.ReadFunction, _pcbRead),
|
||||
CurlOption.ReadFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.ProgressFunction, _pcbProgress),
|
||||
CurlOption.ProgressFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.HeaderFunction, _pcbHeader),
|
||||
CurlOption.HeaderFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.DebugFunction, _pcbDebug),
|
||||
CurlOption.DebugFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt_cb(_pCurl, CurlOption.IoctlFunction, _pcbIoctl),
|
||||
CurlOption.IoctlFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.WriteFunction, _pcbWrite),
|
||||
CurlOption.WriteFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.ReadFunction, _pcbRead),
|
||||
CurlOption.ReadFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.ProgressFunction, _pcbProgress),
|
||||
CurlOption.ProgressFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.HeaderFunction, _pcbHeader),
|
||||
CurlOption.HeaderFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.DebugFunction, _pcbDebug),
|
||||
CurlOption.DebugFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.SslCtxFunction, _pcbSslCtx),
|
||||
CurlOption.SslCtxFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.IoctlFunction, _pcbIoctl),
|
||||
CurlOption.IoctlFunction);
|
||||
setLastError(NativeMethods.curl_easy_setopt(_pCurl, CurlOption.NoProgress, (IntPtr) 0),
|
||||
CurlOption.NoProgress);
|
||||
CurlOption.NoProgress);
|
||||
|
||||
setWriteData(null);
|
||||
setReadData(null);
|
||||
setHeaderData(null);
|
||||
setProgressData(null);
|
||||
setDebugData(null);
|
||||
setSslCtxData(null);
|
||||
setIoctlData(null);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
// called by libcurlshim
|
||||
// called by libcurlshim
|
||||
private static int _shimWriteCallback(IntPtr buf, int sz, int nmemb, IntPtr parm)
|
||||
{
|
||||
var bytes = sz*nmemb;
|
||||
@@ -1958,9 +2062,7 @@ namespace CurlSharp
|
||||
var b = new byte[bytes];
|
||||
var gch = (GCHandle) parm;
|
||||
var curlEasy = (CurlEasy) gch.Target;
|
||||
if (curlEasy == null)
|
||||
return 0;
|
||||
if (curlEasy._pfCurlRead == null)
|
||||
if (curlEasy?._pfCurlRead == null)
|
||||
return 0;
|
||||
var nRead = curlEasy._pfCurlRead(b, sz, nmemb, curlEasy._readData);
|
||||
if (nRead > 0)
|
||||
@@ -1976,9 +2078,7 @@ namespace CurlSharp
|
||||
{
|
||||
var gch = (GCHandle) parm;
|
||||
var curlEasy = (CurlEasy) gch.Target;
|
||||
if (curlEasy == null)
|
||||
return 0;
|
||||
if (curlEasy._pfCurlProgress == null)
|
||||
if (curlEasy?._pfCurlProgress == null)
|
||||
return 0;
|
||||
var nprog = curlEasy._pfCurlProgress(curlEasy._progressData, dlTotal, dlNow, ulTotal, ulNow);
|
||||
return nprog;
|
||||
@@ -1989,12 +2089,10 @@ namespace CurlSharp
|
||||
{
|
||||
var gch = (GCHandle) parm;
|
||||
var curlEasy = (CurlEasy) gch.Target;
|
||||
if (curlEasy == null)
|
||||
return 0;
|
||||
if (curlEasy._pfCurlDebug == null)
|
||||
if (curlEasy?._pfCurlDebug == null)
|
||||
return 0;
|
||||
var message = Marshal.PtrToStringAnsi(msgBuf, msgBufSize);
|
||||
curlEasy._pfCurlDebug(infoType, message, curlEasy._debugData);
|
||||
curlEasy._pfCurlDebug(infoType, message, msgBufSize, curlEasy._debugData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2079,7 +2177,7 @@ namespace CurlSharp
|
||||
if (_pfCurlDebug != null)
|
||||
{
|
||||
var userdata = getObject(pUserData);
|
||||
_pfCurlDebug(infoType, message, userdata);
|
||||
_pfCurlDebug(infoType, message, size, userdata);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2107,7 +2205,7 @@ namespace CurlSharp
|
||||
|
||||
private CurlIoError _curlIoctlCallback(CurlIoCommand cmd, IntPtr parm)
|
||||
{
|
||||
if (_pfCurlIoctl == null || _ioctlData == null)
|
||||
if ((_pfCurlIoctl == null) || (_ioctlData == null))
|
||||
return CurlIoError.UnknownCommand;
|
||||
return _pfCurlIoctl(cmd, _ioctlData);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2014 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -31,7 +31,7 @@ namespace CurlSharp
|
||||
public CurlFormOption Option;
|
||||
|
||||
/// <summary>Value for the option.</summary>
|
||||
public Object Value;
|
||||
public object Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,10 +77,7 @@ namespace CurlSharp
|
||||
}
|
||||
|
||||
// for CurlEasy.SetOpt()
|
||||
internal IntPtr GetHandle()
|
||||
{
|
||||
return _pItems[0];
|
||||
}
|
||||
internal IntPtr GetHandle() => _pItems[0];
|
||||
|
||||
/// <summary>
|
||||
/// Add a multi-part form section.
|
||||
@@ -186,7 +183,7 @@ namespace CurlSharp
|
||||
var formArrayPos = 0;
|
||||
var argArrayPos = 0;
|
||||
var ptrArrayPos = 0;
|
||||
Object obj = null;
|
||||
object obj = null;
|
||||
|
||||
while ((retCode == CurlFormCode.Ok) &&
|
||||
(ptrArrayPos < nRealCount))
|
||||
@@ -207,14 +204,14 @@ namespace CurlSharp
|
||||
{
|
||||
iCode = (CurlFormOption) Convert.ToInt32(
|
||||
args.GetValue(argArrayPos++));
|
||||
obj = (iCode == CurlFormOption.End)
|
||||
obj = iCode == CurlFormOption.End
|
||||
? null
|
||||
: args.GetValue(argArrayPos++);
|
||||
}
|
||||
|
||||
switch (iCode)
|
||||
{
|
||||
// handle byte-array pointer-related items
|
||||
// handle byte-array pointer-related items
|
||||
case CurlFormOption.PtrName:
|
||||
case CurlFormOption.PtrContents:
|
||||
case CurlFormOption.BufferPtr:
|
||||
@@ -240,7 +237,7 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// length values
|
||||
// length values
|
||||
case CurlFormOption.NameLength:
|
||||
case CurlFormOption.ContentsLength:
|
||||
case CurlFormOption.BufferLength:
|
||||
@@ -249,7 +246,7 @@ namespace CurlSharp
|
||||
Convert.ToInt32(obj);
|
||||
break;
|
||||
|
||||
// strings
|
||||
// strings
|
||||
case CurlFormOption.CopyName:
|
||||
case CurlFormOption.CopyContents:
|
||||
case CurlFormOption.FileContent:
|
||||
@@ -259,7 +256,7 @@ namespace CurlSharp
|
||||
case CurlFormOption.Buffer:
|
||||
{
|
||||
aPointers[ptrArrayPos++] = (IntPtr) iCode;
|
||||
var s = obj as String;
|
||||
var s = obj as string;
|
||||
if (s == null)
|
||||
retCode = CurlFormCode.UnknownOption;
|
||||
else
|
||||
@@ -273,7 +270,7 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// array case: already handled
|
||||
// array case: already handled
|
||||
case CurlFormOption.Array:
|
||||
if (aForms != null)
|
||||
retCode = CurlFormCode.IllegalArray;
|
||||
@@ -285,7 +282,7 @@ namespace CurlSharp
|
||||
}
|
||||
break;
|
||||
|
||||
// slist
|
||||
// slist
|
||||
case CurlFormOption.ContentHeader:
|
||||
{
|
||||
aPointers[ptrArrayPos++] = (IntPtr) iCode;
|
||||
@@ -297,12 +294,12 @@ namespace CurlSharp
|
||||
break;
|
||||
}
|
||||
|
||||
// erroneous stuff
|
||||
// erroneous stuff
|
||||
case CurlFormOption.Nothing:
|
||||
retCode = CurlFormCode.Incomplete;
|
||||
break;
|
||||
|
||||
// end
|
||||
// end
|
||||
case CurlFormOption.End:
|
||||
if (aForms != null) // end of form
|
||||
{
|
||||
@@ -313,7 +310,7 @@ namespace CurlSharp
|
||||
aPointers[ptrArrayPos++] = (IntPtr) iCode;
|
||||
break;
|
||||
|
||||
// default is unknown
|
||||
// default is unknown
|
||||
default:
|
||||
retCode = CurlFormCode.UnknownOption;
|
||||
break;
|
||||
@@ -331,9 +328,9 @@ namespace CurlSharp
|
||||
retCode = (CurlFormCode) NativeMethods.curl_shim_formadd(_pItems, aPointers, nRealCount);
|
||||
#else
|
||||
retCode = (CurlFormCode) NativeMethods.curl_formadd(ref _pItems[0], ref _pItems[1],
|
||||
(int) aPointers[0], aPointers[1],
|
||||
(int) aPointers[2], aPointers[3],
|
||||
(int) aPointers[4]);
|
||||
(int) aPointers[0], aPointers[1],
|
||||
(int) aPointers[2], aPointers[3],
|
||||
(int) aPointers[4]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -350,7 +347,7 @@ namespace CurlSharp
|
||||
case CurlFormOption.ContentType:
|
||||
case CurlFormOption.Filename:
|
||||
case CurlFormOption.Buffer:
|
||||
// byte buffer cases
|
||||
// byte buffer cases
|
||||
case CurlFormOption.PtrName:
|
||||
case CurlFormOption.PtrContents:
|
||||
case CurlFormOption.BufferPtr:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2014 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -39,6 +39,7 @@ namespace CurlSharp
|
||||
private NativeMethods.fd_set _fd_read, _fd_write, _fd_except;
|
||||
#endif
|
||||
private IntPtr _pMulti;
|
||||
private CurlPipelining _pipelining;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -74,10 +75,7 @@ namespace CurlSharp
|
||||
/// <summary>
|
||||
/// Max file descriptor
|
||||
/// </summary>
|
||||
public int MaxFd
|
||||
{
|
||||
get { return _maxFd; }
|
||||
}
|
||||
public int MaxFd => _maxFd;
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup unmanaged resources.
|
||||
@@ -149,6 +147,17 @@ namespace CurlSharp
|
||||
return NativeMethods.curl_multi_add_handle(_pMulti, p);
|
||||
}
|
||||
|
||||
public CurlPipelining Pipelining
|
||||
{
|
||||
get { return _pipelining; }
|
||||
set
|
||||
{
|
||||
ensureHandle();
|
||||
_pipelining = value;
|
||||
NativeMethods.curl_multi_setopt(_pMulti, CurlMultiOption.Pipelining, (long) value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an CurlEasy object.
|
||||
/// </summary>
|
||||
@@ -178,10 +187,7 @@ namespace CurlSharp
|
||||
/// string description.
|
||||
/// </param>
|
||||
/// <returns>The string description.</returns>
|
||||
public String StrError(CurlMultiCode errorNum)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(NativeMethods.curl_multi_strerror(errorNum));
|
||||
}
|
||||
public string StrError(CurlMultiCode errorNum) => Marshal.PtrToStringAnsi(NativeMethods.curl_multi_strerror(errorNum));
|
||||
|
||||
/// <summary>
|
||||
/// Read/write data to/from each CurlEasy object.
|
||||
@@ -269,8 +275,6 @@ namespace CurlSharp
|
||||
if (_bGotMultiInfo)
|
||||
return _multiInfo;
|
||||
|
||||
_bGotMultiInfo = true;
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
var nMsgs = 0;
|
||||
var pInfo = NativeMethods.curl_shim_multi_info_read(_pMulti, ref nMsgs);
|
||||
@@ -286,17 +290,14 @@ namespace CurlSharp
|
||||
}
|
||||
NativeMethods.curl_shim_multi_info_free(pInfo);
|
||||
}
|
||||
|
||||
return _multiInfo;
|
||||
|
||||
_bGotMultiInfo = true;
|
||||
#else
|
||||
|
||||
throw new NotImplementedException(
|
||||
"Sorry, CurlMulti.InfoRead is not implemented on this system."
|
||||
);
|
||||
|
||||
_multiInfo = null;
|
||||
throw new NotImplementedException("CurlMulti.InfoRead()");
|
||||
#endif
|
||||
|
||||
#pragma warning disable CS0162 // Unreachable code detected when not compiling with the shim
|
||||
return _multiInfo;
|
||||
#pragma warning restore CS0162 // Unreachable code detected when not compiling with the shim
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2013 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -26,40 +26,28 @@ namespace CurlSharp
|
||||
public sealed class CurlMultiInfo
|
||||
{
|
||||
// private members
|
||||
private readonly CurlEasy _mCurlEasy;
|
||||
private readonly CurlMessage _msg;
|
||||
private readonly CurlCode _result;
|
||||
|
||||
internal CurlMultiInfo(CurlMessage msg, CurlEasy curlEasy, CurlCode result)
|
||||
{
|
||||
_msg = msg;
|
||||
_mCurlEasy = curlEasy;
|
||||
_result = result;
|
||||
Msg = msg;
|
||||
CurlEasyHandle = curlEasy;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the status code from the <see cref="CurlMessage" /> enumeration.
|
||||
/// </summary>
|
||||
public CurlMessage Msg
|
||||
{
|
||||
get { return _msg; }
|
||||
}
|
||||
public CurlMessage Msg { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="CurlEasy" /> object for this child.
|
||||
/// </summary>
|
||||
public CurlEasy CurlEasyHandle
|
||||
{
|
||||
get { return _mCurlEasy; }
|
||||
}
|
||||
public CurlEasy CurlEasyHandle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the return code for the transfer, as a
|
||||
/// <see cref="CurlCode" />.
|
||||
/// </summary>
|
||||
public CurlCode Result
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
public CurlCode Result { get; }
|
||||
}
|
||||
}
|
||||
@@ -31,17 +31,12 @@ namespace CurlSharp
|
||||
{
|
||||
// private members
|
||||
private GCHandle _hThis; // for handle extraction
|
||||
private CurlShareCode _lastErrorCode;
|
||||
private string _lastErrorDescription;
|
||||
#if USE_LIBCURLSHIM
|
||||
private NativeMethods._ShimLockCallback _pDelLock; // lock delegate
|
||||
private NativeMethods._ShimUnlockCallback _pDelUnlock; // unlock delegate
|
||||
#endif
|
||||
private IntPtr _pShare; // share handle
|
||||
private CurlShareLockCallback _pfLock; // client lock delegate
|
||||
private CurlShareUnlockCallback _pfUnlock; // client unlock delegate
|
||||
private IntPtr _ptrThis; // numeric handle
|
||||
private Object _userData; // user data for delegates
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -65,23 +60,11 @@ namespace CurlSharp
|
||||
installDelegates();
|
||||
}
|
||||
|
||||
public object UserData
|
||||
{
|
||||
get { return _userData; }
|
||||
set { _userData = value; }
|
||||
}
|
||||
public object UserData { get; set; }
|
||||
|
||||
public CurlShareUnlockCallback UnlockFunction
|
||||
{
|
||||
get { return _pfUnlock; }
|
||||
set { _pfUnlock = value; }
|
||||
}
|
||||
public CurlShareUnlockCallback UnlockFunction { get; set; }
|
||||
|
||||
public CurlShareLockCallback LockFunction
|
||||
{
|
||||
get { return _pfLock; }
|
||||
set { _pfLock = value; }
|
||||
}
|
||||
public CurlShareLockCallback LockFunction { get; set; }
|
||||
|
||||
public CurlLockData Share
|
||||
{
|
||||
@@ -93,15 +76,9 @@ namespace CurlSharp
|
||||
set { setShareOption(CurlShareOption.Unshare, value); }
|
||||
}
|
||||
|
||||
public CurlShareCode LastErrorCode
|
||||
{
|
||||
get { return _lastErrorCode; }
|
||||
}
|
||||
public CurlShareCode LastErrorCode { get; private set; }
|
||||
|
||||
public string LastErrorDescription
|
||||
{
|
||||
get { return _lastErrorDescription; }
|
||||
}
|
||||
public string LastErrorDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup unmanaged resources.
|
||||
@@ -140,7 +117,7 @@ namespace CurlSharp
|
||||
/// This is thrown if
|
||||
/// the native <c>share</c> handle wasn't created successfully.
|
||||
/// </exception>
|
||||
public CurlShareCode SetOpt(CurlShareOption option, Object parameter)
|
||||
public CurlShareCode SetOpt(CurlShareOption option, object parameter)
|
||||
{
|
||||
EnsureHandle();
|
||||
var retCode = CurlShareCode.Ok;
|
||||
@@ -151,14 +128,14 @@ namespace CurlSharp
|
||||
var lf = parameter as CurlShareLockCallback;
|
||||
if (lf == null)
|
||||
return CurlShareCode.BadOption;
|
||||
_pfLock = lf;
|
||||
LockFunction = lf;
|
||||
break;
|
||||
|
||||
case CurlShareOption.UnlockFunction:
|
||||
var ulf = parameter as CurlShareUnlockCallback;
|
||||
if (ulf == null)
|
||||
return CurlShareCode.BadOption;
|
||||
_pfUnlock = ulf;
|
||||
UnlockFunction = ulf;
|
||||
break;
|
||||
|
||||
case CurlShareOption.Share:
|
||||
@@ -170,7 +147,7 @@ namespace CurlSharp
|
||||
}
|
||||
|
||||
case CurlShareOption.UserData:
|
||||
_userData = parameter;
|
||||
UserData = parameter;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -182,10 +159,10 @@ namespace CurlSharp
|
||||
|
||||
private void setLastError(CurlShareCode code, CurlShareOption opt)
|
||||
{
|
||||
if (_lastErrorCode == CurlShareCode.Ok && code != CurlShareCode.Ok)
|
||||
if ((LastErrorCode == CurlShareCode.Ok) && (code != CurlShareCode.Ok))
|
||||
{
|
||||
_lastErrorCode = code;
|
||||
_lastErrorDescription = string.Format("Error: {0} setting option {1}", StrError(code), opt);
|
||||
LastErrorCode = code;
|
||||
LastErrorDescription = $"Error: {StrError(code)} setting option {opt}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,10 +183,8 @@ namespace CurlSharp
|
||||
/// string description.
|
||||
/// </param>
|
||||
/// <returns>The string description.</returns>
|
||||
public String StrError(CurlShareCode errorNum)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(NativeMethods.curl_share_strerror(errorNum));
|
||||
}
|
||||
public string StrError(CurlShareCode errorNum)
|
||||
=> Marshal.PtrToStringAnsi(NativeMethods.curl_share_strerror(errorNum));
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
@@ -229,10 +204,7 @@ namespace CurlSharp
|
||||
}
|
||||
}
|
||||
|
||||
internal IntPtr GetHandle()
|
||||
{
|
||||
return _pShare;
|
||||
}
|
||||
internal IntPtr GetHandle() => _pShare;
|
||||
|
||||
private void EnsureHandle()
|
||||
{
|
||||
@@ -243,7 +215,7 @@ namespace CurlSharp
|
||||
private void installDelegates()
|
||||
{
|
||||
_hThis = GCHandle.Alloc(this);
|
||||
_ptrThis = (IntPtr)_hThis;
|
||||
_ptrThis = (IntPtr) _hThis;
|
||||
#if USE_LIBCURLSHIM
|
||||
_pDelLock = LockDelegate;
|
||||
_pDelUnlock = UnlockDelegate;
|
||||
@@ -255,22 +227,14 @@ namespace CurlSharp
|
||||
{
|
||||
var gch = (GCHandle) userPtr;
|
||||
var share = (CurlShare) gch.Target;
|
||||
if (share == null)
|
||||
return;
|
||||
if (share.LockFunction == null)
|
||||
return;
|
||||
share.LockFunction((CurlLockData) data, (CurlLockAccess) access, share.UserData);
|
||||
share?.LockFunction?.Invoke((CurlLockData) data, (CurlLockAccess) access, share.UserData);
|
||||
}
|
||||
|
||||
internal static void UnlockDelegate(int data, IntPtr userPtr)
|
||||
{
|
||||
var gch = (GCHandle) userPtr;
|
||||
var share = (CurlShare) gch.Target;
|
||||
if (share == null)
|
||||
return;
|
||||
if (share.UnlockFunction == null)
|
||||
return;
|
||||
share.UnlockFunction((CurlLockData) data, share.UserData);
|
||||
share?.UnlockFunction?.Invoke((CurlLockData) data, share.UserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{74420A79-CC16-442C-8B1E-7C1B913844F0}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CurlSharp</RootNamespace>
|
||||
<AssemblyName>CurlSharp</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<PackageId>CurlSharp</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Curl.cs" />
|
||||
<Compile Include="CurlEasy.cs" />
|
||||
<Compile Include="CurlHttpMultiPartForm.cs" />
|
||||
<Compile Include="CurlMulti.cs" />
|
||||
<Compile Include="CurlMultiInfo.cs" />
|
||||
<Compile Include="CurlShare.cs" />
|
||||
<Compile Include="CurlSlist.cs" />
|
||||
<Compile Include="CurlSslContext.cs" />
|
||||
<Compile Include="CurlVersionInfoData.cs" />
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
<Compile Include="Enums\CurlClosePolicy.cs" />
|
||||
<Compile Include="Enums\CurlCode.cs" />
|
||||
<Compile Include="Enums\CurlFormCode.cs" />
|
||||
<Compile Include="Enums\CurlFormOption.cs" />
|
||||
<Compile Include="Enums\CurlFtpAuth.cs" />
|
||||
<Compile Include="Enums\CurlFtpSsl.cs" />
|
||||
<Compile Include="Enums\CurlHttpAuth.cs" />
|
||||
<Compile Include="Enums\CurlHttpVersion.cs" />
|
||||
<Compile Include="Enums\CurlInfo.cs" />
|
||||
<Compile Include="Enums\CurlInfoType.cs" />
|
||||
<Compile Include="Enums\CurlInitFlag.cs" />
|
||||
<Compile Include="Enums\CurlIoCommand.cs" />
|
||||
<Compile Include="Enums\CurlIoError.cs" />
|
||||
<Compile Include="Enums\CurlIpResolve.cs" />
|
||||
<Compile Include="Enums\CurlLockAccess.cs" />
|
||||
<Compile Include="Enums\CurlLockData.cs" />
|
||||
<Compile Include="Enums\CurlMessage.cs" />
|
||||
<Compile Include="Enums\CurlMultiCode.cs" />
|
||||
<Compile Include="Enums\CurlNetrcOption.cs" />
|
||||
<Compile Include="Enums\CurlOption.cs" />
|
||||
<Compile Include="Enums\CurlProxyType.cs" />
|
||||
<Compile Include="Enums\CurlShareCode.cs" />
|
||||
<Compile Include="Enums\CurlShareOption.cs" />
|
||||
<Compile Include="Enums\CurlSslVersion.cs" />
|
||||
<Compile Include="Enums\CurlTimeCond.cs" />
|
||||
<Compile Include="Enums\CurlVersion.cs" />
|
||||
<Compile Include="Enums\CurlVersionFeatureBitmask.cs" />
|
||||
<Compile Include="Callbacks\CurlEasyCallbacks.cs" />
|
||||
<Compile Include="Callbacks\CurlShareCallbacks.cs" />
|
||||
<Compile Include="SSLFix.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup />
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
<Properties>
|
||||
<Policies>
|
||||
<TextStylePolicy inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
||||
<CSharpFormattingPolicy IndentSwitchBody="True" IndentBlocksInsideExpressions="True" AnonymousMethodBraceStyle="NextLine" PropertyBraceStyle="NextLine" PropertyGetBraceStyle="NextLine" PropertySetBraceStyle="NextLine" EventBraceStyle="NextLine" EventAddBraceStyle="NextLine" EventRemoveBraceStyle="NextLine" StatementBraceStyle="NextLine" ElseNewLinePlacement="NewLine" CatchNewLinePlacement="NewLine" FinallyNewLinePlacement="NewLine" WhileNewLinePlacement="DoNotCare" ArrayInitializerWrapping="DoNotChange" ArrayInitializerBraceStyle="NextLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
||||
</Policies>
|
||||
</Properties>
|
||||
</MonoDevelop>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2013 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -31,19 +31,6 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
public class CurlSlist : IDisposable
|
||||
{
|
||||
#if !USE_LIBCURLSHIM
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private class curl_slist
|
||||
{
|
||||
/// char*
|
||||
[MarshalAs(UnmanagedType.LPStr)] public string data;
|
||||
|
||||
/// curl_slist*
|
||||
public IntPtr next;
|
||||
}
|
||||
#endif
|
||||
private IntPtr _handle;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
@@ -54,12 +41,12 @@ namespace CurlSharp
|
||||
public CurlSlist()
|
||||
{
|
||||
Curl.EnsureCurl();
|
||||
_handle = IntPtr.Zero;
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public CurlSlist(IntPtr handle)
|
||||
{
|
||||
_handle = handle;
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -69,13 +56,13 @@ namespace CurlSharp
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_handle == IntPtr.Zero)
|
||||
if (Handle == IntPtr.Zero)
|
||||
return null;
|
||||
var strings = new List<string>();
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
var slist = new curl_slist();
|
||||
Marshal.PtrToStructure(_handle, slist);
|
||||
Marshal.PtrToStructure(Handle, slist);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -90,6 +77,17 @@ namespace CurlSharp
|
||||
}
|
||||
}
|
||||
|
||||
internal IntPtr Handle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Free all internal strings.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
@@ -105,40 +103,38 @@ namespace CurlSharp
|
||||
public void Append(string str)
|
||||
{
|
||||
#if USE_LIBCURLSHIM
|
||||
_handle = NativeMethods.curl_shim_add_string_to_slist(_handle, str);
|
||||
Handle = NativeMethods.curl_shim_add_string_to_slist(Handle, str);
|
||||
#else
|
||||
_handle = NativeMethods.curl_slist_append(_handle, str);
|
||||
Handle = NativeMethods.curl_slist_append(Handle, str);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free all internal strings.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
internal IntPtr Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_handle != IntPtr.Zero)
|
||||
if (Handle != IntPtr.Zero)
|
||||
{
|
||||
#if USE_LIBCURLSHIM
|
||||
NativeMethods.curl_shim_free_slist(_handle);
|
||||
NativeMethods.curl_shim_free_slist(Handle);
|
||||
#else
|
||||
NativeMethods.curl_slist_free_all(_handle);
|
||||
NativeMethods.curl_slist_free_all(Handle);
|
||||
#endif
|
||||
_handle = IntPtr.Zero;
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private class curl_slist
|
||||
{
|
||||
/// char*
|
||||
[MarshalAs(UnmanagedType.LPStr)] public string data;
|
||||
|
||||
/// curl_slist*
|
||||
public IntPtr next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2013 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
@@ -31,19 +31,14 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
public sealed class CurlSslContext
|
||||
{
|
||||
private readonly IntPtr _pvContext;
|
||||
|
||||
internal CurlSslContext(IntPtr pvContext)
|
||||
{
|
||||
_pvContext = pvContext;
|
||||
Context = pvContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the underlying OpenSSL context.
|
||||
/// </summary>
|
||||
public IntPtr Context
|
||||
{
|
||||
get { return _pvContext; }
|
||||
}
|
||||
public IntPtr Context { get; }
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2013 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
|
||||
@@ -23,9 +23,24 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
Http1_1 = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Enforce HTTP 2 requests.
|
||||
/// </summary>
|
||||
Http2_0 = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Enforce version 2 for HTTPS, version 1.1 for HTTP.
|
||||
/// </summary>
|
||||
Http2_Tls = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Enforce HTTP 2 without HTTP/1.1 upgrade.
|
||||
/// </summary>
|
||||
Http2_PriorKnowledge = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Last entry in enumeration; do not use in application code.
|
||||
/// </summary>
|
||||
Last = 3
|
||||
};
|
||||
Last = 6
|
||||
}
|
||||
}
|
||||
46
src/CurlSharp/Enums/CurlMultiOption.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
//
|
||||
// Copyright (c) 2017, Dr. Masroor Ehsan. All rights reserved.
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Last modified: 25.01.2017 1:29 AM
|
||||
//
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
namespace CurlSharp
|
||||
{
|
||||
public enum CurlMultiOption
|
||||
{
|
||||
/* This is the socket callback function pointer */
|
||||
SocketFunction = CurlOptType.FunctionPoint + 1,
|
||||
/* This is the argument passed to the socket callback */
|
||||
SocketData = CurlOptType.ObjectPoint + 2,
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
Pipelining = CurlOptType.Long + 3,
|
||||
/* This is the timer callback function pointer */
|
||||
TimerFunction = CurlOptType.FunctionPoint + 4,
|
||||
/* This is the argument passed to the timer callback */
|
||||
TimerDate = CurlOptType.ObjectPoint + 5,
|
||||
/* maximum number of entries in the connection cache */
|
||||
MaxConnects = CurlOptType.Long + 6,
|
||||
/* maximum number of (pipelining) connections to one host */
|
||||
MaxHostConnections = CurlOptType.Long + 7,
|
||||
/* maximum number of requests in a pipeline */
|
||||
MaxPipelineLength = CurlOptType.Long + 8,
|
||||
/* a connection with a content-length longer than this will not be considered for pipelining */
|
||||
ContentLengthPenaltySize = CurlOptType.Offset + 9,
|
||||
/* a connection with a chunk length longer than this will not be considered for pipelining */
|
||||
ChunkLengthPenaltySize = CurlOptType.Offset + 10,
|
||||
/* a list of site names(+port) that are blacklisted from pipelining */
|
||||
PipeliningSiteBlackList = CurlOptType.ObjectPoint + 11,
|
||||
/* a list of server types that are blacklisted from pipelining */
|
||||
PipeliningServerBlackList = CurlOptType.ObjectPoint + 12,
|
||||
/* maximum number of open connections in total */
|
||||
MaxTotalConnections = CurlOptType.Long + 13,
|
||||
/* This is the server push callback function pointer */
|
||||
PushFunction = CurlOptType.FunctionPoint + 14,
|
||||
/* This is the argument passed to the server push callback */
|
||||
PushData = CurlOptType.ObjectPoint + 15
|
||||
}
|
||||
}
|
||||
21
src/CurlSharp/Enums/CurlOptType.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
//
|
||||
// Copyright (c) 2017, Dr. Masroor Ehsan. All rights reserved.
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Last modified: 25.01.2017 1:31 AM
|
||||
//
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
namespace CurlSharp
|
||||
{
|
||||
public enum CurlOptType
|
||||
{
|
||||
Long = 0,
|
||||
ObjectPoint = 10000,
|
||||
StringPoint = 10000,
|
||||
FunctionPoint = 20000,
|
||||
Offset = 30000
|
||||
}
|
||||
}
|
||||
@@ -1075,6 +1075,32 @@ namespace CurlSharp
|
||||
/// </summary>
|
||||
SslCipherList = 10083,
|
||||
|
||||
/// <summary>
|
||||
/// Object reference to pass to the ssl context delegate set by the option
|
||||
/// <c>SslCtxFunction</c>, this is the pointer you'll get as the
|
||||
/// second parameter, otherwise <c>null</c>. (Added in 7.11.0)
|
||||
/// </summary>
|
||||
SslCtxData = 10109,
|
||||
|
||||
/// <summary>
|
||||
/// Reference to an <see cref="CurlEasy.CurlSslContextCallback" /> delegate.
|
||||
/// This delegate gets called by libcurl just before the initialization of
|
||||
/// an Ssl connection after having processed all other Ssl related options
|
||||
/// to give a last chance to an application to modify the behaviour of
|
||||
/// openssl's ssl initialization. The <see cref="CurlSslContext" /> parameter
|
||||
/// wraps a pointer to an openssl SSL_CTX. If an error is returned no attempt
|
||||
/// to establish a connection is made and the perform operation will return
|
||||
/// the error code from this callback function. Set the parm argument with
|
||||
/// the <c>SslCtxData</c> option. This option was introduced
|
||||
/// in 7.11.0.
|
||||
/// <note>
|
||||
/// To use this properly, a non-trivial amount of knowledge of the openssl
|
||||
/// libraries is necessary. Using this function allows for example to use
|
||||
/// openssl callbacks to add additional validation code for certificates,
|
||||
/// and even to change the actual URI of an HTTPS request.
|
||||
/// </note>
|
||||
/// </summary>
|
||||
SslCtxFunction = 20108,
|
||||
|
||||
/// <summary>
|
||||
/// Pass an <c>int</c>. Set if we should verify the common name from the
|
||||
|
||||
21
src/CurlSharp/Enums/CurlPipelining.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
//
|
||||
// Copyright (c) 2017, Dr. Masroor Ehsan. All rights reserved.
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Last modified: 25.01.2017 1:23 AM
|
||||
//
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
namespace CurlSharp
|
||||
{
|
||||
/* bitmask bits for CURLMOPT_PIPELINING */
|
||||
|
||||
public enum CurlPipelining : long
|
||||
{
|
||||
Nothing = 0,
|
||||
Http1 = 1,
|
||||
Multiplex = 2
|
||||
}
|
||||
}
|
||||
29
src/CurlSharp/LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
Copyright (c) 2013, Masroor Ehsan Choudhury
|
||||
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 the {organization} 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.
|
||||
|
||||
https://github.com/masroore/CurlSharp
|
||||
@@ -2,8 +2,9 @@
|
||||
*
|
||||
* CurlS#arp
|
||||
*
|
||||
* Copyright (c) 2014 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Copyright (c) 2013-2017 Dr. Masroor Ehsan (masroore@gmail.com)
|
||||
* Portions copyright (c) 2004, 2005 Jeff Phillips (jeff@jeffp.net)
|
||||
* Portions copyright (c) 2017 Katelyn Gigante (https://github.com/silasary)
|
||||
*
|
||||
* This software is licensed as described in the file LICENSE, which you
|
||||
* should have received as part of this distribution.
|
||||
@@ -20,383 +21,598 @@
|
||||
//#define USE_LIBCURLSHIM
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CurlSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// P/Invoke signatures.
|
||||
/// </summary>
|
||||
internal static unsafe class NativeMethods
|
||||
{
|
||||
#if WIN64
|
||||
private const string CURL_LIB = "libcurl64.dll";
|
||||
/// <summary>
|
||||
/// P/Invoke signatures.
|
||||
/// </summary>
|
||||
internal static unsafe class NativeMethods
|
||||
{
|
||||
private const string LIBCURL = "libcurl";
|
||||
|
||||
private const string LIBCURLSHIM = "libcurlshim";
|
||||
|
||||
private const string LIBC_LINUX = "libc";
|
||||
|
||||
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
private const string CURLSHIM_LIB = "libcurlshim64.dll";
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
#if LINUX
|
||||
private const string CURL_LIB = "libcurl";
|
||||
#else
|
||||
private const string CURL_LIB = "libcurl.dll";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
private const string CURLSHIM_LIB = "libcurlshim.dll";
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if !USE_LIBCURLSHIM
|
||||
#if LINUX
|
||||
private const string WINSOCK_LIB = "libc";
|
||||
#else
|
||||
private const string WINSOCK_LIB = "ws2_32.dll";
|
||||
|
||||
private const string LIB_DIR_WIN64 = "amd64";
|
||||
|
||||
private const string LIB_DIR_WIN32 = "i386";
|
||||
|
||||
static NativeMethods()
|
||||
{
|
||||
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
SetDllDirectory(Path.Combine(AssemblyDirectory, LIB_DIR_WIN64));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDllDirectory(Path.Combine(AssemblyDirectory, LIB_DIR_WIN32));
|
||||
}
|
||||
}
|
||||
#if USE_LIBCURLSHIM
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
throw new InvalidOperationException("Can not run on other platform than Win NET");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// internal delegates from cURL
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SetDllDirectory(string lpPathName);
|
||||
|
||||
// libcurl imports
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_global_init (int flags);
|
||||
private static string AssemblyDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
var codeBase = typeof(NativeMethods).GetTypeInfo().Assembly.CodeBase;
|
||||
var uri = new UriBuilder(codeBase);
|
||||
var path = Uri.UnescapeDataString(uri.Path);
|
||||
return Path.GetDirectoryName(path);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_global_cleanup ();
|
||||
#region curl_global_init
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_escape (String url, int length);
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_global_init(int flags);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_unescape (String url, int length);
|
||||
#endregion
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_free (IntPtr p);
|
||||
#region curl_global_cleanup
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_version ();
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_global_cleanup();
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_easy_init ();
|
||||
#endregion
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_easy_cleanup (IntPtr pCurl);
|
||||
#region curl_easy_escape
|
||||
|
||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||
internal delegate int _CurlGenericCallback (IntPtr ptr, int sz, int nmemb, IntPtr userdata);
|
||||
|
||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||
internal delegate int _CurlProgressCallback (
|
||||
IntPtr extraData, double dlTotal, double dlNow, double ulTotal, double ulNow);
|
||||
|
||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||
internal delegate int _CurlDebugCallback (
|
||||
IntPtr ptrCurl, CurlInfoType infoType, string message, int size, IntPtr ptrUserData);
|
||||
|
||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||
internal delegate int _CurlSslCtxCallback (IntPtr ctx, IntPtr parm);
|
||||
|
||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||
internal delegate CurlIoError _CurlIoctlCallback (CurlIoCommand cmd, IntPtr parm);
|
||||
|
||||
// curl_easy_setopt() overloads
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_setopt (IntPtr pCurl, CurlOption opt, IntPtr parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_setopt (IntPtr pCurl, CurlOption opt, string parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_setopt (IntPtr pCurl, CurlOption opt, byte[] parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_setopt (IntPtr pCurl, CurlOption opt, long parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_setopt (IntPtr pCurl, CurlOption opt, bool parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, EntryPoint = "curl_easy_setopt")]
|
||||
internal static extern CurlCode curl_easy_setopt_cb (IntPtr pCurl, CurlOption opt, _CurlGenericCallback parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, EntryPoint = "curl_easy_setopt")]
|
||||
internal static extern CurlCode curl_easy_setopt_cb (IntPtr pCurl, CurlOption opt, _CurlProgressCallback parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, EntryPoint = "curl_easy_setopt")]
|
||||
internal static extern CurlCode curl_easy_setopt_cb (IntPtr pCurl, CurlOption opt, _CurlDebugCallback parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, EntryPoint = "curl_easy_setopt")]
|
||||
internal static extern CurlCode curl_easy_setopt_cb (IntPtr pCurl, CurlOption opt, _CurlSslCtxCallback parm);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, EntryPoint = "curl_easy_setopt")]
|
||||
internal static extern CurlCode curl_easy_setopt_cb (IntPtr pCurl, CurlOption opt, _CurlIoctlCallback parm);
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_multi_fdset (IntPtr pmulti,
|
||||
[In, Out] ref fd_set read_fd_set,
|
||||
[In, Out] ref fd_set write_fd_set,
|
||||
[In, Out] ref fd_set exc_fd_set,
|
||||
[In, Out] ref int max_fd);
|
||||
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct fd_set
|
||||
{
|
||||
internal uint fd_count;
|
||||
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = FD_SETSIZE)] internal IntPtr[] fd_array;
|
||||
internal fixed uint fd_array[FD_SETSIZE];
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_easy_escape(IntPtr pEasy, string url, int length);
|
||||
|
||||
internal const int FD_SETSIZE = 64;
|
||||
#endregion
|
||||
|
||||
internal void Cleanup ()
|
||||
{
|
||||
//fd_array = null;
|
||||
}
|
||||
#region curl_easy_unescape
|
||||
|
||||
internal static fd_set Create ()
|
||||
{
|
||||
return new fd_set {
|
||||
//fd_array = new IntPtr[FD_SETSIZE],
|
||||
fd_count = 0
|
||||
};
|
||||
}
|
||||
|
||||
internal static fd_set Create (IntPtr socket)
|
||||
{
|
||||
var handle = Create ();
|
||||
handle.fd_count = 1;
|
||||
handle.fd_array [0] = (uint)socket;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void FD_ZERO (fd_set fds)
|
||||
{
|
||||
for (var i = 0; i < fd_set.FD_SETSIZE; i++) {
|
||||
//fds.fd_array[i] = (IntPtr) 0;
|
||||
fds.fd_array [i] = 0;
|
||||
}
|
||||
fds.fd_count = 0;
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct timeval
|
||||
{
|
||||
/// <summary>
|
||||
/// Time interval, in seconds.
|
||||
/// </summary>
|
||||
internal int tv_sec;
|
||||
|
||||
/// <summary>
|
||||
/// Time interval, in microseconds.
|
||||
/// </summary>
|
||||
internal int tv_usec;
|
||||
|
||||
internal static timeval Create (int milliseconds)
|
||||
{
|
||||
return new timeval {
|
||||
tv_sec = milliseconds / 1000,
|
||||
tv_usec = (milliseconds % 1000) * 1000
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
[DllImport (WINSOCK_LIB, EntryPoint = "select")]
|
||||
internal static extern int select (
|
||||
int nfds, // number of sockets, (ignored in winsock)
|
||||
[In, Out] ref fd_set readfds, // read sockets to watch
|
||||
[In, Out] ref fd_set writefds, // write sockets to watch
|
||||
[In, Out] ref fd_set exceptfds, // error sockets to watch
|
||||
ref timeval timeout);
|
||||
|
||||
//[DllImport(WINSOCK_LIB, EntryPoint = "select")]
|
||||
//internal static extern int select(int ndfs, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout);
|
||||
#endif
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_perform (IntPtr pCurl);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_easy_duphandle (IntPtr pCurl);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_easy_strerror (CurlCode err);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_getinfo (IntPtr pCurl, CurlInfo info, ref IntPtr pInfo);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlCode curl_easy_getinfo (IntPtr pCurl, CurlInfo info, ref double dblVal);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_easy_reset (IntPtr pCurl);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_multi_init ();
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_multi_cleanup (IntPtr pmulti);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_multi_add_handle (IntPtr pmulti, IntPtr peasy);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_multi_remove_handle (IntPtr pmulti, IntPtr peasy);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_multi_strerror (CurlMultiCode errorNum);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_multi_perform (IntPtr pmulti, ref int runningHandles);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_formfree (IntPtr pForm);
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_formadd (ref IntPtr pHttppost, ref IntPtr pLastPost,
|
||||
int codeFirst, IntPtr bufFirst,
|
||||
int codeNext, IntPtr bufNext,
|
||||
int codeLast);
|
||||
#endif
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_share_init ();
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlShareCode curl_share_cleanup (IntPtr pShare);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_share_strerror (CurlShareCode errorCode);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlShareCode curl_share_setopt (IntPtr pShare, CurlShareOption optCode, IntPtr option);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_slist_append (IntPtr slist, string data);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlShareCode curl_slist_free_all (IntPtr pList);
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_easy_unescape(IntPtr pEasy, string url, int inLength, out int outLength);
|
||||
|
||||
[DllImport (CURL_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_version_info (CurlVersion ver);
|
||||
#endregion
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
|
||||
// libcurlshim imports
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_initialize();
|
||||
#region curl_free
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_cleanup();
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_free(IntPtr p);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_shim_alloc_strings();
|
||||
#endregion
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl,
|
||||
CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_shim_add_string_to_slist(
|
||||
IntPtr pStrings, String str);
|
||||
#region curl_version
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl,
|
||||
CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_shim_get_string_from_slist(
|
||||
IntPtr pSlist, ref IntPtr pStr);
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_version();
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl,
|
||||
CharSet = CharSet.Ansi)]
|
||||
internal static extern IntPtr curl_shim_add_string(IntPtr pStrings, String str);
|
||||
#endregion
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_free_strings(IntPtr pStrings);
|
||||
#region curl_version_info
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_install_delegates(IntPtr pCurl, IntPtr pThis,
|
||||
_ShimWriteCallback pWrite, _ShimReadCallback pRead,
|
||||
_ShimProgressCallback pProgress, _ShimDebugCallback pDebug,
|
||||
_ShimHeaderCallback pHeader, _ShimSslCtxCallback pCtx,
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_version_info(CurlVersion ver);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_init
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_easy_init();
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_cleanup
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_easy_cleanup(IntPtr pCurl);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_setopt
|
||||
|
||||
#region Delegates
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int _CurlGenericCallback(IntPtr ptr, int sz, int nmemb, IntPtr userdata);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int _CurlProgressCallback(
|
||||
IntPtr extraData,
|
||||
double dlTotal,
|
||||
double dlNow,
|
||||
double ulTotal,
|
||||
double ulNow);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int _CurlDebugCallback(
|
||||
IntPtr ptrCurl,
|
||||
CurlInfoType infoType,
|
||||
string message,
|
||||
int size,
|
||||
IntPtr ptrUserData);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int _CurlSslCtxCallback(IntPtr ctx, IntPtr parm);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate CurlIoError _CurlIoctlCallback(CurlIoCommand cmd, IntPtr parm);
|
||||
|
||||
#endregion
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, IntPtr parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, string parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, byte[] parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, long parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, bool parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, _CurlGenericCallback parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, _CurlProgressCallback parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, _CurlDebugCallback parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, _CurlSslCtxCallback parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_setopt(IntPtr pCurl, CurlOption opt, _CurlIoctlCallback parm);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_perform
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_perform(IntPtr pCurl);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_duphandle
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_easy_duphandle(IntPtr pCurl);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_strerror
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_easy_strerror(CurlCode err);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_getinfo
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_getinfo(IntPtr pCurl, CurlInfo info, ref IntPtr pInfo);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlCode curl_easy_getinfo(IntPtr pCurl, CurlInfo info, ref double dblVal);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_easy_reset
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_easy_reset(IntPtr pCurl);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_init
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_multi_init();
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_cleanup
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_cleanup(IntPtr pmulti);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_add_handle
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_add_handle(IntPtr pmulti, IntPtr peasy);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_remove_handle
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_remove_handle(IntPtr pmulti, IntPtr peasy);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_setopt
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_setopt(IntPtr pmulti, CurlMultiOption opt, bool parm);
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_setopt(IntPtr pmulti, CurlMultiOption opt, long parm);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_strerror
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_multi_strerror(CurlMultiCode errorNum);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_multi_perform
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_perform(IntPtr pmulti, ref int runningHandles);
|
||||
|
||||
#endregion
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
|
||||
#region curl_multi_fdset
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_multi_fdset(IntPtr pmulti,
|
||||
[In] [Out] ref fd_set read_fd_set,
|
||||
[In] [Out] ref fd_set write_fd_set,
|
||||
[In] [Out] ref fd_set exc_fd_set,
|
||||
[In] [Out] ref int max_fd);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct fd_set
|
||||
{
|
||||
public uint fd_count;
|
||||
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = FD_SETSIZE)] public IntPtr[] fd_array;
|
||||
public fixed uint fd_array[FD_SETSIZE];
|
||||
|
||||
public const int FD_SETSIZE = 64;
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
// fd_array = null;
|
||||
}
|
||||
|
||||
public static fd_set Create()
|
||||
{
|
||||
return new fd_set
|
||||
{
|
||||
// fd_array = new IntPtr[FD_SETSIZE],
|
||||
fd_count = 0
|
||||
};
|
||||
}
|
||||
|
||||
public static fd_set Create(IntPtr socket)
|
||||
{
|
||||
var handle = Create();
|
||||
handle.fd_count = 1;
|
||||
handle.fd_array[0] = (uint)socket;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public static void FD_ZERO(fd_set fds)
|
||||
{
|
||||
for (var i = 0; i < fd_set.FD_SETSIZE; i++)
|
||||
{
|
||||
fds.fd_array[i] = 0;
|
||||
}
|
||||
fds.fd_count = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region select
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct timeval
|
||||
{
|
||||
/// <summary>
|
||||
/// Time interval, in seconds.
|
||||
/// </summary>
|
||||
public int tv_sec;
|
||||
|
||||
/// <summary>
|
||||
/// Time interval, in microseconds.
|
||||
/// </summary>
|
||||
public int tv_usec;
|
||||
|
||||
public static timeval Create(int milliseconds)
|
||||
{
|
||||
return new timeval
|
||||
{
|
||||
tv_sec = milliseconds / 1000,
|
||||
tv_usec = milliseconds % 1000 * 1000
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(LIBC_LINUX, EntryPoint = "select")]
|
||||
private static extern int select_unix(
|
||||
int nfds, // number of sockets, (ignored in winsock)
|
||||
[In] [Out] ref fd_set readfds, // read sockets to watch
|
||||
[In] [Out] ref fd_set writefds, // write sockets to watch
|
||||
[In] [Out] ref fd_set exceptfds, // error sockets to watch
|
||||
ref timeval timeout);
|
||||
|
||||
[DllImport(WINSOCK_LIB, EntryPoint = "select")]
|
||||
private static extern int select_win(
|
||||
int nfds, // number of sockets, (ignored in winsock)
|
||||
[In] [Out] ref fd_set readfds, // read sockets to watch
|
||||
[In] [Out] ref fd_set writefds, // write sockets to watch
|
||||
[In] [Out] ref fd_set exceptfds, // error sockets to watch
|
||||
ref timeval timeout);
|
||||
|
||||
public static int select(
|
||||
int nfds, // number of sockets, (ignored in winsock)
|
||||
[In] [Out] ref fd_set readfds, // read sockets to watch
|
||||
[In] [Out] ref fd_set writefds, // write sockets to watch
|
||||
[In] [Out] ref fd_set exceptfds, // error sockets to watch
|
||||
ref timeval timeout)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
result = select_win(
|
||||
nfds, // number of sockets, (ignored in winsock)
|
||||
ref readfds, // read sockets to watch
|
||||
ref writefds, // write sockets to watch
|
||||
ref exceptfds, // error sockets to watch
|
||||
ref timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = select_unix(
|
||||
nfds, // number of sockets, (ignored in winsock)
|
||||
ref readfds, // read sockets to watch
|
||||
ref writefds, // write sockets to watch
|
||||
ref exceptfds, // error sockets to watch
|
||||
ref timeout);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endif
|
||||
|
||||
#region curl_share_init
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_share_init();
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_share_cleanup
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlShareCode curl_share_cleanup(IntPtr pShare);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_share_strerror
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_share_strerror(CurlShareCode errorCode);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_share_setopt
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlShareCode curl_share_setopt(
|
||||
IntPtr pShare,
|
||||
CurlShareOption optCode,
|
||||
IntPtr option);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_formadd
|
||||
|
||||
#if !USE_LIBCURLSHIM
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_formadd(ref IntPtr pHttppost, ref IntPtr pLastPost,
|
||||
int codeFirst, IntPtr bufFirst,
|
||||
int codeNext, IntPtr bufNext,
|
||||
int codeLast);
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_formfree
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_formfree(IntPtr pForm);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_slist_append
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_slist_append(IntPtr slist, string data);
|
||||
|
||||
#endregion
|
||||
|
||||
#region curl_slist_free_all
|
||||
|
||||
[DllImport(LIBCURL, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_slist_free_all(IntPtr pList);
|
||||
|
||||
#endregion
|
||||
|
||||
#if USE_LIBCURLSHIM
|
||||
|
||||
#region libcurlshim imports
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_initialize();
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_cleanup();
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_shim_alloc_strings();
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_shim_add_string_to_slist(IntPtr pStrings, string str);
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_shim_get_string_from_slist(IntPtr pSlist, ref IntPtr pStr);
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr curl_shim_add_string(IntPtr pStrings, string str);
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_free_strings(IntPtr pStrings);
|
||||
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_install_delegates(
|
||||
IntPtr pCurl,
|
||||
IntPtr pThis,
|
||||
_ShimWriteCallback pWrite,
|
||||
_ShimReadCallback pRead,
|
||||
_ShimProgressCallback pProgress,
|
||||
_ShimDebugCallback pDebug,
|
||||
_ShimHeaderCallback pHeader,
|
||||
_ShimSslCtxCallback pCtx,
|
||||
_ShimIoctlCallback pIoctl);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_cleanup_delegates(IntPtr pThis);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_cleanup_delegates(IntPtr pThis);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_get_file_time(int unixTime,
|
||||
ref int yy, ref int mm, ref int dd, ref int hh, ref int mn, ref int ss);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_get_file_time(
|
||||
int unixTime,
|
||||
ref int yy,
|
||||
ref int mm,
|
||||
ref int dd,
|
||||
ref int hh,
|
||||
ref int mn,
|
||||
ref int ss);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_free_slist(IntPtr p);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_free_slist(IntPtr p);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_shim_alloc_fd_sets();
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_shim_alloc_fd_sets();
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_free_fd_sets(IntPtr fdsets);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_free_fd_sets(IntPtr fdsets);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern CurlMultiCode curl_shim_multi_fdset(IntPtr multi,
|
||||
IntPtr fdsets, ref int maxFD);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern CurlMultiCode curl_shim_multi_fdset(IntPtr multi, IntPtr fdsets, ref int maxFD);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_select(int maxFD, IntPtr fdsets,
|
||||
int milliseconds);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_select(int maxFD, IntPtr fdsets, int milliseconds);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_shim_multi_info_read(IntPtr multi,
|
||||
ref int nMsgs);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_shim_multi_info_read(IntPtr multi, ref int nMsgs);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_multi_info_free(IntPtr multiInfo);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_multi_info_free(IntPtr multiInfo);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_formadd(IntPtr[] ppForms, IntPtr[] pParams, int nParams);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_formadd(IntPtr[] ppForms, IntPtr[] pParams, int nParams);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_install_share_delegates(IntPtr pShare,
|
||||
IntPtr pThis, _ShimLockCallback pLock, _ShimUnlockCallback pUnlock);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_install_share_delegates(
|
||||
IntPtr pShare,
|
||||
IntPtr pThis,
|
||||
_ShimLockCallback pLock,
|
||||
_ShimUnlockCallback pUnlock);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern void curl_shim_cleanup_share_delegates(IntPtr pShare);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void curl_shim_cleanup_share_delegates(IntPtr pShare);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_get_version_int_value(IntPtr p, int offset);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_get_version_int_value(IntPtr p, int offset);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_shim_get_version_char_ptr(IntPtr p, int offset);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_shim_get_version_char_ptr(IntPtr p, int offset);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern int curl_shim_get_number_of_protocols(IntPtr p, int offset);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int curl_shim_get_number_of_protocols(IntPtr p, int offset);
|
||||
|
||||
[DllImport(CURLSHIM_LIB, CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr curl_shim_get_protocol_string(IntPtr p, int offset, int index);
|
||||
[DllImport(LIBCURLSHIM, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr curl_shim_get_protocol_string(IntPtr p, int offset, int index);
|
||||
|
||||
internal delegate void _ShimLockCallback(int data, int access, IntPtr userPtr);
|
||||
public delegate void _ShimLockCallback(int data, int access, IntPtr userPtr);
|
||||
|
||||
internal delegate void _ShimUnlockCallback(int data, IntPtr userPtr);
|
||||
public delegate void _ShimUnlockCallback(int data, IntPtr userPtr);
|
||||
|
||||
internal delegate int _ShimDebugCallback(CurlInfoType infoType, IntPtr msgBuf, int msgBufSize, IntPtr parm);
|
||||
public delegate int _ShimDebugCallback(CurlInfoType infoType, IntPtr msgBuf, int msgBufSize, IntPtr parm);
|
||||
|
||||
internal delegate int _ShimHeaderCallback(IntPtr buf, int sz, int nmemb, IntPtr stream);
|
||||
public delegate int _ShimHeaderCallback(IntPtr buf, int sz, int nmemb, IntPtr stream);
|
||||
|
||||
internal delegate CurlIoError _ShimIoctlCallback(CurlIoCommand cmd, IntPtr parm);
|
||||
public delegate CurlIoError _ShimIoctlCallback(CurlIoCommand cmd, IntPtr parm);
|
||||
|
||||
internal delegate int _ShimProgressCallback(IntPtr parm, double dlTotal, double dlNow, double ulTotal, double ulNow);
|
||||
public delegate int _ShimProgressCallback(
|
||||
IntPtr parm,
|
||||
double dlTotal,
|
||||
double dlNow,
|
||||
double ulTotal,
|
||||
double ulNow);
|
||||
|
||||
internal delegate int _ShimReadCallback(IntPtr buf, int sz, int nmemb, IntPtr parm);
|
||||
public delegate int _ShimReadCallback(IntPtr buf, int sz, int nmemb, IntPtr parm);
|
||||
|
||||
internal delegate int _ShimSslCtxCallback(IntPtr ctx, IntPtr parm);
|
||||
public delegate int _ShimSslCtxCallback(IntPtr ctx, IntPtr parm);
|
||||
|
||||
public delegate int _ShimWriteCallback(IntPtr buf, int sz, int nmemb, IntPtr parm);
|
||||
|
||||
#endregion
|
||||
|
||||
internal delegate int _ShimWriteCallback(IntPtr buf, int sz, int nmemb, IntPtr parm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Information about this assembly is defined by the following attributes.
|
||||
// Change them to the values specific to your project.
|
||||
[assembly: AssemblyTitle ("CurlSharp")]
|
||||
[assembly: AssemblyDescription ("")]
|
||||
[assembly: AssemblyConfiguration ("")]
|
||||
[assembly: AssemblyCompany ("")]
|
||||
[assembly: AssemblyProduct ("")]
|
||||
[assembly: AssemblyCopyright ("max")]
|
||||
[assembly: AssemblyTrademark ("")]
|
||||
[assembly: AssemblyCulture ("")]
|
||||
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
[assembly: AssemblyVersion ("1.0.*")]
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
||||
|
||||
114
src/CurlSharp/README.md
Normal file
@@ -0,0 +1,114 @@
|
||||
CurlSharp
|
||||
=========
|
||||
|
||||
CurlSharp is a .Net binding and object-oriented wrapper for [libcurl](http://curl.haxx.se/libcurl/).
|
||||
|
||||
libcurl is a web-client library that can provide cross-platform .Net applications with an easy way to implement such things as:
|
||||
|
||||
- HTTP ( GET / HEAD / PUT / POST / multi-part / form-data )
|
||||
- FTP ( upload / download / list / 3rd-party )
|
||||
- HTTPS, FTPS, SSL, TLS ( via OpenSSL or GnuTLS )
|
||||
- Proxies, proxy tunneling, cookies, user+password authentication.
|
||||
- File transfer resume, byte ranges, multiple asynchronous transfers.
|
||||
- and much more...
|
||||
|
||||
CurlSharp provides simple get/set properties for libcurl's options and information functions, event-based hooks to libcurl's I/O, status, and progress callbacks, and wraps the c-style file I/O behind simple filename properties. The `CurlEasy` class contains has more than 100 different properties and methods to handle a wide variety of URL transfer requirements. While this may seem overwhelming at first glance, the good news is you will probably need only a tiny subset of these for most situations.
|
||||
|
||||
The CurlSharp library consists of these parts:
|
||||
|
||||
- Pure C# P/Invoke bindings to the libcurl API.
|
||||
- Optional libcurlshim helper DLL [WIN32].
|
||||
- The `CurlEasy` class which provides a wrapper around a `curl_easy` session.
|
||||
- The `CurlMulti` class, which serves as a container for multiple CurlEasy objects, and provides a wrapper around a `curl_multi` session.
|
||||
- The `CurlShare` class which provides an infrastructure for serializing access to data shared by multiple `CurlEasy` objects, including cookie data and DNS hosts. It implements the `curl_share_xxx` API.
|
||||
- The `CurlHttpMultiPartForm` to easily construct multi-part forms.
|
||||
- The `CurlSlist` class which wraps a linked list of strings used in cURL.
|
||||
|
||||
CurlSharp is available for these platforms:
|
||||
|
||||
- [Stable] Windows 32-bit
|
||||
- [Experimental] Win64 port
|
||||
- [Experimental] Mono Linux & OS X support
|
||||
|
||||
#### Examples ####
|
||||
|
||||
A simple HTTP download program...
|
||||
|
||||
```c#
|
||||
using System;
|
||||
using CurlSharp;
|
||||
|
||||
internal class EasyGet
|
||||
{
|
||||
public static void Main(String[] args)
|
||||
{
|
||||
Curl.GlobalInit(CurlInitFlag.All);
|
||||
|
||||
try
|
||||
{
|
||||
using (var easy = new CurlEasy())
|
||||
{
|
||||
easy.Url = "http://www.google.com/";
|
||||
easy.WriteFunction = OnWriteData;
|
||||
easy.Perform();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Curl.GlobalCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public static Int32 OnWriteData(byte[] buf, Int32 size, Int32 nmemb, object data)
|
||||
{
|
||||
Console.Write(Encoding.UTF8.GetString(buf));
|
||||
return size*nmemb;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Simple HTTP Post example:
|
||||
|
||||
```c#
|
||||
using (var easy = new CurlEasy())
|
||||
{
|
||||
easy.Url = "http://hostname/testpost.php";
|
||||
easy.Post = true;
|
||||
var postData = "parm1=12345&parm2=Hello+world%21";
|
||||
easy.PostFields = postData;
|
||||
easy.PostFieldSize = postData.Length;
|
||||
easy.Perform();
|
||||
}
|
||||
```
|
||||
|
||||
HTTP/2.0 download:
|
||||
|
||||
```c#
|
||||
|
||||
using (var easy = new CurlEasy())
|
||||
{
|
||||
easy.Url = "https://google.com/";
|
||||
easy.WriteFunction = OnWriteData;
|
||||
|
||||
// HTTP/2 please
|
||||
easy.HttpVersion = CurlHttpVersion.Http2_0;
|
||||
|
||||
// skip SSL verification during debugging
|
||||
easy.SslVerifyPeer = false;
|
||||
easy.SslVerifyhost = false;
|
||||
|
||||
easy.Perform();
|
||||
}
|
||||
```
|
||||
|
||||
More samples are included in the Samples folder.
|
||||
|
||||
#### Credits ####
|
||||
|
||||
CurlSharp Written by Dr. Masroor Ehsan.
|
||||
|
||||
CurlSharp is based on original code by Jeff Phillips [libcurl.NET](http://sourceforge.net/projects/libcurl-net/). Original code has been modified and greatly enhanced.
|
||||
|
||||
----------
|
||||
|
||||
CurlSharp Copyright © 2013-17 Dr. Masroor Ehsan
|
||||
621
src/DateTimeRoutines/DateTimeRoutines.cs
Normal file
@@ -0,0 +1,621 @@
|
||||
//********************************************************************************************
|
||||
//Author: Sergey Stoyan, CliverSoft.com
|
||||
// http://cliversoft.com
|
||||
// stoyan@cliversoft.com
|
||||
// sergey.stoyan@gmail.com
|
||||
// 27 February 2007
|
||||
//********************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
namespace Cliver
|
||||
{
|
||||
/// <summary>
|
||||
/// Miscellaneous and parsing methods for DateTime
|
||||
/// </summary>
|
||||
public static class DateTimeRoutines
|
||||
{
|
||||
#region miscellaneous methods
|
||||
|
||||
/// <summary>
|
||||
/// Amount of seconds elapsed between 1970-01-01 00:00:00 and the date-time.
|
||||
/// </summary>
|
||||
/// <param name="date_time">date-time</param>
|
||||
/// <returns>seconds</returns>
|
||||
public static uint GetSecondsSinceUnixEpoch(this DateTime date_time)
|
||||
{
|
||||
TimeSpan t = date_time - new DateTime(1970, 1, 1);
|
||||
int ss = (int)t.TotalSeconds;
|
||||
if (ss < 0)
|
||||
return 0;
|
||||
return (uint)ss;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing definitions
|
||||
|
||||
/// <summary>
|
||||
/// Defines a substring where date-time was found and result of conversion
|
||||
/// </summary>
|
||||
public class ParsedDateTime
|
||||
{
|
||||
/// <summary>
|
||||
/// Index of first char of a date substring found in the string
|
||||
/// </summary>
|
||||
readonly public int IndexOfDate = -1;
|
||||
/// <summary>
|
||||
/// Length a date substring found in the string
|
||||
/// </summary>
|
||||
readonly public int LengthOfDate = -1;
|
||||
/// <summary>
|
||||
/// Index of first char of a time substring found in the string
|
||||
/// </summary>
|
||||
readonly public int IndexOfTime = -1;
|
||||
/// <summary>
|
||||
/// Length of a time substring found in the string
|
||||
/// </summary>
|
||||
readonly public int LengthOfTime = -1;
|
||||
/// <summary>
|
||||
/// DateTime found in the string
|
||||
/// </summary>
|
||||
readonly public DateTime DateTime;
|
||||
/// <summary>
|
||||
/// True if a date was found within the string
|
||||
/// </summary>
|
||||
readonly public bool IsDateFound;
|
||||
/// <summary>
|
||||
/// True if a time was found within the string
|
||||
/// </summary>
|
||||
readonly public bool IsTimeFound;
|
||||
/// <summary>
|
||||
/// UTC offset if it was found within the string
|
||||
/// </summary>
|
||||
readonly public TimeSpan UtcOffset;
|
||||
/// <summary>
|
||||
/// True if UTC offset was found in the string
|
||||
/// </summary>
|
||||
readonly public bool IsUtcOffsetFound;
|
||||
/// <summary>
|
||||
/// Utc gotten from DateTime if IsUtcOffsetFound is True
|
||||
/// </summary>
|
||||
public DateTime UtcDateTime;
|
||||
|
||||
internal ParsedDateTime(int index_of_date, int length_of_date, int index_of_time, int length_of_time, DateTime date_time)
|
||||
{
|
||||
IndexOfDate = index_of_date;
|
||||
LengthOfDate = length_of_date;
|
||||
IndexOfTime = index_of_time;
|
||||
LengthOfTime = length_of_time;
|
||||
DateTime = date_time;
|
||||
IsDateFound = index_of_date > -1;
|
||||
IsTimeFound = index_of_time > -1;
|
||||
UtcOffset = new TimeSpan(25, 0, 0);
|
||||
IsUtcOffsetFound = false;
|
||||
UtcDateTime = new DateTime(1, 1, 1);
|
||||
}
|
||||
|
||||
internal ParsedDateTime(int index_of_date, int length_of_date, int index_of_time, int length_of_time, DateTime date_time, TimeSpan utc_offset)
|
||||
{
|
||||
IndexOfDate = index_of_date;
|
||||
LengthOfDate = length_of_date;
|
||||
IndexOfTime = index_of_time;
|
||||
LengthOfTime = length_of_time;
|
||||
DateTime = date_time;
|
||||
IsDateFound = index_of_date > -1;
|
||||
IsTimeFound = index_of_time > -1;
|
||||
UtcOffset = utc_offset;
|
||||
IsUtcOffsetFound = Math.Abs(utc_offset.TotalHours) < 12;
|
||||
if (!IsUtcOffsetFound)
|
||||
UtcDateTime = new DateTime(1, 1, 1);
|
||||
else
|
||||
{
|
||||
if (index_of_date < 0)//to avoid negative date exception when date is undefined
|
||||
{
|
||||
TimeSpan ts = date_time.TimeOfDay + utc_offset;
|
||||
if (ts < new TimeSpan(0))
|
||||
UtcDateTime = new DateTime(1, 1, 2) + ts;
|
||||
else
|
||||
UtcDateTime = new DateTime(1, 1, 1) + ts;
|
||||
}
|
||||
else
|
||||
UtcDateTime = date_time + utc_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Date that is accepted in the following cases:
|
||||
/// - no date was parsed by TryParseDateOrTime();
|
||||
/// - no year was found by TryParseDate();
|
||||
/// It is ignored if DefaultDateIsNow = true was set after DefaultDate
|
||||
/// </summary>
|
||||
public static DateTime DefaultDate
|
||||
{
|
||||
set
|
||||
{
|
||||
_DefaultDate = value;
|
||||
DefaultDateIsNow = false;
|
||||
}
|
||||
get
|
||||
{
|
||||
if (DefaultDateIsNow)
|
||||
return DateTime.Now;
|
||||
else
|
||||
return _DefaultDate;
|
||||
}
|
||||
}
|
||||
static DateTime _DefaultDate = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// If true then DefaultDate property is ignored and DefaultDate is always DateTime.Now
|
||||
/// </summary>
|
||||
public static bool DefaultDateIsNow = true;
|
||||
|
||||
/// <summary>
|
||||
/// Defines default date-time format.
|
||||
/// </summary>
|
||||
public enum DateTimeFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// month number goes before day number
|
||||
/// </summary>
|
||||
USA_DATE,
|
||||
/// <summary>
|
||||
/// day number goes before month number
|
||||
/// </summary>
|
||||
UK_DATE,
|
||||
///// <summary>
|
||||
///// time is specifed through AM or PM
|
||||
///// </summary>
|
||||
//USA_TIME,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing derived methods for DateTime output
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date and time within the passed string and return it as DateTime structure.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date and/or time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="date_time">parsed date-time output</param>
|
||||
/// <returns>true if both date and time were found, else false</returns>
|
||||
static public bool TryParseDateTime(this string str, DateTimeFormat default_format, out DateTime date_time)
|
||||
{
|
||||
ParsedDateTime parsed_date_time;
|
||||
if (!TryParseDateTime(str, default_format, out parsed_date_time))
|
||||
{
|
||||
date_time = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
date_time = parsed_date_time.DateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date and/or time within the passed string and return it as DateTime structure.
|
||||
/// If only date was found, time in the returned DateTime is always 0:0:0.
|
||||
/// If only time was found, date in the returned DateTime is DefaultDate.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date and(or) time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="date_time">parsed date-time output</param>
|
||||
/// <returns>true if date and/or time was found, else false</returns>
|
||||
static public bool TryParseDateOrTime(this string str, DateTimeFormat default_format, out DateTime date_time)
|
||||
{
|
||||
ParsedDateTime parsed_date_time;
|
||||
if (!TryParseDateOrTime(str, default_format, out parsed_date_time))
|
||||
{
|
||||
date_time = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
date_time = parsed_date_time.DateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find time within the passed string and return it as DateTime structure.
|
||||
/// It recognizes only time while ignoring date, so date in the returned DateTime is always 1/1/1.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="time">parsed time output</param>
|
||||
/// <returns>true if time was found, else false</returns>
|
||||
public static bool TryParseTime(this string str, DateTimeFormat default_format, out DateTime time)
|
||||
{
|
||||
ParsedDateTime parsed_time;
|
||||
if (!TryParseTime(str, default_format, out parsed_time, null))
|
||||
{
|
||||
time = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
time = parsed_time.DateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date within the passed string and return it as DateTime structure.
|
||||
/// It recognizes only date while ignoring time, so time in the returned DateTime is always 0:0:0.
|
||||
/// If year of the date was not found then it accepts the current year.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="date">parsed date output</param>
|
||||
/// <returns>true if date was found, else false</returns>
|
||||
static public bool TryParseDate(this string str, DateTimeFormat default_format, out DateTime date)
|
||||
{
|
||||
ParsedDateTime parsed_date;
|
||||
if (!TryParseDate(str, default_format, out parsed_date))
|
||||
{
|
||||
date = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
date = parsed_date.DateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing derived methods for ParsedDateTime output
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date and time within the passed string and return it as ParsedDateTime object.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date-time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="parsed_date_time">parsed date-time output</param>
|
||||
/// <returns>true if both date and time were found, else false</returns>
|
||||
static public bool TryParseDateTime(this string str, DateTimeFormat default_format, out ParsedDateTime parsed_date_time)
|
||||
{
|
||||
if (DateTimeRoutines.TryParseDateOrTime(str, default_format, out parsed_date_time)
|
||||
&& parsed_date_time.IsDateFound
|
||||
&& parsed_date_time.IsTimeFound
|
||||
)
|
||||
return true;
|
||||
|
||||
parsed_date_time = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find time within the passed string and return it as ParsedDateTime object.
|
||||
/// It recognizes only time while ignoring date, so date in the returned ParsedDateTime is always 1/1/1
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date-time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="parsed_time">parsed date-time output</param>
|
||||
/// <returns>true if time was found, else false</returns>
|
||||
static public bool TryParseTime(this string str, DateTimeFormat default_format, out ParsedDateTime parsed_time)
|
||||
{
|
||||
return TryParseTime(str, default_format, out parsed_time, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date and/or time within the passed string and return it as ParsedDateTime object.
|
||||
/// If only date was found, time in the returned ParsedDateTime is always 0:0:0.
|
||||
/// If only time was found, date in the returned ParsedDateTime is DefaultDate.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date-time</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="parsed_date_time">parsed date-time output</param>
|
||||
/// <returns>true if date or time was found, else false</returns>
|
||||
static public bool TryParseDateOrTime(this string str, DateTimeFormat default_format, out ParsedDateTime parsed_date_time)
|
||||
{
|
||||
parsed_date_time = null;
|
||||
|
||||
ParsedDateTime parsed_date;
|
||||
ParsedDateTime parsed_time;
|
||||
if (!TryParseDate(str, default_format, out parsed_date))
|
||||
{
|
||||
if (!TryParseTime(str, default_format, out parsed_time, null))
|
||||
return false;
|
||||
|
||||
DateTime date_time = new DateTime(DefaultDate.Year, DefaultDate.Month, DefaultDate.Day, parsed_time.DateTime.Hour, parsed_time.DateTime.Minute, parsed_time.DateTime.Second);
|
||||
parsed_date_time = new ParsedDateTime(-1, -1, parsed_time.IndexOfTime, parsed_time.LengthOfTime, date_time, parsed_time.UtcOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryParseTime(str, default_format, out parsed_time, parsed_date))
|
||||
{
|
||||
DateTime date_time = new DateTime(parsed_date.DateTime.Year, parsed_date.DateTime.Month, parsed_date.DateTime.Day, 0, 0, 0);
|
||||
parsed_date_time = new ParsedDateTime(parsed_date.IndexOfDate, parsed_date.LengthOfDate, -1, -1, date_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTime date_time = new DateTime(parsed_date.DateTime.Year, parsed_date.DateTime.Month, parsed_date.DateTime.Day, parsed_time.DateTime.Hour, parsed_time.DateTime.Minute, parsed_time.DateTime.Second);
|
||||
parsed_date_time = new ParsedDateTime(parsed_date.IndexOfDate, parsed_date.LengthOfDate, parsed_time.IndexOfTime, parsed_time.LengthOfTime, date_time, parsed_time.UtcOffset);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing base methods
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find time within the passed string (relatively to the passed parsed_date if any) and return it as ParsedDateTime object.
|
||||
/// It recognizes only time while ignoring date, so date in the returned ParsedDateTime is always 1/1/1
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="parsed_time">parsed date-time output</param>
|
||||
/// <param name="parsed_date">ParsedDateTime object if the date was found within this string, else NULL</param>
|
||||
/// <returns>true if time was found, else false</returns>
|
||||
public static bool TryParseTime(this string str, DateTimeFormat default_format, out ParsedDateTime parsed_time, ParsedDateTime parsed_date)
|
||||
{
|
||||
parsed_time = null;
|
||||
|
||||
string time_zone_r;
|
||||
if(default_format == DateTimeFormat.USA_DATE)
|
||||
time_zone_r = @"(?:\s*(?'time_zone'UTC|GMT|CST|EST))?";
|
||||
else
|
||||
time_zone_r = @"(?:\s*(?'time_zone'UTC|GMT))?";
|
||||
|
||||
Match m;
|
||||
if (parsed_date != null && parsed_date.IndexOfDate > -1)
|
||||
{//look around the found date
|
||||
//look for <date> hh:mm:ss <UTC offset>
|
||||
m = Regex.Match(str.Substring(parsed_date.IndexOfDate + parsed_date.LengthOfDate), @"(?<=^\s*,?\s+|^\s*at\s*|^\s*[T\-]\s*)(?'hour'\d{2})\s*:\s*(?'minute'\d{2})\s*:\s*(?'second'\d{2})\s+(?'offset_sign'[\+\-])(?'offset_hh'\d{2}):?(?'offset_mm'\d{2})(?=$|[^\d\w])", RegexOptions.Compiled);
|
||||
if (!m.Success)
|
||||
//look for <date> [h]h:mm[:ss] [PM/AM] [UTC/GMT]
|
||||
m = Regex.Match(str.Substring(parsed_date.IndexOfDate + parsed_date.LengthOfDate), @"(?<=^\s*,?\s+|^\s*at\s*|^\s*[T\-]\s*)(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?"+time_zone_r+@"(?=$|[^\d\w])", RegexOptions.Compiled);
|
||||
if (!m.Success)
|
||||
//look for [h]h:mm:ss [PM/AM] [UTC/GMT] <date>
|
||||
m = Regex.Match(str.Substring(0, parsed_date.IndexOfDate), @"(?<=^|[^\d])(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?"+time_zone_r+@"(?=$|[\s,]+)", RegexOptions.Compiled);
|
||||
if (!m.Success)
|
||||
//look for [h]h:mm:ss [PM/AM] [UTC/GMT] within <date>
|
||||
m = Regex.Match(str.Substring(parsed_date.IndexOfDate, parsed_date.LengthOfDate), @"(?<=^|[^\d])(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?"+time_zone_r+@"(?=$|[\s,]+)", RegexOptions.Compiled);
|
||||
}
|
||||
else//look anywhere within string
|
||||
{
|
||||
//look for hh:mm:ss <UTC offset>
|
||||
m = Regex.Match(str, @"(?<=^|\s+|\s*T\s*)(?'hour'\d{2})\s*:\s*(?'minute'\d{2})\s*:\s*(?'second'\d{2})\s+(?'offset_sign'[\+\-])(?'offset_hh'\d{2}):?(?'offset_mm'\d{2})?(?=$|[^\d\w])", RegexOptions.Compiled);
|
||||
if (!m.Success)
|
||||
//look for [h]h:mm[:ss] [PM/AM] [UTC/GMT]
|
||||
m = Regex.Match(str, @"(?<=^|\s+|\s*T\s*)(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?"+time_zone_r+@"(?=$|[^\d\w])", RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
//try
|
||||
//{
|
||||
int hour = int.Parse(m.Groups["hour"].Value);
|
||||
if (hour < 0 || hour > 23)
|
||||
return false;
|
||||
|
||||
int minute = int.Parse(m.Groups["minute"].Value);
|
||||
if (minute < 0 || minute > 59)
|
||||
return false;
|
||||
|
||||
int second = 0;
|
||||
if (!string.IsNullOrEmpty(m.Groups["second"].Value))
|
||||
{
|
||||
second = int.Parse(m.Groups["second"].Value);
|
||||
if (second < 0 || second > 59)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.Compare(m.Groups["ampm"].Value, "PM", true) == 0 && hour < 12)
|
||||
hour += 12;
|
||||
else if (string.Compare(m.Groups["ampm"].Value, "AM", true) == 0 && hour == 12)
|
||||
hour -= 12;
|
||||
|
||||
DateTime date_time = new DateTime(1, 1, 1, hour, minute, second);
|
||||
|
||||
if (m.Groups["offset_hh"].Success)
|
||||
{
|
||||
int offset_hh = int.Parse(m.Groups["offset_hh"].Value);
|
||||
int offset_mm = 0;
|
||||
if (m.Groups["offset_mm"].Success)
|
||||
offset_mm = int.Parse(m.Groups["offset_mm"].Value);
|
||||
TimeSpan utc_offset = new TimeSpan(offset_hh, offset_mm, 0);
|
||||
if (m.Groups["offset_sign"].Value == "-")
|
||||
utc_offset = -utc_offset;
|
||||
parsed_time = new ParsedDateTime(-1, -1, m.Index, m.Length, date_time, utc_offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m.Groups["time_zone"].Success)
|
||||
{
|
||||
TimeSpan utc_offset;
|
||||
switch (m.Groups["time_zone"].Value)
|
||||
{
|
||||
case "UTC":
|
||||
case "GMT":
|
||||
utc_offset = new TimeSpan(0, 0, 0);
|
||||
break;
|
||||
case "CST":
|
||||
utc_offset = new TimeSpan(-6, 0, 0);
|
||||
break;
|
||||
case "EST":
|
||||
utc_offset = new TimeSpan(-5, 0, 0);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Time zone: " + m.Groups["time_zone"].Value + " is not defined.");
|
||||
}
|
||||
parsed_time = new ParsedDateTime(-1, -1, m.Index, m.Length, date_time, utc_offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
parsed_time = new ParsedDateTime(-1, -1, m.Index, m.Length, date_time);
|
||||
//}
|
||||
//catch(Exception e)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find date within the passed string and return it as ParsedDateTime object.
|
||||
/// It recognizes only date while ignoring time, so time in the returned ParsedDateTime is always 0:0:0.
|
||||
/// If year of the date was not found then it accepts the current year.
|
||||
/// </summary>
|
||||
/// <param name="str">string that contains date</param>
|
||||
/// <param name="default_format">format to be used preferably in ambivalent instances</param>
|
||||
/// <param name="parsed_date">parsed date output</param>
|
||||
/// <returns>true if date was found, else false</returns>
|
||||
static public bool TryParseDate(this string str, DateTimeFormat default_format, out ParsedDateTime parsed_date)
|
||||
{
|
||||
parsed_date = null;
|
||||
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return false;
|
||||
|
||||
//look for dd/mm/yy
|
||||
Match m = Regex.Match(str, @"(?<=^|[^\d])(?'day'\d{1,2})\s*(?'separator'[\\/\.])+\s*(?'month'\d{1,2})\s*\'separator'+\s*(?'year'\d{2}|\d{4})(?=$|[^\d])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (m.Success)
|
||||
{
|
||||
DateTime date;
|
||||
if ((default_format ^ DateTimeFormat.USA_DATE) == DateTimeFormat.USA_DATE)
|
||||
{
|
||||
if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["day"].Value), int.Parse(m.Groups["month"].Value), out date))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out date))
|
||||
return false;
|
||||
}
|
||||
parsed_date = new ParsedDateTime(m.Index, m.Length, -1, -1, date);
|
||||
return true;
|
||||
}
|
||||
|
||||
//look for [yy]yy-mm-dd
|
||||
m = Regex.Match(str, @"(?<=^|[^\d])(?'year'\d{2}|\d{4})\s*(?'separator'[\-])\s*(?'month'\d{1,2})\s*\'separator'+\s*(?'day'\d{1,2})(?=$|[^\d])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (m.Success)
|
||||
{
|
||||
DateTime date;
|
||||
if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out date))
|
||||
return false;
|
||||
parsed_date = new ParsedDateTime(m.Index, m.Length, -1, -1, date);
|
||||
return true;
|
||||
}
|
||||
|
||||
//look for month dd yyyy
|
||||
m = Regex.Match(str, @"(?:^|[^\d\w])(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?\s*,?\s*(?'year'\d{4})(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (!m.Success)
|
||||
//look for dd month [yy]yy
|
||||
m = Regex.Match(str, @"(?:^|[^\d\w:])(?'day'\d{1,2})(?:-?st\s+|-?th\s+|-?rd\s+|-?nd\s+|-|\s+)(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*(?:\s*,?\s*|-)'?(?'year'\d{2}|\d{4})(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (!m.Success)
|
||||
//look for yyyy month dd
|
||||
m = Regex.Match(str, @"(?:^|[^\d\w])(?'year'\d{4})\s+(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (!m.Success)
|
||||
//look for month dd hh:mm:ss MDT|UTC yyyy
|
||||
m = Regex.Match(str, @"(?:^|[^\d\w])(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})\s+\d{2}\:\d{2}\:\d{2}\s+(?:MDT|UTC)\s+(?'year'\d{4})(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (!m.Success)
|
||||
//look for month dd [yyyy]
|
||||
m = Regex.Match(str, @"(?:^|[^\d\w])(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?(?:\s*,?\s*(?'year'\d{4}))?(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
if (m.Success)
|
||||
{
|
||||
int month = -1;
|
||||
int index_of_date = m.Index;
|
||||
int length_of_date = m.Length;
|
||||
|
||||
switch (m.Groups["month"].Value)
|
||||
{
|
||||
case "Jan":
|
||||
case "JAN":
|
||||
month = 1;
|
||||
break;
|
||||
case "Feb":
|
||||
case "FEB":
|
||||
month = 2;
|
||||
break;
|
||||
case "Mar":
|
||||
case "MAR":
|
||||
month = 3;
|
||||
break;
|
||||
case "Apr":
|
||||
case "APR":
|
||||
month = 4;
|
||||
break;
|
||||
case "May":
|
||||
case "MAY":
|
||||
month = 5;
|
||||
break;
|
||||
case "Jun":
|
||||
case "JUN":
|
||||
month = 6;
|
||||
break;
|
||||
case "Jul":
|
||||
month = 7;
|
||||
break;
|
||||
case "Aug":
|
||||
case "AUG":
|
||||
month = 8;
|
||||
break;
|
||||
case "Sep":
|
||||
case "SEP":
|
||||
month = 9;
|
||||
break;
|
||||
case "Oct":
|
||||
case "OCT":
|
||||
month = 10;
|
||||
break;
|
||||
case "Nov":
|
||||
case "NOV":
|
||||
month = 11;
|
||||
break;
|
||||
case "Dec":
|
||||
case "DEC":
|
||||
month = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
int year;
|
||||
if (!string.IsNullOrEmpty(m.Groups["year"].Value))
|
||||
year = int.Parse(m.Groups["year"].Value);
|
||||
else
|
||||
year = DefaultDate.Year;
|
||||
|
||||
DateTime date;
|
||||
if (!convert_to_date(year, month, int.Parse(m.Groups["day"].Value), out date))
|
||||
return false;
|
||||
parsed_date = new ParsedDateTime(index_of_date, length_of_date, -1, -1, date);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool convert_to_date(int year, int month, int day, out DateTime date)
|
||||
{
|
||||
if (year >= 100)
|
||||
{
|
||||
if (year < 1000)
|
||||
{
|
||||
date = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (year > 30)
|
||||
year += 1900;
|
||||
else
|
||||
year += 2000;
|
||||
|
||||
try
|
||||
{
|
||||
date = new DateTime(year, month, day);
|
||||
}
|
||||
catch
|
||||
{
|
||||
date = new DateTime(1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
7
src/DateTimeRoutines/DateTimeRoutines.csproj
Normal file
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
1
src/Jackett.Common/Content/css/bootstrap-multiselect.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}
|
||||
@@ -1,275 +1,275 @@
|
||||
body {
|
||||
background-image: url("binding_dark.png");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
#page {
|
||||
border-radius: 6px;
|
||||
background-color: white;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
}
|
||||
|
||||
#templates {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#indexers {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.indexer-table {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.test-success {
|
||||
color: #449d44;
|
||||
}
|
||||
|
||||
.test-error {
|
||||
color: #c9302c;
|
||||
}
|
||||
|
||||
.test-inprogress {
|
||||
color: #286090;
|
||||
}
|
||||
|
||||
.indexer-buttons {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.indexer-buttons > .btn {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.indexer-button-test {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.setup-item-inputstring {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
.setup-item-inputbool input {
|
||||
max-width: 100px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.setup-item-inputselect {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
[data-type=hiddendata]{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
-moz-animation: spin 2s infinite linear;
|
||||
-o-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
@-moz-keyframes spin {
|
||||
from {
|
||||
-moz-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-moz-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#setup-indexer-go {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top-color: #cdcdcd;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
margin: 4px 0px;
|
||||
}
|
||||
|
||||
.input-area > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.input-area > p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.input-header {
|
||||
font-size: 18px;
|
||||
width: 160px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.input-right {
|
||||
width: 300px;
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#sonarr-warning {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#logo {
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
#header-title {
|
||||
font-size: 34px;
|
||||
vertical-align: middle;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
color: #444444;
|
||||
margin: 0 auto;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease {
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.modal-fillwidth {
|
||||
width: 1200px;
|
||||
min-width:80%;
|
||||
}
|
||||
|
||||
.indexer-caps {
|
||||
padding: 0px 15px 15px 15px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.indexer-caps table {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.jackettlogWarn {
|
||||
background-color: #FFFF8E !important;
|
||||
}
|
||||
|
||||
.jackettlogError {
|
||||
background-color: #FF6060 !important;
|
||||
}
|
||||
|
||||
.jackettdownloaded {
|
||||
color: blueviolet;
|
||||
}
|
||||
|
||||
.jacketdownloadlocal {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.downloadcolumn {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 3px;
|
||||
margin: 0 0 0px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: transparent;
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.modal-open .modal {
|
||||
overflow-x: auto; /* Model can be bigger than the screen on mobiles */
|
||||
}
|
||||
|
||||
.dataTables_filter input {
|
||||
width: 400px
|
||||
}
|
||||
|
||||
#unconfigured-indexers-template {
|
||||
display: none;
|
||||
}
|
||||
.jackett-apikey{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.jackett-apikey .input-header{
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.setup-item-displayinfo:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table td.fit{
|
||||
white-space: nowrap;
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
.label-imdb {
|
||||
background-color: #d0ab44;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
max-width: 500px !important;
|
||||
}
|
||||
|
||||
.tooltip-inner img {
|
||||
max-width: 250px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.type-public {
|
||||
color: #449d44
|
||||
}
|
||||
|
||||
.type-private {
|
||||
color: #c9302c
|
||||
}
|
||||
|
||||
.type-semi-private {
|
||||
color: #ec971f
|
||||
}
|
||||
|
||||
.dataTables_deadfilter {
|
||||
float: right;
|
||||
text-align: right;
|
||||
margin-right: 1em;
|
||||
}
|
||||
input#searchquery{
|
||||
width:400px;
|
||||
}
|
||||
body {
|
||||
background-image: url("binding_dark.png");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
#page {
|
||||
border-radius: 6px;
|
||||
background-color: white;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
}
|
||||
|
||||
#templates {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#indexers {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.indexer-table {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.test-success {
|
||||
color: #449d44;
|
||||
}
|
||||
|
||||
.test-error {
|
||||
color: #c9302c;
|
||||
}
|
||||
|
||||
.test-inprogress {
|
||||
color: #286090;
|
||||
}
|
||||
|
||||
.indexer-buttons {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.indexer-buttons > .btn {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.indexer-button-test {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.setup-item-inputstring {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
.setup-item-inputbool input {
|
||||
max-width: 100px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.setup-item-inputselect {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
[data-type=hiddendata]{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
-webkit-animation: spin 2s infinite linear;
|
||||
-moz-animation: spin 2s infinite linear;
|
||||
-o-animation: spin 2s infinite linear;
|
||||
animation: spin 2s infinite linear;
|
||||
}
|
||||
|
||||
@-moz-keyframes spin {
|
||||
from {
|
||||
-moz-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-moz-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#setup-indexer-go {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top-color: #cdcdcd;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
margin: 4px 0px;
|
||||
}
|
||||
|
||||
.input-area > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.input-area > p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.input-header {
|
||||
font-size: 18px;
|
||||
width: 160px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.input-right {
|
||||
width: 300px;
|
||||
display: inline-block;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#sonarr-warning {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#logo {
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
#header-title {
|
||||
font-size: 34px;
|
||||
vertical-align: middle;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
color: #444444;
|
||||
margin: 0 auto;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease {
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.modal-fillwidth {
|
||||
width: 1200px;
|
||||
min-width:80%;
|
||||
}
|
||||
|
||||
.indexer-caps {
|
||||
padding: 0px 15px 15px 15px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.indexer-caps table {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.jackettlogWarn {
|
||||
background-color: #FFFF8E !important;
|
||||
}
|
||||
|
||||
.jackettlogError {
|
||||
background-color: #FF6060 !important;
|
||||
}
|
||||
|
||||
.jackettdownloaded {
|
||||
color: blueviolet;
|
||||
}
|
||||
|
||||
.jacketdownloadlocal {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.downloadcolumn {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
padding: 3px;
|
||||
margin: 0 0 0px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: transparent;
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.modal-open .modal {
|
||||
overflow-x: auto; /* Model can be bigger than the screen on mobiles */
|
||||
}
|
||||
|
||||
.dataTables_filter input {
|
||||
width: 400px
|
||||
}
|
||||
|
||||
#unconfigured-indexers-template {
|
||||
display: none;
|
||||
}
|
||||
.jackett-apikey{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.jackett-apikey .input-header{
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.setup-item-displayinfo:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table td.fit{
|
||||
white-space: nowrap;
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
.label-imdb {
|
||||
background-color: #d0ab44;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
max-width: 500px !important;
|
||||
}
|
||||
|
||||
.tooltip-inner img {
|
||||
max-width: 250px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.type-public {
|
||||
color: #449d44
|
||||
}
|
||||
|
||||
.type-private {
|
||||
color: #c9302c
|
||||
}
|
||||
|
||||
.type-semi-private {
|
||||
color: #ec971f
|
||||
}
|
||||
|
||||
.dataTables_deadfilter {
|
||||
float: right;
|
||||
text-align: right;
|
||||
margin-right: 1em;
|
||||
}
|
||||
input#searchquery{
|
||||
width:400px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 361 KiB |
|
Before Width: | Height: | Size: 306 KiB After Width: | Height: | Size: 306 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
|
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
89
src/Jackett.Common/Content/libs/api.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var api = {
|
||||
version: "2.0",
|
||||
root: "/api",
|
||||
key: "",
|
||||
|
||||
getApiPath: function(category, action) {
|
||||
var path = this.root + "/v" + this.version + "/" + category;
|
||||
if (action !== undefined)
|
||||
path = path + "/" + action
|
||||
return path;
|
||||
},
|
||||
|
||||
getAllIndexers: function(callback) {
|
||||
return $.get(this.getApiPath("indexers"), callback);
|
||||
},
|
||||
|
||||
getServerConfig: function(callback) {
|
||||
return $.get(this.getApiPath("server", "config"), callback);
|
||||
},
|
||||
|
||||
getIndexerConfig: function(indexerId, callback) {
|
||||
return $.get(this.getApiPath("indexers", indexerId + "/config"), callback);
|
||||
},
|
||||
|
||||
updateIndexerConfig: function(indexerId, config, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("indexers", indexerId + "/config"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(config),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
deleteIndexer: function(indexerId, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("indexers", indexerId),
|
||||
type: 'DELETE',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
testIndexer: function(indexerId, callback) {
|
||||
return $.post(this.getApiPath("indexers", indexerId + "/test"), callback);
|
||||
},
|
||||
|
||||
resultsForIndexer: function(indexerId, query, callback) {
|
||||
return $.get(this.getApiPath("indexers", indexerId + "/results?apikey=" + this.key), query, callback);
|
||||
},
|
||||
|
||||
getServerCache: function(callback) {
|
||||
return $.get(this.getApiPath("indexers", "cache"), callback);
|
||||
},
|
||||
|
||||
getServerLogs: function(callback) {
|
||||
return $.get(this.getApiPath("server", "logs"), callback);
|
||||
},
|
||||
|
||||
updateServerConfig: function(serverConfig, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("server", "config"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(serverConfig),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
updateServer: function(callback) {
|
||||
return $.post(this.getApiPath("server", "update"), callback);
|
||||
},
|
||||
|
||||
updateAdminPassword: function(password, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("server", "adminpassword"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(password),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
}
|
||||
}
|
||||
1716
src/Jackett.Common/Content/libs/bootstrap-multiselect.js
vendored
Normal file
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
2015 Jason Mulligan
|
||||
@version 3.1.2
|
||||
*/
|
||||
"use strict"; !function (a) { var b = /b$/, c = { bits: ["B", "kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"], bytes: ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] }, d = function (a) { var d = void 0 === arguments[1] ? {} : arguments[1], e = [], f = !1, g = 0, h = void 0, i = void 0, j = void 0, k = void 0, l = void 0, m = void 0, n = void 0, o = void 0, p = void 0, q = void 0, r = void 0; if (isNaN(a)) throw new Error("Invalid arguments"); return j = d.bits === !0, p = d.unix === !0, i = void 0 !== d.base ? d.base : 2, o = void 0 !== d.round ? d.round : p ? 1 : 2, q = void 0 !== d.spacer ? d.spacer : p ? "" : " ", r = void 0 !== d.suffixes ? d.suffixes : {}, n = void 0 !== d.output ? d.output : "string", h = void 0 !== d.exponent ? d.exponent : -1, m = Number(a), l = 0 > m, k = i > 2 ? 1e3 : 1024, l && (m = -m), 0 === m ? (e[0] = 0, e[1] = p ? "" : "B") : ((-1 === h || isNaN(h)) && (h = Math.floor(Math.log(m) / Math.log(k))), h > 8 && (g = 1e3 * g * (h - 8), h = 8), g = 2 === i ? m / Math.pow(2, 10 * h) : m / Math.pow(1e3, h), j && (g = 8 * g, g > k && (g /= k, h++)), e[0] = Number(g.toFixed(h > 0 ? o : 0)), e[1] = c[j ? "bits" : "bytes"][h], !f && p && (j && b.test(e[1]) && (e[1] = e[1].toLowerCase()), e[1] = e[1].charAt(0), "B" === e[1] ? (e[0] = Math.floor(e[0]), e[1] = "") : j || "k" !== e[1] || (e[1] = "K"))), l && (e[0] = -e[0]), e[1] = r[e[1]] || e[1], "array" === n ? e : "exponent" === n ? h : "object" === n ? { value: e[0], suffix: e[1] } : e.join(q) }; "undefined" != typeof exports ? module.exports = d : "function" == typeof define ? define(function () { return d }) : a.filesize = d }("undefined" != typeof global ? global : window);
|
||||
/*
|
||||
2015 Jason Mulligan
|
||||
@version 3.1.2
|
||||
*/
|
||||
"use strict"; !function (a) { var b = /b$/, c = { bits: ["B", "kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"], bytes: ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] }, d = function (a) { var d = void 0 === arguments[1] ? {} : arguments[1], e = [], f = !1, g = 0, h = void 0, i = void 0, j = void 0, k = void 0, l = void 0, m = void 0, n = void 0, o = void 0, p = void 0, q = void 0, r = void 0; if (isNaN(a)) throw new Error("Invalid arguments"); return j = d.bits === !0, p = d.unix === !0, i = void 0 !== d.base ? d.base : 2, o = void 0 !== d.round ? d.round : p ? 1 : 2, q = void 0 !== d.spacer ? d.spacer : p ? "" : " ", r = void 0 !== d.suffixes ? d.suffixes : {}, n = void 0 !== d.output ? d.output : "string", h = void 0 !== d.exponent ? d.exponent : -1, m = Number(a), l = 0 > m, k = i > 2 ? 1e3 : 1024, l && (m = -m), 0 === m ? (e[0] = 0, e[1] = p ? "" : "B") : ((-1 === h || isNaN(h)) && (h = Math.floor(Math.log(m) / Math.log(k))), h > 8 && (g = 1e3 * g * (h - 8), h = 8), g = 2 === i ? m / Math.pow(2, 10 * h) : m / Math.pow(1e3, h), j && (g = 8 * g, g > k && (g /= k, h++)), e[0] = Number(g.toFixed(h > 0 ? o : 0)), e[1] = c[j ? "bits" : "bytes"][h], !f && p && (j && b.test(e[1]) && (e[1] = e[1].toLowerCase()), e[1] = e[1].charAt(0), "B" === e[1] ? (e[0] = Math.floor(e[0]), e[1] = "") : j || "k" !== e[1] || (e[1] = "K"))), l && (e[0] = -e[0]), e[1] = r[e[1]] || e[1], "array" === n ? e : "exponent" === n ? h : "object" === n ? { value: e[0], suffix: e[1] } : e.join(q) }; "undefined" != typeof exports ? module.exports = d : "function" == typeof define ? define(function () { return d }) : a.filesize = d }("undefined" != typeof global ? global : window);
|
||||
//# sourceMappingURL=filesize.min.js.map
|
||||
@@ -1,37 +1,37 @@
|
||||
|
||||
Handlebars.registerHelper('dateFormat', function (context, block) {
|
||||
if (window.moment) {
|
||||
var f = block.hash.format || "MMM DD, YYYY hh:mm:ss A";
|
||||
return moment(context).format(f); //had to remove Date(context)
|
||||
} else {
|
||||
return context; // moment plugin not available. return data as is.
|
||||
};
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('jacketTimespan', function (context, block) {
|
||||
var now = moment();
|
||||
var from = moment(context);
|
||||
var timeSpan = moment.duration(now.diff(from));
|
||||
|
||||
var minutes = timeSpan.asMinutes();
|
||||
if (minutes < 120) {
|
||||
return Math.round(minutes) + 'm ago';
|
||||
}
|
||||
|
||||
var hours = timeSpan.asHours();
|
||||
if (hours < 48) {
|
||||
return Math.round(hours) + 'h ago';
|
||||
}
|
||||
|
||||
var days = timeSpan.asDays();
|
||||
if (days < 365) {
|
||||
return Math.round(days) + 'd ago';
|
||||
}
|
||||
|
||||
var years = timeSpan.asYears();
|
||||
return Math.round(years) + 'y ago';
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('jacketSize', function (context, block) {
|
||||
return filesize(context, { round: 1 });
|
||||
|
||||
Handlebars.registerHelper('dateFormat', function (context, block) {
|
||||
if (window.moment) {
|
||||
var f = block.hash.format || "MMM DD, YYYY hh:mm:ss A";
|
||||
return moment(context).format(f); //had to remove Date(context)
|
||||
} else {
|
||||
return context; // moment plugin not available. return data as is.
|
||||
};
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('jacketTimespan', function (context, block) {
|
||||
var now = moment();
|
||||
var from = moment(context);
|
||||
var timeSpan = moment.duration(now.diff(from));
|
||||
|
||||
var minutes = timeSpan.asMinutes();
|
||||
if (minutes < 120) {
|
||||
return Math.round(minutes) + 'm ago';
|
||||
}
|
||||
|
||||
var hours = timeSpan.asHours();
|
||||
if (hours < 48) {
|
||||
return Math.round(hours) + 'h ago';
|
||||
}
|
||||
|
||||
var days = timeSpan.asDays();
|
||||
if (days < 365) {
|
||||
return Math.round(days) + 'd ago';
|
||||
}
|
||||
|
||||
var years = timeSpan.asYears();
|
||||
return Math.round(years) + 'y ago';
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('jacketSize', function (context, block) {
|
||||
return filesize(context, { round: 1 });
|
||||
});
|
||||
@@ -10,6 +10,8 @@ using System.Net.Http.Headers;
|
||||
using Jackett.Utils;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using Jacket.Common;
|
||||
using Jackett.Models.Config;
|
||||
|
||||
namespace Jackett
|
||||
{
|
||||
@@ -25,7 +27,7 @@ namespace Jackett
|
||||
public HttpMethod Method { get; private set; }
|
||||
public IEnumerable<KeyValuePair<string, string>> PostData { get; set; }
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
public string RawPOSTDdata { get; set;}
|
||||
public string RawPOSTDdata { get; set; }
|
||||
|
||||
public CurlRequest(HttpMethod method, string url, string cookies = null, string referer = null, Dictionary<string, string> headers = null, string rawPOSTData = null)
|
||||
{
|
||||
@@ -54,31 +56,31 @@ namespace Jackett
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<CurlResponse> GetAsync(string url, string cookies = null, string referer = null, Dictionary<string, string> headers = null)
|
||||
public static async Task<CurlResponse> GetAsync(string url, ServerConfig config, string cookies = null, string referer = null, Dictionary<string, string> headers = null)
|
||||
{
|
||||
var curlRequest = new CurlRequest(HttpMethod.Get, url, cookies, referer, headers);
|
||||
var result = await PerformCurlAsync(curlRequest);
|
||||
var result = await PerformCurlAsync(curlRequest, config);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<CurlResponse> PostAsync(string url, IEnumerable<KeyValuePair<string, string>> formData, string cookies = null, string referer = null, Dictionary<string, string> headers = null, string rawPostData =null)
|
||||
public static async Task<CurlResponse> PostAsync(string url, ServerConfig config, IEnumerable<KeyValuePair<string, string>> formData, string cookies = null, string referer = null, Dictionary<string, string> headers = null, string rawPostData = null)
|
||||
{
|
||||
var curlRequest = new CurlRequest(HttpMethod.Post, url, cookies, referer, headers);
|
||||
curlRequest.PostData = formData;
|
||||
curlRequest.RawPOSTDdata = rawPostData;
|
||||
var result = await PerformCurlAsync(curlRequest);
|
||||
var result = await PerformCurlAsync(curlRequest, config);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<CurlResponse> PerformCurlAsync(CurlRequest curlRequest)
|
||||
public static async Task<CurlResponse> PerformCurlAsync(CurlRequest curlRequest, ServerConfig config)
|
||||
{
|
||||
return await Task.Run(() => PerformCurl(curlRequest));
|
||||
return await Task.Run(() => PerformCurl(curlRequest, config));
|
||||
}
|
||||
|
||||
public delegate void ErrorMessage(string s);
|
||||
public static ErrorMessage OnErrorMessage;
|
||||
|
||||
public static CurlResponse PerformCurl(CurlRequest curlRequest)
|
||||
public static CurlResponse PerformCurl(CurlRequest curlRequest, ServerConfig config)
|
||||
{
|
||||
lock (instance)
|
||||
{
|
||||
@@ -87,13 +89,12 @@ namespace Jackett
|
||||
|
||||
using (var easy = new CurlEasy())
|
||||
{
|
||||
|
||||
easy.Url = curlRequest.Url;
|
||||
easy.BufferSize = 64 * 1024;
|
||||
easy.UserAgent = BrowserUtil.ChromeUserAgent;
|
||||
easy.FollowLocation = false;
|
||||
easy.ConnectTimeout = 20;
|
||||
if(curlRequest.Headers != null)
|
||||
if (curlRequest.Headers != null)
|
||||
{
|
||||
CurlSlist curlHeaders = new CurlSlist();
|
||||
foreach (var header in curlRequest.Headers)
|
||||
@@ -138,7 +139,7 @@ namespace Jackett
|
||||
}
|
||||
}
|
||||
|
||||
if (Startup.DoSSLFix == true)
|
||||
if (config.RuntimeSettings.DoSSLFix == true)
|
||||
{
|
||||
// http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio
|
||||
// https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html
|
||||
@@ -147,16 +148,23 @@ namespace Jackett
|
||||
easy.ForbidReuse = true;
|
||||
}
|
||||
|
||||
if (Startup.IgnoreSslErrors == true)
|
||||
if (config.RuntimeSettings.IgnoreSslErrors == true)
|
||||
{
|
||||
easy.SetOpt(CurlOption.SslVerifyhost, false);
|
||||
easy.SetOpt(CurlOption.SslVerifyPeer, false);
|
||||
}
|
||||
|
||||
if (Startup.ProxyConnection != null)
|
||||
var proxy = config.GetProxyUrl();
|
||||
if (proxy != null)
|
||||
{
|
||||
easy.SetOpt(CurlOption.HttpProxyTunnel, 1);
|
||||
easy.SetOpt(CurlOption.Proxy, Startup.ProxyConnection);
|
||||
easy.SetOpt(CurlOption.Proxy, proxy);
|
||||
|
||||
var authString = config.GetProxyAuthString();
|
||||
if (authString != null)
|
||||
{
|
||||
easy.SetOpt(CurlOption.ProxyUserPwd, authString);
|
||||
}
|
||||
}
|
||||
|
||||
easy.Perform();
|
||||
@@ -173,7 +181,7 @@ namespace Jackett
|
||||
|
||||
var headerBytes = Combine(headerBuffers.ToArray());
|
||||
var headerString = Encoding.UTF8.GetString(headerBytes);
|
||||
if (Startup.ProxyConnection != null)
|
||||
if (config.GetProxyUrl() != null)
|
||||
{
|
||||
var firstcrlf = headerString.IndexOf("\r\n\r\n");
|
||||
var secondcrlf = headerString.IndexOf("\r\n\r\n", firstcrlf + 1);
|
||||
@@ -209,7 +217,8 @@ namespace Jackett
|
||||
if (key == "set-cookie")
|
||||
{
|
||||
var nameSplit = value.IndexOf('=');
|
||||
if (nameSplit > -1) {
|
||||
if (nameSplit > -1)
|
||||
{
|
||||
var cKey = value.Substring(0, nameSplit);
|
||||
var cVal = value.Split(';')[0] + ";";
|
||||
cookies.Add(new Tuple<string, string>(cKey, cVal));
|
||||
@@ -241,12 +250,12 @@ namespace Jackett
|
||||
OnErrorMessage("request.Cookies: " + curlRequest.Cookies);
|
||||
OnErrorMessage("request.Referer: " + curlRequest.Referer);
|
||||
OnErrorMessage("request.RawPOSTDdata: " + curlRequest.RawPOSTDdata);
|
||||
OnErrorMessage("cookies: "+ cookieBuilder.ToString().Trim());
|
||||
OnErrorMessage("cookies: " + cookieBuilder.ToString().Trim());
|
||||
OnErrorMessage("headerString:\n" + headerString);
|
||||
|
||||
|
||||
foreach (var headerPart in headerParts)
|
||||
{
|
||||
OnErrorMessage("headerParts: "+headerPart);
|
||||
OnErrorMessage("headerParts: " + headerPart);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -254,7 +263,7 @@ namespace Jackett
|
||||
OnErrorMessage(string.Format("CurlHelper: error while handling NotImplemented/InternalServerError:\n{0}", ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var contentBytes = Combine(contentBuffers.ToArray());
|
||||
var curlResponse = new CurlResponse(headers, contentBytes, status, cookieBuilder.ToString().Trim());
|
||||
return curlResponse;
|
||||
192
src/Jackett.Common/Definitions/1337x.yml
Normal file
@@ -0,0 +1,192 @@
|
||||
---
|
||||
site: 1337x
|
||||
name: 1337x
|
||||
description: "1337X is a Public torrent site that offers verified torrent downloads"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://1337x.to
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
#Anime
|
||||
- {id: 28, cat: TV/Anime, desc: "Anime/Anime"}
|
||||
- {id: 78, cat: TV/Anime, desc: "Anime/Dual Audio"}
|
||||
- {id: 79, cat: TV/Anime, desc: "Anime/Dubbed"}
|
||||
- {id: 80, cat: TV/Anime, desc: "Anime/Subbed"}
|
||||
- {id: 81, cat: TV/Anime, desc: "Anime/Raw"}
|
||||
|
||||
#Audio
|
||||
- {id: 22, cat: Audio/MP3, desc: "Music/MP3"}
|
||||
- {id: 23, cat: Audio/Lossless, desc: "Music/Lossless"}
|
||||
- {id: 24, cat: Audio, desc: "Music/DVD"}
|
||||
- {id: 25, cat: Audio/Video, desc: "Music/Video"}
|
||||
- {id: 26, cat: Audio, desc: "Music/Radio"}
|
||||
- {id: 27, cat: Audio/Other, desc: "Music/Other"}
|
||||
- {id: 53, cat: Audio, desc: "Music/Album"}
|
||||
- {id: 58, cat: Audio, desc: "Music/Box set"}
|
||||
- {id: 59, cat: Audio, desc: "Music/Discography"}
|
||||
- {id: 60, cat: Audio, desc: "Music/Single"}
|
||||
- {id: 68, cat: Audio, desc: "Music/Concerts"}
|
||||
- {id: 69, cat: Audio, desc: "Music/AAC"}
|
||||
|
||||
#Movies
|
||||
- {id: 1, cat: Movies/DVD, desc: "Movies/DVD"}
|
||||
- {id: 2, cat: Movies/SD, desc: "Movies/Divx/Xvid"}
|
||||
- {id: 3, cat: Movies, desc: "Movies/SVCD/VCD"}
|
||||
- {id: 4, cat: Movies/Foreign, desc: "Movies/Dubs/Dual Audio"}
|
||||
- {id: 9, cat: Movies, desc: "Documentaries/Documentary"}
|
||||
- {id: 42, cat: Movies/HD, desc: "Movies/HD"}
|
||||
- {id: 54, cat: Movies, desc: "Movies/h.264/x264"}
|
||||
- {id: 55, cat: Movies, desc: "Movies/Mp4"}
|
||||
- {id: 66, cat: Movies/3D, desc: "Movies/3D"}
|
||||
- {id: 70, cat: Movies, desc: "Movies/HEVC/x265"}
|
||||
- {id: 73, cat: Movies, desc: "Movies/Bollywood"}
|
||||
- {id: 76, cat: Movies, desc: "Movies/UHD"}
|
||||
|
||||
#TV
|
||||
- {id: 5, cat: TV, desc: "TV/DVD"}
|
||||
- {id: 6, cat: TV, desc: "TV/Divx/Xvid"}
|
||||
- {id: 7, cat: TV, desc: "TV/SVCD/VCD"}
|
||||
- {id: 41, cat: TV/HD, desc: "TV/HD"}
|
||||
- {id: 71, cat: TV, desc: "TV/HEVC/x265"}
|
||||
- {id: 74, cat: TV, desc: "TV/Cartoons"}
|
||||
- {id: 75, cat: TV/SD, desc: "TV/SD"}
|
||||
|
||||
#Apps
|
||||
- {id: 18, cat: PC, desc: "Apps/PC Software"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Apps/Mac"}
|
||||
- {id: 20, cat: PC, desc: "Apps/Linux"}
|
||||
- {id: 21, cat: PC, desc: "Apps/Other"}
|
||||
- {id: 56, cat: PC/Phone-Android, desc: "Apps/Android"}
|
||||
- {id: 57, cat: PC/Phone-IOS, desc: "Apps/iOS"}
|
||||
|
||||
#Games
|
||||
- {id: 10, cat: PC/Games, desc: "Games/PC Game"}
|
||||
- {id: 11, cat: Console/Other, desc: "Games/PS2"}
|
||||
- {id: 12, cat: Console/PSP, desc: "Games/PSP"}
|
||||
- {id: 13, cat: Console/Xbox, desc: "Games/Xbox"}
|
||||
- {id: 14, cat: Console/Xbox 360, desc: "Games/Xbox360"}
|
||||
- {id: 15, cat: Console/Other, desc: "Games/PS1"}
|
||||
- {id: 16, cat: Console/Other, desc: "Games/Dreamcast"}
|
||||
- {id: 17, cat: PC/Phone-Other, desc: "Games/Other"}
|
||||
- {id: 43, cat: Console/PS3, desc: "Games/PS3"}
|
||||
- {id: 44, cat: Console/Wii, desc: "Games/Wii"}
|
||||
- {id: 45, cat: Console/NDS, desc: "Games/DS"}
|
||||
- {id: 46, cat: Console, desc: "Games/GameCube"}
|
||||
- {id: 72, cat: Console/3DS, desc: "Games/3DS"}
|
||||
- {id: 77, cat: Console/PS4, desc: "Games/PS4"}
|
||||
- {id: 82, cat: Console/Other, desc: "Games/Switch"}
|
||||
|
||||
#XXX
|
||||
- {id: 48, cat: XXX/DVD, desc: "XXX/Video"}
|
||||
- {id: 49, cat: XXX/Imageset, desc: "XXX/Picture"}
|
||||
- {id: 50, cat: XXX, desc: "XXX/Magazine"}
|
||||
- {id: 51, cat: XXX, desc: "XXX/Hentai"}
|
||||
- {id: 67, cat: XXX, desc: "XXX/Games"}
|
||||
|
||||
#Other
|
||||
- {id: 33, cat: Other, desc: "Other/Emulation"}
|
||||
- {id: 34, cat: Books, desc: "Other/Tutorial"}
|
||||
- {id: 35, cat: Other, desc: "Other/Sounds"}
|
||||
- {id: 36, cat: Books/Ebook, desc: "Other/E-books"}
|
||||
- {id: 37, cat: Other, desc: "Other/Images"}
|
||||
- {id: 38, cat: Other, desc: "Other/Mobile Phone"}
|
||||
- {id: 39, cat: Books/Comics, desc: "Other/Comics"}
|
||||
- {id: 40, cat: Other/Misc, desc: "Other/Other"}
|
||||
- {id: 47, cat: Other, desc: "Other/Nulled Script"}
|
||||
- {id: 52, cat: Audio/Audiobook, desc: "Other/Audiobook"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: downloadlink
|
||||
type: select
|
||||
label: Download link
|
||||
default: "magnet:"
|
||||
options:
|
||||
"http://itorrents.org/" : "iTorrents.org"
|
||||
"magnet:": "magnet"
|
||||
|
||||
download:
|
||||
# the .torrent url is on the on the details page
|
||||
selector: ul li a[href^="{{ .Config.downloadlink }}"]
|
||||
|
||||
search:
|
||||
paths:
|
||||
# present trending results if there are no search parms supplied
|
||||
- path: "{{if .Keywords}}/search/{{ .Keywords}}/1/{{else}}/trending{{end}}"
|
||||
rows:
|
||||
selector: tr:has(a[href^="/torrent/"])
|
||||
fields:
|
||||
title:
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
category:
|
||||
optional: true
|
||||
selector: td[class^="coll-1"] a[href^="/sub/"]
|
||||
attribute: href
|
||||
filters:
|
||||
# extract the third part
|
||||
- name: split
|
||||
args: ["/", 2]
|
||||
details:
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
attribute: href
|
||||
download:
|
||||
# .torrent link is on the details page
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
attribute: href
|
||||
# dates come in three flavours:
|
||||
date:
|
||||
# (within this year) 7am Sep. 14th
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:not(:contains(":")):not(:contains("'"))
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["st", ""]
|
||||
- name: replace
|
||||
args: ["nd", ""]
|
||||
- name: replace
|
||||
args: ["rd", ""]
|
||||
- name: replace
|
||||
args: ["th", ""]
|
||||
- name: dateparse
|
||||
args: "3pm Jan. 2"
|
||||
date:
|
||||
# (more than a year ago) Apr. 18th '11
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:contains("'")
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["'", ""]
|
||||
- name: replace
|
||||
args: ["st", ""]
|
||||
- name: replace
|
||||
args: ["nd", ""]
|
||||
- name: replace
|
||||
args: ["rd", ""]
|
||||
- name: replace
|
||||
args: ["th", ""]
|
||||
- name: dateparse
|
||||
args: "Jan. 2 06"
|
||||
date:
|
||||
# # (today) 12:25am
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:contains(":")
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "3:04pm"
|
||||
size:
|
||||
selector: td[class^="coll-4"]
|
||||
seeders:
|
||||
selector: td[class^="coll-2"]
|
||||
leechers:
|
||||
selector: td[class^="coll-3"]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: 2fast4you
|
||||
name: 2 Fast 4 You
|
||||
description: "2 Fast 4 You is a FRENCH Private site for TV / MOVIES / GENERAL"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -95,7 +96,8 @@
|
||||
path: torrents-search.php
|
||||
|
||||
search:
|
||||
path: torrents-search.php
|
||||
paths:
|
||||
- path: torrents-search.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
@@ -112,6 +114,9 @@
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
title:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: replace
|
||||
args: [" - (Nouveau!)", ""]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
@@ -136,4 +141,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
@@ -42,7 +42,7 @@
|
||||
pwd: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img.captcha
|
||||
selector: img.captcha
|
||||
input: private_key
|
||||
error:
|
||||
- selector: span.errormsg
|
||||
@@ -53,7 +53,8 @@
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
paths:
|
||||
- path: index.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
171
src/Jackett.Common/Definitions/Bittorrentfiles.yml
Normal file
@@ -0,0 +1,171 @@
|
||||
---
|
||||
site: Bittorrentfiles
|
||||
name: Bittorrentfiles
|
||||
description: "Bittorrentfiles is a Private GERMAN tracker"
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.Bittorrentfiles.me/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Movie
|
||||
- {id: 48, cat: Movies/HD, desc: "1080p"}
|
||||
- {id: 31, cat: Movies/3D, desc: "3D"}
|
||||
- {id: 21, cat: Movies/HD, desc: "720p"}
|
||||
- {id: 28, cat: Movies/SD, desc: "AVI"}
|
||||
- {id: 20, cat: Movies/DVD, desc: "DVD-R"}
|
||||
- {id: 40, cat: Movies/HD, desc: "h264/x264"}
|
||||
- {id: 30, cat: Movies/HD, desc: "HD/BD"}
|
||||
- {id: 49, cat: Movies/Foreign, desc: "International"}
|
||||
- {id: 78, cat: Movies/HD, desc: "UHD"}
|
||||
|
||||
# Serien
|
||||
- {id: 79, cat: TV/HD, desc: "Staffeln HD"}
|
||||
- {id: 56, cat: TV/SD, desc: "Staffeln SD"}
|
||||
- {id: 54, cat: TV/HD, desc: "Folgen HD"}
|
||||
- {id: 80, cat: TV/HD, desc: "Folgen HD/BD"}
|
||||
- {id: 7, cat: TV/SD, desc: "Folgen SD"}
|
||||
- {id: 55, cat: TV/Foreign, desc: "International"}
|
||||
|
||||
# Doku
|
||||
- {id: 64, cat: TV/Documentary, desc: "HD"}
|
||||
- {id: 36, cat: TV/Documentary, desc: "SD"}
|
||||
- {id: 81, cat: TV/Documentary, desc: "3D"}
|
||||
- {id: 82, cat: TV/Documentary, desc: "Packs"}
|
||||
|
||||
# Spiele
|
||||
- {id: 4, cat: PC/Games, desc: "Windows"}
|
||||
- {id: 72, cat: Console/XBox360, desc: "XBOX 360"}
|
||||
- {id: 44, cat: Console/XBoxOne, desc: "XBOX One"}
|
||||
- {id: 43, cat: Console/Wii, desc: "Wii"}
|
||||
- {id: 69, cat: Console, desc: "PS2"}
|
||||
- {id: 70, cat: Console/PS3, desc: "PS3"}
|
||||
- {id: 70, cat: Console/PS4, desc: "PS4"}
|
||||
- {id: 70, cat: Console/PSP, desc: "PSP"}
|
||||
- {id: 42, cat: Console/Other, desc: "Misc"}
|
||||
|
||||
# Musik
|
||||
- {id: 66, cat: Audio, desc: "Alben"}
|
||||
- {id: 75, cat: Audio, desc: "Singles"}
|
||||
- {id: 50, cat: Audio, desc: "Charts"}
|
||||
- {id: 52, cat: Audio, desc: "Packs"}
|
||||
- {id: 53, cat: Audio/Video, desc: "Video"}
|
||||
- {id: 61, cat: Audio/Video, desc: "DVD-R"}
|
||||
- {id: 83, cat: Audio, desc: "Flac"}
|
||||
- {id: 68, cat: Audio, desc: "Live"}
|
||||
- {id: 6, cat: Audio, desc: "Misc"}
|
||||
- {id: 51, cat: Audio, desc: "OST"}
|
||||
- {id: 67, cat: Audio, desc: "Sampler"}
|
||||
|
||||
# App
|
||||
- {id: 22, cat: PC/0day, desc: "Windows"}
|
||||
- {id: 62, cat: PC/Mac, desc: "Mac OS"}
|
||||
- {id: 63, cat: PC/0day, desc: "Linux"}
|
||||
- {id: 34, cat: PC, desc: "Andere"}
|
||||
|
||||
# Sport
|
||||
- {id: 74, cat: TV/Sport, desc: "HD"}
|
||||
- {id: 39, cat: TV/Sport, desc: "SD"}
|
||||
|
||||
# Sonstiges
|
||||
- {id: 41, cat: Books/Comics, desc: "A-Book"}
|
||||
- {id: 33, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 35, cat: Books, desc: "e-Book"}
|
||||
- {id: 65, cat: Other, desc: "E-Learning"}
|
||||
- {id: 65, cat: PC, desc: "Mobile"}
|
||||
- {id: 9, cat: Other, desc: "Other"}
|
||||
|
||||
#XXX
|
||||
- {id: 58, cat: Books/Comics, desc: "HD"}
|
||||
- {id: 33, cat: XXX, desc: "Hentai"}
|
||||
- {id: 35, cat: XXX/Other, desc: "Other"}
|
||||
- {id: 65, cat: XXX/Packs, desc: "Pack"}
|
||||
- {id: 65, cat: XXX, desc: "SD"}
|
||||
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings:
|
||||
- name: user
|
||||
type: text
|
||||
label: Username
|
||||
- name: pass
|
||||
type: password
|
||||
label: Password
|
||||
|
||||
login:
|
||||
path: signin.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
user: "{{ .Config.user }}"
|
||||
pass: "{{ .Config.pass }}"
|
||||
error:
|
||||
- selector: .error
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
|
||||
rows:
|
||||
selector: table.tableinborder > tbody > tr:has(a[href^="details.php"])
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php"]
|
||||
attribute: title
|
||||
category:
|
||||
selector: a[href^="/browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="/download.php"]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5) > a
|
||||
grabs:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2)
|
||||
size:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(6)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
seeders:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2)
|
||||
leechers:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(10)
|
||||
filters:
|
||||
- name: split
|
||||
args: ["by", 0]
|
||||
- name: replace
|
||||
args: ["Heute", "Today"]
|
||||
- name: replace
|
||||
args: ["Gestern", "Yesterday"]
|
||||
- name: dateparse
|
||||
args: "02.01.2006 15:04:05"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt="OU"]: "0"
|
||||
img[alt="D/2"]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img[alt="2xU"]: "2"
|
||||
"*": "1"
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: acidlounge
|
||||
name: Acid-Lounge
|
||||
description: "Acid Lounge (A-L) is a Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -64,7 +65,7 @@
|
||||
form: form#login
|
||||
captcha:
|
||||
type: image
|
||||
image: img[alt="Security code"]
|
||||
selector: img[alt="Security code"]
|
||||
input: code
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: anidex
|
||||
name: Anidex
|
||||
description: "Anidex is a torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
language: en-us
|
||||
encoding: UTF-8
|
||||
type: public
|
||||
@@ -34,42 +34,23 @@
|
||||
- name: cat-id
|
||||
type: text
|
||||
label: Category Id
|
||||
- name: lang-id
|
||||
type: text
|
||||
label: Language Id
|
||||
- name: info
|
||||
type: info
|
||||
label: Category Id Note
|
||||
default: "You can filter your searches by using any of the following category numbers (comma delimited):<br>1 :Anime - Sub<br>2 :Anime - Raw<br>3 :Anime - Dub<br>4 :LA - Sub<br>5 :LA - Raw<br>6 :Light Novel<br>7 :Manga - TLed<br>8 :Manga - Raw<br>9 :♫ - Lossy<br>10 :♫ - Lossless<br>11 :♫ - Video<br>12 :Games<br>13 :Applications<br>14 :Pictures<br>15 :Adult Video<br>16 :Other"
|
||||
|
||||
search:
|
||||
path: "ajax/page.ajax.php"
|
||||
headers:
|
||||
x-requested-with: ["XMLHttpRequest"]
|
||||
inputs:
|
||||
page: "torrents"
|
||||
filename: "{{ .Query.Keywords }}"
|
||||
category: "{{ .Config.cat-id }}"
|
||||
lang_id: "{{ .Config.lang-id }}"
|
||||
paths:
|
||||
- path: "?{{if .Config.cat-id}}id={{.Config.cat-id }}&{{else}}{{end}}q={{if .Keywords}}{{.Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: div.table-responsive > table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: td:nth-child(1) > div
|
||||
case:
|
||||
":contains(\"Anime - Sub\")": 1
|
||||
":contains(\"Anime - Raw\")": 2
|
||||
":contains(\"Anime - Dub\")": 3
|
||||
":contains(\"LA - Sub\")": 4
|
||||
":contains(\"LA - Raw\")": 5
|
||||
":contains(\"Light Novel\")": 6
|
||||
":contains(\"Manga - TLed\")": 7
|
||||
":contains(\"Manga - Raw\")": 8
|
||||
":contains(\"♫ - Lossy\")": 9
|
||||
":contains(\"♫ - Lossless\")": 10
|
||||
":contains(\"♫ - Video\")": 11
|
||||
":contains(\"Games\")": 12
|
||||
":contains(\"Applications\")": 13
|
||||
":contains(\"Pictures\")": 14
|
||||
":contains(\"Adult Video\")": 15
|
||||
":contains(\"Other\")": 16
|
||||
"*": 0 # some old torrents don't have a category
|
||||
selector: a[href^="/?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: id
|
||||
title:
|
||||
selector: td:nth-child(3) > a.torrent > span.span-1440
|
||||
details:
|
||||
@@ -78,6 +59,9 @@
|
||||
download:
|
||||
selector: td:nth-child(5) > a
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:?"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
@@ -92,3 +76,9 @@
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
grabs:
|
||||
selector: td:nth-child(11)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
78
src/Jackett.Common/Definitions/anirena.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
site: aniRena
|
||||
name: AniRena
|
||||
description: "AniRena is a Public torrent tracker for the latest anime and Japanese related torrents"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.anirena.com/
|
||||
|
||||
settings: []
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 1, cat: TV/Anime, desc: "Raw Animes"}
|
||||
- {id: 2, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 3, cat: TV/Anime, desc: "Hentai"}
|
||||
- {id: 4, cat: TV/Anime, desc: "Drama"}
|
||||
- {id: 9, cat: TV/Anime, desc: "Anime Music Videos"}
|
||||
- {id: 10, cat: TV/Anime, desc: "Non-English"}
|
||||
# Software
|
||||
- {id: 5, cat: PC/ISO, desc: "DVD/ISO"}
|
||||
- {id: 6, cat: PC, desc: "Hentai-Game"}
|
||||
# Literature
|
||||
- {id: 7, cat: Books, desc: "Manga"}
|
||||
# Audio
|
||||
- {id: 8, cat: Audio, desc: "Audio"}
|
||||
# Other
|
||||
- {id: 11, cat: Other, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "/{{if .Keywords}}?s={{ .Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: table tbody tr:has(td.torrents_small_type_data1)
|
||||
fields:
|
||||
title:
|
||||
selector: .torrents_small_info_data1 div
|
||||
download:
|
||||
selector: .torrents_small_info_data2 a[title="Download Torrent"]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: .torrents_small_info_data2 a[title="Magnet Link"]
|
||||
attribute: href
|
||||
date:
|
||||
text: now
|
||||
size:
|
||||
selector: .torrents_small_size_data1
|
||||
seeders:
|
||||
selector: .torrents_small_seeders_data1 b big
|
||||
leechers:
|
||||
selector: .torrents_small_leechers_data1 b big
|
||||
grabs:
|
||||
selector: .torrents_small_downloads_data1
|
||||
category:
|
||||
selector: .torrents_small_type_data1 img
|
||||
attribute: src
|
||||
case:
|
||||
"[src=\"./styles/tracker/imageset/cat_raw_small.png\"]": "1"
|
||||
"[src=\"./styles/tracker/imageset/cat_anime_small.png\"]": "2"
|
||||
"[src=\"./styles/tracker/imageset/cat_hentai_small.png\"]": "3"
|
||||
"[src=\"./styles/tracker/imageset/cat_drama_small.png\"]": "4"
|
||||
"[src=\"./styles/tracker/imageset/cat_dvd_small.png\"]": "5"
|
||||
"[src=\"./styles/tracker/imageset/cat_hgame2_small.png\"]": "6"
|
||||
"[src=\"./styles/tracker/imageset/cat_manga_small.png\"]": "7"
|
||||
"[src=\"./styles/tracker/imageset/cat_music_small.png\"]": "8"
|
||||
"[src=\"./styles/tracker/imageset/cat_musicvid_small.png\"]": "9"
|
||||
"[src=\"./styles/tracker/imageset/cat_noneng_small.png\"]": "10"
|
||||
"[src=\"./styles/tracker/imageset/cat_other_small.png\"]": "11"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: aox
|
||||
name: AOX
|
||||
description: "AOX (Chippu) is a Private Torrent Tracker for ASIAN MOVIES / TV"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -54,7 +55,8 @@
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
paths:
|
||||
- path: index.php
|
||||
inputs:
|
||||
search: "{{ .Query.Keywords }}"
|
||||
page: "torrents"
|
||||
@@ -121,4 +123,4 @@
|
||||
- name: prepend
|
||||
args: "<br>Language: "
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: arabafenice
|
||||
name: ArabaFenice
|
||||
description: "Araba Fenice (Phoenix) is an ITALIAN Private site for TV / MOVIES / GENERAL"
|
||||
language: it-it
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -96,7 +97,8 @@
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
paths:
|
||||
- path: index.php
|
||||
inputs:
|
||||
search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
|
||||
page: "torrents"
|
||||
143
src/Jackett.Common/Definitions/archetorrent.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
site: archetorrent
|
||||
name: ArcheTorrent
|
||||
description: "ArcheTorrent is a FRENCH Private Torrent Tracker"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://archetorrent.com
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 18, cat: PC, desc: "Applications: PC"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Applications: Mac"}
|
||||
- {id: 54, cat: PC, desc: "Applications: linux"}
|
||||
- {id: 56, cat: XXX/Other, desc: "Autres: ebook xxx"}
|
||||
- {id: 36, cat: Books, desc: "Autres: E-Books"}
|
||||
- {id: 37, cat: Other, desc: "Autres: Images"}
|
||||
- {id: 38, cat: PC/Phone-Other, desc: "Autres: Telephone-mobile"}
|
||||
- {id: 47, cat: Movies, desc: "Films: Animé"}
|
||||
- {id: 1, cat: Movies/DVD, desc: "Films: DVD"}
|
||||
- {id: 2, cat: Movies/SD, desc: "Films: Dvdrip"}
|
||||
- {id: 68, cat: Movies, desc: "Films: TAT Releases"}
|
||||
- {id: 70, cat: Movies/HD, desc: "Films: UHD 4K"}
|
||||
- {id: 69, cat: Movies, desc: "Films: Retro"}
|
||||
- {id: 3, cat: Movies/HD, desc: "Films: HD1080"}
|
||||
- {id: 42, cat: Movies/HD, desc: "Films: HD720"}
|
||||
- {id: 4, cat: Movies, desc: "Films: Cam/Ts"}
|
||||
- {id: 22, cat: Movies/BluRay, desc: "Films: bluray"}
|
||||
- {id: 23, cat: Movies/3D, desc: "Films: 3D"}
|
||||
- {id: 24, cat: Movies/Foreign, desc: "Films: VOSTFR"}
|
||||
- {id: 25, cat: XXX, desc: "Films: Adulte"}
|
||||
- {id: 48, cat: TV/Documentary, desc: "Films: Documentaire"}
|
||||
- {id: 49, cat: Movies/Other, desc: "Films: Spectacle"}
|
||||
- {id: 51, cat: Movies/SD, desc: "Films: R5"}
|
||||
- {id: 52, cat: Movies/SD, desc: "Films: bdrip"}
|
||||
- {id: 53, cat: Movies/SD, desc: "Films: brrip"}
|
||||
- {id: 55, cat: Movies/DVD, desc: "Films: dvd-pack"}
|
||||
- {id: 57, cat: Movies, desc: "Films: manga"}
|
||||
- {id: 59, cat: Movies/WEBDL, desc: "Films: Webrip"}
|
||||
- {id: 63, cat: Movies/SD, desc: "Films: M-HD"}
|
||||
- {id: 10, cat: PC/Games, desc: "Jeux: PC"}
|
||||
- {id: 11, cat: Console/Other, desc: "Jeux: PS2"}
|
||||
- {id: 43, cat: Console/PS3, desc: "Jeux: PS3"}
|
||||
- {id: 12, cat: Console/PSP, desc: "Jeux: PSP"}
|
||||
- {id: 14, cat: Console/Xbox 360, desc: "Jeux: Xbox360"}
|
||||
- {id: 44, cat: Console/Wii, desc: "Jeux: Wii"}
|
||||
- {id: 45, cat: Console/NDS, desc: "Jeux: DS"}
|
||||
- {id: 27, cat: Audio/Video, desc: "Musique: Clip Video"}
|
||||
- {id: 62, cat: TV/SD, desc: "Serie tv: TV BDRip"}
|
||||
- {id: 5, cat: TV/SD, desc: "Serie tv: Dvdrip"}
|
||||
- {id: 41, cat: TV/HD, desc: "Serie tv: Hd"}
|
||||
- {id: 60, cat: TV/SD, desc: "Serie tv: pack série tv"}
|
||||
- {id: 64, cat: TV/FOREIGN, desc: "Serie tv: vostfr"}
|
||||
- {id: 65, cat: TV/HD, desc: "Serie tv: Série tv 720P"}
|
||||
- {id: 66, cat: TV/HD, desc: "Serie tv: Série tv 1080P"}
|
||||
- {id: 67, cat: TV/HD, desc: "Serie tv: Série tv PackHD"}
|
||||
- {id: 73, cat: TV/Anime, desc: "Serie tv: Anime "}
|
||||
- {id: 72, cat: TV/Sport, desc: "Sport: sport"}
|
||||
- {id: 61, cat: TV/SD, desc: "Tv: DVDRip"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: account-login.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: form:contains("Erreur")
|
||||
message:
|
||||
selector: form
|
||||
remove: table
|
||||
test:
|
||||
path: torrents-search.php
|
||||
|
||||
search:
|
||||
keywordsfilters:
|
||||
- name: replace
|
||||
args: ["-", " "] # remove special search character (negative search)
|
||||
- name: replace
|
||||
args: ["+", " "] # remove special search character (positive search)
|
||||
- name: re_replace
|
||||
args: ["(\\w+)", " +$1"] # prepend + to each word
|
||||
paths:
|
||||
- path: torrents-search.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Keywords }}"
|
||||
incldead: "1"
|
||||
|
||||
rows:
|
||||
selector: table.ttable_headinner > tbody > tr[class^="t-row"]
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
date:
|
||||
selector: td:nth-child(3) a
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Poster le: </b>(.*?)<br />"
|
||||
- name: dateparse
|
||||
args: "02-01-2006"
|
||||
title:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: replace
|
||||
args: [" - (Nouveau!)", ""]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
banner:
|
||||
selector: img.rounded-img
|
||||
attribute: src
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
grabs:
|
||||
selector: td:nth-child(9) font b
|
||||
seeders:
|
||||
selector: td:nth-child(7) font b
|
||||
leechers:
|
||||
selector: td:nth-child(8) font b
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[title="freeleech"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: asiandvdclub
|
||||
name: AsianDVDClub
|
||||
description: "AsianDVDClub is an ASIAN Private Torrent Tracker for HD MOVIES / TV"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -44,7 +45,8 @@
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
paths:
|
||||
- path: browse.php
|
||||
keywordsfilters:
|
||||
- name: replace
|
||||
args: ["-", " "]
|
||||
111
src/Jackett.Common/Definitions/ast4u.yml
Normal file
@@ -0,0 +1,111 @@
|
||||
---
|
||||
site: ast4u
|
||||
name: AST4u
|
||||
description: "AST4u is a GERMAN Private site for TV / MOVIES / ANIME / HENTAI"
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- https://www.ast4u.me/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 35, cat: TV/Anime, desc: "Anime Movie"}
|
||||
- {id: 36, cat: TV/Anime, desc: "Anime Serie"}
|
||||
- {id: 37, cat: Audio/Foreign, desc: "Anime Musik"}
|
||||
- {id: 41, cat: Books, desc: "Anime Pic & Manga"}
|
||||
- {id: 42, cat: XXX, desc: "Hentai Movie & OVA"}
|
||||
- {id: 43, cat: XXX, desc: "Hentai Serie"}
|
||||
- {id: 44, cat: PC, desc: "Hentai Game"}
|
||||
- {id: 45, cat: Movies, desc: "Cartoon Movie"}
|
||||
- {id: 46, cat: TV, desc: "Cartoon Serie"}
|
||||
- {id: 47, cat: TV, desc: "TV-Serie"}
|
||||
- {id: 49, cat: TV/Documentary, desc: "Sonstiges Doku"}
|
||||
- {id: 50, cat: Audio, desc: "Sonstiges Soundtrack"}
|
||||
- {id: 52, cat: Movies/HD, desc: "Movie HD"}
|
||||
- {id: 53, cat: Other, desc: "Sonstiges"}
|
||||
- {id: 55, cat: Movies/Foreign, desc: "Movie Asia & MartialArts"}
|
||||
- {id: 56, cat: TV/Anime, desc: "Anime OVA"}
|
||||
- {id: 58, cat: Movies, desc: "Movie"}
|
||||
- {id: 59, cat: Audio/Audiobook, desc: "Sonstiges Hoerspiele"}
|
||||
- {id: 62, cat: Console, desc: "Sonstiges Game"}
|
||||
- {id: 65, cat: Movies/BluRay, desc: "Movie BluRay"}
|
||||
- {id: 66, cat: TV, desc: "TV-Serie BluRay"}
|
||||
- {id: 67, cat: TV/HD, desc: "TV-Serie HD"}
|
||||
- {id: 68, cat: TV/Anime, desc: "Anime Movie HD & BD"}
|
||||
- {id: 69, cat: TV/Anime, desc: "Anime OVA HD & BD"}
|
||||
- {id: 70, cat: TV/Anime, desc: "Anime Serie HD & BD"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
returnto: "/index.php"
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "0"
|
||||
orderby: "added"
|
||||
sort: "desc"
|
||||
|
||||
rows:
|
||||
selector: table.tableinborder > tbody > tr:has(a[href^="details.php"])
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php"]
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^=" /gettorrent/ssl/"]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
|
||||
grabs:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
|
||||
size:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
seeders:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
|
||||
leechers:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +2:00"
|
||||
- name: replace
|
||||
args: ["\xA0", " "]
|
||||
- name: dateparse
|
||||
args: "02.01.2006 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[src="/pic/free.gif"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: audiobooktorrents
|
||||
name: Audiobook Torrents
|
||||
description: "Audiobook Torrents (ABT) is a Private Torrent Tracker for AUDIOBOOKS"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -61,7 +62,8 @@
|
||||
path: /browse.php
|
||||
|
||||
search:
|
||||
path: /browse.php
|
||||
paths:
|
||||
- path: /browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Keywords }}"
|
||||
@@ -133,4 +135,4 @@
|
||||
selector: td[colspan=13]
|
||||
filters:
|
||||
- name: prepend
|
||||
args: "{{ .Result.description }}<br>\n"
|
||||
args: "{{ .Result.description }}<br>\n"
|
||||
3
src/Jackett/Definitions/awesomehd.yml → src/Jackett.Common/Definitions/awesomehd.yml
Executable file → Normal file
@@ -29,7 +29,8 @@
|
||||
path: index.php
|
||||
|
||||
search:
|
||||
path: torrents.php
|
||||
paths:
|
||||
- path: torrents.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
searchstr: "{{ .Query.Keywords }}"
|
||||
286
src/Jackett.Common/Definitions/b2s-share.yml
Normal file
@@ -0,0 +1,286 @@
|
||||
---
|
||||
site: b2s-share
|
||||
name: B2S-Share
|
||||
description: "B2S-Share is a Brazilian Private site for TV / MOVIES / GENERAL"
|
||||
language: pt-br
|
||||
type: private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- http://www.b2s-share.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
#3D
|
||||
- {id: 141, cat: Movies/3D, desc: "3D Ação"}
|
||||
- {id: 142, cat: Movies/3D, desc: "3D Animação"}
|
||||
- {id: 143, cat: Movies/3D, desc: "3D Aventura"}
|
||||
- {id: 144, cat: Movies/3D, desc: "3D Clássico"}
|
||||
- {id: 145, cat: Movies/3D, desc: "3D Comédia"}
|
||||
- {id: 146, cat: Movies/3D, desc: "3D Documentário"}
|
||||
- {id: 147, cat: Movies/3D, desc: "3D Drama"}
|
||||
- {id: 149, cat: Movies/3D, desc: "3D Ficção"}
|
||||
- {id: 150, cat: Movies/3D, desc: "3D Guerra"}
|
||||
- {id: 151, cat: Movies/3D, desc: "3D Infantil"}
|
||||
- {id: 152, cat: Movies/3D, desc: "3D Musical"}
|
||||
- {id: 154, cat: Movies/3D, desc: "3D Outros"}
|
||||
- {id: 155, cat: Movies/3D, desc: "3D Policial"}
|
||||
- {id: 156, cat: Movies/3D, desc: "3D Religioso"}
|
||||
- {id: 157, cat: Movies/3D, desc: "3D Romance"}
|
||||
- {id: 158, cat: Movies/3D, desc: "3D Shows"}
|
||||
- {id: 159, cat: Movies/3D, desc: "3D Suspense"}
|
||||
- {id: 160, cat: Movies/3D, desc: "3D Terror"}
|
||||
- {id: 161, cat: Movies/3D, desc: "3D Thriller"}
|
||||
- {id: 162, cat: Movies/3D, desc: "3D Western"}
|
||||
|
||||
#4K
|
||||
- {id: 173, cat: Movies, desc: "4K Ação"}
|
||||
- {id: 191, cat: Movies, desc: "4K Animação"}
|
||||
- {id: 190, cat: Movies, desc: "4K Aventura"}
|
||||
- {id: 188, cat: Movies, desc: "4K Clássico"}
|
||||
- {id: 175, cat: Movies, desc: "4K Comédia"}
|
||||
- {id: 186, cat: Movies, desc: "4K Documentário"}
|
||||
- {id: 185, cat: Movies, desc: "4K Drama"}
|
||||
- {id: 177, cat: Movies, desc: "4K Ficção"}
|
||||
- {id: 178, cat: Movies, desc: "4K Guerra"}
|
||||
- {id: 179, cat: Movies, desc: "4K Infantil"}
|
||||
- {id: 180, cat: Movies, desc: "4K Musical"}
|
||||
- {id: 184, cat: Movies, desc: "4K Outros"}
|
||||
- {id: 176, cat: Movies, desc: "4K Policial"}
|
||||
- {id: 187, cat: Movies, desc: "4K Religioso"}
|
||||
- {id: 174, cat: Movies, desc: "4K Romance"}
|
||||
- {id: 181, cat: Movies, desc: "4K Shows"}
|
||||
- {id: 182, cat: Movies, desc: "4K Suspense"}
|
||||
- {id: 189, cat: Movies, desc: "4K Terror"}
|
||||
- {id: 183, cat: Movies, desc: "4K Thriller"}
|
||||
|
||||
#ANIME
|
||||
- {id: 11, cat: TV/Anime, desc: "Anime"}
|
||||
|
||||
#PC-APPS
|
||||
- {id: 2, cat: PC, desc: "PC APPS - Linux"}
|
||||
- {id: 3, cat: PC, desc: "PC APPS - Mac"}
|
||||
- {id: 33, cat: PC, desc: "PC APPS - Portateis"}
|
||||
- {id: 1, cat: PC, desc: "PC APPS - Windows"}
|
||||
|
||||
#BD-R
|
||||
- {id: 140, cat: Movies, desc: "BD-R Autorado"}
|
||||
- {id: 119, cat: Movies, desc: "BD-R"}
|
||||
|
||||
#MOBILE
|
||||
- {id: 163, cat: Other, desc: "Mobile App/Jogos-Android"}
|
||||
- {id: 164, cat: Other, desc: "Mobile App/Jogos-iPhone"}
|
||||
- {id: 93, cat: Other, desc: "Mobile App/Jogos-Java"}
|
||||
- {id: 169, cat: Other, desc: "Mobile App/Jogos-Outros"}
|
||||
- {id: 168, cat: Other, desc: "Mobile App/Jogos-Win"}
|
||||
- {id: 92, cat: Other, desc: "Mobile Filmes"}
|
||||
- {id: 118, cat: Other, desc: "Mobile Séries"}
|
||||
- {id: 94, cat: Other, desc: "Mobile Wallpapers"}
|
||||
|
||||
#CARTOON
|
||||
- {id: 172, cat: TV/Other, desc: "Desenho Animado"}
|
||||
|
||||
#OTHER
|
||||
- {id: 4, cat: Other, desc: "Apostilas/Cursos"}
|
||||
- {id: 12, cat: Books, desc: "Diversos"}
|
||||
- {id: 167, cat: Books, desc: "E-book/Livros"}
|
||||
- {id: 7, cat: PC/Games, desc: "Emuladores / Roms"}
|
||||
- {id: 166, cat: Books/Comics, desc: "HQ"}
|
||||
- {id: 165, cat: Books, desc: "Revistas"}
|
||||
|
||||
#DVD-R
|
||||
- {id: 41, cat: Movies/SD, desc: "DVD-R Autorado"}
|
||||
- {id: 32, cat: Movies/SD, desc: "DVD-R"}
|
||||
|
||||
#MOVIES
|
||||
- {id: 14, cat: Movies, desc: "Filmes Ação"}
|
||||
- {id: 99, cat: Movies, desc: "Filmes Animação"}
|
||||
- {id: 15, cat: Movies, desc: "Filmes Aventura"}
|
||||
- {id: 16, cat: Movies, desc: "Filmes Clássico"}
|
||||
- {id: 17, cat: Movies, desc: "Filmes Comédia"}
|
||||
- {id: 31, cat: Movies, desc: "Filmes Documentário"}
|
||||
- {id: 18, cat: Movies, desc: "Filmes Drama"}
|
||||
- {id: 19, cat: Movies, desc: "Filmes Ficção"}
|
||||
- {id: 20, cat: Movies, desc: "Filmes Guerra"}
|
||||
- {id: 126, cat: Movies, desc: "Filmes Infantil"}
|
||||
- {id: 96, cat: Movies, desc: "Filmes Musical"}
|
||||
- {id: 24, cat: Movies, desc: "Filmes Outros"}
|
||||
- {id: 40, cat: Movies, desc: "Filmes Policial"}
|
||||
- {id: 39, cat: Movies, desc: "Filmes Religioso"}
|
||||
- {id: 30, cat: Movies, desc: "Filmes Romance"}
|
||||
- {id: 22, cat: Movies, desc: "Filmes Suspense"}
|
||||
- {id: 23, cat: Movies, desc: "Filmes Terror"}
|
||||
- {id: 130, cat: Movies, desc: "Filmes Thriller"}
|
||||
- {id: 131, cat: Movies, desc: "Filmes Western"}
|
||||
- {id: 34, cat: Movies, desc: "Filmes x264"}
|
||||
|
||||
#HD-1080p
|
||||
- {id: 73, cat: Movies/HD, desc: "Filmes 1080p Ação"}
|
||||
- {id: 87, cat: Movies/HD, desc: "Filmes 1080p Animação"}
|
||||
- {id: 74, cat: Movies/HD, desc: "Filmes 1080p Aventura"}
|
||||
- {id: 75, cat: Movies/HD, desc: "Filmes 1080p Clássico"}
|
||||
- {id: 76, cat: Movies/HD, desc: "Filmes 1080p Comédia"}
|
||||
- {id: 77, cat: Movies/HD, desc: "Filmes 1080p Documentário"}
|
||||
- {id: 78, cat: Movies/HD, desc: "Filmes 1080p Drama"}
|
||||
- {id: 79, cat: Movies/HD, desc: "Filmes 1080p Ficção"}
|
||||
- {id: 80, cat: Movies/HD, desc: "Filmes 1080p Guerra"}
|
||||
- {id: 127, cat: Movies/HD, desc: "Filmes 1080p Infantil"}
|
||||
- {id: 97, cat: Movies/HD, desc: "Filmes 1080p Musical"}
|
||||
- {id: 63, cat: Movies/HD, desc: "Filmes 1080p Outros"}
|
||||
- {id: 82, cat: Movies/HD, desc: "Filmes 1080p Policial"}
|
||||
- {id: 83, cat: Movies/HD, desc: "Filmes 1080p Religioso"}
|
||||
- {id: 84, cat: Movies/HD, desc: "Filmes 1080p Romance"}
|
||||
- {id: 88, cat: Movies/HD, desc: "Filmes 1080p Shows"}
|
||||
- {id: 85, cat: Movies/HD, desc: "Filmes 1080p Suspense"}
|
||||
- {id: 86, cat: Movies/HD, desc: "Filmes 1080p Terror"}
|
||||
- {id: 132, cat: Movies/HD, desc: "Filmes 1080p Thriller"}
|
||||
- {id: 135, cat: Movies/HD, desc: "Filmes 1080p Western"}
|
||||
|
||||
#HD-720p
|
||||
- {id: 58, cat: Movies/HD, desc: "Filmes 720p Ação"}
|
||||
- {id: 89, cat: Movies/HD, desc: "Filmes 720p Animação"}
|
||||
- {id: 60, cat: Movies/HD, desc: "Filmes 720p Aventura"}
|
||||
- {id: 61, cat: Movies/HD, desc: "Filmes 720p Clássico"}
|
||||
- {id: 62, cat: Movies/HD, desc: "Filmes 720p Comédia"}
|
||||
- {id: 72, cat: Movies/HD, desc: "Filmes 720p Documentário"}
|
||||
- {id: 64, cat: Movies/HD, desc: "Filmes 720p Drama"}
|
||||
- {id: 65, cat: Movies/HD, desc: "Filmes 720p Ficção"}
|
||||
- {id: 66, cat: Movies/HD, desc: "Filmes 720p Guerra"}
|
||||
- {id: 129, cat: Movies/HD, desc: "Filmes 720p Infantil"}
|
||||
- {id: 98, cat: Movies/HD, desc: "Filmes 720p Musical"}
|
||||
- {id: 59, cat: Movies/HD, desc: "Filmes 720p Outros"}
|
||||
- {id: 70, cat: Movies/HD, desc: "Filmes 720p Policial"}
|
||||
- {id: 57, cat: Movies/HD, desc: "Filmes 720p Religioso"}
|
||||
- {id: 71, cat: Movies/HD, desc: "Filmes 720p Romance"}
|
||||
- {id: 90, cat: Movies/HD, desc: "Filmes 720p Shows"}
|
||||
- {id: 68, cat: Movies/HD, desc: "Filmes 720p Suspense"}
|
||||
- {id: 69, cat: Movies/HD, desc: "Filmes 720p Terror"}
|
||||
- {id: 134, cat: Movies/HD, desc: "Filmes 720p Thriller"}
|
||||
- {id: 137, cat: Movies/HD, desc: "Filmes 720p Western"}
|
||||
|
||||
#GAMES
|
||||
- {id: 6, cat: Console, desc: "Jogos Console"}
|
||||
- {id: 51, cat: PC/Games, desc: "Jogos Emuladores"}
|
||||
- {id: 44, cat: Console, desc: "Jogos Gamecube"}
|
||||
- {id: 43, cat: Console/NDS, desc: "Jogos Nintendo DS"}
|
||||
- {id: 52, cat: Console, desc: "Jogos Outros"}
|
||||
- {id: 5, cat: PC/Games, desc: "Jogos PC"}
|
||||
- {id: 47, cat: Console, desc: "Jogos PS2"}
|
||||
- {id: 48, cat: Console, desc: "Jogos PS3"}
|
||||
- {id: 170, cat: Console, desc: "Jogos PS4"}
|
||||
- {id: 46, cat: Console, desc: "Jogos PSP"}
|
||||
- {id: 45, cat: Console/Wii, desc: "Jogos Wii"}
|
||||
- {id: 49, cat: Console/Xbox, desc: "Jogos XBOX"}
|
||||
- {id: 50, cat: Console/Xbox 360, desc: "Jogos XBOX360"}
|
||||
- {id: 171, cat: Console, desc: "Jogos XBOXONE"}
|
||||
|
||||
#MUSIC
|
||||
- {id: 29, cat: Audio, desc: "Musica Discografia"}
|
||||
- {id: 28, cat: Audio, desc: "Musica Gospel"}
|
||||
- {id: 139, cat: Audio, desc: "Musica Infantil"}
|
||||
- {id: 27, cat: Audio, desc: "Musica Internacionais"}
|
||||
- {id: 26, cat: Audio, desc: "Musica Nacionais"}
|
||||
- {id: 91, cat: Audio, desc: "Musica Outros"}
|
||||
|
||||
#TV-SERIES
|
||||
- {id: 35, cat: TV/HD, desc: "Séries HD"}
|
||||
- {id: 8, cat: TV, desc: "Séries"}
|
||||
|
||||
#SHOWS
|
||||
- {id: 13, cat: Audio/Video, desc: "Show"}
|
||||
- {id: 56, cat: Audio/Video, desc: "Video Clipes"}
|
||||
|
||||
#TV
|
||||
- {id: 53, cat: TV, desc: "Entretenimento"}
|
||||
- {id: 54, cat: TV/Sport, desc: "Esportes"}
|
||||
- {id: 138, cat: TV, desc: "Infantil"}
|
||||
- {id: 55, cat: TV, desc: "Jornalismo"}
|
||||
|
||||
#XXX
|
||||
- {id: 36, cat: XXX/Other, desc: "Anime Hentai"}
|
||||
- {id: 10, cat: XXX, desc: "Filmes Adultos"}
|
||||
- {id: 37, cat: XXX/Other, desc: "XXX Fotos"}
|
||||
- {id: 95, cat: XXX/Other, desc: "XXX Revistas"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: account-login.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
test:
|
||||
path: torrents.php
|
||||
selector: div:has(a[href*="account-logout.php"])
|
||||
search:
|
||||
paths:
|
||||
- path: torrents-search.php
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["[Ss][0-9]{2}[Ee][0-9]{2,3}", ""] # remove season and episode from search
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
inputs:
|
||||
search: "{{ .Keywords }}"
|
||||
rows:
|
||||
selector: table[class^="ttable_headinner"] > tbody > tr:has(a[href^="torrents-details.php?id="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
details:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
is_anime:
|
||||
optional: true
|
||||
selector: a[href^="torrents.php?cat=11"]
|
||||
attribute: href
|
||||
title_anime:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["(Ep[\\.]?[ ]?)|([S]\\d\\d[Ee])", "E"]
|
||||
title_normal:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["^(.*)[ ]([Ss][0-9]{2}[Ee][0-9]{2,3}).*(?:(?:\\((.*?)\\)))(.*$)", "$3 $2 $4"] # Convert series title from "Translated Name SXXEXX (Original Name) [Other stuffs]" to "Original Name SXXEXX [Other stuffs]"
|
||||
- name: re_replace
|
||||
args: ["^(.*)[ ].*(?:(?:\\((.*?)\\)))(.*$)", "$2 $3"] # Convert movies title from "Translated Name (Original Name) [Other stuffs]" to "Original Name [Other stuffs]"
|
||||
title:
|
||||
text: "{{if .Result.is_anime }}{{ .Result.title_anime }}{{else}}{{ .Result.title_normal }}{{end}}"
|
||||
download:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
date:
|
||||
selector: td:nth-child(2) > span
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["(", ""]
|
||||
- name: replace
|
||||
args: [")", ""]
|
||||
size:
|
||||
selector: td:nth-child(3)
|
||||
grabs:
|
||||
selector: td:nth-child(4) > font > b
|
||||
seeders:
|
||||
selector: td:nth-child(5) > b > font
|
||||
leechers:
|
||||
selector: td:nth-child(6) > font > b
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"img[alt=\"[free]\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"img[alt=\"[+UP x2]\"]": "2"
|
||||
"*": "1"
|
||||