diff --git a/Cargo.lock b/Cargo.lock index a3ff4d5..8620123 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bumpalo" -version = "3.12.2" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" @@ -41,6 +47,12 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.0" @@ -63,13 +75,13 @@ dependencies = [ ] [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "combine" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ - "termcolor", - "unicode-width", + "bytes", + "memchr", ] [[package]] @@ -77,64 +89,33 @@ name = "configparser" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5458d9d1a587efaf5091602c59d299696a3877a439c8f6d461a2d3cce11df87a" - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "indexmap", ] [[package]] -name = "cxx" -version = "1.0.94" +name = "core-foundation" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", + "core-foundation-sys", + "libc", ] [[package]] -name = "cxxbridge-flags" -version = "1.0.94" +name = "core-foundation-sys" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] -name = "cxxbridge-macro" -version = "1.0.94" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", ] [[package]] @@ -158,6 +139,7 @@ dependencies = [ "discord-rich-presence", "serde", "ureq", + "webbrowser", ] [[package]] @@ -190,6 +172,21 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "iana-time-zone" version = "0.1.56" @@ -206,12 +203,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -224,17 +220,49 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "js-sys" -version = "0.3.62" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -246,23 +274,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] -name = "link-cplusplus" -version = "1.0.8" +name = "log" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cc", + "cfg-if", ] [[package]] -name = "log" -version = "0.4.17" +name = "malloc_buf" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" dependencies = [ - "cfg-if", + "libc", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -272,6 +306,12 @@ dependencies = [ "adler", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "num-integer" version = "0.1.45" @@ -291,6 +331,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -305,9 +354,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ "unicode-ident", ] @@ -321,6 +370,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "ring" version = "0.16.20" @@ -355,10 +410,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] -name = "scratch" -version = "1.0.5" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] name = "sct" @@ -409,9 +467,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -419,12 +477,23 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.2.0" +name = "thiserror" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ - "winapi-util", + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -474,12 +543,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "untrusted" version = "0.7.1" @@ -524,6 +587,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -538,9 +611,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -548,9 +621,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", @@ -563,9 +636,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -573,9 +646,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", @@ -586,20 +659,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "web-sys" -version = "0.3.62" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + [[package]] name = "webpki" version = "0.22.0" @@ -656,7 +746,40 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -665,51 +788,93 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 985d252..71aa7fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,10 @@ exclude = [ [dependencies] discord-rich-presence = "0.2.0" ureq = { version = "2.4.0", features = ["json"] } -configparser = "3.0.0" +configparser = { version = "3.0.2", features = ["indexmap"] } serde = { version = "1.0.163", features = ["derive"] } chrono = "0.4.19" +webbrowser = "0.8.7" [profile.release] -strip = "debuginfo" \ No newline at end of file +strip = "debuginfo" diff --git a/credentials.ini b/credentials.ini index 9a4ec7e..a62f39e 100644 --- a/credentials.ini +++ b/credentials.ini @@ -1,6 +1,11 @@ [Trakt API] traktClientID = 543dhkjlasfkjdsgh0928354237489230954sdkfjsdlfjhsdh4327 traktUser = exampleuser +enabledOAuth = false +traktClientSecret = +OAuthAccessToken = +OAuthRefreshToken = +OAuthRefreshTokenExpiresAt = [Discord] discordClientID = 457098328950423 diff --git a/src/main.rs b/src/main.rs index ffc99c6..2f21b99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,9 +6,14 @@ use discrakt::{ use std::{thread::sleep, time::Duration}; fn main() -> Result<(), Box> { - let cfg = load_config(); + let mut cfg = load_config(); + cfg.check_oauth(); let mut discord = Discord::new(cfg.discord_token); - let mut trakt = Trakt::new(cfg.trakt_client_id, cfg.trakt_username); + let mut trakt = Trakt::new( + cfg.trakt_client_id, + cfg.trakt_username, + cfg.trakt_access_token, + ); let tmdb_token = cfg.tmdb_token; Discord::connect(&mut discord); diff --git a/src/trakt.rs b/src/trakt.rs index be6d14a..087d463 100644 --- a/src/trakt.rs +++ b/src/trakt.rs @@ -60,10 +60,11 @@ pub struct Trakt { agent: Agent, client_id: String, username: String, + oauth_access_token: Option, } impl Trakt { - pub fn new(client_id: String, username: String) -> Trakt { + pub fn new(client_id: String, username: String, oauth_access_token: Option) -> Trakt { Trakt { rating_cache: HashMap::default(), image_cache: HashMap::default(), @@ -73,20 +74,30 @@ impl Trakt { .build(), client_id, username, + oauth_access_token, } } pub fn get_watching(&self) -> Option { let endpoint = format!("https://api.trakt.tv/users/{}/watching", self.username); - let response = match self + let request = self .agent .get(&endpoint) .set("Content-Type", "application/json") .set("trakt-api-version", "2") - .set("trakt-api-key", &self.client_id) - .call() + .set("trakt-api-key", &self.client_id); + // add Authorization header if there is a (valid) OAuth access token + let request = if self.oauth_access_token.is_some() + && !self.oauth_access_token.as_ref().unwrap().is_empty() { + let authorization = format!("Bearer {}", self.oauth_access_token.as_ref().unwrap()); + request.set("Authorization", &authorization) + } else { + request + }; + + let response = match request.call() { Ok(response) => response, Err(_) => return None, }; diff --git a/src/utils.rs b/src/utils.rs index dea1695..d101fee 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,18 @@ use chrono::{DateTime, FixedOffset, SecondsFormat, Utc}; use configparser::ini::Ini; +use serde::Deserialize; +use std::{io, time::Duration}; +use ureq::AgentBuilder; + +#[derive(Deserialize)] +pub struct TraktAccessToken { + pub access_token: String, + pub token_type: String, + pub expires_in: u64, + pub refresh_token: String, + pub scope: String, + pub created_at: u64, +} use crate::trakt::TraktWatchingResponse; @@ -7,6 +20,11 @@ pub struct Env { pub discord_token: String, pub trakt_username: String, pub trakt_client_id: String, + pub trakt_oauth_enabled: bool, + pub trakt_client_secret: Option, + pub trakt_access_token: Option, + pub trakt_refresh_token: Option, + pub trakt_refresh_token_expires_at: Option, pub tmdb_token: String, } @@ -16,6 +34,113 @@ pub struct WatchStats { pub end_date: DateTime, } +impl Env { + pub fn check_oauth(&mut self) { + if self.trakt_oauth_enabled { + if self.trakt_access_token.is_none() + || self.trakt_access_token.as_ref().unwrap().is_empty() + { + self.authorize_app(); + } else if let Some(expires_at) = self.trakt_refresh_token_expires_at { + if Utc::now().timestamp() as u64 > expires_at { + self.exchange_refresh_token_for_access_token(); + } + } + } + } + + fn authorize_app(&mut self) { + if webbrowser::open( + &format!("https://trakt.tv/oauth/authorize?response_type=code&client_id={}&redirect_uri=urn:ietf:wg:oauth:2.0:oob", self.trakt_client_id) + ).is_err() { + eprintln!("Failed to open webbrowser to authorize discrakt"); + return; + }; + self.exchange_code_for_access_token(); + } + + fn exchange_code_for_access_token(&mut self) { + // read OAuth code from command line + print!("Enter code from website: "); + io::Write::flush(&mut io::stdout()).expect("Failed to flush stdout"); + let mut code = String::new(); + io::stdin() + .read_line(&mut code) + .expect("Failed to read line"); + let code = code.trim(); + + let agent = AgentBuilder::new() + .timeout_read(Duration::from_secs(5)) + .timeout_write(Duration::from_secs(5)) + .build(); + let response = match agent + .post("https://api.trakt.tv/oauth/token") + .set("Content-Type", "application/json") + .send_json(ureq::json!({ + "code": code, + "client_id": self.trakt_client_id, + "client_secret": self.trakt_client_secret.as_ref().expect("client_secret not found"), + "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", + "grant_type": "authorization_code", + })) + { + Ok(response) => response, + Err(_) => return, + }; + + let json_response: Option = match response.into_json() { + Ok(body) => body, + Err(_) => None, + }; + + if let Some(json_response) = json_response { + self.trakt_access_token = Some(json_response.access_token.clone()); + self.trakt_refresh_token = Some(json_response.refresh_token.clone()); + self.trakt_refresh_token_expires_at = + Some(json_response.created_at + 60 * 60 * 24 * 30 * 3); // secs * mins * hours * days * months => 3 months + set_oauth_tokens(&json_response); + } else { + eprintln!("Failed to exchange code for access token"); + } + } + + fn exchange_refresh_token_for_access_token(&mut self) { + let agent = AgentBuilder::new() + .timeout_read(Duration::from_secs(5)) + .timeout_write(Duration::from_secs(5)) + .build(); + let response = match agent + .post("https://api.trakt.tv/oauth/token") + .set("Content-Type", "application/json") + .send_json(ureq::json!({ + "code": "Get the code from the webbrowser", + "client_id": self.trakt_client_id, + "client_secret": self.trakt_client_secret.as_ref().expect("client_secret not found"), + "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", + "grant_type": "refresh_token", + })) + { + Ok(response) => response, + Err(_) => return, + }; + + let json_response: Option = match response.into_json() { + Ok(body) => body, + Err(_) => None, + }; + + if let Some(json_response) = json_response { + self.trakt_access_token = Some(json_response.access_token.clone()); + self.trakt_refresh_token = Some(json_response.refresh_token.clone()); + self.trakt_refresh_token_expires_at = + Some(json_response.created_at + 60 * 60 * 24 * 30 * 3); // secs * mins * hours * days * months => 3 months + set_oauth_tokens(&json_response); + } else { + eprintln!("Failed to exchange refresh token for access token"); + } + } +} + pub fn load_config() -> Env { let mut config = Ini::new(); config.load("credentials.ini").unwrap(); @@ -30,12 +155,47 @@ pub fn load_config() -> Env { trakt_client_id: config .get("Trakt API", "traktClientID") .expect("traktClientID not found"), + trakt_oauth_enabled: config + .getbool("Trakt API", "enabledOAuth") + .expect("enableOAuth not found") + .unwrap_or(false), + trakt_client_secret: config.get("Trakt API", "traktClientSecret"), + trakt_access_token: config.get("Trakt API", "OAuthAccessToken"), + trakt_refresh_token: config.get("Trakt API", "OAuthRefreshToken"), + trakt_refresh_token_expires_at: config + .getuint("Trakt API", "OAuthRefreshTokenExpiresAt") + .unwrap_or_default(), tmdb_token: config .get("TMDB API", "tmdbToken") .expect("tmdbToken not found"), } } +fn set_oauth_tokens(json_response: &TraktAccessToken) { + let mut config = Ini::new_cs(); + config + .load("credentials.ini") + .expect("Failed to load credentials.ini"); + config.setstr( + "Trakt API", + "OAuthAccessToken", + Some(json_response.access_token.as_str()), + ); + config.setstr( + "Trakt API", + "OAuthRefreshToken", + Some(json_response.refresh_token.as_str()), + ); + config.set( + "Trakt API", + "OAuthRefreshTokenExpiresAt", + Some(json_response.created_at.to_string()), + ); + config + .write("credentials.ini") + .expect("Failed to write credentials.ini"); +} + pub fn log(message: &str) { println!( "{} : {message}",