mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-12-06 06:36:25 +00:00
Compare commits
1743 Commits
v1.0.0
...
feat/anime
| Author | SHA1 | Date | |
|---|---|---|---|
| 650f4866d0 | |||
| ad35c95e25 | |||
| 7ffc392492 | |||
|
|
71b5a04027 | ||
|
|
053b8dbef0 | ||
|
|
622f49c5ad | ||
|
|
e47df32173 | ||
| 9ed662c8c8 | |||
|
|
3088a8fc88 | ||
| 25fc182bad | |||
| d744235141 | |||
|
|
b28df77237 | ||
| 6e9a4a7ec4 | |||
|
|
78c2916286 | ||
|
|
9ec74446a1 | ||
| cdfe1d0c94 | |||
| af66b31e35 | |||
| c203fa8eea | |||
| 45fb4f0db2 | |||
| 4c4421f243 | |||
| a87c6d1a09 | |||
| cb96e87ad7 | |||
| 13309bce20 | |||
| 26a3c2c984 | |||
| 6458f419aa | |||
| c08134bf08 | |||
| 2ee71f8d8f | |||
| ef0260f3f5 | |||
| 21e1fa6376 | |||
| e015882834 | |||
| a9a74ddc14 | |||
| defa902184 | |||
| cc3f6f611e | |||
| d178b78e86 | |||
| cdf482ac4a | |||
| 97e3257aee | |||
| db2204258a | |||
|
|
c35e41aebe | ||
| 654cc3b2a0 | |||
| 361fedd9bb | |||
| 4cc36f4690 | |||
| 95086777af | |||
|
|
cc50444384 | ||
| cad81b70b6 | |||
| 6336074544 | |||
| 75a05296f7 | |||
| 12742162ff | |||
| 61e25f8b95 | |||
| ad80fd3bde | |||
| 261c97f97b | |||
| f005f2022c | |||
| 27b0c753bb | |||
|
|
aec23ae749 | ||
| a37ace7d46 | |||
| 5393f1bf97 | |||
| 7b45b205a5 | |||
| bb14d9944a | |||
| f3fb96504a | |||
| 2a1b805a7f | |||
| 393c58b10a | |||
| 2756397898 | |||
| 444de0af26 | |||
| 9f8b2da76e | |||
| 9061b2e8d9 | |||
| c8cc2fc057 | |||
| ed200907a5 | |||
| 5049ad25b5 | |||
| f0b5b55b13 | |||
| 9048927c89 | |||
| da13535e3e | |||
| 150a9dbd53 | |||
| 0124275d8c | |||
| e0935d7faa | |||
| a937e445de | |||
| 513f10c629 | |||
| b453fb180c | |||
| 7adb1cd504 | |||
| ec60dccb7b | |||
| a711f74063 | |||
|
|
55ba86bd5f | ||
|
|
76fc857457 | ||
|
|
4ac66686a0 | ||
| 26394ecb7f | |||
| b2b09c58db | |||
| 299b3e2328 | |||
| c249816808 | |||
| 3ce8a49282 | |||
| e02912119b | |||
| 47f364840b | |||
| 13e7d87134 | |||
| d0a7d5766e | |||
| 6af791ca72 | |||
| 95a2766aee | |||
| fee6faceaa | |||
| 7577d757f8 | |||
| 8c6b99e31b | |||
| 497ba48f1b | |||
| d08a86a724 | |||
| 5f61f4d3a3 | |||
| a29cfc0123 | |||
| c96a544021 | |||
| 3d2e837022 | |||
| 740703a845 | |||
| dde38381e2 | |||
| a6b6067b0b | |||
| 1c483fa14f | |||
| 465562b563 | |||
| a44b66caa9 | |||
|
|
b6e0b5b328 | ||
| 9919f69720 | |||
| a346800724 | |||
| b228fbb35c | |||
| f8c6602604 | |||
| ca7dd81452 | |||
| 710e3cf10b | |||
| c8402780f3 | |||
| f1e1fe3e34 | |||
|
|
4488ee3a6f | ||
|
|
83ede9328e | ||
|
|
06525a78e0 | ||
|
|
fbd47b8ea6 | ||
|
|
b93cf56607 | ||
|
|
366d71d869 | ||
| f4895f8e59 | |||
|
|
67c4bdc09c | ||
|
|
2db7ca822a | ||
| b532bb31d1 | |||
|
|
324afc8022 | ||
|
|
8a2343e76b | ||
|
|
9222b2e2d3 | ||
|
|
be0bd81107 | ||
| a978e99e8a | |||
| afa57df5c2 | |||
| 2472df4a3a | |||
| fa7229f6f9 | |||
| fb0af0855c | |||
| 833775fede | |||
| e1169d1d26 | |||
| a0a5788683 | |||
| 516af3ee9b | |||
| 8c1bb7cc1e | |||
| fe38cd65b8 | |||
| d5d15eaea6 | |||
| bbe88382e5 | |||
| 83b1c6b398 | |||
| cd46050c94 | |||
| 0b4f40190d | |||
| 7e10a9162c | |||
| 5de584d6e3 | |||
| 764fff7677 | |||
| 69a2821477 | |||
| 55f55db030 | |||
| 7e95370ce0 | |||
| 30e2a5c867 | |||
| 14f2f8cb8c | |||
| 491150c261 | |||
| b0f9be17de | |||
| bd71be580d | |||
| 871aaa032d | |||
| 1572bd26c5 | |||
| 6c880b0909 | |||
| 9a81da0154 | |||
| 629acf4855 | |||
| 5364359788 | |||
|
|
c7521b4af0 | ||
| 9de087a92e | |||
| 6b37ee8100 | |||
| 8e9aff9a25 | |||
| 2303baf15b | |||
| 4130601856 | |||
| b07f164ace | |||
| 3725ed89db | |||
| bc75576e4b | |||
| 9d00aa6d2f | |||
| 13ade4dc44 | |||
| f7c4e49426 | |||
| efd2ac179d | |||
| 3521d577c1 | |||
| 21414d6c2f | |||
| c1ed16b871 | |||
| d63ad87971 | |||
| 6925c6b225 | |||
| 57842ea31c | |||
| 6076e3af87 | |||
| e9c5e5e627 | |||
| 997cc054d4 | |||
|
|
b45069137c | ||
| 4602f4ee65 | |||
| 36f6cd5631 | |||
| c52d818a1d | |||
| c07d5ca5b9 | |||
| 8303df35cc | |||
| 0d5957c3f8 | |||
| 21841604a3 | |||
| cd18ec1747 | |||
| d617d8c32a | |||
| 4c31e8cd70 | |||
| e0923807c6 | |||
| f67a7b4fd4 | |||
| 8ee280de87 | |||
| 316e5dd208 | |||
| e1f1106c8d | |||
| 5f20d9102f | |||
| 3665070b97 | |||
|
|
af79670292 | ||
| a8eb1c52b6 | |||
| 7824a78e85 | |||
| a8b25b9ef6 | |||
| 111e8f7943 | |||
| 0489ae6917 | |||
| cc1cff8033 | |||
| 8ada5c9da2 | |||
| 2e122d9cd7 | |||
| 7daa10ef8d | |||
| 8308bce42d | |||
| 9e089b21ed | |||
| fccc5b6ad9 | |||
| d9d7fd5000 | |||
|
|
08bb1ccbf2 | ||
|
|
f431e7930d | ||
| 8b1524c155 | |||
| 9445b71c5c | |||
| cd7bde944e | |||
| 67cbf674b1 | |||
| 283ba04f5e | |||
| cbe4fbf082 | |||
| 53d483f34d | |||
| 04d4b7ab1d | |||
| b30c83751d | |||
| 4ffc112196 | |||
| edf482de03 | |||
| ba7931e205 | |||
| 6eb21b7ca3 | |||
| 5a4575a93d | |||
| 2eecb5174c | |||
| da0f415ecf | |||
| 59e1832c3e | |||
| f871f4e1bf | |||
| a2a58422a0 | |||
| 580109666f | |||
| 2641a36352 | |||
| 733817216f | |||
| 9ee35534bd | |||
| 58f0f3d74b | |||
| 7c3f4d3c20 | |||
| e898f49402 | |||
| 9b486c0c55 | |||
| 92ec734276 | |||
| d51ffa6848 | |||
| 7d354249d4 | |||
| 7c79c37d8c | |||
| b2c30ee059 | |||
| 12aa73376a | |||
| 525da02fce | |||
| 2273e99074 | |||
| 526ac1b8ab | |||
| 5c6bcee763 | |||
| 274d2987d2 | |||
| 4688868f04 | |||
| 5a6da7441f | |||
|
|
3e5007de75 | ||
| 41130cab1c | |||
| 996209d205 | |||
| 9e38c3f333 | |||
| aca7c815a0 | |||
| d5d0a6bda9 | |||
| 1e73998aa9 | |||
| c4b42c9961 | |||
| 00cd94d624 | |||
| e846a1cc18 | |||
| d36a20ce5e | |||
| 8b256e4c60 | |||
| e9b29dd814 | |||
| b904f25d33 | |||
| d872e66f7d | |||
| ac3b593b8b | |||
| bfbc66cdc0 | |||
| c576babde8 | |||
| f15b92aae1 | |||
| fb4424fb6b | |||
| d46e6eda64 | |||
| e1c04bef51 | |||
| 5b4dc1e9b0 | |||
| 1d553daeaf | |||
| 69e8340c95 | |||
| dc5fd8f5a3 | |||
| 8a816b587f | |||
| d34d87957e | |||
|
|
76a1b5c38f | ||
| c2a519923a | |||
|
|
c46385d467 | ||
|
|
2e568abc45 | ||
| 9163cef0f0 | |||
| ec88da2434 | |||
| 9255695af2 | |||
| 0c66363920 | |||
| c4cd4ead44 | |||
| e39337f8f1 | |||
| 7140d308fd | |||
| 5a9b846f7c | |||
| c1ecdad916 | |||
| 8392c6ad47 | |||
| dcda8c9072 | |||
|
|
097cbe6cf5 | ||
|
|
f08ea4b8dd | ||
|
|
f1899aef55 | ||
|
|
0e685de325 | ||
|
|
98c02176a4 | ||
| 1252016fff | |||
| 9c1908ecea | |||
| cff4553108 | |||
| 81557741b2 | |||
| 18b56724bb | |||
| 0f3f33a9e6 | |||
| d0901c7267 | |||
| a085650a2e | |||
| e4403cc17c | |||
| 8d8e984669 | |||
| 27dfb71838 | |||
| 3bb0565f18 | |||
| 8da6085df0 | |||
| 52380bcb29 | |||
| a18fa7ebad | |||
| e284f771df | |||
| 00c41fb704 | |||
|
|
9b3d8a390d | ||
| 686239ac7d | |||
| 762b8047da | |||
|
|
57246cade1 | ||
|
|
3fa0cd04d1 | ||
|
|
c078d7a82e | ||
|
|
0ce7e74614 | ||
|
|
1bfaf7b142 | ||
|
|
2c71809f0d | ||
| 0e906b5d86 | |||
|
|
152916b543 | ||
| 1e82c1d0f3 | |||
|
|
8adca4f4ca | ||
| a2624f85dd | |||
|
|
04850b2982 | ||
|
|
9d83f02c8b | ||
|
|
9ffc1d6d92 | ||
|
|
ed3c58da12 | ||
| e2ff1d07a0 | |||
|
|
bd723a07cd | ||
| e07523f612 | |||
| 939aaed64d | |||
| 55ddbf72d9 | |||
|
|
ecbccc5fb6 | ||
|
|
32a7f2cb1f | ||
| 8aa4d3f7d0 | |||
| dde3af188d | |||
| e04093df48 | |||
| 37ed58b201 | |||
| 1217ee3e54 | |||
| a8c7ecc865 | |||
| 0f42775282 | |||
| 7c9bb11d14 | |||
| 3abdb0a4c4 | |||
| 17a4e418a2 | |||
| 25be3d77a5 | |||
| 8758c7447e | |||
| 8a639a3aee | |||
| 7ee28f4557 | |||
| 1b4d1ef45e | |||
| de2308f319 | |||
| f64cf161ab | |||
| 436cbee752 | |||
| 9bd1e50de3 | |||
| 13ad35a9ac | |||
| 266caa3f02 | |||
| ea98598399 | |||
| 83110374f8 | |||
| 1f16271354 | |||
| 0c387fc19a | |||
| 7d423bb049 | |||
| c3bebdec01 | |||
| d26934b602 | |||
| e16fdc1036 | |||
| 0008aa95c2 | |||
| a8d29b5b26 | |||
| 61a8b07f4b | |||
| d3ec0cab9b | |||
| 5e054e12f7 | |||
| e8896b7787 | |||
| 0cf7b1369b | |||
| 7428147100 | |||
| 88f3f7a9ae | |||
| 2ff507f641 | |||
| 3de751c880 | |||
| 9a9e43269d | |||
| 12276ed034 | |||
| 22b68f4dc7 | |||
| 80e928ee43 | |||
| bb3e57ff2a | |||
| 78247acba7 | |||
| e4f00d34bc | |||
| 81d4a13735 | |||
| 5d430f8ee8 | |||
| aba6c873df | |||
| d140a6e392 | |||
| f7603db588 | |||
| 87754ae928 | |||
| ecbf1f5db5 | |||
| 8ddf22d661 | |||
| 13df17544c | |||
| 39ce601344 | |||
| db6670f699 | |||
| bd7991942a | |||
| da594d6df1 | |||
| f6bb77a6a5 | |||
| ea979d9663 | |||
| 646df0f393 | |||
| d24d18ea8e | |||
| 9740a5d0d4 | |||
| 034a554bf4 | |||
| fb1c006cd9 | |||
| 928bfe7876 | |||
| 6485c733bb | |||
| b44bdb8a75 | |||
| 71f56699c8 | |||
| 66fa07f341 | |||
| 2c8467090e | |||
| a18d5d0532 | |||
| c5b0a76982 | |||
| f352085f62 | |||
| 5374666ac9 | |||
| 411bbef65c | |||
| f798f2c025 | |||
| 44c88a885f | |||
| b08bfeceb6 | |||
| be8bf53cc6 | |||
| fee6032e78 | |||
| 64eb70d292 | |||
| dc7f7feab1 | |||
| 8afbc63b85 | |||
| c942794b89 | |||
| e58b5a063f | |||
| dee3af3016 | |||
| 9f42c29714 | |||
| 95bc5b9f7c | |||
| 1cd3704bc3 | |||
| 8bbccd42d5 | |||
| f89ce7a965 | |||
| 7905edaf24 | |||
| 851baa030c | |||
| 567d2ac686 | |||
| 71bf334ac4 | |||
| 2df874e786 | |||
| fe9aa865f9 | |||
| 1e8316e16d | |||
| 380c80bbaf | |||
| a8fe8e2e13 | |||
| 22d0d064f7 | |||
| a5c7aef3b8 | |||
| e1f889f862 | |||
| c6f12ab2a8 | |||
| 31d8dcd6a8 | |||
| 1f3a985d3a | |||
| 6937a982d4 | |||
| 44bb88910f | |||
| 115b9fa4b3 | |||
| b6f9c050e1 | |||
| cbb05ac977 | |||
| f1d72cb480 | |||
| 3a5d6ed2cd | |||
| c15dcb02ec | |||
| 0d91001376 | |||
| 6143125f7a | |||
| ee0f703120 | |||
| 34393bf050 | |||
| 5a461bca7d | |||
| 5fedce71a0 | |||
| c9663ff14f | |||
| 18e301f26a | |||
| 35e37bbe76 | |||
| 5997921eb9 | |||
| e7bedd6a29 | |||
| 7194dcb2c7 | |||
| d62bdfc637 | |||
| ec6b90b33c | |||
| 0c0037416a | |||
| ad9d1ee430 | |||
| d7e5b8b916 | |||
| 3e44d38a90 | |||
| 9493531eaa | |||
| 64031668c1 | |||
| b6d122e449 | |||
| 19f26c6d91 | |||
| 4108434788 | |||
| 01d7f62c36 | |||
| 5cffeea4fd | |||
| e0fb29bd80 | |||
| ad9a59f894 | |||
| ddad768cd8 | |||
| 8ee4446b30 | |||
| 5f936d36b1 | |||
| 08f3e9c06b | |||
| 25b7903c37 | |||
| c6dd7203bb | |||
| 08c7ca99b6 | |||
| 8f7320c298 | |||
| 92bfbf662b | |||
| 44e7323720 | |||
| 78a3ae8aeb | |||
| 041abb732d | |||
| 9ee07794a8 | |||
| 7adfef9f36 | |||
| a3ec224cf0 | |||
| 6d4a6ee52a | |||
| 0add402434 | |||
| 6933aecfa4 | |||
| 93decb02af | |||
| c0acf1c1a0 | |||
| a6c3ab33b1 | |||
| 079a2cdbe3 | |||
| d9022fde9f | |||
| 830a518b86 | |||
| fef04409af | |||
| 4bc54d350b | |||
| e3cc80d32a | |||
| 411e05e998 | |||
| c319f6117a | |||
| a7fd96800a | |||
| a09e229711 | |||
| 7abb66b86f | |||
| f1707db5fb | |||
| 35e1cc7253 | |||
| e8b4a26eda | |||
| 93f93f0186 | |||
| 7c5de3c131 | |||
| a2a3134523 | |||
| 3821950e49 | |||
| d52cc045e0 | |||
| 158058b720 | |||
| df6f9ea71d | |||
| f4464578c0 | |||
| c48ee975c6 | |||
| e60e2306b7 | |||
| af422e62e1 | |||
| 952beccafc | |||
| 06171ae638 | |||
| b3a341847e | |||
| 0d325f2c73 | |||
| 577f3f768d | |||
| 15d479f1eb | |||
| 2b93076146 | |||
| 68c83d8a5d | |||
| 239ad9a4dc | |||
| 5f8d0d1b99 | |||
| 5827a18866 | |||
| 633db89031 | |||
| 1335ae13e8 | |||
| 115d52977d | |||
| 3bb36f5e78 | |||
| 98e9ba0fa7 | |||
| 35a69edfa2 | |||
| 7df1a295f3 | |||
| 85fbd37434 | |||
| 07f0862219 | |||
| bc99408652 | |||
| 461dad2724 | |||
| 6cf76f6535 | |||
| 33a5893da1 | |||
| c14c0a6af5 | |||
| fc7926c2cc | |||
| faf8832572 | |||
| d047e5d48a | |||
| 7baa586738 | |||
| 4c7e335ef4 | |||
| df8a1d3b26 | |||
| 6a1fff227e | |||
| 4810d6cc5c | |||
| 1b73beccf1 | |||
| ff8a791a51 | |||
| 98ead6ac69 | |||
| 8b6741641c | |||
| b035ad07ec | |||
| 25fc5d5835 | |||
| c1cdcddf41 | |||
| 9a5142ced3 | |||
| 586b7900bb | |||
| 0ccb03f004 | |||
| 90676ff8a4 | |||
| 2cacd94f41 | |||
| de3013eebf | |||
| 1c71258984 | |||
| 00831fdb61 | |||
| f5c629cb8a | |||
| 9531795066 | |||
| 71fe10efaf | |||
| b042b4cf60 | |||
| f4980cefde | |||
| 25901cef45 | |||
| d71cd625d0 | |||
| 43350ee1fd | |||
| ae1dee9d51 | |||
| ff2d077a7f | |||
| a383de971a | |||
| 800fa13071 | |||
| 490c68a9f5 | |||
| 1ba03ba909 | |||
| 346750931d | |||
| e612869027 | |||
| 2673ddaf13 | |||
| a3172c7918 | |||
| 8269d80620 | |||
| d1158cab05 | |||
| 09430e56b8 | |||
| 51d3684fcc | |||
| 2968ca3562 | |||
| ee3d8916ed | |||
| acedb77c07 | |||
| 32b1681573 | |||
| 5389e1b783 | |||
| f54a876636 | |||
| 2afed432f7 | |||
| b687d8ea95 | |||
| 2594afc60f | |||
| f5be4a8b99 | |||
| a8b0eeb973 | |||
| ff5ecb474f | |||
| 0a0939fa3d | |||
| 19485a110a | |||
| 79dc4e5f33 | |||
| 7f6721147a | |||
| 20bf6851c0 | |||
| 7adbb5d299 | |||
| 2a3d5de54b | |||
| 18ff6fe71b | |||
| a278e3a565 | |||
| 9f003189e9 | |||
| 050b420f9a | |||
| 2b59a35bf3 | |||
| 7f20a3f36a | |||
| 784289a792 | |||
| d79a73d311 | |||
| 13c0430c93 | |||
| 1e4081a03f | |||
| 275cc70e96 | |||
| 3fccbae676 | |||
| 1fb3088f0e | |||
| 81131edf2d | |||
| 973685ec08 | |||
| 6139deb175 | |||
| 93daed8ec8 | |||
| 08c34a18f2 | |||
| 682dd1093f | |||
| 6806d1f242 | |||
| 394fe4871f | |||
| edc1619962 | |||
| 970d613285 | |||
| 4167704f85 | |||
| 1e0ff4a950 | |||
| 4993d34835 | |||
| 3f9446d46f | |||
| 030a4e0e86 | |||
| d27cf2afc8 | |||
| 5b27eab680 | |||
| 345eabafb2 | |||
| c635fc00c3 | |||
| 2877083ebe | |||
| bb29b7e7f7 | |||
| 7aca2b2d6d | |||
| fe5ba9a84a | |||
| 2067a58c70 | |||
| 8b2c0f732f | |||
| fbd76594ea | |||
| a055dfac5b | |||
| e772a798f7 | |||
| ed9c4ebb68 | |||
| 0439e1f37a | |||
| eb4f88bc60 | |||
| 666477e448 | |||
| 6787400056 | |||
| 2ecda09ee4 | |||
| 0bd497279d | |||
| 1023cf0120 | |||
| f4dc4c315d | |||
| 8b92d0525f | |||
| 530811b699 | |||
| cee7ca2ca0 | |||
| c26a95ed60 | |||
| b43b6d6f75 | |||
| c969908ff5 | |||
| a5638203a6 | |||
| 042cc018cb | |||
| 42d2b8009c | |||
| 5264214eb3 | |||
| bba1fd964d | |||
| 5821a79af9 | |||
| 9dde2475fc | |||
| f90d2d2f04 | |||
| b4ba255afc | |||
| 1abee46f6d | |||
| 0fbfd5731d | |||
| 6265f9bc2c | |||
| 8c910fa532 | |||
| 08d2bb2fd5 | |||
| 885b784f92 | |||
| 7c56ec8285 | |||
| b21fc9db25 | |||
| e06989f2ae | |||
| fab2784e16 | |||
| b323736774 | |||
| a0c1fdbd74 | |||
| 2db6255fae | |||
| 898e7b272e | |||
| f0e6ee5835 | |||
| a01ce5c11c | |||
| c7e6114480 | |||
| e3908da7a9 | |||
| 93608c9549 | |||
| ecc2b70e43 | |||
| 92a3c2945c | |||
| 0be1bf4f15 | |||
| 65b0b22b01 | |||
| 7b4b572802 | |||
| 049474e4bd | |||
| 5c11372543 | |||
| de0eb0b4e9 | |||
| e60a1e5a25 | |||
| 27ae6b512b | |||
| 5f89c6e498 | |||
| b760287ca2 | |||
| e80543e0a2 | |||
| af6436c3d8 | |||
| f65e4bc417 | |||
| 68c28ed358 | |||
| fed94eab1b | |||
| 1dbee1d79f | |||
| 09b146928c | |||
| 983b558510 | |||
| 9fd7ca35f1 | |||
| e886fbcc5f | |||
| 853bfd5f9b | |||
| 6ba0786608 | |||
| b33b428d3b | |||
| 19c5efaed0 | |||
|
|
53285059c5 | ||
| a8e4b74fba | |||
| 2374c2d22e | |||
| 1df8d6589a | |||
| 90498eb117 | |||
| 0cc6274894 | |||
| 085d337fb7 | |||
| a56c06ca33 | |||
| d026f9b418 | |||
| 7803f8f11a | |||
| ec90862262 | |||
| 5efcfb8b61 | |||
| 7193a599b7 | |||
| 6ec387e724 | |||
| c3e8f87562 | |||
| ac846ad351 | |||
| 647a4c3782 | |||
| 1901c908ff | |||
| 797ea13982 | |||
| 6b006e78e5 | |||
| 733d6c8c7b | |||
| d3d59443fa | |||
| a74fbce48e | |||
| cecf7b0f74 | |||
| 8a862c86a5 | |||
| e6a9e2c7da | |||
| b147ee8850 | |||
| 2d8bd207ed | |||
| 3a125263b7 | |||
| a6a26cdf8d | |||
| ec1184d5c9 | |||
| ae518cafe5 | |||
| 3ae167bd16 | |||
| 82c342c7db | |||
| 0e10f29cd2 | |||
| 9c03bac804 | |||
| 6ff41c55fe | |||
| 992b64df8a | |||
| 53ac4a2050 | |||
|
|
d9f4a6ff8d | ||
| 521a68b4c7 | |||
| 8e74413e18 | |||
|
|
5f7ef2a18e | ||
|
|
fa969fa702 | ||
|
|
4aaba75c18 | ||
|
|
b98df08f44 | ||
|
|
4332bfee9b | ||
|
|
4430450431 | ||
|
|
aea6253094 | ||
|
|
37acfa1eec | ||
|
|
0955da489c | ||
|
|
2544f8f333 | ||
|
|
409a613e43 | ||
| 14da738cc8 | |||
| 7a8cc242ae | |||
| c0e6012d70 | |||
| b6df0ba2b1 | |||
| b9c1c766d6 | |||
| 802a872880 | |||
| 415b5b45b9 | |||
| dd9e0b4fc7 | |||
| 6c9a0ea576 | |||
| 995f50cc21 | |||
| 2a491ded00 | |||
| 0517f85d76 | |||
| f1c3844bd3 | |||
| 7309a435c5 | |||
| 2c26072560 | |||
| 425de0b315 | |||
| 30cb171612 | |||
| 43ba1bb449 | |||
| d630f29753 | |||
| 7b13733c9e | |||
| ca6ec6a8ed | |||
| efe07e39c2 | |||
| c738e5bda3 | |||
| 9d7e520168 | |||
| bc61c2e0ff | |||
| f82e720aeb | |||
| afacf61fbc | |||
| 677cab6a57 | |||
| 9df5eb4758 | |||
| 892060334c | |||
| f04d1dcf1e | |||
| 6bb23d7acd | |||
| aef30fecaa | |||
| 5f33172297 | |||
| 23feea4acc | |||
| e9738c2bc1 | |||
| e5954712e2 | |||
| 5d47a28ba6 | |||
| 95b1caeb26 | |||
| 049965cdc9 | |||
| 88406c6ee5 | |||
| 80d1b1af0f | |||
| d3a1c57111 | |||
| 8f824654e0 | |||
| 2d36c6ad6e | |||
| 4193b6b391 | |||
| b312403201 | |||
| a6076eb856 | |||
| 1cb54f44b1 | |||
| 1c2049f918 | |||
| 5c83162a29 | |||
| 45091da5ac | |||
| b0c0ca0e0f | |||
| 46cf60a3b9 | |||
| 68304af99e | |||
| 8805f0f804 | |||
| 570f08755d | |||
| 512aae252c | |||
| e53a90a75d | |||
| b2a0dfa702 | |||
| 439407ea59 | |||
| aa26fd7d54 | |||
| ca35611925 | |||
| c3dae2c704 | |||
| 9fe24cd115 | |||
| b97942b10f | |||
| c528d4dd78 | |||
| ab6e8962e4 | |||
| 6407579dd6 | |||
| da4b877b0d | |||
| 65a254d808 | |||
| 08d9b9d950 | |||
| a374e23821 | |||
| 329b6fc67e | |||
| b4281188d4 | |||
| 1d6d27c0ee | |||
| 721d9937e0 | |||
| c5c527ec10 | |||
| ff154b03f3 | |||
| 8e861faa24 | |||
| fabafcb78b | |||
| e668cdd89c | |||
| 656dc493b8 | |||
| 3d697fbcd0 | |||
| 0b55bd7dbb | |||
| b180429505 | |||
| 472718c595 | |||
| 6e6098b03a | |||
| e1b555781c | |||
| f9d6a816b0 | |||
| d10eb66542 | |||
| 8318a87d5d | |||
| 1b140661ba | |||
| 813d998bfb | |||
| a270edbde4 | |||
| e034d51ae0 | |||
| f110509ea0 | |||
| 5f787bedfe | |||
| b552ca7c51 | |||
| b3ddac60f6 | |||
| 91c88e7f43 | |||
| 5d7fc1ca0c | |||
| d063bd479c | |||
| 47e6c5f978 | |||
| df7b6ae71d | |||
| 80a6ac0c80 | |||
|
|
1dd5c6b9f4 | ||
|
|
fdd3b72e52 | ||
|
|
5664465df5 | ||
|
|
9a55262856 | ||
|
|
df451f56b1 | ||
| 9bee5df036 | |||
| e843b73472 | |||
| 7a99bae541 | |||
| 650ed8056e | |||
| 5ae386bac3 | |||
| 9963bf6179 | |||
| c7061c8c75 | |||
| 2919e07606 | |||
| b406ea6088 | |||
| 7f6da9d79e | |||
| e921095226 | |||
| 2b005d6ea5 | |||
| d4ab42d98f | |||
| a8ab835365 | |||
| c0c39ab4d0 | |||
| 55a246d806 | |||
| 85ba643bcc | |||
| 022cd239d5 | |||
| 4a035327ef | |||
| 78e30cd516 | |||
| 14540081be | |||
| 883f39e4b5 | |||
| 213d5b74b5 | |||
| c0cf11ee79 | |||
| 2e0a0e5eb0 | |||
| 7b035411c0 | |||
| fb04daff9f | |||
| 71d29a303f | |||
| f1cc396bfc | |||
| a483955763 | |||
| 3a2e5f5eb1 | |||
| b51c77dfa7 | |||
| 2603c1b29d | |||
| dd62f8f8ac | |||
| e176664bb4 | |||
| e8bd663ad7 | |||
| c67a11b8b6 | |||
| 10924e2410 | |||
| 8b0faf8a0b | |||
| 0fc23e2c86 | |||
| 0f7a8bd4f3 | |||
| 8640fefc8b | |||
| 21c4a7c577 | |||
| c453422317 | |||
| 60977f3631 | |||
| 57b4463c01 | |||
| fbc8e14125 | |||
| e13f2a7e42 | |||
| d593eb3134 | |||
| 6f81eeef7e | |||
| 991e5004d7 | |||
| 91498f45cd | |||
| 3d53693e68 | |||
| 1c7c4d3ab2 | |||
| 7451452088 | |||
| 7403be6519 | |||
| 7de920154c | |||
| cdccc9bc8b | |||
| dab297413f | |||
| 257ead2415 | |||
| 445f193dbb | |||
| bf68f6b52c | |||
| 7895b535fa | |||
| 545e729f2e | |||
| dfe061e611 | |||
| 21dffc846e | |||
| e3824fc740 | |||
| ac55a56e4a | |||
| 5e95516190 | |||
| 9304c7ad2f | |||
| 0272b82166 | |||
| d5a839b3c6 | |||
| 5d26dd1945 | |||
| a6eb744cc9 | |||
| 6e530786b9 | |||
| ce17229985 | |||
| 869c6fac12 | |||
| 2c465d5249 | |||
| a27b4072be | |||
| 25e4978583 | |||
| 457a3c6709 | |||
|
|
ddb9b2926d | ||
|
|
1e5ef4003a | ||
|
|
f246b6ce32 | ||
|
|
b246f43c70 | ||
|
|
fbf660d532 | ||
|
|
db3f03dc6c | ||
|
|
ba16d7873f | ||
|
|
ee33c71dfe | ||
|
|
1eadcb6521 | ||
|
|
b3a9c9dae8 | ||
|
|
c475691939 | ||
|
|
e6ac7e502c | ||
|
|
30581a4ee1 | ||
| a54311c53f | |||
| 0c9711baea | |||
| bffd71fea5 | |||
| 7e6e56a366 | |||
| baa78b9417 | |||
| b28bf5803d | |||
|
|
ee3eed6c23 | ||
| bf831dba45 | |||
| a43d54ee1d | |||
| f536713f04 | |||
| f438e80d3a | |||
| 38cb4c4f28 | |||
| 1178e8fd6c | |||
| e2414f94f3 | |||
| c87001d91e | |||
| 4cf9609153 | |||
| 83877d8dab | |||
| bab97fba5f | |||
| c289161400 | |||
| 7810f626c6 | |||
| 0294f538eb | |||
| ce07cece06 | |||
| 74013cf113 | |||
| 1eb7198e6f | |||
| c24c8914bf | |||
| e5dde472c9 | |||
| 7ccfab4d8b | |||
| 0bc6512bcc | |||
| e70174cb24 | |||
| fe155898bb | |||
| bd48032a50 | |||
| e124113d41 | |||
| 6974ef0163 | |||
| 015bfe983c | |||
| 275a892ee1 | |||
| 0ac4a1daa0 | |||
| 7bf3ba2443 | |||
| cfa12b0fed | |||
| 2f309440cc | |||
| db3d7f1f2e | |||
| d1febd13fd | |||
| 6fbd00a38f | |||
| 948c98f95b | |||
| 4139362677 | |||
| b9932383c6 | |||
| aa4ea2134a | |||
| 48f77c2f7a | |||
| 6567e78c8c | |||
| 32050bcdcd | |||
| 2aa10c9b1f | |||
| 4f9c06c7bd | |||
| b6bb190e69 | |||
| 4135fc5703 | |||
| c1ba51b903 | |||
| a218271001 | |||
| f4442fad0c | |||
| 87fdc1a444 | |||
| eed764c6e0 | |||
| f9a2185748 | |||
| 4f7c449ea7 | |||
| 7dab3fd094 | |||
| 49d225532c | |||
| b2c67e7df4 | |||
| 07259a7635 | |||
| d63c601812 | |||
| ecd1b55fc6 | |||
| 4c955e4115 | |||
| 14319a5c89 | |||
| 0ac388f3eb | |||
| fbf43fb10f | |||
| e0f41be887 | |||
| bd84989454 | |||
| e0b2e8e937 | |||
| f2ebc5659e | |||
| b72553aa11 | |||
| 0ed35e0354 | |||
| 29d846a944 | |||
| 9609fb150a | |||
| 9a5c4ab087 | |||
| f59f9a7ba0 | |||
| 8a925b35dd | |||
| 3e31c51f65 | |||
| 3c959ff532 | |||
| fa6deb7f82 | |||
| b7f5ede7cd | |||
| b2e0363594 | |||
| 73f4187087 | |||
| 1f63991ca0 | |||
| 8ea8d3ff57 | |||
| 070a94d87d | |||
| 22348e1554 | |||
| 0e2950ab69 | |||
| 2b0f6837a8 | |||
| ee4cc6706e | |||
| 948f8694f2 | |||
| 29314d473f | |||
| 5f177e9338 | |||
| d7dd2bd138 | |||
| ba37786038 | |||
| 179b79c926 | |||
| 411054afe9 | |||
| 067eafbbe4 | |||
| 253e256458 | |||
| 238fdf5d40 | |||
| 13ddeaaf0a | |||
| 07afbdaa4b | |||
| 0ff74d331f | |||
| 3eff6228be | |||
| edc6d11824 | |||
| e9aaa184cf | |||
| e8351e960d | |||
| 0ff03fb413 | |||
| ba83edd26c | |||
| eed058c891 | |||
| 48f82a6f13 | |||
| 177391a74c | |||
| 9ea177e2f6 | |||
| ca6a4d8ab5 | |||
| c5a2a05af6 | |||
| 0034f93caa | |||
| d01ef02389 | |||
| e8f2a72516 | |||
| bc66d35497 | |||
| e1d0d2c186 | |||
| e7c878b30a | |||
| 8fb46099d4 | |||
| 72628519a5 | |||
| f7375428b6 | |||
| ead8a44fe0 | |||
| a1aa71e271 | |||
| a72691a81f | |||
| 3be409ec70 | |||
| 9409197766 | |||
| 1a92094eaf | |||
| fa47ccfd85 | |||
| 6b4468bf7d | |||
| b0927b8388 | |||
| 593dc3ca55 | |||
| a124a1a71f | |||
| 0e71242fd3 | |||
| 556b2a2317 | |||
| 4bfd7c348d | |||
| 972007f9e5 | |||
| 9bfd1a78bd | |||
| 05d8332358 | |||
| dd62611588 | |||
| f0d6402529 | |||
| d73a37fbed | |||
| 9084a78420 | |||
| 1769aa45c9 | |||
| 3386263fbe | |||
| 0eb7a58494 | |||
| b995b86cee | |||
| a825912ad3 | |||
| e788dea8a4 | |||
| 7622420f06 | |||
| 66fff153e1 | |||
| a33171ba87 | |||
| 4bb7b4b6c4 | |||
| f8e887c1f2 | |||
| 47dc244a15 | |||
| f872deffb8 | |||
| 5489f601d2 | |||
| d77813d82f | |||
| b0f9d7906a | |||
| eec08d4a3e | |||
| 320c45096b | |||
| 68a83c31be | |||
| 88eb325079 | |||
| b2f4933a5f | |||
| e12a1d369d | |||
| c4f1e420f8 | |||
| 15a4280a36 | |||
| 3e39ef1705 | |||
| 0dd3a6190e | |||
| f03fbd42df | |||
| dfc86e4b96 | |||
| 167e2853f0 | |||
| 1698de332c | |||
| 377d85c7f1 | |||
| 68a3af0b52 | |||
| 5b7bfa79f9 | |||
| d7dee62e97 | |||
| 4368f0cbe5 | |||
| 12f35fefc4 | |||
| 49a1dad51e | |||
| 40c0403962 | |||
| 068e153ae9 | |||
| 42869cb28f | |||
| 56a96540b4 | |||
| 5a6bb57fd5 | |||
| 44521d0d5f | |||
| 43a4a0e6ee | |||
| 1373d0ce26 | |||
| c9c1ac5126 | |||
| d136b98411 | |||
| 7e0e359f46 | |||
| 86427cf6ef | |||
| c7db07f7ba | |||
| d3fbec1a9d | |||
| c621c45695 | |||
| bb456738f0 | |||
| 0112acdd2f | |||
| ae6121f3aa | |||
| 9b606cf9ac | |||
| 234d3c9c7c | |||
| ce4663d512 | |||
| 97de98b89a | |||
| 76d0c53cc1 | |||
| 8b102b083f | |||
| e13f9c6aa8 | |||
| e8b929d4ca | |||
| 034f048883 | |||
| aceb6ee14c | |||
| 7698a1490e | |||
| 59a25fbee9 | |||
| fc598838c4 | |||
| 11712b5b13 | |||
| d2799adad0 | |||
| 872639dab9 | |||
| e4562648ba | |||
| 941137ff51 | |||
| eaec736676 | |||
| 9ba7cb1ba5 | |||
| 2ce8e7f866 | |||
| 5a618a8db2 | |||
| d21e4ffba2 | |||
| 28855046b8 | |||
| eb351f9bed | |||
| 0e0bb17ad9 | |||
| e95f001dd2 | |||
| 0d4b9fe488 | |||
| 4be4fa2c4f | |||
| 8d4da63855 | |||
| 3a9941f69f | |||
| 01486dfbec | |||
| fb2280798a | |||
| 29f874e390 | |||
| dc6bdf7715 | |||
| 6022f5b9d2 | |||
| 30b6d4791f | |||
| e5c185627d | |||
| 573852d852 | |||
| 385c580358 | |||
| ec2b0e0f78 | |||
| c3816b709c | |||
| 4b8528af65 | |||
| 69ba636d74 | |||
| 1b035035ce | |||
| 4dc0d6a97c | |||
| 34e4036f66 | |||
| 1dd3e37a37 | |||
| e79e568a4c | |||
| 1641ba2898 | |||
| 31d9507033 | |||
| 67deef897f | |||
| 3b84161ec5 | |||
| a04bffbec9 | |||
| 7ad1383acb | |||
| 4217d471c4 | |||
| 5f6e96333c | |||
| 7962d3a16f | |||
| de6d831498 | |||
| be076616cc | |||
| 0a38fdd8d3 | |||
| 2fa5587fbf | |||
| 4bfffa579f | |||
| 010fab93d7 | |||
| 6f3eefb611 | |||
| 328b378978 | |||
| 1f518c2d33 | |||
| a1a5e665fb | |||
| 70afa7cc9b | |||
| 5f1ea76cad | |||
| 462aa44473 | |||
| dc0f0df92f | |||
| 0ec22766ba | |||
| 3549f8b2d2 | |||
| 8a3a2fecf5 | |||
| 5c8c7b8804 | |||
| e88d4c2ca7 | |||
| 83a91eea97 | |||
| 13ef0ba14a | |||
| 938ccd9215 | |||
| d394c390f7 | |||
| 4c705a4605 | |||
| 105aa7874f | |||
| 27ab3b0b21 | |||
| 03af604e94 | |||
| 05b8f5b400 | |||
| e8654ca181 | |||
| 68b4e71281 | |||
| b89617d125 | |||
| 70466aba7e | |||
| 5ddfe1ddb2 | |||
| 25418071fe | |||
| a9d4fb769d | |||
| 1faf234255 | |||
| c06afcd56d | |||
| 607b973dbd | |||
| 22e136d9fd | |||
| 7b2f44d19a | |||
| 74c31a0f18 | |||
| fd3c2e5f9b | |||
| be3724c6b1 | |||
| b8e6c21538 | |||
| 60afaf6211 | |||
| 090f305f02 | |||
| 0a30e5022b | |||
| 6733fe9c40 | |||
| 76ce4b8058 | |||
| 36f4bbc7e7 | |||
| 30d52c6061 | |||
| 7018915686 | |||
| a1fb4ce8eb | |||
| 5446dbce83 | |||
| 93b36f1bd4 | |||
| ab12de8287 | |||
| 3cdfc91c93 | |||
| a6c8105d8c | |||
| ca99421624 | |||
| 5c270a0362 | |||
| 19ae15f53f | |||
| 386c6bf268 | |||
| e075306363 | |||
| 9591350c3e | |||
| 45b18eb8e6 | |||
| 0f59798e73 | |||
| 7b56924466 | |||
| 3d30d65184 | |||
| 9bb896e84b | |||
| e0ee364929 | |||
| 8e9cd2d2f3 | |||
| f58597379b | |||
| e6f263b6de | |||
| c69864d0f5 | |||
| ae901b257b | |||
| fdc537d69a | |||
| f12c1053ca | |||
| 6435114384 | |||
| c55c3bca72 | |||
| 83b8627717 | |||
| 95ccceb259 | |||
| 31d8f5f7b9 | |||
|
|
f1660bbc74 | ||
|
|
5d72fe44ab | ||
| 714b7d845a | |||
| 066229eb0e | |||
| 0f96f02df5 | |||
| b753fdd2b0 | |||
| f9df0b8a12 | |||
| db41c55230 | |||
| 58b799edb4 | |||
| 94d3b8676f | |||
| de7aa58195 | |||
| 5d4e251251 | |||
| 45baa804e6 | |||
| 2c49848dd7 | |||
| be499b3085 | |||
| 4fde5fb65f | |||
| 4c84f857e7 | |||
| 1e55b7bf50 | |||
| 479d3e9f07 | |||
| dcf14c6e6f | |||
| 96d5ca0f3c | |||
| 32fa639d4a | |||
| 69760dd5f8 | |||
| 1237a9157c | |||
| fee59833f2 | |||
| 12f685010b | |||
| 6ac8af9946 | |||
| e8d4c128da | |||
| d2a5d4b3ec | |||
| 7797a7bf53 | |||
| e5430a7aed | |||
| 88cd4a3ec2 | |||
| 8650c2d4c8 | |||
| 1734e57d43 | |||
| 28d0fc161b | |||
| 8ebc767b76 | |||
| bbe8a19189 | |||
| 4bffd359b9 | |||
| 08bbfd91fe | |||
| 1e3cd64ec9 | |||
| 663de0e720 | |||
| 7cffd75749 | |||
| 327ea4912a | |||
| efa743a714 | |||
| cd44e8e4c3 | |||
| e185625f4a | |||
| 3e140e4f43 | |||
| 47a22b6540 | |||
| 72e74cea32 | |||
| 4993ae50fe | |||
| eeb111dd9e | |||
| 4bb992fc67 | |||
| 58040f8f49 | |||
| 4f2cefb1be | |||
| 2b33191db7 | |||
| 0969d68adc | |||
| 86533153bf | |||
| 6349763abc | |||
| 67693d6c31 | |||
| 31a757a5cd | |||
| 2c59dddca0 | |||
| 206466f9cc | |||
| 039c644453 | |||
| 5d377654aa | |||
| ff163026c7 | |||
| 1d431ecad6 | |||
| 6a4c2c6aea | |||
| 3f928ad507 | |||
| 735edf1529 | |||
| f49882fb0d | |||
| 6f4936f6be | |||
| e8eb36284b | |||
| cec8400145 | |||
| 22d8ea8215 | |||
| e6a6131a14 | |||
| 92b5e33940 | |||
| 63f7a75394 | |||
| dbe85322ea | |||
| 64d4ee9168 | |||
| f7f40be956 | |||
| f42eaeb953 | |||
| 954909fecd | |||
| 95133deeb0 | |||
| 8ba80e93e3 | |||
| 47c7617d24 | |||
| a5fc5b3753 | |||
| 0b2d8a7e2e | |||
| 5ee0a0044a | |||
| 6e39690d7a | |||
| ca4e9e0052 | |||
| f76ce5dae1 | |||
| 4e4a90b2d2 | |||
| 98f6fda99f | |||
| 9a125e0359 | |||
| 3778b2148c | |||
| 3ab76006af | |||
| c96db3a3dc | |||
| ea52ce1c65 | |||
| f80289aef1 | |||
| 5cdcff0cd0 | |||
| 4c523d56f5 | |||
| 67e4764a72 | |||
| e7ace4d497 | |||
| c6edf4e2cb | |||
| 2939ea0787 | |||
| 64adc63920 | |||
| 33d212bd84 | |||
| 5543bc4c9d | |||
| d106988fd7 | |||
| bc6fdec360 | |||
| a7d8863998 | |||
| a3b2b80c1e | |||
| 0b614ec4b6 | |||
| 0e2c029249 | |||
| deade0010b | |||
| e94fae1d85 | |||
| 259ca2e14e | |||
| e9f9ae5154 | |||
| 3b98263fbc | |||
| ca1d2dd16f | |||
| 9e254e6813 | |||
| 9e250e6129 | |||
| 8f22785d2f | |||
| bb716ab6b6 | |||
| 5acd231292 | |||
| 7ebe0adace | |||
| 9e3337e9c5 | |||
| 298dc9af27 | |||
| 840b0c07ff | |||
| 592c92785f | |||
| d0db4815f1 | |||
| 8cf105a550 | |||
| 9c6055a52e | |||
| a554b7681f | |||
| cbcc2f30b7 | |||
| 565125da67 | |||
| ec8782ad81 | |||
| 7388719cad | |||
| 75fb4b5809 | |||
| 408873b844 | |||
| 31a349704b | |||
| c3b8595cd7 | |||
| 2334afb3eb | |||
| ce9dc48d81 | |||
| 20f7f87072 | |||
| a9ce596381 | |||
| 8ac5f02d93 | |||
| 10b291b4aa | |||
| c894f33c11 | |||
| 1167cfa3a4 | |||
| 541a7c9e2b | |||
| 8b2dd048d3 | |||
| d4d223dbf0 | |||
| 6b9842c9d3 | |||
| e2387158dc | |||
| 89fbb3a3cf | |||
| 55da64a702 | |||
| edff93917e | |||
| 424390417a | |||
| 7427de1bb4 | |||
| 42adf023d9 | |||
| 02214a127c | |||
| 9e98bf3532 | |||
| 86955cf0cb | |||
| bf281820b9 | |||
| 4d0dd674ad | |||
| 973f9cfdc2 | |||
| 13d79c5338 | |||
| dca91feff8 | |||
| 505ebb48bc | |||
| eaa4060f2a | |||
| 5e87a669de | |||
| 9ce8043667 | |||
| edf2941e01 | |||
| da0c1087e9 | |||
| a4f9d5b461 | |||
| ebb3b962a8 | |||
| 38040ba1d3 | |||
| e17b4c6e23 | |||
| 03bd5b4c78 | |||
| ebe2da0309 | |||
| 201892ea7f | |||
| e12ac9b3a4 | |||
| 2b86a469a9 | |||
| dae11994c2 | |||
| 3e53b28a10 | |||
| 4c4e22a0e0 | |||
| b5f8799d0a | |||
| 875c6eaa5e | |||
| a56af56009 | |||
| eee51216b9 | |||
| 73578736bc | |||
| 33db01cbbf | |||
| a716fd1e22 | |||
| 19c3f44d9a | |||
| ae095b3e2c | |||
| eb92eed532 | |||
| 2652e558d2 | |||
| 262a26e3df | |||
|
|
4af4119561 | ||
|
|
04eae360a7 | ||
|
|
a6c645c33f | ||
| 4b7f59e2e9 | |||
| da17fc3e6d | |||
| b62af8d2ae | |||
| ef3e4dc39b | |||
| fbe624ca6d | |||
| 67112a37da | |||
| c0c263c4d7 | |||
| e32c09f48f | |||
| 91aa673dcb | |||
| 95257771a5 | |||
| fa6bb695f3 | |||
| 9f5b5282b1 | |||
| ea53eb9b24 | |||
| 98a0466761 | |||
| e3be74d519 | |||
| fdc6a88317 | |||
| d67bd62393 | |||
|
|
ea986917af | ||
|
|
ffbf4be19e | ||
|
|
2b87aacc58 | ||
|
|
b62b272492 | ||
|
|
e5027cf00d | ||
|
|
e7b4c01f93 | ||
|
|
304951e463 | ||
|
|
e9622edee9 | ||
|
|
80be960f29 | ||
|
|
d2d736a7ec | ||
|
|
341d799207 | ||
|
|
91289c8588 | ||
|
|
bc878a2e90 | ||
|
|
bb4e7b7712 | ||
|
|
dad0a7d30a | ||
|
|
b0ea38b047 | ||
|
|
9c35801196 | ||
|
|
f5338fc8a8 | ||
|
|
aa38b34191 | ||
|
|
01eae3f680 | ||
|
|
6a098b6317 | ||
|
|
e242867ddb | ||
|
|
e11af205f8 | ||
|
|
9dc9431170 | ||
|
|
1e182e0d75 | ||
|
|
a501c8e571 | ||
|
|
95eb703788 | ||
|
|
942f4f1c75 | ||
|
|
8ca120aa6f | ||
|
|
1f33d52429 | ||
|
|
257e78dcaa | ||
|
|
b88cd583d3 | ||
|
|
67da1563be | ||
|
|
4b92b8a38e | ||
|
|
39ae631cf1 | ||
|
|
84b4c998a7 | ||
|
|
e741b5aa6d | ||
|
|
162891ba1d | ||
|
|
1139a726c9 | ||
|
|
b0eb8c3b42 | ||
|
|
7315d5f5a1 | ||
|
|
7a1bde1b73 | ||
|
|
b1b8772717 | ||
|
|
856eaffda6 | ||
|
|
2c16fdad19 | ||
|
|
c79a991024 | ||
|
|
7b8d916685 | ||
|
|
3c447f5708 | ||
|
|
4f5023f745 | ||
|
|
2c5d37083b | ||
|
|
4f6024a473 | ||
|
|
2ac4c434f5 | ||
|
|
eabf5e1faf | ||
|
|
1ee955fbfe | ||
|
|
de06c7f81f | ||
|
|
4347df0b9b | ||
|
|
b951ef5ce4 | ||
|
|
a12f78761d | ||
|
|
894cbb3c9d | ||
|
|
26f9cf646b | ||
|
|
8c28df9517 | ||
|
|
1b76bbf6c2 | ||
|
|
e5b236f51c | ||
|
|
a213c39445 | ||
|
|
be6551888e | ||
|
|
3b29e1a87a | ||
|
|
bb63340555 | ||
|
|
24dddc3075 | ||
|
|
47ca25fe1c | ||
|
|
1cd418991c | ||
|
|
d15c3ed047 | ||
|
|
26e5ce6852 | ||
|
|
f834e08273 | ||
|
|
26e40adb21 | ||
|
|
43ed65bc76 | ||
|
|
1f049952cc | ||
|
|
869c1fbe51 | ||
|
|
5b78146db9 | ||
|
|
fff73ed2b8 | ||
|
|
71a506443f | ||
|
|
2e50be6254 | ||
|
|
ceaafc495d | ||
|
|
67de27578e | ||
|
|
e82e515a23 | ||
|
|
20c740ce07 | ||
|
|
9a9538d14d | ||
|
|
ca50b53bae | ||
|
|
d420c7d0a9 | ||
|
|
4195371efb | ||
|
|
27e309f04d | ||
|
|
b20a4fa149 | ||
|
|
2c4bcb9c39 | ||
|
|
07b41716e8 | ||
|
|
e92e7758e7 | ||
|
|
c64c34a9fb | ||
|
|
a221e6358e | ||
|
|
f40122d5b2 | ||
|
|
a065205ea0 | ||
|
|
856f42ce27 | ||
|
|
016d50e383 | ||
|
|
1507b279f7 | ||
|
|
000f7cbfe1 | ||
|
|
cbbd04efb6 | ||
|
|
3488aeb03b | ||
|
|
d7dc66301e | ||
|
|
2c06924792 | ||
|
|
6bcff8d9a2 | ||
|
|
6534f3bd25 | ||
|
|
6e4f5feb7c | ||
|
|
edc33f3c37 | ||
|
|
0652ffef68 | ||
|
|
07e8504cea | ||
|
|
6eccb2cede | ||
|
|
9b62cb8a93 | ||
|
|
251b80b152 | ||
|
|
5dfd65c16f | ||
|
|
3edec54fbb | ||
|
|
9a09572722 | ||
|
|
88b1c04367 | ||
|
|
5f73f86787 | ||
|
|
506a16e10a | ||
|
|
9f455b8065 | ||
|
|
03b05dfc87 | ||
|
|
ca41ddb271 | ||
|
|
a776278caf | ||
|
|
649eee099e | ||
|
|
aeef6bd44d | ||
|
|
9f6cdcdf91 | ||
|
|
0ba5a97d2e | ||
|
|
23cc667692 | ||
|
|
f95d8b565e | ||
|
|
6cd976e057 | ||
|
|
608bc15e1f | ||
|
|
9b80b340e3 | ||
|
|
dfe6fa7cda | ||
|
|
090d613266 | ||
|
|
50507a1379 | ||
|
|
fb436fd0f5 | ||
|
|
a3bdb8953c | ||
|
|
92ff8f71eb | ||
|
|
86639629ee | ||
|
|
56d0f1edd8 | ||
|
|
dd86e2aae4 | ||
|
|
68e908fb4d | ||
|
|
b6daaf6aaa | ||
|
|
54caa2956d | ||
|
|
25ceac2ef4 | ||
|
|
f6557e6bbc | ||
|
|
9dd783fd2f | ||
|
|
54ed8df2d8 | ||
|
|
5eddacb7d9 | ||
|
|
dc8152dfaf | ||
|
|
fc67a19915 | ||
|
|
f13046681a | ||
|
|
ee20ab496f | ||
|
|
6db43bb19a | ||
|
|
f226b4c8b2 | ||
|
|
8bfea04c6a | ||
|
|
f233ae8c66 | ||
|
|
7a8964c336 | ||
|
|
b322b514fc | ||
|
|
b5821b0d02 | ||
|
|
d257901c64 | ||
|
|
14d23af0fd | ||
|
|
ad57df45d7 | ||
|
|
aa673e1acc | ||
|
|
9468346617 | ||
|
|
673cb48b75 | ||
|
|
1a534d2325 | ||
|
|
3962c0eb7a | ||
|
|
425c80237b | ||
|
|
341d20883d | ||
|
|
fcf56c205a | ||
|
|
a84a9fed85 | ||
|
|
4644fc522a | ||
|
|
48ae67168b | ||
|
|
6348ae9aa6 | ||
|
|
a71c22db92 | ||
|
|
22c600bd09 | ||
|
|
b01198c110 | ||
|
|
76a57459af | ||
|
|
0f06033b42 | ||
|
|
34b06bd2fb |
@@ -1,8 +0,0 @@
|
||||
.git
|
||||
**/build
|
||||
**/dist
|
||||
src/Kyoo.WebApp/Front/nodes_modules
|
||||
**/bin
|
||||
**/obj
|
||||
docs
|
||||
tests
|
||||
@@ -9,85 +9,6 @@ indent_style = tab
|
||||
indent_size = tab
|
||||
smart_tab = true
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
[{*.yaml,*.yml,*.nix}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.cs]
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
csharp_using_directive_placement = outside_namespace:warning
|
||||
# Avoid "this." if not necessary
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
# Use language keywords instead of framework type names for type references
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
# Suggest more modern language features when available
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
# Disable strange throw.
|
||||
csharp_style_throw_expression = false:suggestion
|
||||
# Forbid "var" everywhere
|
||||
csharp_style_var_for_built_in_types = false:warning
|
||||
csharp_style_var_when_type_is_apparent = false:warning
|
||||
csharp_style_var_elsewhere = false:warning
|
||||
# Prefer method-like constructs to have a block body
|
||||
csharp_style_expression_bodied_methods = false:none
|
||||
csharp_style_expression_bodied_constructors = false:none
|
||||
csharp_style_expression_bodied_operators = false:none
|
||||
# Prefer property-like constructs to have an expression-body
|
||||
csharp_style_expression_bodied_properties = true:none
|
||||
csharp_style_expression_bodied_indexers = true:none
|
||||
csharp_style_expression_bodied_accessors = true:none
|
||||
# Newline settings
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = false
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
# Indentation settings
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
# Modifiers
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
|
||||
# Naming style
|
||||
dotnet_naming_symbols.privates.applicable_kinds = property,method,event,delegate
|
||||
dotnet_naming_symbols.privates.applicable_accessibilities = private
|
||||
dotnet_naming_style.underscore_pascal.capitalization = pascal_case
|
||||
dotnet_naming_style.underscore_pascal.required_prefix = _
|
||||
dotnet_naming_rule.privates_with_underscore.symbols = privates
|
||||
dotnet_naming_rule.privates_with_underscore.style = underscore_pascal
|
||||
dotnet_naming_rule.privates_with_underscore.severity = warning
|
||||
dotnet_diagnostic.IDE1006.severity = warning
|
||||
# ReSharper properties
|
||||
resharper_align_multiline_binary_expressions_chain = false
|
||||
resharper_csharp_empty_block_style = together_same_line
|
||||
resharper_indent_nested_foreach_stmt = true
|
||||
resharper_indent_nested_for_stmt = true
|
||||
resharper_indent_nested_while_stmt = true
|
||||
resharper_keep_existing_embedded_arrangement = false
|
||||
resharper_place_accessorholder_attribute_on_same_line = true
|
||||
resharper_place_simple_embedded_statement_on_same_line = false
|
||||
resharper_wrap_before_arrow_with_expressions = true
|
||||
resharper_xmldoc_attribute_indent = align_by_first_attribute
|
||||
resharper_xmldoc_indent_child_elements = RemoveIndent
|
||||
resharper_xmldoc_indent_text = RemoveIndent
|
||||
|
||||
# Waiting for https://github.com/dotnet/roslyn/issues/44596 to get fixed.
|
||||
# file_header_template = Kyoo - A portable and vast media library solution.\nCopyright (c) Kyoo.\n\nSee AUTHORS.md and LICENSE file in the project root for full license information.\n\nKyoo is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\nany later version.\n\nKyoo is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
90
.env.example
Normal file
90
.env.example
Normal file
@@ -0,0 +1,90 @@
|
||||
# vi: ft=sh
|
||||
# shellcheck disable=SC2034
|
||||
|
||||
|
||||
# Useful config options
|
||||
|
||||
# Library root can either be an absolute path or a relative path to your docker-compose.yml file.
|
||||
LIBRARY_ROOT=./video
|
||||
# You should set this to a path where kyoo can write large amount of data, this is used as a cache by the transcoder.
|
||||
# It will automatically be cleaned up on kyoo's startup/shutdown/runtime.
|
||||
CACHE_ROOT=/tmp/kyoo_cache
|
||||
LIBRARY_LANGUAGES=en
|
||||
# A pattern (regex) to ignore video files.
|
||||
LIBRARY_IGNORE_PATTERN=".*/[dD]ownloads?/.*"
|
||||
|
||||
# If this is true, new accounts wont have any permissions before you approve them in your admin dashboard.
|
||||
REQUIRE_ACCOUNT_VERIFICATION=true
|
||||
# Specify permissions of guest accounts, default is no permissions.
|
||||
UNLOGGED_PERMISSIONS=
|
||||
# but you can allow anyone to use your instance without account by doing:
|
||||
# UNLOGGED_PERMISSIONS=overall.read,overall.play
|
||||
# You can specify this to allow guests users to see your collection without behing able to play videos for example:
|
||||
# UNLOGGED_PERMISSIONS=overall.read
|
||||
|
||||
# Specify permissions of new accounts.
|
||||
DEFAULT_PERMISSIONS=overall.read,overall.play
|
||||
|
||||
# Hardware transcoding (equivalent of --profile docker compose option).
|
||||
COMPOSE_PROFILES=cpu # cpu (no hardware acceleration) or vaapi or qsv or nvidia
|
||||
# the preset used during transcode. faster means worst quality, you can probably use a slower preset with hwaccels
|
||||
# warning: using vaapi hwaccel disable presets (they are not supported).
|
||||
GOCODER_PRESET=fast
|
||||
|
||||
|
||||
# The following value should be set to a random sequence of characters.
|
||||
# You MUST change it when installing kyoo (for security)
|
||||
# You can input multiple api keys separated by a ,
|
||||
KYOO_APIKEYS=t7H5!@4iMNsAaSJQ49pat4jprJgTcF656if#J3
|
||||
|
||||
# Keep those empty to use kyoo's default api key. You can also specify a custom API key if you want.
|
||||
# go to https://www.themoviedb.org/settings/api and copy the api key (not the read access token, the api key)
|
||||
THEMOVIEDB_APIKEY=
|
||||
# go to https://thetvdb.com/api-information/signup and copy the api key
|
||||
TVDB_APIKEY=
|
||||
# you can also input your subscriber's pin to support TVDB
|
||||
TVDB_PIN=
|
||||
|
||||
|
||||
# The url you can use to reach your kyoo instance. This is used during oidc to redirect users to your instance.
|
||||
PUBLIC_URL=http://localhost:5000
|
||||
|
||||
# Use a builtin oidc service (google, discord, trakt, or simkl):
|
||||
# When you create a client_id, secret combo you may be asked for a redirect url. You need to specify https://YOUR-PUBLIC-URL/api/auth/logged/YOUR-SERVICE-NAME
|
||||
OIDC_DISCORD_CLIENTID=
|
||||
OIDC_DISCORD_SECRET=
|
||||
# Or add your custom one:
|
||||
OIDC_SERVICE_NAME=YourPrettyName
|
||||
OIDC_SERVICE_LOGO=https://url-of-your-logo.com
|
||||
OIDC_SERVICE_CLIENTID=
|
||||
OIDC_SERVICE_SECRET=
|
||||
OIDC_SERVICE_AUTHORIZATION=https://url-of-the-authorization-endpoint-of-the-oidc-service.com/auth
|
||||
OIDC_SERVICE_TOKEN=https://url-of-the-token-endpoint-of-the-oidc-service.com/token
|
||||
OIDC_SERVICE_PROFILE=https://url-of-the-profile-endpoint-of-the-oidc-service.com/userinfo
|
||||
OIDC_SERVICE_SCOPE="the list of scopes space separeted like email identity"
|
||||
# Token authentication method as seen in https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
|
||||
# Supported values: ClientSecretBasic (default) or ClientSecretPost
|
||||
# If in doupt, leave this empty.
|
||||
OIDC_SERVICE_AUTHMETHOD=ClientSecretBasic
|
||||
# on the previous list, service is the internal name of your service, you can add as many as you want.
|
||||
|
||||
|
||||
# Following options are optional and only useful for debugging.
|
||||
|
||||
# To debug the front end, you can set the following to an external backend
|
||||
KYOO_URL=
|
||||
|
||||
# Database things
|
||||
POSTGRES_USER=KyooUser
|
||||
POSTGRES_PASSWORD=KyooPassword
|
||||
POSTGRES_DB=kyooDB
|
||||
POSTGRES_SERVER=postgres
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
MEILI_HOST="http://meilisearch:7700"
|
||||
MEILI_MASTER_KEY="ghvjkgisbgkbgskegblfqbgjkebbhgwkjfb"
|
||||
|
||||
RABBITMQ_HOST=rabbitmq
|
||||
RABBITMQ_PORT=5672
|
||||
RABBITMQ_DEFAULT_USER=kyoo
|
||||
RABBITMQ_DEFAULT_PASS=aohohunuhouhuhhoahothonseuhaoensuthoaentsuhha
|
||||
3
.git-blame-ignore-revs
Normal file
3
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,3 @@
|
||||
7e6e56a366babe17e7891a5897180efbf93c00c5
|
||||
a5638203a6ecb9f372a5a61e1c8fd443bf3a17fe
|
||||
18e301f26acd7f2e97eac26c5f48377fa13956f5
|
||||
64
.gitattributes
vendored
64
.gitattributes
vendored
@@ -1,63 +1 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
*.Designer.cs linguist-generated=true
|
||||
|
||||
20
.github/ISSUE_TEMPLATE/bug-report.md
vendored
20
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a bug report to help improve Kyoo
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1.
|
||||
|
||||
**Expected Behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Environment:**
|
||||
- Platform [e.g. Windows / Linux]
|
||||
- Action Version [e.g. v0.0.1 or a git commit's SHA]
|
||||
11
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
11
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: Bug Report
|
||||
description: Create a bug report to help improve Kyoo
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Kyoo's version"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
18
.github/ISSUE_TEMPLATE/feature-request.md
vendored
18
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature for Kyoo (don't forget to check projects first)
|
||||
title: "[FEATURE] "
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? If yes, please describe.**
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
**Describe the feature you'd like**
|
||||
A clear and concise description of what you want Kyoo to have.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
7
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
7
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature for Kyoo (don't forget to check projects first)
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,20 +0,0 @@
|
||||
## Proposed changes
|
||||
|
||||
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
|
||||
If it fixes a bug or resolves a feature request, be sure to link to that issue.
|
||||
|
||||
## Information
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] New public API added
|
||||
- [ ] Non-breaking changes
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] I have added necessary documentation (if appropriate)
|
||||
|
||||
## Further comments
|
||||
|
||||
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did
|
||||
and what alternatives you considered, etc...
|
||||
|
||||
65
.github/workflows/analysis.yml
vendored
65
.github/workflows/analysis.yml
vendored
@@ -1,65 +0,0 @@
|
||||
name: Analysis
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Static Analysis
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Cache SonarCloud packages
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
restore-keys: ${{ runner.os }}-sonar
|
||||
- name: Cache SonarCloud scanner
|
||||
id: cache-sonar-scanner
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ./.sonar/scanner
|
||||
key: ${{ runner.os }}-sonar-scanner
|
||||
restore-keys: ${{ runner.os }}-sonar-scanner
|
||||
- name: Install SonarCloud scanner
|
||||
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ./.sonar/scanner
|
||||
dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner
|
||||
- name: Wait for tests to run
|
||||
uses: lewagon/wait-on-check-action@master
|
||||
with:
|
||||
ref: ${{github.ref}}
|
||||
check-name: tests
|
||||
repo-token: ${{secrets.GITHUB_TOKEN}}
|
||||
running-workflow-name: analysis
|
||||
allowed-conclusions: success,skipped,cancelled,neutral,failure
|
||||
- name: Download coverage report
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
commit: ${{env.COMMIT_SHA}}
|
||||
workflow: tests.yml
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
- name: Build and analyze
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
shell: bash
|
||||
run: |
|
||||
find . -name 'coverage.opencover.xml'
|
||||
dotnet build-server shutdown
|
||||
|
||||
./.sonar/scanner/dotnet-sonarscanner begin \
|
||||
-k:"AnonymusRaccoon_Kyoo" \
|
||||
-o:"anonymus-raccoon" \
|
||||
-d:sonar.login="${{ secrets.SONAR_TOKEN }}" \
|
||||
-d:sonar.host.url="https://sonarcloud.io" \
|
||||
-d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" \
|
||||
-d:sonar.cs.vstest.reportsPaths="**/TestOutputResults.xml"
|
||||
|
||||
dotnet build --no-incremental '-p:SkipTranscoder=true;SkipWebApp=true'
|
||||
|
||||
./.sonar/scanner/dotnet-sonarscanner end -d:sonar.login="${{ secrets.SONAR_TOKEN }}"
|
||||
170
.github/workflows/build.yml
vendored
170
.github/workflows/build.yml
vendored
@@ -1,170 +0,0 @@
|
||||
name: Build
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: "${{matrix.artifact}}'s Build"
|
||||
runs-on: ${{matrix.os}}
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
runtime: linux-x64
|
||||
artifact: linux
|
||||
- os: windows-latest
|
||||
runtime: win-x64
|
||||
artifact: windows
|
||||
- os: macOS-latest
|
||||
runtime: osx-x64
|
||||
artifact: macos
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.x
|
||||
- name: Install ffmpeg
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{runner.os}}" == "Windows" ]]; then
|
||||
choco install ffmpeg-shared
|
||||
elif [[ "${{runner.os}}" == "macOS" ]]; then
|
||||
brew install ffmpeg
|
||||
else
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libavutil-dev libavcodec-dev libavformat-dev
|
||||
fi
|
||||
- name: Enabling windows compilations tools
|
||||
if: matrix.artifact == 'windows'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Select the project to build
|
||||
shell: bash
|
||||
run: |
|
||||
echo "PROJECT=$([ "${{runner.os}}" == "Windows" ] \
|
||||
&& echo " -p:IncludeConsole=true -p:CheckCodingStyle=false src/Kyoo.Host.WindowsTrait" \
|
||||
|| echo " -p:CheckCodingStyle=false src/Kyoo.Host.Console")" >> $GITHUB_ENV
|
||||
- name: Build the app
|
||||
env:
|
||||
INCLUDE: ${{env.INCLUDE}};C:\Program Files\FFmpeg\include
|
||||
LIB: ${{env.LIB}};C:\Program Files\FFmpeg\lib
|
||||
LIBPATH: ${{env.LIBPATH}};C:\Program Files\FFmpeg\lib
|
||||
CFLAGS: -I/usr/local/include
|
||||
LDFLAGS: -L/usr/local/lib
|
||||
run: dotnet publish -r ${{matrix.runtime}} -c Release -o dist ${{env.PROJECT}}
|
||||
- name: Compression output
|
||||
shell: bash
|
||||
run: |
|
||||
assets=kyoo_${{matrix.artifact}}
|
||||
if [[ "${{runner.os}}" == "Windows" ]]; then
|
||||
cd dist
|
||||
cp -r "/C/Program Files/FFmpeg/bin/." .
|
||||
7z a "../$assets.zip"
|
||||
else
|
||||
rootgrp=$([ "${{runner.os}}" == "macOS" ] && echo wheel || echo root)
|
||||
sudo chown -R root:$rootgrp dist
|
||||
tar -C dist -czf "$assets.tar.gz" .
|
||||
fi
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kyoo_${{matrix.artifact}}
|
||||
path: |
|
||||
*.zip
|
||||
*.tar.gz
|
||||
|
||||
windows_release:
|
||||
name: Create windows release
|
||||
runs-on: windows-latest
|
||||
needs: build
|
||||
if: ${{ github.ref == 'refs/heads/master' || contains(github.ref, 'tags') }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download windows build
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kyoo_windows
|
||||
path: artifact
|
||||
- name: Unzip windows files
|
||||
run: mkdir dist_win && 7z x artifact/kyoo_windows.zip -odist_win
|
||||
- name: Install Inno Setup
|
||||
shell: cmd
|
||||
run: |
|
||||
curl -L https://jrsoftware.org/download.php/is.exe > innosetup.exe
|
||||
innosetup.exe /VERYSILENT /SUPPRESSMSGBOXES /Log=log.txt || (cat log.txt && exit 1)
|
||||
- name: Create windows installer
|
||||
shell: bash
|
||||
run: iscc -Dkyoo=$(realpath dist_win) -O./ -Fkyoo-windows deployment/kyoo-windows.iss
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kyoo_windows_installer
|
||||
path: ./kyoo-windows.exe
|
||||
|
||||
release:
|
||||
name: Create debian, rpm & arch releases
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: ${{ github.ref == 'refs/heads/master' || contains(github.ref, 'tags') }}
|
||||
env:
|
||||
description: "A media browser"
|
||||
version: v0.0.1 #${{ github.ref }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download linux build
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kyoo_linux
|
||||
path: artifact
|
||||
- name: Unzip the published files.
|
||||
run: mkdir dist && tar -C dist -xzf artifact/kyoo_linux.tar.gz
|
||||
- name: Create the package structure
|
||||
run: |
|
||||
sudo mkdir -p pkg/usr/lib/
|
||||
sudo cp -r --no-preserve ownership dist pkg/usr/lib/kyoo
|
||||
sudo install -Dm 644 deployment/kyoo.service -t pkg/usr/lib/systemd/system/
|
||||
sudo install -Dm 644 deployment/kyoo.sysusers pkg/usr/lib/sysusers.d/kyoo.conf
|
||||
sudo install -Dm 644 deployment/kyoo.tmpfiles pkg/usr/lib/tmpfiles.d/kyoo.conf
|
||||
- name: Build debian package
|
||||
uses: jiro4989/build-deb-action@v2
|
||||
with:
|
||||
package: kyoo
|
||||
package_root: pkg
|
||||
maintainer: Zoe Roux <zoe.roux@sdg.moe>
|
||||
version: ${{env.version}}
|
||||
depends: "libavutil-dev, libavcodec-dev, libavformat-dev"
|
||||
arch: amd64
|
||||
desc: ${{env.description}}
|
||||
- name: Build rpm package
|
||||
run: |
|
||||
mkdir out
|
||||
sudo rm -rf pkg/DEBIAN
|
||||
rpmbuild -bb --buildroot $(pwd)/out --build-in-place --define "_rpmdir $(pwd)/rpm" deployment/kyoo.spec
|
||||
- name: Prepare arch package
|
||||
run: |
|
||||
mkdir deployment/output
|
||||
mv deployment/PKGBUILD.github deployment/PKGBUILD
|
||||
cp -a pkg/usr deployment/output/usr
|
||||
- uses: edlanglois/pkgbuild-action@v1
|
||||
id: makepkg
|
||||
with:
|
||||
pkgdir: deployment
|
||||
namcapDisable: true
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kyoo_rpm
|
||||
path: ./rpm/x86_64/*.rpm
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kyoo_debian
|
||||
path: ./*.deb
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kyoo_arch
|
||||
path: ${{steps.makepkg.outputs.pkgfile0}}
|
||||
|
||||
# new-version:
|
||||
# if: startsWith(github.ref, 'refs/tags/v')
|
||||
# runs-on: ubuntu-latest
|
||||
|
||||
59
.github/workflows/coding-style.yml
vendored
59
.github/workflows/coding-style.yml
vendored
@@ -1,15 +1,56 @@
|
||||
name: CodingStyle
|
||||
name: Coding Style
|
||||
on: [pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: "Coding style check"
|
||||
back:
|
||||
name: "Lint Back"
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./back
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Check coding style
|
||||
run: |
|
||||
dotnet tool restore
|
||||
dotnet csharpier . --check
|
||||
|
||||
front:
|
||||
name: "Lint Front"
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./front
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Biome
|
||||
uses: biomejs/setup-biome@v2
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Run Biome
|
||||
run: biome ci .
|
||||
|
||||
scanner:
|
||||
name: "Lint scanner/autosync"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v1
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: chartboost/ruff-action@v1
|
||||
with:
|
||||
dotnet-version: 5.0.x
|
||||
- name: Build the app
|
||||
run: dotnet build -p:CheckCodingStyle=true -p:TreatWarningsAsErrors=true '-p:SkipTranscoder=true;SkipWebApp=true'
|
||||
args: format --check
|
||||
|
||||
transcoder:
|
||||
name: "Lint transcoder"
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./transcoder
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run go fmt
|
||||
run: if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then exit 1; fi
|
||||
|
||||
117
.github/workflows/docker.yml
vendored
117
.github/workflows/docker.yml
vendored
@@ -1,36 +1,123 @@
|
||||
name: Docker
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- next
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- context: ./back
|
||||
dockerfile: Dockerfile
|
||||
label: back
|
||||
image: zoriya/kyoo_back
|
||||
|
||||
- context: ./back
|
||||
dockerfile: Dockerfile.migrations
|
||||
label: migrations
|
||||
image: zoriya/kyoo_migrations
|
||||
|
||||
- context: ./front
|
||||
dockerfile: Dockerfile
|
||||
label: front
|
||||
image: zoriya/kyoo_front
|
||||
|
||||
- context: ./scanner
|
||||
dockerfile: Dockerfile
|
||||
label: scanner
|
||||
image: zoriya/kyoo_scanner
|
||||
|
||||
- context: ./autosync
|
||||
dockerfile: Dockerfile
|
||||
label: autosync
|
||||
image: zoriya/kyoo_autosync
|
||||
|
||||
- context: ./transcoder
|
||||
dockerfile: Dockerfile
|
||||
label: transcoder
|
||||
image: zoriya/kyoo_transcoder
|
||||
name: Build ${{matrix.label}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
submodules: recursive
|
||||
filters: |
|
||||
should_run:
|
||||
- '${{matrix.context}}/**'
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: crazy-max/ghaction-docker-meta@v2
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{github.repository_owner}}/Kyoo
|
||||
images: |
|
||||
docker.io/${{matrix.image}}
|
||||
ghcr.io/${{matrix.image}}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=edge
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
|
||||
- name: Check if a package should be pushed
|
||||
run: |
|
||||
echo "SHOULD_PUSH=$([ "${GITHUB_REF##*/}" == "master" ] || [ "${GITHUB_REF##*/}" == "next" ] || [ "${GITHUB_REF_TYPE}" == "tag" ] && echo "true" || echo "false")" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
if: env.SHOULD_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: env.SHOULD_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{github.repository_owner}}
|
||||
password: ${{secrets.GITHUB_TOKEN}}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v5
|
||||
if: steps.filter.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.event.ref, 'refs/tags/v')
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
context: ${{matrix.context}}
|
||||
file: ${{matrix.context}}/${{matrix.dockerfile}}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
build-args: |
|
||||
VERSION=0.0.0
|
||||
push: ${{env.SHOULD_PUSH}}
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Sync README.MD
|
||||
if: env.SHOULD_PUSH == 'true'
|
||||
uses: ms-jpq/sync-dockerhub-readme@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
repository: ${{ matrix.image }}
|
||||
readme: "./README.md"
|
||||
|
||||
32
.github/workflows/documentation.yml
vendored
32
.github/workflows/documentation.yml
vendored
@@ -1,32 +0,0 @@
|
||||
name: Update the documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
Building:
|
||||
runs-on: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: nikeee/docfx-action@v1.0.0
|
||||
name: Build Documentation
|
||||
with:
|
||||
args: docs/docfx.json
|
||||
- name: Update the docs
|
||||
run: |
|
||||
cd docs/_site
|
||||
sudo chown $(whoami):$(whoami) . -R
|
||||
echo -n docs.kyoo.moe > CNAME
|
||||
git config --global user.email "${GITHUB_ACTOR}@github.com"
|
||||
git config --global user.name "${GITHUB_ACTOR}"
|
||||
git init
|
||||
git add -A
|
||||
git commit -m "Deploying the documentation"
|
||||
git remote add origin https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@${GITHUB_REPO}
|
||||
git checkout -b gh-pages
|
||||
git push --force origin gh-pages
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPO: "github.com/AnonymusRaccoon/Kyoo"
|
||||
64
.github/workflows/native-build.yml
vendored
Normal file
64
.github/workflows/native-build.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Native build
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Expo Build
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./front
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for EXPO_TOKEN
|
||||
run: |
|
||||
if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
|
||||
echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: yarn
|
||||
cache-dependency-path: front/yarn.lock
|
||||
|
||||
- name: Setup Expo
|
||||
uses: expo/expo-github-action@v8
|
||||
with:
|
||||
expo-version: latest
|
||||
eas-version: latest
|
||||
token: ${{ secrets.EXPO_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Build Mobile Release
|
||||
run: yarn build:mobile:apk | tee log.txt
|
||||
|
||||
- name: Parse Asset URL
|
||||
id: url
|
||||
run: |
|
||||
ASSET_URL=$(cat log.txt | jq '.[0].artifacts.buildUrl' -r)
|
||||
echo The android url is $ASSET_URL
|
||||
echo "assetUrl=$ASSET_URL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download APK Asset
|
||||
run: wget -O kyoo.apk ${{ steps.url.outputs.assetUrl }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: kyoo.apk
|
||||
path: ./front/kyoo.apk
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: ./front/kyoo.apk
|
||||
43
.github/workflows/native-update.yml
vendored
Normal file
43
.github/workflows/native-update.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Native update
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Expo Update
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./front
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for EXPO_TOKEN
|
||||
run: |
|
||||
if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
|
||||
echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: yarn
|
||||
cache-dependency-path: front/yarn.lock
|
||||
|
||||
- name: Setup Expo
|
||||
uses: expo/expo-github-action@v8
|
||||
with:
|
||||
expo-version: latest
|
||||
eas-version: latest
|
||||
token: ${{ secrets.EXPO_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Publish update
|
||||
run: yarn update
|
||||
54
.github/workflows/release.yml
vendored
54
.github/workflows/release.yml
vendored
@@ -1,44 +1,30 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
release:
|
||||
update:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set commit environment
|
||||
run: echo "COMMIT_SHA=$(git rev-list -n 1 ${{github.ref}})" >> $GITHUB_ENV
|
||||
- name: Wait for builds & tests to finish
|
||||
uses: lewagon/wait-on-check-action@master
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set correct versions
|
||||
run: |
|
||||
VERSION=${{ github.ref_name }}
|
||||
VERSION=${VERSION:1} # Remove v prefix
|
||||
VERSION=${VERSION%.*} # Remove minor version
|
||||
sed "s/edge/$VERSION/" -i docker-compose.yml
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
ref: ${{github.ref}}
|
||||
repo-token: ${{secrets.GITHUB_TOKEN}}
|
||||
running-workflow-name: release
|
||||
allowed-conclusions: success,skipped,cancelled,neutral
|
||||
- name: Download artifacts
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
name: docker-compose.yml
|
||||
path: ./docker-compose.yml
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
commit: ${{env.COMMIT_SHA}}
|
||||
workflow: build.yml
|
||||
path: ./artifacts
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
# - name: Public the abstractions to nuget
|
||||
# id: publish_nuget
|
||||
# uses: rohith/publish-nuget@v2
|
||||
# with:
|
||||
# PROJECT_FILE_PATH: Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||
# PACKAGE_NAME: Kyoo.Abstractions
|
||||
# VERSION_REGEX: ^\s*<PackageVersion>(.*)<\/PackageVersion>\s*$
|
||||
# NUGET_KEY: ${{secrets.NUGET_API_KEY}}
|
||||
# INCLUDE_SYMBOLS: true
|
||||
- name: Create Release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
generateReleaseNotes: true
|
||||
artifacts: ./artifacts/**/*
|
||||
token: ${{secrets.GITHUB_TOKEN}}
|
||||
files: ./docker-compose.yml
|
||||
|
||||
50
.github/workflows/robot.yml
vendored
Normal file
50
.github/workflows/robot.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: RobotTests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- next
|
||||
pull_request:
|
||||
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Run Robot Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Pull images
|
||||
run: |
|
||||
cp .env.example .env
|
||||
docker compose version
|
||||
docker compose pull
|
||||
|
||||
- name: Docker cache
|
||||
uses: satackey/action-docker-layer-caching@v0.0.11
|
||||
continue-on-error: true
|
||||
|
||||
- name: Start the service
|
||||
run: |
|
||||
docker compose up -d back postgres traefik meilisearch --wait
|
||||
|
||||
- name: Perform healthchecks
|
||||
run: |
|
||||
docker compose ps -a
|
||||
docker compose logs
|
||||
wget --retry-connrefused --retry-on-http-error=502 http://localhost:8901/api/health || (docker compose logs && exit 1)
|
||||
|
||||
- name: Run robot tests
|
||||
run: |
|
||||
pip install -r back/tests/robot/requirements.txt
|
||||
robot -d out back/tests/robot/
|
||||
|
||||
- name: Show logs
|
||||
if: failure()
|
||||
run: docker compose logs
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: results
|
||||
path: out
|
||||
|
||||
48
.github/workflows/tests.yml
vendored
48
.github/workflows/tests.yml
vendored
@@ -1,48 +0,0 @@
|
||||
name: Testing
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
container: mcr.microsoft.com/dotnet/sdk:5.0
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: |
|
||||
dotnet build --no-restore '-p:SkipWebApp=true;SkipTranscoder=true' -p:CopyLocalLockFileAssemblies=true
|
||||
cp ./src/Kyoo.Abstractions/bin/Debug/net5.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net5.0/
|
||||
- name: Test
|
||||
run: dotnet test --no-build '-p:CollectCoverage=true;CoverletOutputFormat=opencover' --logger "trx;LogFileName=TestOutputResults.xml"
|
||||
env:
|
||||
POSTGRES_HOST: postgres
|
||||
POSTGRES_USERNAME: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
- name: Sanitize coverage output
|
||||
if: ${{ always() }}
|
||||
run: sed -i "s'$(pwd)'.'" tests/Kyoo.Tests/coverage.opencover.xml
|
||||
- name: Upload tests results
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: results.xml
|
||||
path: "**/TestOutputResults.xml"
|
||||
- name: Upload coverage report
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: coverage.xml
|
||||
path: "**/coverage.opencover.xml"
|
||||
361
.gitignore
vendored
361
.gitignore
vendored
@@ -1,353 +1,8 @@
|
||||
## PROJECT CUSTOM IGNORES
|
||||
# Transcoder build (auto generated from Kyoo.Transcoder sub-project)
|
||||
Kyoo/Transcoder/Kyoo.Transcoder.dll
|
||||
Kyoo/Transcoder/Kyoo.Transcoder.ilk
|
||||
Kyoo/Transcoder/Kyoo.Transcoder.lib
|
||||
Kyoo/Transcoder/Kyoo.Transcoder.pdb
|
||||
Kyoo/Transcoder/Kyoo.Transcoder.exp
|
||||
|
||||
libtranscoder.so
|
||||
libtranscoder.dylib
|
||||
transcoder.dll
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- Backup*.rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
/Kyoo/TheTVDB-Credentials.json
|
||||
/video
|
||||
.env
|
||||
.venv
|
||||
.idea
|
||||
.vscode
|
||||
log.html
|
||||
output.xml
|
||||
report.html
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
||||
[submodule "transcoder"]
|
||||
path = src/Kyoo.Transcoder
|
||||
url = ../Kyoo.Transcoder.git
|
||||
branch = master
|
||||
5
.pg_format
Normal file
5
.pg_format
Normal file
@@ -0,0 +1,5 @@
|
||||
tabs=1
|
||||
function-case=1 #lowercase
|
||||
keyword-case=1
|
||||
type-case=1
|
||||
no-space-function=1
|
||||
@@ -1,4 +1,4 @@
|
||||
# Authors
|
||||
Ordered by the date of the first commit.
|
||||
|
||||
* Zoe Roux ([@AnonymusRaccoon](http://github.com/AnonymusRaccoon))
|
||||
* Zoe Roux ([@zoriya](http://github.com/zoriya))
|
||||
|
||||
@@ -3,21 +3,19 @@
|
||||
Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
|
||||
|
||||
Contributions to this project are [released](https://docs.github.com/en/github/site-policy/github-terms-of-service#6-contributions-under-repository-license)
|
||||
to the public under the [GPL-3.0 License](https://github.com/AnonymusRaccoon/Kyoo/blob/master/LICENSE).
|
||||
to the public under the [GPL-3.0 License](https://github.com/zoriya/Kyoo/blob/master/LICENSE).
|
||||
|
||||
## Submitting a pull request
|
||||
|
||||
1. [Fork](https://github.com/AnonymusRaccoon/Kyoo/fork) and clone the repository
|
||||
2. Install the toolstack and/or download precompiled binaries for the transcoder (see [Development & Build](https://github.com/AnonymusRaccoon/Kyoo#development--build))
|
||||
3. Create a new branch: `git checkout -b my-branch-name`
|
||||
4. Make your changes (Please try to follow the same coding style as what has already been made - indent with tabs, align with spaces etc)
|
||||
5. Make sure the tests pass: `dotnet tests`
|
||||
6. Push to your fork and [submit a pull request](https://github.com/AnonymusRaccoon/Kyoo/compare)
|
||||
7. Pat your self on the back and wait for your pull request to be reviewed and merged.
|
||||
1. [Fork](https://github.com/zoriya/Kyoo/fork) and clone the repository
|
||||
2. Create a new branch: `git checkout -b my-branch-name`
|
||||
3. Make your changes (Please try to follow the same coding style as what has already been made - indent with tabs, align with spaces etc).
|
||||
Don't forget to run the auto-formatter.
|
||||
4. Push to your fork and [submit a pull request](https://github.com/zoriya/Kyoo/compare)
|
||||
5. Pat your self on the back and wait for your pull request to be reviewed and merged.
|
||||
|
||||
Here are a few things you can do that will increase the likelihood of your pull request being accepted:
|
||||
|
||||
- Write tests.
|
||||
- Make sure the `README.md` and any other relevant **documentation are kept up-to-date**.
|
||||
- We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option.
|
||||
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as **separate pull requests**.
|
||||
|
||||
25
Dockerfile
25
Dockerfile
@@ -1,25 +0,0 @@
|
||||
FROM gcc:latest as transcoder
|
||||
RUN apt-get update && apt-get install -y cmake make libavutil-dev libavcodec-dev libavformat-dev
|
||||
WORKDIR /transcoder
|
||||
COPY src/Kyoo.Transcoder .
|
||||
RUN cmake . && make -j
|
||||
|
||||
FROM node:14-alpine as webapp
|
||||
WORKDIR /webapp
|
||||
COPY front .
|
||||
RUN npm install -g @angular/cli
|
||||
RUN yarn install --frozen-lockfile
|
||||
RUN yarn run build --configuration production
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:5.0 as builder
|
||||
COPY . .
|
||||
RUN dotnet publish -c Release -o /opt/kyoo '-p:SkipWebApp=true;SkipTranscoder=true;CheckCodingStyle=false' src/Kyoo.Host.Console
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:5.0
|
||||
RUN apt-get update && apt-get install -y libavutil-dev libavcodec-dev libavformat-dev
|
||||
EXPOSE 5000
|
||||
COPY --from=builder /opt/kyoo /usr/lib/kyoo
|
||||
COPY --from=transcoder /transcoder/libtranscoder.so /usr/lib/kyoo
|
||||
COPY --from=webapp /webapp/dist/* /usr/lib/kyoo/wwwroot/
|
||||
CMD ["/usr/lib/kyoo/Kyoo.Host.Console"]
|
||||
|
||||
90
INSTALLING.md
Normal file
90
INSTALLING.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Installing TLDR
|
||||
|
||||
1. Install docker & docker-compose
|
||||
2. Download the
|
||||
[`docker-compose.yml`](https://github.com/zoriya/kyoo/releases/latest/download/docker-compose.yml) and
|
||||
[`.env`](https://raw.githubusercontent.com/zoriya/Kyoo/master/.env.example) files
|
||||
3. Fill the `.env` file with your configuration options
|
||||
4. Look at [Hardware Acceleration section](#Hardware-Acceleration) if you need it
|
||||
5. Run `docker compose up -d` and see kyoo at `http://localhost:8901`
|
||||
|
||||
# Installing
|
||||
|
||||
To install Kyoo, you need docker and docker-compose. Those can be installed from here for
|
||||
[Linux](https://docs.docker.com/engine/install/)
|
||||
[Mac](https://docs.docker.com/desktop/install/mac-install/)
|
||||
or [Windows](https://docs.docker.com/desktop/install/windows-install/). Docker is used to run each services of Kyoo in
|
||||
an isolated environment with all the dependencies they need.
|
||||
|
||||
Kyoo also needs 2 files to work properly. The first should be downloaded from the latest release artifact, the other needs to be filled in with your configurations.
|
||||
Those files can be put in any directory of your choice.
|
||||
|
||||
Those files are:
|
||||
|
||||
- A `docker-compose.yml` (simply download docker-compose.yml from [the latest release](https://github.com/zoriya/kyoo/releases/latest/download/docker-compose.yml)).
|
||||
- A `.env` file that you will need to **fill**. Look at the example [.env.example](https://raw.githubusercontent.com/zoriya/Kyoo/master/.env.example)
|
||||
|
||||
> If you want an explanation of what are those files, you can read the following:
|
||||
> The `docker-compose.yml` file describes the different services of Kyoo, where they should be downloaded and their start order. \
|
||||
> The `.env` file contains all the configuration options that the services in `docker-compose.yml` will read.
|
||||
|
||||
If you need hardware acceleration, look at [Hardware Acceleration section](#Hardware-Acceleration) if you need it
|
||||
|
||||
The next and last step is actually starting Kyoo. To do that, open a terminal in the same directory as the 3 configurations files
|
||||
and run `docker-compose up -d`.
|
||||
|
||||
Congratulation, everything is now ready to use Kyoo. You can navigate to `http://localhost:8901` on a web browser to see your instance of Kyoo.
|
||||
|
||||
# Updating
|
||||
|
||||
Updating Kyoo is exactly the same as installing it. Get an updated version of the `docker-compose.yml` file and
|
||||
unsure that your `.env` contains all the options specified in the updated `.env.example` file.
|
||||
|
||||
After that, you will need to update Kyoo's services. For that, open a terminal in the configuration's directory and run
|
||||
the command `docker-compose pull`. You are now ready to restart Kyoo, you can run `docker-compose up -d`.
|
||||
|
||||
# Uninstalling
|
||||
|
||||
To uninstall Kyoo, you need to open a terminal in the configuration's directory and run `docker-compose down`. This will
|
||||
stop Kyoo's services. You can then remove the configuration files.
|
||||
|
||||
# Hardware Acceleration
|
||||
|
||||
## VA-API (intel, amd)
|
||||
|
||||
First install necessary drivers on your system, when running `vainfo` you should have something like this:
|
||||
```
|
||||
libva info: VA-API version 1.20.0
|
||||
libva info: Trying to open /run/opengl-driver/lib/dri/iHD_drv_video.so
|
||||
libva info: Found init function __vaDriverInit_1_20
|
||||
libva info: va_openDriver() returns 0
|
||||
vainfo: VA-API version: 1.20 (libva 2.20.1)
|
||||
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 23.3.5 ()
|
||||
vainfo: Supported profile and entrypoints
|
||||
VAProfileH264Main : VAEntrypointVLD
|
||||
VAProfileH264Main : VAEntrypointEncSlice
|
||||
...Truncated...
|
||||
VAProfileHEVCSccMain444_10 : VAEntrypointVLD
|
||||
VAProfileHEVCSccMain444_10 : VAEntrypointEncSliceLP
|
||||
```
|
||||
Kyoo will default to use your primary card (located at `/dev/dri/renderD128`). If you need to specify a secondary one, you
|
||||
can use the `GOCODER_VAAPI_RENDERER` env-var to specify `/dev/dri/renderD129` or another one.
|
||||
|
||||
Then you can simply run kyoo using `docker compose --profile vaapi up -d` (notice the `--profile vaapi` added)
|
||||
You can also add `COMPOSE_PROFILES=vaapi` to your `.env` instead of adding the `--profile` flag.
|
||||
|
||||
## Nvidia
|
||||
|
||||
To enable nvidia hardware acceleration, first install necessary drivers on your system.
|
||||
|
||||
Then, install the [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html), you can simply
|
||||
follow the instructions on the official webpage or your distribution wiki.
|
||||
|
||||
To test if everything works, you can run `sudo docker run --rm --gpus all ubuntu nvidia-smi`. If your version of docker is older,
|
||||
you might need to add `--runtime nvidia` like so: `sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi`
|
||||
|
||||
After that, you can now use `docker compose --profile nvidia up -d` to start kyoo with nvidia hardware acceleration (notice the `--profile nvidia` added).
|
||||
You can also add `COMPOSE_PROFILES=nvidia` to your `.env` instead of adding the `--profile` flag.
|
||||
|
||||
Note that most nvidia cards have an artificial limit on the number of encodes. You can confirm your card limit [here](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new).
|
||||
This limit can also be removed by applying an [unofficial patch](https://github.com/keylase/nvidia-patch) to you driver.
|
||||
116
Kyoo.sln
116
Kyoo.sln
@@ -1,116 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kyoo.Core", "src\Kyoo.Core\Kyoo.Core.csproj", "{0F8275B6-C7DD-42DF-A168-755C81B1C329}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Abstractions", "src\Kyoo.Abstractions\Kyoo.Abstractions.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Database", "src\Kyoo.Database\Kyoo.Database.csproj", "{6F91B645-F785-46BB-9C4F-1EFC83E489B6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "src\Kyoo.Postgresql\Kyoo.Postgresql.csproj", "{3213C96D-0BF3-460B-A8B5-B9977229408A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "src\Kyoo.Authentication\Kyoo.Authentication.csproj", "{7A841335-6523-47DB-9717-80AA7BD943FD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.SqLite", "src\Kyoo.SqLite\Kyoo.SqLite.csproj", "{6515380E-1E57-42DA-B6E3-E1C8A848818A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.TheTvdb", "src\Kyoo.TheTvdb\Kyoo.TheTvdb.csproj", "{D06BF829-23F5-40F3-A62D-627D9F4B4D6C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.TheMovieDb", "src\Kyoo.TheMovieDb\Kyoo.TheMovieDb.csproj", "{BAB270D4-E0EA-4329-BA65-512FDAB01001}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Tests\Kyoo.Tests.csproj", "{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WebApp", "src\Kyoo.WebApp\Kyoo.WebApp.csproj", "{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host.WindowsTrait", "src\Kyoo.Host.WindowsTrait\Kyoo.Host.WindowsTrait.csproj", "{98851001-40DD-46A6-94B3-2F8D90722076}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host.Console", "src\Kyoo.Host.Console\Kyoo.Host.Console.csproj", "{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FEAE1B0E-D797-470F-9030-0EF743575ECC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{8D28F5EF-0CD7-4697-A2A7-24EC31A48F21}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Databases", "Databases", "{865461CA-EC06-4B42-91CF-8723B0A9BB67}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosts", "Hosts", "{C569FF25-7E01-484C-9F72-5B99845AD94B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host.Generic", "src\Kyoo.Host.Generic\Kyoo.Host.Generic.csproj", "{0938459E-2E2B-457F-8120-7D8CA93866A6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6F91B645-F785-46BB-9C4F-1EFC83E489B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6F91B645-F785-46BB-9C4F-1EFC83E489B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6F91B645-F785-46BB-9C4F-1EFC83E489B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6F91B645-F785-46BB-9C4F-1EFC83E489B6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D06BF829-23F5-40F3-A62D-627D9F4B4D6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D06BF829-23F5-40F3-A62D-627D9F4B4D6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D06BF829-23F5-40F3-A62D-627D9F4B4D6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D06BF829-23F5-40F3-A62D-627D9F4B4D6C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAB270D4-E0EA-4329-BA65-512FDAB01001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAB270D4-E0EA-4329-BA65-512FDAB01001}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAB270D4-E0EA-4329-BA65-512FDAB01001}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAB270D4-E0EA-4329-BA65-512FDAB01001}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98851001-40DD-46A6-94B3-2F8D90722076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98851001-40DD-46A6-94B3-2F8D90722076}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98851001-40DD-46A6-94B3-2F8D90722076}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98851001-40DD-46A6-94B3-2F8D90722076}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0938459E-2E2B-457F-8120-7D8CA93866A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5} = {FEAE1B0E-D797-470F-9030-0EF743575ECC}
|
||||
{BAB270D4-E0EA-4329-BA65-512FDAB01001} = {8D28F5EF-0CD7-4697-A2A7-24EC31A48F21}
|
||||
{D06BF829-23F5-40F3-A62D-627D9F4B4D6C} = {8D28F5EF-0CD7-4697-A2A7-24EC31A48F21}
|
||||
{6F91B645-F785-46BB-9C4F-1EFC83E489B6} = {865461CA-EC06-4B42-91CF-8723B0A9BB67}
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A} = {865461CA-EC06-4B42-91CF-8723B0A9BB67}
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A} = {865461CA-EC06-4B42-91CF-8723B0A9BB67}
|
||||
{D8658BEA-8949-45AC-BEBB-A4FFC4F800F5} = {C569FF25-7E01-484C-9F72-5B99845AD94B}
|
||||
{98851001-40DD-46A6-94B3-2F8D90722076} = {C569FF25-7E01-484C-9F72-5B99845AD94B}
|
||||
{0938459E-2E2B-457F-8120-7D8CA93866A6} = {C569FF25-7E01-484C-9F72-5B99845AD94B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
44
PRIVACY.md
Normal file
44
PRIVACY.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Privacy Policy for Kyoo
|
||||
|
||||
Effective Date: 2023-06-15
|
||||
|
||||
Thank you for using Kyoo. This Privacy Policy outlines how we collect, use, and protect your personal information when you use our service. We are committed to ensuring the privacy and security of your data. Please read this policy carefully to understand our practices regarding your information.
|
||||
|
||||
### 1. Information We Collect:
|
||||
|
||||
We collect and store only the email addresses you provide during the registration process. No other personal information is requested or stored.
|
||||
|
||||
### 2. Use of Personal Information:
|
||||
|
||||
We use your email address solely for the purpose of user authentication and login. We do not use, access, or share your email address with any third parties.
|
||||
|
||||
### 3. Data Storage and Security:
|
||||
|
||||
All personal information, limited to email addresses, is stored securely on our self-hosted servers. We take appropriate technical and organizational measures to protect against unauthorized access, alteration, disclosure, or destruction of your personal information.
|
||||
|
||||
### 4. Data Sharing:
|
||||
|
||||
We do not share any personal information, including email addresses, with any third parties. Your data remains confidential and is used only for the purposes stated in this Privacy Policy.
|
||||
|
||||
### 5. Account Deletion:
|
||||
|
||||
You have the right to delete your Kyoo account at any time. To do so, please click on the `Delete your account` button on the account's menu of the app/website. Upon account deletion, all associated personal information, including your email address, will be permanently and irreversibly removed from our servers.
|
||||
|
||||
### 6. Cookies and Tracking Technologies:
|
||||
|
||||
Kyoo does not use any cookies or tracking technologies to collect or store user information.
|
||||
|
||||
### 7. Legal Basis for Processing:
|
||||
|
||||
Our collection and processing of your email address is based on your consent, as it is necessary for the performance of the contract between you and Kyoo.
|
||||
|
||||
### 8. Changes to this Privacy Policy:
|
||||
|
||||
We may update this Privacy Policy from time to time. Any changes will be posted on this page, and the effective date will be indicated at the top of the policy. Please review this policy periodically for any updates.
|
||||
|
||||
### 9. Contact Us:
|
||||
|
||||
If you have any questions, concerns, or requests regarding this Privacy Policy or the processing of your personal information, please contact us at https://github.com/zoriya/kyoo/issues.
|
||||
|
||||
|
||||
By using Kyoo, you acknowledge and agree to the practices described in this Privacy Policy.
|
||||
182
README.md
182
README.md
@@ -1,96 +1,90 @@
|
||||
# <img width="24px" src="./icons/icon-256x256.png" alt="Kyoo"> Kyoo
|
||||
<p>
|
||||
<a href="https://github.com/AnonymusRaccoon/Kyoo/actions/workflows/build.yml"><img src="https://img.shields.io/github/workflow/status/AnonymusRaccoon/Kyoo/Build?style=flat-square" alt="Build status"></a>
|
||||
<a href="https://github.com/AnonymusRaccoon/Kyoo/actions/workflows/tests.yml"><img src="https://img.shields.io/github/workflow/status/AnonymusRaccoon/Kyoo/Testing?label=tests&style=flat-square" alt="Tests status"></a>
|
||||
<a href="https://github.com/users/AnonymusRaccoon/packages/container/package/kyoo"><img src="https://img.shields.io/github/workflow/status/AnonymusRaccoon/Kyoo/Docker?label=docker&style=flat-square" alt="Docker status"/></a>
|
||||
<a href="https://sonarcloud.io/dashboard?id=AnonymusRaccoon_Kyoo"><img src="https://img.shields.io/sonar/tests/AnonymusRaccoon_Kyoo?compact_message&server=https%3A%2F%2Fsonarcloud.io&style=flat-square" alt="Test report"></a>
|
||||
<a href="https://sonarcloud.io/dashboard?id=AnonymusRaccoon_Kyoo"><img src="https://img.shields.io/sonar/coverage/AnonymusRaccoon_Kyoo?server=https%3A%2F%2Fsonarcloud.io&style=flat-square" alt="Coverage"></a>
|
||||
<a href="./LICENSE"><img src="https://img.shields.io/github/license/AnonymusRaccoon/Kyoo?style=flat-square" alt="License"></a>
|
||||
# <img width="24px" src="./icons/icon-256x256.png" alt=""> Kyoo
|
||||
|
||||
Kyoo is a self-hosted media server focused on video content (Movies, Series & Anime). It is an alternative to Jellyfin or Plex.
|
||||
|
||||
It aims to have a low amount of maintenance needed (no folder structure required nor manual metadata edits). Media not being scanned correctly (even with weird names) is considered a bug.
|
||||
|
||||
Kyoo does not have a plugin system and aim to have every features built-in (see [#Features](#-features) for the list).
|
||||
|
||||

|
||||
|
||||
## 🌐 Getting Started
|
||||
|
||||
- **[Installation](./INSTALLING.md):** Basic installation guidelines, how to start Kyoo, enable OIDC or hardware transcoding.
|
||||
- **[Join the discord](https://discord.gg/E6Apw3aFaA):** Ask questions, talk about the development, feature you might want or bugs you might encounter.
|
||||
- **[API Documentation](https://kyoo.zoriya.dev/api/doc):** The API to integrate Kyoo with other services, if you have any questions, please ask on github or discord!
|
||||
- **[Contributing](./CONTRIBUTING.md):** Feel free to open issues, submit pull requests, and contribute to making Kyoo even better. We need you!
|
||||
|
||||
[](https://discord.gg/zpA74Qpvj5)
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- **Dynamic Transcoding:** Transcode your media to any quality, change on the fly with auto quality, and seek instantly without waiting for the transcoder.
|
||||
|
||||
- **Video Preview Thumbnails:** Simply hover the video's progress bar and see a preview of the video.
|
||||
|
||||
- **Meilisearch-Powered Search:** Advanced, typo-resilient search system powered by Meilisearch.
|
||||
|
||||
- **OIDC Connection:** Connect using any OIDC compliant service (Google, Discord, Authelia, you name it).
|
||||
|
||||
- **Watch List Scrubbing Support:** Your watch list is automatically synced to connected services (SIMKL and soon others [#351](https://github.com/zoriya/Kyoo/issues/351), [#352](https://github.com/zoriya/Kyoo/issues/352)). No need to manually mark episodes as watched.
|
||||
|
||||
- **Download and Offline Support:** Download videos to watch them without internet access, you progress will automatically be synced next time your devices goes online.
|
||||
|
||||
- **Enhanced Subtitle Support:** Subtitles are important, Kyoo supports SSA/ASS and uses the video's embedded fonts when available.
|
||||
|
||||
- **Anime Name Parsing**: While there are still some issues (see [#466](https://github.com/zoriya/Kyoo/issues/466), Kyoo will match weird anime names (like `[Some-Stuffs] Jojo's Bizarre Adventure Stone Ocean 24 (1920x1080 Blu-Ray Opus) [2750810F].mkv`) without issue.
|
||||
|
||||
- **Cloud Native:** Still an ongoing effort (see [#357](https://github.com/zoriya/Kyoo/issues/357)) but Kyoo is made with the idea that it could run distributed or standalone, on an RPI or on huge home-datacenters.
|
||||
|
||||
## 📺 Clients
|
||||
|
||||
Clients is a bit part of media servers but for now, Kyoo's focus is on features. Only a web version and an android apps are available for now. The front is written with react-native (expo) so adapting for others platform is possible. Here is a rough roadmap of clients supports:
|
||||
- Today: Web & Android
|
||||
- End of 2024: Chromecast support
|
||||
- Summer 2025: Android TV app
|
||||
|
||||
Apple devices are not planned for now because I do not own any of their device, and it requires $100/year.
|
||||
|
||||
If you would like to have a client sooner or on devices not listed on the roadmap, come hang on the discord and consider contributing to Kyoo.
|
||||
|
||||
## 📖 Translations
|
||||
|
||||
If Kyoo is not available on your language, you can use [weblate](https://hosted.weblate.org/engage/kyoo/) to add translations easily.
|
||||
|
||||
[](https://hosted.weblate.org/engage/kyoo/)
|
||||
|
||||
## 📜 Why another media-browser?
|
||||
|
||||
From a technical standpoint, both Jellyfin and Plex lean on SQLite and confine everything within a single container, Kyoo takes a different route. We're not afraid to bring in additional containers when it makes sense – whether for specialized features like Meilisearch powering our search system or for scalability, as seen with our transcoder.
|
||||
|
||||
Kyoo embraces the "setup once, forget about it" philosophy. Unlike Plex and Jellyfin, we don't burden you with manual file renaming or specific folder structures. Kyoo seamlessly works with files straight from your download directory, minimizing the maintenance headache for server admins.
|
||||
|
||||
Kyoo narrows its focus to movies, TV shows, and anime streaming. No music, ebooks, or games – just pure cinematic delight.
|
||||
|
||||
## 🔗 Live Demo
|
||||
|
||||
Curious to see Kyoo in action? Check out our live demo featuring copyright-free movies at [kyoo.zoriya.dev](https://kyoo.zoriya.dev). Special thanks to the Blender Studio for providing open-source movies available for all.
|
||||
|
||||
## 👀 Screens
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
<p align="center">
|
||||
<img
|
||||
src="https://raw.githubusercontent.com/zoriya/kyoo/screens/android-movie.png"
|
||||
alt="Android Movie"
|
||||
width="350"
|
||||
/>
|
||||
</p>
|
||||
Ready to elevate your streaming experience? Dive into Kyoo now! 🎬🎉
|
||||
|
||||
Kyoo is an open-source media browser which allow you to stream your movies, tv-shows or anime.
|
||||
It is an alternative to Plex, Emby or Jellyfin.
|
||||
|
||||
Kyoo has been created from scratch, it is not a fork. Everything is and always will be free and open-source.
|
||||
|
||||
Feel free to open issues or pull requests, all contribution are welcomed.
|
||||
|
||||
## Getting started
|
||||
|
||||
- [Installation](https://docs.kyoo.moe/start/install.html)
|
||||
- [Setting Up](https://docs.kyoo.moe/start/setting_up.html)
|
||||
- [Api Documentation](https://demo.kyoo.moe/redoc)
|
||||
- [Documentation (work in progress)](https://docs.kyoo.moe)
|
||||
- [Contributing](./CONTRIBUTING.md)
|
||||
|
||||
## Features
|
||||
- Manage your movies, tv-series & anime
|
||||
- Download metadata automatically
|
||||
- Transmux files to make them available on every platform (Transcode coming soon)
|
||||
- Account system with a permission system
|
||||
- Handle subtitles natively with embedded fonts (ass, subrip or vtt)
|
||||
- Entirely free and works without internet (when metadata have already been downloaded)
|
||||
- Works on Linux, Windows, Docker and probably Mac
|
||||
- A powerful plugin system
|
||||
|
||||
## Live Demo
|
||||
|
||||
You can see a live demo with copyright-free movies here: [demo.kyoo.moe](https://demo.kyoo.moe).
|
||||
Thanks to the [blender studio](https://www.blender.org/about/studio/) for providing open-source movies available for all.
|
||||
|
||||
The demo server is simply created using the following docker compose:
|
||||
|
||||
```yml
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
kyoo:
|
||||
image: ghcr.io/anonymusraccoon/kyoo:master
|
||||
restart: on-failure
|
||||
environment:
|
||||
- KYOO_DATADIR=/var/lib/kyoo
|
||||
- BASICS__PUBLICURL=https://demo.kyoo.moe
|
||||
- BASICS__MetadataInShow=false
|
||||
- DATABASE__ENABLED=postgres
|
||||
- DATABASE__CONFIGURATIONS__POSTGRES__SERVER=postgres
|
||||
- DATABASE__CONFIGURATIONS__POSTGRES__USER ID=kyoo
|
||||
- DATABASE__CONFIGURATIONS__POSTGRES__PASSWORD=kyooPassword
|
||||
- TVDB__APIKEY=TheTvDbApiKey
|
||||
- THE-MOVIEDB__APIKEY=TheMovieDbApiKey
|
||||
ports:
|
||||
- "80:5000"
|
||||
depends_on:
|
||||
- postgres
|
||||
volumes:
|
||||
- kyoo:/var/lib/kyoo
|
||||
- video:/video
|
||||
postgres:
|
||||
image: "postgres"
|
||||
restart: on-failure
|
||||
environment:
|
||||
- POSTGRES_USER=kyoo
|
||||
- POSTGRES_PASSWORD=kyooPassword
|
||||
volumes:
|
||||
- db:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
kyoo:
|
||||
video:
|
||||
db:
|
||||
```
|
||||
|
||||
## Screens
|
||||
|
||||

|
||||
- - -
|
||||

|
||||
- - -
|
||||

|
||||
- - -
|
||||

|
||||
- - -
|
||||

|
||||
- - -
|
||||

|
||||
- - -
|
||||

|
||||
<!-- vim: set wrap: -->
|
||||
|
||||
1
autosync/.gitignore
vendored
Normal file
1
autosync/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
__pycache__
|
||||
8
autosync/Dockerfile
Normal file
8
autosync/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM python:3.12
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./requirements.txt .
|
||||
RUN pip3 install -r ./requirements.txt
|
||||
|
||||
COPY . .
|
||||
ENTRYPOINT ["python3", "-m", "autosync"]
|
||||
11
autosync/autosync/__init__.py
Normal file
11
autosync/autosync/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
async def main():
|
||||
import logging
|
||||
from autosync.services.simkl import Simkl
|
||||
from autosync.services.aggregate import Aggregate
|
||||
from autosync.consumer import Consumer
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
service = Aggregate([Simkl()])
|
||||
async with Consumer() as consumer:
|
||||
await consumer.listen(service)
|
||||
6
autosync/autosync/__main__.py
Normal file
6
autosync/autosync/__main__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import asyncio
|
||||
import autosync
|
||||
|
||||
asyncio.run(autosync.main())
|
||||
51
autosync/autosync/consumer.py
Normal file
51
autosync/autosync/consumer.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import asyncio
|
||||
from msgspec import json
|
||||
import os
|
||||
from logging import getLogger
|
||||
from aio_pika import ExchangeType, connect_robust
|
||||
from aio_pika.abc import AbstractIncomingMessage
|
||||
|
||||
from autosync.services.service import Service
|
||||
from autosync.models.message import Message
|
||||
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class Consumer:
|
||||
QUEUE = "autosync"
|
||||
|
||||
async def __aenter__(self):
|
||||
self._con = await connect_robust(
|
||||
host=os.environ.get("RABBITMQ_HOST", "rabbitmq"),
|
||||
port=int(os.environ.get("RABBITMQ_PORT", "5672")),
|
||||
login=os.environ.get("RABBITMQ_DEFAULT_USER", "guest"),
|
||||
password=os.environ.get("RABBITMQ_DEFAULT_PASS", "guest"),
|
||||
)
|
||||
self._channel = await self._con.channel()
|
||||
self._exchange = await self._channel.declare_exchange(
|
||||
"events.watched", type=ExchangeType.TOPIC
|
||||
)
|
||||
self._queue = await self._channel.declare_queue(self.QUEUE)
|
||||
await self._queue.bind(self._exchange, routing_key="#")
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_value, exc_tb):
|
||||
await self._con.close()
|
||||
|
||||
async def listen(self, service: Service):
|
||||
async def on_message(message: AbstractIncomingMessage):
|
||||
try:
|
||||
msg = json.decode(message.body, type=Message)
|
||||
service.update(msg.value.user, msg.value.resource, msg.value)
|
||||
await message.ack()
|
||||
except Exception as e:
|
||||
logger.exception("Unhandled error", exc_info=e)
|
||||
await message.reject()
|
||||
|
||||
# Allow up to 20 requests to run in parallel on the same listener.
|
||||
# Since most work is calling API not doing that is a waste.
|
||||
await self._channel.set_qos(prefetch_count=20)
|
||||
await self._queue.consume(on_message)
|
||||
logger.info("Listening for autosync.")
|
||||
await asyncio.Future()
|
||||
12
autosync/autosync/models/episode.py
Normal file
12
autosync/autosync/models/episode.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from msgspec import Struct
|
||||
from autosync.models.show import Show
|
||||
|
||||
from .metadataid import EpisodeID
|
||||
|
||||
|
||||
class Episode(Struct, rename="camel", tag_field="kind", tag="episode"):
|
||||
external_id: dict[str, EpisodeID]
|
||||
show: Show
|
||||
season_number: int
|
||||
episode_number: int
|
||||
absolute_number: int
|
||||
17
autosync/autosync/models/message.py
Normal file
17
autosync/autosync/models/message.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from msgspec import Struct
|
||||
from autosync.models.episode import Episode
|
||||
from autosync.models.movie import Movie
|
||||
from autosync.models.show import Show
|
||||
from autosync.models.user import User
|
||||
from autosync.models.watch_status import WatchStatus
|
||||
|
||||
|
||||
class WatchStatusMessage(WatchStatus):
|
||||
user: User
|
||||
resource: Movie | Show | Episode
|
||||
|
||||
|
||||
class Message(Struct, rename="camel"):
|
||||
action: str
|
||||
type: str
|
||||
value: WatchStatusMessage
|
||||
14
autosync/autosync/models/metadataid.py
Normal file
14
autosync/autosync/models/metadataid.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from msgspec import Struct
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class MetadataID(Struct, rename="camel"):
|
||||
data_id: str
|
||||
link: Optional[str]
|
||||
|
||||
|
||||
class EpisodeID(Struct, rename="camel"):
|
||||
show_id: str
|
||||
season: Optional[int]
|
||||
episode: int
|
||||
link: Optional[str]
|
||||
15
autosync/autosync/models/movie.py
Normal file
15
autosync/autosync/models/movie.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from typing import Optional
|
||||
from datetime import date
|
||||
from msgspec import Struct
|
||||
|
||||
from .metadataid import MetadataID
|
||||
|
||||
|
||||
class Movie(Struct, rename="camel", tag_field="kind", tag="movie"):
|
||||
name: str
|
||||
air_date: Optional[date]
|
||||
external_id: dict[str, MetadataID]
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
return self.air_date.year if self.air_date is not None else None
|
||||
15
autosync/autosync/models/show.py
Normal file
15
autosync/autosync/models/show.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from typing import Optional
|
||||
from datetime import date
|
||||
from msgspec import Struct
|
||||
|
||||
from .metadataid import MetadataID
|
||||
|
||||
|
||||
class Show(Struct, rename="camel", tag_field="kind", tag="show"):
|
||||
name: str
|
||||
start_air: Optional[date]
|
||||
external_id: dict[str, MetadataID]
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
return self.start_air.year if self.start_air is not None else None
|
||||
26
autosync/autosync/models/user.py
Normal file
26
autosync/autosync/models/user.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from msgspec import Struct
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class JwtToken(Struct):
|
||||
token_type: str
|
||||
access_token: str
|
||||
refresh_token: Optional[str]
|
||||
expire_at: datetime
|
||||
|
||||
|
||||
class ExternalToken(Struct, rename="camel"):
|
||||
id: str
|
||||
username: str
|
||||
profile_url: Optional[str]
|
||||
token: JwtToken
|
||||
|
||||
|
||||
class User(Struct, rename="camel", tag_field="kind", tag="user"):
|
||||
id: str
|
||||
username: str
|
||||
email: str
|
||||
permissions: list[str]
|
||||
settings: dict[str, str]
|
||||
external_id: dict[str, ExternalToken]
|
||||
21
autosync/autosync/models/watch_status.py
Normal file
21
autosync/autosync/models/watch_status.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
|
||||
from msgspec import Struct
|
||||
|
||||
|
||||
class Status(str, Enum):
|
||||
COMPLETED = "Completed"
|
||||
WATCHING = "Watching"
|
||||
DROPED = "Droped"
|
||||
PLANNED = "Planned"
|
||||
DELETED = "Deleted"
|
||||
|
||||
|
||||
class WatchStatus(Struct, rename="camel"):
|
||||
added_date: datetime
|
||||
played_date: Optional[datetime]
|
||||
status: Status
|
||||
watched_time: Optional[int]
|
||||
watched_percent: Optional[int]
|
||||
28
autosync/autosync/services/aggregate.py
Normal file
28
autosync/autosync/services/aggregate.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from logging import getLogger
|
||||
from autosync.services.service import Service
|
||||
from ..models.user import User
|
||||
from ..models.show import Show
|
||||
from ..models.movie import Movie
|
||||
from ..models.episode import Episode
|
||||
from ..models.watch_status import WatchStatus
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class Aggregate(Service):
|
||||
def __init__(self, services: list[Service]):
|
||||
self._services = [x for x in services if x.enabled]
|
||||
logger.info("Autosync enabled with %s", [x.name for x in self._services])
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "aggragate"
|
||||
|
||||
def update(self, user: User, resource: Movie | Show | Episode, status: WatchStatus):
|
||||
for service in self._services:
|
||||
try:
|
||||
service.update(user, resource, status)
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
"Unhandled error on autosync %s:", service.name, exc_info=e
|
||||
)
|
||||
21
autosync/autosync/services/service.py
Normal file
21
autosync/autosync/services/service.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from abc import abstractmethod, abstractproperty
|
||||
|
||||
from ..models.user import User
|
||||
from ..models.show import Show
|
||||
from ..models.movie import Movie
|
||||
from ..models.episode import Episode
|
||||
from ..models.watch_status import WatchStatus
|
||||
|
||||
|
||||
class Service:
|
||||
@abstractproperty
|
||||
def name(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractproperty
|
||||
def enabled(self) -> bool:
|
||||
return True
|
||||
|
||||
@abstractmethod
|
||||
def update(self, user: User, resource: Movie | Show | Episode, status: WatchStatus):
|
||||
raise NotImplementedError
|
||||
117
autosync/autosync/services/simkl.py
Normal file
117
autosync/autosync/services/simkl.py
Normal file
@@ -0,0 +1,117 @@
|
||||
import os
|
||||
import requests
|
||||
from logging import getLogger
|
||||
from autosync.models.metadataid import MetadataID
|
||||
|
||||
from autosync.services.service import Service
|
||||
from ..models.user import User
|
||||
from ..models.show import Show
|
||||
from ..models.movie import Movie
|
||||
from ..models.episode import Episode
|
||||
from ..models.watch_status import WatchStatus, Status
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class Simkl(Service):
|
||||
def __init__(self) -> None:
|
||||
self._api_key = os.environ.get("OIDC_SIMKL_CLIENTID")
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "simkl"
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
return self._api_key is not None
|
||||
|
||||
def update(self, user: User, resource: Movie | Show | Episode, status: WatchStatus):
|
||||
if "simkl" not in user.external_id or self._api_key is None:
|
||||
return
|
||||
|
||||
watch_date = status.played_date or status.added_date
|
||||
|
||||
if isinstance(resource, Episode):
|
||||
if status.status != Status.COMPLETED:
|
||||
return
|
||||
|
||||
resp = requests.post(
|
||||
"https://api.simkl.com/sync/history",
|
||||
json={
|
||||
"shows": [
|
||||
{
|
||||
"watched_at": watch_date.isoformat(),
|
||||
"title": resource.show.name,
|
||||
"year": resource.show.year,
|
||||
"ids": self._map_external_ids(resource.show.external_id),
|
||||
"seasons": [
|
||||
{
|
||||
"number": resource.season_number,
|
||||
"episodes": [{"number": resource.episode_number}],
|
||||
},
|
||||
{
|
||||
"number": 1,
|
||||
"episodes": [{"number": resource.absolute_number}],
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
headers={
|
||||
"Authorization": f"Bearer {user.external_id['simkl'].token.access_token}",
|
||||
"simkl-api-key": self._api_key,
|
||||
},
|
||||
)
|
||||
logger.info("Simkl response: %s %s", resp.status_code, resp.text)
|
||||
return
|
||||
|
||||
category = "movies" if isinstance(resource, Movie) else "shows"
|
||||
|
||||
simkl_status = self._map_status(status.status)
|
||||
if simkl_status is None:
|
||||
return
|
||||
|
||||
resp = requests.post(
|
||||
"https://api.simkl.com/sync/add-to-list",
|
||||
json={
|
||||
category: [
|
||||
{
|
||||
"to": simkl_status,
|
||||
"watched_at": watch_date.isoformat()
|
||||
if status.status == Status.COMPLETED
|
||||
else None,
|
||||
"title": resource.name,
|
||||
"year": resource.year,
|
||||
"ids": self._map_external_ids(resource.external_id),
|
||||
}
|
||||
]
|
||||
},
|
||||
headers={
|
||||
"Authorization": f"Bearer {user.external_id['simkl'].token.access_token}",
|
||||
"simkl-api-key": self._api_key,
|
||||
},
|
||||
)
|
||||
logger.info("Simkl response: %s %s", resp.status_code, resp.text)
|
||||
|
||||
def _map_status(self, status: Status):
|
||||
match status:
|
||||
case Status.COMPLETED:
|
||||
return "completed"
|
||||
case Status.WATCHING:
|
||||
return "watching"
|
||||
case Status.COMPLETED:
|
||||
return "completed"
|
||||
case Status.PLANNED:
|
||||
return "plantowatch"
|
||||
case Status.DELETED:
|
||||
# do not delete items on simkl, most of deleted status are for a rewatch.
|
||||
return None
|
||||
case _:
|
||||
return None
|
||||
|
||||
def _map_external_ids(self, ids: dict[str, MetadataID]):
|
||||
return {service: id.data_id for service, id in ids.items()} | {
|
||||
"tmdb": int(ids["themoviedatabase"].data_id)
|
||||
if "themoviedatabase" in ids
|
||||
else None
|
||||
}
|
||||
2
autosync/pyproject.toml
Normal file
2
autosync/pyproject.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[tool.ruff.format]
|
||||
indent-style = "tab"
|
||||
3
autosync/requirements.txt
Normal file
3
autosync/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
aio-pika
|
||||
msgspec
|
||||
requests
|
||||
18
back/.config/dotnet-tools.json
Normal file
18
back/.config/dotnet-tools.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "8.0.6",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
},
|
||||
"csharpier": {
|
||||
"version": "0.28.2",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
17
back/.dockerignore
Normal file
17
back/.dockerignore
Normal file
@@ -0,0 +1,17 @@
|
||||
Dockerfile
|
||||
Dockerfile.dev
|
||||
Dockerfile.*
|
||||
.dockerignore
|
||||
.gitignore
|
||||
docker-compose.yml
|
||||
README.md
|
||||
**/build
|
||||
**/dist
|
||||
**/bin
|
||||
**/obj
|
||||
out
|
||||
docs
|
||||
tests
|
||||
front
|
||||
video
|
||||
nginx.conf.template
|
||||
99
back/.editorconfig
Normal file
99
back/.editorconfig
Normal file
@@ -0,0 +1,99 @@
|
||||
root = false
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = tab
|
||||
smart_tab = true
|
||||
|
||||
[*.cs]
|
||||
csharp_prefer_braces = false
|
||||
dotnet_diagnostic.IDE0046.severity = none
|
||||
dotnet_diagnostic.IDE0055.severity = none
|
||||
dotnet_diagnostic.IDE0058.severity = none
|
||||
dotnet_diagnostic.IDE0130.severity = none
|
||||
|
||||
# Convert to file-scoped namespace
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
csharp_using_directive_placement = outside_namespace:warning
|
||||
# Avoid "this." if not necessary
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
# Use language keywords instead of framework type names for type references
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
# Suggest more modern language features when available
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
# Disable strange throw.
|
||||
csharp_style_throw_expression = false:suggestion
|
||||
# Forbid "var" everywhere
|
||||
csharp_style_var_for_built_in_types = false:suggestion
|
||||
csharp_style_var_when_type_is_apparent = false:suggestion
|
||||
csharp_style_var_elsewhere = false:suggestion
|
||||
# Prefer method-like constructs to have a block body
|
||||
csharp_style_expression_bodied_methods = false:none
|
||||
csharp_style_expression_bodied_constructors = false:none
|
||||
csharp_style_expression_bodied_operators = false:none
|
||||
# Prefer property-like constructs to have an expression-body
|
||||
csharp_style_expression_bodied_properties = true:none
|
||||
csharp_style_expression_bodied_indexers = true:none
|
||||
csharp_style_expression_bodied_accessors = true:none
|
||||
# Newline settings
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = false
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
# Indentation settings
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
# Modifiers
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
|
||||
# Naming style
|
||||
dotnet_naming_symbols.privates.applicable_kinds = property,method,event,delegate
|
||||
dotnet_naming_symbols.privates.applicable_accessibilities = private
|
||||
dotnet_naming_style.underscore_pascal.capitalization = pascal_case
|
||||
dotnet_naming_style.underscore_pascal.required_prefix = _
|
||||
dotnet_naming_rule.privates_with_underscore.symbols = privates
|
||||
dotnet_naming_rule.privates_with_underscore.style = underscore_pascal
|
||||
dotnet_naming_rule.privates_with_underscore.severity = warning
|
||||
dotnet_diagnostic.IDE1006.severity = warning
|
||||
# ReSharper properties
|
||||
resharper_align_multiline_binary_expressions_chain = false
|
||||
resharper_csharp_empty_block_style = together_same_line
|
||||
resharper_indent_nested_foreach_stmt = true
|
||||
resharper_indent_nested_for_stmt = true
|
||||
resharper_indent_nested_while_stmt = true
|
||||
resharper_keep_existing_embedded_arrangement = false
|
||||
resharper_place_accessorholder_attribute_on_same_line = true
|
||||
resharper_place_simple_embedded_statement_on_same_line = false
|
||||
resharper_wrap_before_arrow_with_expressions = true
|
||||
resharper_xmldoc_attribute_indent = align_by_first_attribute
|
||||
resharper_xmldoc_indent_child_elements = RemoveIndent
|
||||
resharper_xmldoc_indent_text = RemoveIndent
|
||||
# Switch on enum
|
||||
dotnet_diagnostic.CS8509.severity=error # missing switch case for named enum value
|
||||
dotnet_diagnostic.CS8524.severity=none # missing switch case for unnamed enum value
|
||||
|
||||
# Waiting for https://github.com/dotnet/roslyn/issues/44596 to get fixed.
|
||||
# file_header_template = Kyoo - A portable and vast media library solution.\nCopyright (c) Kyoo.\n\nSee AUTHORS.md and LICENSE file in the project root for full license information.\n\nKyoo is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\nany later version.\n\nKyoo is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
352
back/.gitignore
vendored
Normal file
352
back/.gitignore
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
out
|
||||
libtranscoder.so
|
||||
libtranscoder.dylib
|
||||
transcoder.dll
|
||||
kyoo_datadir
|
||||
|
||||
video
|
||||
.env
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- Backup*.rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
/Kyoo/TheTVDB-Credentials.json
|
||||
|
||||
.vscode
|
||||
.netcoredbg_hist
|
||||
29
back/Dockerfile
Normal file
29
back/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 as builder
|
||||
ARG TARGETARCH
|
||||
WORKDIR /kyoo
|
||||
|
||||
COPY Kyoo.sln ./Kyoo.sln
|
||||
COPY nuget.config ./nuget.config
|
||||
COPY src/Directory.Build.props src/Directory.Build.props
|
||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||
RUN dotnet restore -a $TARGETARCH
|
||||
|
||||
COPY . .
|
||||
ARG VERSION
|
||||
RUN dotnet publish -a $TARGETARCH --no-restore -c Release -o /app "-p:Version=${VERSION:-"0.0.0-dev"}" src/Kyoo.Core
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||
RUN apt-get update && apt-get install -y curl
|
||||
COPY --from=builder /app /app
|
||||
|
||||
WORKDIR /app
|
||||
EXPOSE 5000
|
||||
# The back can take a long time to start if meilisearch is initializing
|
||||
HEALTHCHECK --interval=5s --retries=15 CMD curl --fail http://localhost:5000/health || exit
|
||||
ENTRYPOINT ["/app/kyoo"]
|
||||
22
back/Dockerfile.dev
Normal file
22
back/Dockerfile.dev
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0
|
||||
RUN apt-get update && apt-get install -y curl
|
||||
WORKDIR /app
|
||||
|
||||
COPY Kyoo.sln ./Kyoo.sln
|
||||
COPY nuget.config ./nuget.config
|
||||
COPY src/Directory.Build.props src/Directory.Build.props
|
||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||
RUN dotnet restore
|
||||
|
||||
WORKDIR /app
|
||||
EXPOSE 5000
|
||||
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
|
||||
# HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit
|
||||
HEALTHCHECK CMD true
|
||||
ENTRYPOINT ["dotnet", "watch", "--non-interactive", "run", "--no-restore", "--project", "/app/src/Kyoo.Core"]
|
||||
30
back/Dockerfile.migrations
Normal file
30
back/Dockerfile.migrations
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 as builder
|
||||
ARG TARGETARCH
|
||||
WORKDIR /kyoo
|
||||
|
||||
COPY .config/dotnet-tools.json .config/dotnet-tools.json
|
||||
RUN dotnet tool restore
|
||||
|
||||
COPY Kyoo.sln ./Kyoo.sln
|
||||
COPY nuget.config ./nuget.config
|
||||
COPY src/Directory.Build.props src/Directory.Build.props
|
||||
COPY src/Kyoo.Authentication/Kyoo.Authentication.csproj src/Kyoo.Authentication/Kyoo.Authentication.csproj
|
||||
COPY src/Kyoo.Abstractions/Kyoo.Abstractions.csproj src/Kyoo.Abstractions/Kyoo.Abstractions.csproj
|
||||
COPY src/Kyoo.Core/Kyoo.Core.csproj src/Kyoo.Core/Kyoo.Core.csproj
|
||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||
COPY src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj src/Kyoo.RabbitMq/Kyoo.RabbitMq.csproj
|
||||
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||
RUN dotnet restore -a $TARGETARCH
|
||||
|
||||
COPY . .
|
||||
RUN dotnet build
|
||||
RUN dotnet ef migrations bundle \
|
||||
--msbuildprojectextensionspath out/obj/Kyoo.Postgresql \
|
||||
--no-build --self-contained -r linux-${TARGETARCH} -f \
|
||||
-o /app/migrate -p src/Kyoo.Postgresql --verbose
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0
|
||||
COPY --from=builder /app/migrate /app/migrate
|
||||
|
||||
ENTRYPOINT ["/app/migrate"]
|
||||
@@ -2,6 +2,7 @@
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.MaintainabilityRules">
|
||||
<Rule Id="SA1413" Action="None" /> <!-- UseTrailingCommasInMultiLineInitializers -->
|
||||
<Rule Id="SA1414" Action="None" /> <!-- UseTrailingCommasInMultiLineInitializers -->
|
||||
<Rule Id="SA1114" Action="None" /> <!-- UseTrailingCommasInMultiLineInitializers -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.OrderingRules">
|
||||
<Rule Id="SA1201" Action="None" /> <!-- ElementsMustAppearInTheCorrectOrder -->
|
||||
@@ -27,18 +28,20 @@
|
||||
<Rule Id="SA1027" Action="None"/> <!-- UseTabsCorrectly (smarts tabs are broken). TODO find a way to enable smart tabs -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.LayoutRules">
|
||||
<Rule Id="SA1402" Action="None"/> <!-- SingleClassPerFile -->
|
||||
<Rule Id="SA1649" Action="None"/> <!-- Class name must be filename -->
|
||||
<Rule Id="SA1503" Action="None"/> <!-- BracesMustNotBeOmitted -->
|
||||
<Rule Id="SA1512" Action="None"/> <!-- Let me comment -->
|
||||
<Rule Id="SA1520" Action="None"/> <!-- UseBracesConsistently -->
|
||||
<Rule Id="SA1515" Action="None"/> <!-- SingleLineCommentMustBePrecededByBlankLine -->
|
||||
<Rule Id="SA1513" Action="None"/> <!-- ClosingBraceMustBeFollowedByBlankLine -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.DocumentationRules">
|
||||
<Rule Id="SA1600" Action="None" /> <!-- Elements Shuld be Documented -->
|
||||
<Rule Id="SA1602" Action="None" /> <!-- Enums should be documented -->
|
||||
<Rule Id="SA1642" Action="None" /> <!-- ConstructorSummaryDocumentationMustBeginWithStandardText -->
|
||||
<Rule Id="SA1643" Action="None" /> <!-- DestructorSummaryDocumentationMustBeginWithStandardText -->
|
||||
<Rule Id="SA1623" Action="None" /> <!-- PropertySummaryDocumentationMustMatchAccessors -->
|
||||
|
||||
|
||||
|
||||
<Rule Id="SA1629" Action="None" /> <!-- DocumentationTextMustEndWithAPeriod TODO remove this, this is only temporary -->
|
||||
<Rule Id="SA1629" Action="None" /> <!-- DocumentationTextMustEndWithAPeriod -->
|
||||
</Rules>
|
||||
</RuleSet>
|
||||
64
back/Kyoo.sln
Normal file
64
back/Kyoo.sln
Normal file
@@ -0,0 +1,64 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
#
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kyoo.Core", "src\Kyoo.Core\Kyoo.Core.csproj", "{0F8275B6-C7DD-42DF-A168-755C81B1C329}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Abstractions", "src\Kyoo.Abstractions\Kyoo.Abstractions.csproj", "{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "src\Kyoo.Postgresql\Kyoo.Postgresql.csproj", "{3213C96D-0BF3-460B-A8B5-B9977229408A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "src\Kyoo.Authentication\Kyoo.Authentication.csproj", "{7A841335-6523-47DB-9717-80AA7BD943FD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.RabbitMq", "src\Kyoo.RabbitMq\Kyoo.RabbitMq.csproj", "{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0F8275B6-C7DD-42DF-A168-755C81B1C329}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAB2CAE1-AC28-4509-AA3E-8DC75BD59220}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3213C96D-0BF3-460B-A8B5-B9977229408A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7A841335-6523-47DB-9717-80AA7BD943FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7D1A7596-73F6-4D35-842E-A5AD9C620596}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B97AD4A8-E6E6-41CD-87DF-5F1326FD7198}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
4
back/ef.rsp
Normal file
4
back/ef.rsp
Normal file
@@ -0,0 +1,4 @@
|
||||
--project
|
||||
src/Kyoo.Postgresql
|
||||
--msbuildprojectextensionspath
|
||||
out/obj/Kyoo.Postgresql
|
||||
BIN
back/icon.ico
Normal file
BIN
back/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
14
back/nuget.config
Normal file
14
back/nuget.config
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear/>
|
||||
<add key="feedz" value="https://f.feedz.io/zoriya/entityframeworkcore-projectables/nuget/index.json"/>
|
||||
<add key="nuget" value="https://api.nuget.org/v3/index.json"/>
|
||||
</packageSources>
|
||||
<disabledPackageSources>
|
||||
<clear/>
|
||||
</disabledPackageSources>
|
||||
<fallbackPackageFolders>
|
||||
<clear/>
|
||||
</fallbackPackageFolders>
|
||||
</configuration>
|
||||
47
back/src/Directory.Build.props
Normal file
47
back/src/Directory.Build.props
Normal file
@@ -0,0 +1,47 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<LangVersion>default</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Company>Kyoo</Company>
|
||||
<Authors>Kyoo</Authors>
|
||||
<Copyright>Copyright (c) Kyoo</Copyright>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||
<RequireLicenseAcceptance>true</RequireLicenseAcceptance>
|
||||
|
||||
<RepositoryUrl>https://github.com/zoriya/Kyoo</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/zoriya/Kyoo</PackageProjectUrl>
|
||||
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
|
||||
<ApplicationIcon>$(MSBuildThisFileDirectory)../icon.ico</ApplicationIcon>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CheckCodingStyle Condition="$(CheckCodingStyle) == ''">true</CheckCodingStyle>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BaseIntermediateOutputPath>$(MsBuildThisFileDirectory)/../out/obj/$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<BaseOutputPath>$(MsBuildThisFileDirectory)/../out/bin/$(MSBuildProjectName)</BaseOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="$(CheckCodingStyle) == true">
|
||||
<None Include="$(MSBuildThisFileDirectory)../.editorconfig" Link=".editorconfig" Visible="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="$(CheckCodingStyle) == true">
|
||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)../Kyoo.ruleset</CodeAnalysisRuleSet>
|
||||
<NoWarn>1591;1305;8618;SYSLIB1045;CS1573</NoWarn>
|
||||
<!-- <AnalysisMode>All</AnalysisMode> -->
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- vim: ft=xml -->
|
||||
</Project>
|
||||
35
back/src/Kyoo.Abstractions/Controllers/IIssueRepository.cs
Normal file
35
back/src/Kyoo.Abstractions/Controllers/IIssueRepository.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
public interface IIssueRepository
|
||||
{
|
||||
Task<ICollection<Issue>> GetAll(Filter<Issue>? filter = default);
|
||||
|
||||
Task<int> GetCount(Filter<Issue>? filter = default);
|
||||
|
||||
Task<Issue> Upsert(Issue issue);
|
||||
|
||||
Task DeleteAll(Filter<Issue>? filter = default);
|
||||
}
|
||||
80
back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
Normal file
80
back/src/Kyoo.Abstractions/Controllers/ILibraryManager.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// An interface to interact with the database. Every repository is mapped through here.
|
||||
/// </summary>
|
||||
public interface ILibraryManager
|
||||
{
|
||||
IRepository<T> Repository<T>()
|
||||
where T : IResource, IQuery;
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle libraries items (a wrapper around shows and collections).
|
||||
/// </summary>
|
||||
IRepository<ILibraryItem> LibraryItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle new items.
|
||||
/// </summary>
|
||||
IRepository<INews> News { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle watched items.
|
||||
/// </summary>
|
||||
IWatchStatusRepository WatchStatus { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle collections.
|
||||
/// </summary>
|
||||
IRepository<Collection> Collections { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle shows.
|
||||
/// </summary>
|
||||
IRepository<Movie> Movies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle shows.
|
||||
/// </summary>
|
||||
IRepository<Show> Shows { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle seasons.
|
||||
/// </summary>
|
||||
IRepository<Season> Seasons { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle episodes.
|
||||
/// </summary>
|
||||
IRepository<Episode> Episodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle studios.
|
||||
/// </summary>
|
||||
IRepository<Studio> Studios { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle users.
|
||||
/// </summary>
|
||||
IRepository<User> Users { get; }
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// A service to validate permissions.
|
||||
/// </summary>
|
||||
public interface IPermissionValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The permission attribute to validate.</param>
|
||||
/// <returns>An authorization filter used to validate the permission.</returns>
|
||||
IFilterMetadata Create(PermissionAttribute attribute);
|
||||
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// A partial attribute to validate. See <see cref="PartialPermissionAttribute"/>.
|
||||
/// </param>
|
||||
/// <returns>An authorization filter used to validate the permission.</returns>
|
||||
IFilterMetadata Create(PartialPermissionAttribute attribute);
|
||||
}
|
||||
267
back/src/Kyoo.Abstractions/Controllers/IRepository.cs
Normal file
267
back/src/Kyoo.Abstractions/Controllers/IRepository.cs
Normal file
@@ -0,0 +1,267 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// A common repository for every resources.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The resource's type that this repository manage.</typeparam>
|
||||
public interface IRepository<T> : IBaseRepository
|
||||
where T : IResource, IQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// The event handler type for all events of this repository.
|
||||
/// </summary>
|
||||
/// <param name="resource">The resource created/modified/deleted</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
public delegate Task ResourceEventHandler(T resource);
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the resource</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T> Get(Guid id, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's slug.
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the resource</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T> Get(string slug, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the first resource that match the predicate.
|
||||
/// </summary>
|
||||
/// <param name="filter">A predicate to filter the resource.</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||
/// <param name="reverse">Reverse the sort.</param>
|
||||
/// <param name="afterId">Select the first element after this id if it was in a list.</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item could not be found.</exception>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T> Get(
|
||||
Filter<T> filter,
|
||||
Include<T>? include = default,
|
||||
Sort<T>? sortBy = default,
|
||||
bool reverse = false,
|
||||
Guid? afterId = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's ID or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the resource</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T?> GetOrDefault(Guid id, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's slug or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the resource</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T?> GetOrDefault(string slug, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get the first resource that match the predicate or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="filter">A predicate to filter the resource.</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||
/// <param name="reverse">Reverse the sort.</param>
|
||||
/// <param name="afterId">Select the first element after this id if it was in a list.</param>
|
||||
/// <returns>The resource found</returns>
|
||||
Task<T?> GetOrDefault(
|
||||
Filter<T>? filter,
|
||||
Include<T>? include = default,
|
||||
Sort<T>? sortBy = default,
|
||||
bool reverse = false,
|
||||
Guid? afterId = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for resources with the database.
|
||||
/// </summary>
|
||||
/// <param name="query">The query string.</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources found</returns>
|
||||
Task<ICollection<T>> Search(string query, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get every resources that match all filters
|
||||
/// </summary>
|
||||
/// <param name="filter">A filter predicate</param>
|
||||
/// <param name="sort">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <param name="limit">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
Task<ICollection<T>> GetAll(
|
||||
Filter<T>? filter = null,
|
||||
Sort<T>? sort = default,
|
||||
Include<T>? include = default,
|
||||
Pagination? limit = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of resources that match the filter's predicate.
|
||||
/// </summary>
|
||||
/// <param name="filter">A filter predicate</param>
|
||||
/// <returns>How many resources matched that filter</returns>
|
||||
Task<int> GetCount(Filter<T>? filter = null);
|
||||
|
||||
/// <summary>
|
||||
/// Map a list of ids to a list of items (keep the order).
|
||||
/// </summary>
|
||||
/// <param name="ids">The list of items id.</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources mapped from ids.</returns>
|
||||
Task<ICollection<T>> FromIds(IList<Guid> ids, Include<T>? include = default);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new resource.
|
||||
/// </summary>
|
||||
/// <param name="obj">The item to register</param>
|
||||
/// <returns>The resource registers and completed by database's information (related items and so on)</returns>
|
||||
Task<T> Create(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to create</param>
|
||||
/// <returns>The newly created item or the existing value if it existed.</returns>
|
||||
Task<T> CreateIfNotExists(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a resource has been created.
|
||||
/// </summary>
|
||||
static event ResourceEventHandler OnCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been created.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly created.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceCreated(T obj) => OnCreated?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Edit a resource and replace every property
|
||||
/// </summary>
|
||||
/// <param name="edited">The resource to edit, it's ID can't change.</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The resource edited and completed by database's information (related items and so on)</returns>
|
||||
Task<T> Edit(T edited);
|
||||
|
||||
/// <summary>
|
||||
/// Edit only specific properties of a resource
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the resource to edit</param>
|
||||
/// <param name="patch">
|
||||
/// A method that will be called when you need to update every properties that you want to
|
||||
/// persist.
|
||||
/// </param>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The resource edited and completed by database's information (related items and so on)</returns>
|
||||
Task<T> Patch(Guid id, Func<T, T> patch);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a resource has been edited.
|
||||
/// </summary>
|
||||
static event ResourceEventHandler OnEdited;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been edited.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly edited.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceEdited(T obj) => OnEdited?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource by it's ID
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the resource</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource by it's slug
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the resource</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete(string slug);
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource to delete</param>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Delete all resources that match the predicate.
|
||||
/// </summary>
|
||||
/// <param name="filter">A predicate to filter resources to delete. Every resource that match this will be deleted.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task DeleteAll(Filter<T> filter);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a resource has been edited.
|
||||
/// </summary>
|
||||
static event ResourceEventHandler OnDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been deleted.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly deleted.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceDeleted(T obj) => OnDeleted?.Invoke(obj) ?? Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A base class for repositories. Every service implementing this will be handled by the <see cref="ILibraryManager"/>.
|
||||
/// </summary>
|
||||
public interface IBaseRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// The type for witch this repository is responsible or null if non applicable.
|
||||
/// </summary>
|
||||
Type RepositoryType { get; }
|
||||
}
|
||||
|
||||
public interface IUserRepository : IRepository<User>
|
||||
{
|
||||
Task<User?> GetByExternalId(string provider, string id);
|
||||
Task<User> AddExternalToken(Guid userId, string provider, ExternalToken token);
|
||||
Task<User> DeleteExternalToken(Guid userId, string provider);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
@@ -17,12 +17,12 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
public interface IScanner
|
||||
{
|
||||
/// <summary>
|
||||
/// Remove an property from the serialization pipeline. It will simply be skipped.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class SerializeIgnoreAttribute : Attribute { }
|
||||
Task SendRescanRequest();
|
||||
Task SendRefreshRequest(string kind, Guid id);
|
||||
}
|
||||
119
back/src/Kyoo.Abstractions/Controllers/ISearchManager.cs
Normal file
119
back/src/Kyoo.Abstractions/Controllers/ISearchManager.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// The service to search items.
|
||||
/// </summary>
|
||||
public interface ISearchManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Search for items.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<ILibraryItem>.SearchResult> SearchItems(
|
||||
string? query,
|
||||
Sort<ILibraryItem> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<ILibraryItem>? include = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for movies.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<Movie>.SearchResult> SearchMovies(
|
||||
string? query,
|
||||
Sort<Movie> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<Movie>? include = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for shows.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<Show>.SearchResult> SearchShows(
|
||||
string? query,
|
||||
Sort<Show> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<Show>? include = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for collections.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<Collection>.SearchResult> SearchCollections(
|
||||
string? query,
|
||||
Sort<Collection> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<Collection>? include = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for episodes.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<Episode>.SearchResult> SearchEpisodes(
|
||||
string? query,
|
||||
Sort<Episode> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<Episode>? include = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Search for studios.
|
||||
/// </summary>
|
||||
/// <param name="query">The seach query.</param>
|
||||
/// <param name="sortBy">Sort information about the query (sort by, sort order)</param>
|
||||
/// <param name="pagination">How pagination should be done (where to start and how many to return)</param>
|
||||
/// <param name="include">The related fields to include.</param>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
public Task<SearchPage<Studio>.SearchResult> SearchStudios(
|
||||
string? query,
|
||||
Sort<Studio> sortBy,
|
||||
SearchPagination pagination,
|
||||
Include<Studio>? include = default
|
||||
);
|
||||
}
|
||||
41
back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
Normal file
41
back/src/Kyoo.Abstractions/Controllers/IThumbnailsManager.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
public interface IThumbnailsManager
|
||||
{
|
||||
Task DownloadImages<T>(T item)
|
||||
where T : IThumbnails;
|
||||
|
||||
Task DownloadImage(Image? image, string what);
|
||||
|
||||
string GetImagePath(Guid imageId, ImageQuality quality);
|
||||
|
||||
Task DeleteImages<T>(T item)
|
||||
where T : IThumbnails;
|
||||
|
||||
Task<Stream> GetUserImage(Guid userId);
|
||||
|
||||
Task SetUserImage(Guid userId, Stream? image);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// A local repository to handle watched items
|
||||
/// </summary>
|
||||
public interface IWatchStatusRepository
|
||||
{
|
||||
public delegate Task ResourceEventHandler<T>(T resource);
|
||||
|
||||
Task<ICollection<IWatchlist>> GetAll(
|
||||
Filter<IWatchlist>? filter = default,
|
||||
Include<IWatchlist>? include = default,
|
||||
Pagination? limit = default
|
||||
);
|
||||
|
||||
Task<MovieWatchStatus?> GetMovieStatus(Guid movieId, Guid userId);
|
||||
|
||||
Task<MovieWatchStatus?> SetMovieStatus(
|
||||
Guid movieId,
|
||||
Guid userId,
|
||||
WatchStatus status,
|
||||
int? watchedTime,
|
||||
int? percent
|
||||
);
|
||||
|
||||
static event ResourceEventHandler<WatchStatus<Movie>> OnMovieStatusChangedHandler;
|
||||
protected static Task OnMovieStatusChanged(WatchStatus<Movie> obj) =>
|
||||
OnMovieStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
Task DeleteMovieStatus(Guid movieId, Guid userId);
|
||||
|
||||
Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId);
|
||||
|
||||
Task<ShowWatchStatus?> SetShowStatus(Guid showId, Guid userId, WatchStatus status);
|
||||
|
||||
static event ResourceEventHandler<WatchStatus<Show>> OnShowStatusChangedHandler;
|
||||
protected static Task OnShowStatusChanged(WatchStatus<Show> obj) =>
|
||||
OnShowStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
Task DeleteShowStatus(Guid showId, Guid userId);
|
||||
|
||||
Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId);
|
||||
|
||||
/// <param name="watchedTime">Where the user has stopped watching. Only usable if Status
|
||||
/// is <see cref="WatchStatus.Watching"/></param>
|
||||
Task<EpisodeWatchStatus?> SetEpisodeStatus(
|
||||
Guid episodeId,
|
||||
Guid userId,
|
||||
WatchStatus status,
|
||||
int? watchedTime,
|
||||
int? percent
|
||||
);
|
||||
|
||||
static event ResourceEventHandler<WatchStatus<Episode>> OnEpisodeStatusChangedHandler;
|
||||
protected static Task OnEpisodeStatusChanged(WatchStatus<Episode> obj) =>
|
||||
OnEpisodeStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);
|
||||
}
|
||||
64
back/src/Kyoo.Abstractions/Extensions.cs
Normal file
64
back/src/Kyoo.Abstractions/Extensions.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Authentication.Models;
|
||||
|
||||
namespace Kyoo.Authentication;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods.
|
||||
/// </summary>
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the permissions of an user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user</param>
|
||||
/// <returns>The list of permissions</returns>
|
||||
public static ICollection<string> GetPermissions(this ClaimsPrincipal user)
|
||||
{
|
||||
return user.Claims.FirstOrDefault(x => x.Type == Claims.Permissions)?.Value.Split(',')
|
||||
?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the id of the current user or null if unlogged or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>The id of the user or null.</returns>
|
||||
public static Guid? GetId(this ClaimsPrincipal user)
|
||||
{
|
||||
Claim? value = user.FindFirst(Claims.Id);
|
||||
if (Guid.TryParse(value?.Value, out Guid id))
|
||||
return id;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Guid GetIdOrThrow(this ClaimsPrincipal user)
|
||||
{
|
||||
Guid? ret = user.GetId();
|
||||
if (ret == null)
|
||||
throw new UnauthorizedException();
|
||||
return ret.Value;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>default</LangVersion>
|
||||
<Title>Kyoo.Abstractions</Title>
|
||||
<Description>Base package to create plugins for Kyoo.</Description>
|
||||
<RootNamespace>Kyoo.Abstractions</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.2.0" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
|
||||
<PackageReference Include="Dapper" Version="2.1.44" />
|
||||
<PackageReference Include="EntityFrameworkCore.Projectables" Version="4.1.4-prebeta" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="System.ComponentModel.Composition" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Sprache" Version="2.3.1" />
|
||||
<PackageReference Include="System.ComponentModel.Composition" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,51 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// An attribute to specify on apis to specify it's documentation's name and category.
|
||||
/// If this is applied on a method, the specified method will be exploded from the controller's page and be
|
||||
/// included on the specified tag page.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class ApiDefinitionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The public name of this api.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the group in witch this API is. You can also specify a custom sort order using the following
|
||||
/// format: <code>order:name</code>. Everything before the first <c>:</c> will be removed but kept for
|
||||
/// th alphabetical ordering.
|
||||
/// </summary>
|
||||
public string? Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ApiDefinitionAttribute"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the api that will be used on the documentation page.</param>
|
||||
public ApiDefinitionAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// An attribute to inform that the property is computed automatically and can't be assigned manually.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ComputedAttribute : NotMergeableAttribute { }
|
||||
@@ -17,33 +17,37 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// The targeted relation can be loaded.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class LoadableRelationAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The targeted relation can be loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||
/// The name of the field containing the related resource's ID.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class LoadableRelationAttribute : Attribute
|
||||
public string? RelationID { get; }
|
||||
|
||||
public string? Sql { get; set; }
|
||||
|
||||
public string? On { get; set; }
|
||||
|
||||
public string? Projected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="LoadableRelationAttribute"/>.
|
||||
/// </summary>
|
||||
public LoadableRelationAttribute() { }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="LoadableRelationAttribute"/> with a baking relationID field.
|
||||
/// </summary>
|
||||
/// <param name="relationID">The name of the RelationID field.</param>
|
||||
public LoadableRelationAttribute(string relationID)
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the field containing the related resource's ID.
|
||||
/// </summary>
|
||||
public string RelationID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="LoadableRelationAttribute"/>.
|
||||
/// </summary>
|
||||
public LoadableRelationAttribute() { }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="LoadableRelationAttribute"/> with a baking relationID field.
|
||||
/// </summary>
|
||||
/// <param name="relationID">The name of the RelationID field.</param>
|
||||
public LoadableRelationAttribute(string relationID)
|
||||
{
|
||||
RelationID = relationID;
|
||||
}
|
||||
RelationID = relationID;
|
||||
}
|
||||
}
|
||||
@@ -16,26 +16,24 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.Authentication.Models
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// Specify that a property can't be merged.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class NotMergeableAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// An interface with a method called when this object is merged.
|
||||
/// </summary>
|
||||
public interface IOnMerge
|
||||
{
|
||||
/// <summary>
|
||||
/// Permission options.
|
||||
/// This function is called after the object has been merged.
|
||||
/// </summary>
|
||||
public class PermissionOption
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to get this option from the root configuration.
|
||||
/// </summary>
|
||||
public const string Path = "authentication:permissions";
|
||||
|
||||
/// <summary>
|
||||
/// The default permissions that will be given to a non-connected user.
|
||||
/// </summary>
|
||||
public string[] Default { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Permissions applied to a new user.
|
||||
/// </summary>
|
||||
public string[] NewUser { get; set; }
|
||||
}
|
||||
/// <param name="merged">The object that has been merged with this.</param>
|
||||
void OnMerge(object merged);
|
||||
}
|
||||
@@ -16,21 +16,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.Authentication.Models.DTO
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// An attribute to inform that this interface is a type union
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Interface)]
|
||||
public class OneOfAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// A model to represent an otac request
|
||||
/// The types this union concist of.
|
||||
/// </summary>
|
||||
public class OtacRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The One Time Access Code
|
||||
/// </summary>
|
||||
public string Otac { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the user stay logged
|
||||
/// </summary>
|
||||
public bool StayLoggedIn { get; set; }
|
||||
}
|
||||
public Type[] Types { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions;
|
||||
|
||||
/// <summary>
|
||||
/// Specify one part of a permissions needed for the API (the kind or the type).
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PartialPermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission type.
|
||||
/// </summary>
|
||||
public string? Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind? Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The group of this permission.
|
||||
/// </summary>
|
||||
public Group Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="type">The type of the action</param>
|
||||
public PartialPermissionAttribute(string type)
|
||||
{
|
||||
Type = type.ToLower();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="permission">The kind of permission needed.</param>
|
||||
public PartialPermissionAttribute(Kind permission)
|
||||
{
|
||||
Kind = permission;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions;
|
||||
|
||||
/// <summary>
|
||||
/// The kind of permission needed.
|
||||
/// </summary>
|
||||
public enum Kind
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow the user to read for this kind of data.
|
||||
/// </summary>
|
||||
Read,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to write for this kind of data.
|
||||
/// </summary>
|
||||
Write,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to create this kind of data.
|
||||
/// </summary>
|
||||
Create,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to delete this kind of data.
|
||||
/// </summary>
|
||||
Delete,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to play this file.
|
||||
/// </summary>
|
||||
Play,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The group of the permission.
|
||||
/// </summary>
|
||||
public enum Group
|
||||
{
|
||||
/// <summary>
|
||||
/// Default group indicating no value.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Allow all operations on basic items types.
|
||||
/// </summary>
|
||||
Overall,
|
||||
|
||||
/// <summary>
|
||||
/// Allow operation on sensitive items like libraries path, configurations and so on.
|
||||
/// </summary>
|
||||
Admin
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify permissions needed for the API.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission as string.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The group of this permission.
|
||||
/// </summary>
|
||||
public Group Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The type of the action
|
||||
/// </param>
|
||||
/// <param name="permission">
|
||||
/// The kind of permission needed.
|
||||
/// </param>
|
||||
/// <param name="group">
|
||||
/// The group of this permission (allow grouped permission like overall.read
|
||||
/// for all read permissions of this group).
|
||||
/// </param>
|
||||
public PermissionAttribute(string type, Kind permission, Group group = Group.Overall)
|
||||
{
|
||||
Type = type.ToLower();
|
||||
Kind = permission;
|
||||
Group = group;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
|
||||
/// <summary>
|
||||
/// Return this permission attribute as a string.
|
||||
/// </summary>
|
||||
/// <returns>The string representation.</returns>
|
||||
public string AsPermissionString()
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions;
|
||||
|
||||
/// <summary>
|
||||
/// The annotated route can only be accessed by a logged in user.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class UserOnlyAttribute : Attribute
|
||||
{
|
||||
// TODO: Implement a Filter Attribute to make this work. For now, this attribute is only useful as documentation.
|
||||
}
|
||||
@@ -16,26 +16,22 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.Core.Models.Options
|
||||
using System;
|
||||
using Kyoo.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class SqlFirstColumnAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for media registering.
|
||||
/// The name of the first column of the element. Used to split multiples
|
||||
/// items on a single sql query. If not specified, it defaults to "Id".
|
||||
/// </summary>
|
||||
public class MediaOptions
|
||||
public string Name { get; set; }
|
||||
|
||||
public SqlFirstColumnAttribute(string name)
|
||||
{
|
||||
/// <summary>
|
||||
/// The path of this options
|
||||
/// </summary>
|
||||
public const string Path = "Media";
|
||||
|
||||
/// <summary>
|
||||
/// A regex for episodes
|
||||
/// </summary>
|
||||
public string[] Regex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A regex for subtitles
|
||||
/// </summary>
|
||||
public string[] SubtitleRegex { get; set; }
|
||||
Name = name.ToSnakeCase();
|
||||
}
|
||||
}
|
||||
@@ -16,21 +16,19 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.TheTvdb.Models
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// An exception raised when an item already exists in the database.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DuplicatedItemException(object? existing = null)
|
||||
: Exception("Already exists in the database.")
|
||||
{
|
||||
/// <summary>
|
||||
/// The option containing the api key for the tvdb.
|
||||
/// The existing object.
|
||||
/// </summary>
|
||||
public class TvdbOption
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to get this option from the root configuration.
|
||||
/// </summary>
|
||||
public const string Path = "tvdb";
|
||||
|
||||
/// <summary>
|
||||
/// The api key of the tvdb.
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; }
|
||||
}
|
||||
public object? Existing { get; } = existing;
|
||||
}
|
||||
@@ -18,23 +18,24 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// An exception raised when an item could not be found.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ItemNotFoundException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Specify that a property can't be merged.
|
||||
/// Create a default <see cref="ItemNotFoundException"/> with no message.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class NotMergeableAttribute : Attribute { }
|
||||
public ItemNotFoundException()
|
||||
: base("Item not found") { }
|
||||
|
||||
/// <summary>
|
||||
/// An interface with a method called when this object is merged.
|
||||
/// Create a new <see cref="ItemNotFoundException"/> with a message
|
||||
/// </summary>
|
||||
public interface IOnMerge
|
||||
{
|
||||
/// <summary>
|
||||
/// This function is called after the object has been merged.
|
||||
/// </summary>
|
||||
/// <param name="merged">The object that has been merged with this.</param>
|
||||
void OnMerge(object merged);
|
||||
}
|
||||
/// <param name="message">The message of the exception</param>
|
||||
public ItemNotFoundException(string message)
|
||||
: base(message) { }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Exceptions;
|
||||
|
||||
[Serializable]
|
||||
public class UnauthorizedException : Exception
|
||||
{
|
||||
public UnauthorizedException()
|
||||
: base("User not authenticated or token invalid.") { }
|
||||
|
||||
public UnauthorizedException(string message)
|
||||
: base(message) { }
|
||||
}
|
||||
50
back/src/Kyoo.Abstractions/Models/Genre.cs
Normal file
50
back/src/Kyoo.Abstractions/Models/Genre.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A genre that allow one to specify categories for shows.
|
||||
/// </summary>
|
||||
public enum Genre
|
||||
{
|
||||
Action,
|
||||
Adventure,
|
||||
Animation,
|
||||
Comedy,
|
||||
Crime,
|
||||
Documentary,
|
||||
Drama,
|
||||
Family,
|
||||
Fantasy,
|
||||
History,
|
||||
Horror,
|
||||
Music,
|
||||
Mystery,
|
||||
Romance,
|
||||
ScienceFiction,
|
||||
Thriller,
|
||||
War,
|
||||
Western,
|
||||
Kids,
|
||||
News,
|
||||
Reality,
|
||||
Soap,
|
||||
Talk,
|
||||
Politics,
|
||||
}
|
||||
31
back/src/Kyoo.Abstractions/Models/ILibraryItem.cs
Normal file
31
back/src/Kyoo.Abstractions/Models/ILibraryItem.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A show, a movie or a collection.
|
||||
/// </summary>
|
||||
[OneOf(Types = new[] { typeof(Show), typeof(Movie), typeof(Collection) })]
|
||||
public interface ILibraryItem : IResource, IThumbnails, IMetadata, IAddedDate, IQuery
|
||||
{
|
||||
static Sort IQuery.DefaultSort => new Sort<ILibraryItem>.By(nameof(Movie.Name));
|
||||
}
|
||||
31
back/src/Kyoo.Abstractions/Models/INews.cs
Normal file
31
back/src/Kyoo.Abstractions/Models/INews.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A show, a movie or a collection.
|
||||
/// </summary>
|
||||
[OneOf(Types = [typeof(Episode), typeof(Movie)])]
|
||||
public interface INews : IResource, IThumbnails, IAddedDate, IQuery
|
||||
{
|
||||
static Sort IQuery.DefaultSort => new Sort<INews>.By(nameof(AddedDate), true);
|
||||
}
|
||||
27
back/src/Kyoo.Abstractions/Models/IWatchlist.cs
Normal file
27
back/src/Kyoo.Abstractions/Models/IWatchlist.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A watch list item.
|
||||
/// </summary>
|
||||
[OneOf(Types = new[] { typeof(Show), typeof(Movie) })]
|
||||
public interface IWatchlist : IResource, IThumbnails, IMetadata, IAddedDate { }
|
||||
52
back/src/Kyoo.Abstractions/Models/Issues.cs
Normal file
52
back/src/Kyoo.Abstractions/Models/Issues.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An issue that occured on kyoo.
|
||||
/// </summary>
|
||||
public class Issue : IAddedDate
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of issue (for example, "Scanner" if this issue was created due to scanning error).
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Why this issue was caused? An unique cause that can be used to identify this issue.
|
||||
/// For the scanner, a cause should be a video path.
|
||||
/// </summary>
|
||||
public string Cause { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A human readable string explaining why this issue occured.
|
||||
/// </summary>
|
||||
public string Reason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Some extra data that could store domain-specific info.
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Extra { get; set; } = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime AddedDate { get; set; }
|
||||
}
|
||||
61
back/src/Kyoo.Abstractions/Models/MetadataID.cs
Normal file
61
back/src/Kyoo.Abstractions/Models/MetadataID.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// ID and link of an item on an external provider.
|
||||
/// </summary>
|
||||
public class MetadataId
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the resource on the external provider.
|
||||
/// </summary>
|
||||
public string DataId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL of the resource on the external provider.
|
||||
/// </summary>
|
||||
public string? Link { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID informations about an episode.
|
||||
/// </summary>
|
||||
public class EpisodeId
|
||||
{
|
||||
/// <summary>
|
||||
/// The Id of the show on the metadata database.
|
||||
/// </summary>
|
||||
public string ShowId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The season number or null if absolute numbering is used in this database.
|
||||
/// </summary>
|
||||
public int? Season { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The episode number or absolute number if Season is null.
|
||||
/// </summary>
|
||||
public int Episode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL of the resource on the external provider.
|
||||
/// </summary>
|
||||
public string? Link { get; set; }
|
||||
}
|
||||
105
back/src/Kyoo.Abstractions/Models/Page.cs
Normal file
105
back/src/Kyoo.Abstractions/Models/Page.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Kyoo.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A page of resource that contains information about the pagination of resources.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of resource contained in this page.</typeparam>
|
||||
public class Page<T>
|
||||
where T : IResource
|
||||
{
|
||||
/// <summary>
|
||||
/// The link of the current page.
|
||||
/// </summary>
|
||||
public string This { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The link of the first page.
|
||||
/// </summary>
|
||||
public string First { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The link of the previous page.
|
||||
/// </summary>
|
||||
public string? Previous { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The link of the next page.
|
||||
/// </summary>
|
||||
public string? Next { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of items in the current page.
|
||||
/// </summary>
|
||||
public int Count => Items.Count;
|
||||
|
||||
/// <summary>
|
||||
/// The list of items in the page.
|
||||
/// </summary>
|
||||
public ICollection<T> Items { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="Page{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="items">The list of items in the page.</param>
|
||||
/// <param name="this">The link of the current page.</param>
|
||||
/// <param name="previous">The link of the previous page.</param>
|
||||
/// <param name="next">The link of the next page.</param>
|
||||
/// <param name="first">The link of the first page.</param>
|
||||
public Page(ICollection<T> items, string @this, string? previous, string? next, string first)
|
||||
{
|
||||
Items = items;
|
||||
This = @this;
|
||||
Previous = previous;
|
||||
Next = next;
|
||||
First = first;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="Page{T}"/> and compute the urls.
|
||||
/// </summary>
|
||||
/// <param name="items">The list of items in the page.</param>
|
||||
/// <param name="url">The base url of the resources available from this page.</param>
|
||||
/// <param name="query">The list of query strings of the current page</param>
|
||||
/// <param name="limit">The number of items requested for the current page.</param>
|
||||
public Page(ICollection<T> items, string url, Dictionary<string, string> query, int limit)
|
||||
{
|
||||
Items = items;
|
||||
This = url + query.ToQueryString();
|
||||
if (items.Count > 0 && query.ContainsKey("afterID"))
|
||||
{
|
||||
query["afterID"] = items.First().Id.ToString();
|
||||
query["reverse"] = "true";
|
||||
Previous = url + query.ToQueryString();
|
||||
}
|
||||
query.Remove("reverse");
|
||||
if (items.Count == limit && limit > 0)
|
||||
{
|
||||
query["afterID"] = items.Last().Id.ToString();
|
||||
Next = url + query.ToQueryString();
|
||||
}
|
||||
query.Remove("afterID");
|
||||
First = url + query.ToQueryString();
|
||||
}
|
||||
}
|
||||
46
back/src/Kyoo.Abstractions/Models/Patch.cs
Normal file
46
back/src/Kyoo.Abstractions/Models/Patch.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Models;
|
||||
|
||||
public class Patch<T> : Dictionary<string, JsonDocument>
|
||||
where T : class, IResource
|
||||
{
|
||||
public Guid? Id => this.GetValueOrDefault(nameof(IResource.Id))?.Deserialize<Guid>();
|
||||
|
||||
public string? Slug => this.GetValueOrDefault(nameof(IResource.Slug))?.Deserialize<string>();
|
||||
|
||||
public T Apply(T current)
|
||||
{
|
||||
foreach ((string property, JsonDocument value) in this)
|
||||
{
|
||||
PropertyInfo prop = typeof(T).GetProperty(
|
||||
property,
|
||||
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance
|
||||
)!;
|
||||
prop.SetValue(current, value.Deserialize(prop.PropertyType));
|
||||
}
|
||||
return current;
|
||||
}
|
||||
}
|
||||
100
back/src/Kyoo.Abstractions/Models/Resources/Collection.cs
Normal file
100
back/src/Kyoo.Abstractions/Models/Resources/Collection.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Utils;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A class representing collections of <see cref="Show"/>.
|
||||
/// </summary>
|
||||
public class Collection
|
||||
: IQuery,
|
||||
IResource,
|
||||
IMetadata,
|
||||
IThumbnails,
|
||||
IAddedDate,
|
||||
IRefreshable,
|
||||
ILibraryItem
|
||||
{
|
||||
public static Sort DefaultSort => new Sort<Collection>.By(nameof(Collection.Name));
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[MaxLength(256)]
|
||||
public string Slug { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this collection.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The description of this collection.
|
||||
/// </summary>
|
||||
public string? Overview { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime AddedDate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Poster { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Thumbnail { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Logo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of movies contained in this collection.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<Movie>? Movies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of shows contained in this collection.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<Show>? Shows { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, MetadataId> ExternalId { get; set; } = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime? NextMetadataRefresh { get; set; }
|
||||
|
||||
public Collection() { }
|
||||
|
||||
[JsonConstructor]
|
||||
public Collection(string name)
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
Slug = Utility.ToSlug(name);
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
302
back/src/Kyoo.Abstractions/Models/Resources/Episode.cs
Normal file
302
back/src/Kyoo.Abstractions/Models/Resources/Episode.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using EntityFrameworkCore.Projectables;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A class to represent a single show's episode.
|
||||
/// </summary>
|
||||
public class Episode : IQuery, IResource, IThumbnails, IAddedDate, IRefreshable, INews
|
||||
{
|
||||
// Use absolute numbers by default and fallback to season/episodes if it does not exists.
|
||||
public static Sort DefaultSort =>
|
||||
new Sort<Episode>.Conglomerate(
|
||||
new Sort<Episode>.By(x => x.AbsoluteNumber),
|
||||
new Sort<Episode>.By(x => x.SeasonNumber),
|
||||
new Sort<Episode>.By(x => x.EpisodeNumber)
|
||||
);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[Computed]
|
||||
[MaxLength(256)]
|
||||
public string Slug
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ShowSlug != null || Show?.Slug != null)
|
||||
return GetSlug(ShowSlug ?? Show!.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
|
||||
return GetSlug(ShowId.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber);
|
||||
}
|
||||
private set
|
||||
{
|
||||
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)e(?<episode>\d+)");
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
ShowSlug = match.Groups["show"].Value;
|
||||
SeasonNumber = int.Parse(match.Groups["season"].Value);
|
||||
EpisodeNumber = int.Parse(match.Groups["episode"].Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
match = Regex.Match(value, @"(?<show>.+)-(?<absolute>\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
ShowSlug = match.Groups["show"].Value;
|
||||
AbsoluteNumber = int.Parse(match.Groups["absolute"].Value);
|
||||
}
|
||||
else
|
||||
ShowSlug = value;
|
||||
SeasonNumber = null;
|
||||
EpisodeNumber = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string? ShowSlug { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the Show containing this episode.
|
||||
/// </summary>
|
||||
public Guid ShowId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The show that contains this episode.
|
||||
/// </summary>
|
||||
[LoadableRelation(nameof(ShowId))]
|
||||
public Show? Show { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the Season containing this episode.
|
||||
/// </summary>
|
||||
public Guid? SeasonId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The season that contains this episode.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be null if the season is unknown and the episode is only identified
|
||||
/// by it's <see cref="AbsoluteNumber"/>.
|
||||
/// </remarks>
|
||||
[LoadableRelation(nameof(SeasonId))]
|
||||
public Season? Season { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The season in witch this episode is in.
|
||||
/// </summary>
|
||||
public int? SeasonNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of this episode in it's season.
|
||||
/// </summary>
|
||||
public int? EpisodeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
||||
/// </summary>
|
||||
public int? AbsoluteNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path of the video file for this episode.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The title of this episode.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The overview of this episode.
|
||||
/// </summary>
|
||||
public string? Overview { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How long is this episode? (in minutes)
|
||||
/// </summary>
|
||||
public int? Runtime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The release date of this episode. It can be null if unknown.
|
||||
/// </summary>
|
||||
public DateOnly? ReleaseDate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime AddedDate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Poster { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Thumbnail { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Image? Logo { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, EpisodeId> ExternalId { get; set; } = [];
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime? NextMetadataRefresh { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous episode that should be seen before viewing this one.
|
||||
/// </summary>
|
||||
[Projectable(UseMemberBody = nameof(_PreviousEpisode), OnlyOnInclude = true)]
|
||||
[LoadableRelation(
|
||||
// language=PostgreSQL
|
||||
Sql = """
|
||||
select
|
||||
pe.* -- Episode as pe
|
||||
from
|
||||
episodes as "pe"
|
||||
where
|
||||
pe.show_id = "this".show_id
|
||||
and (pe.absolute_number < "this".absolute_number
|
||||
or pe.season_number < "this".season_number
|
||||
or (pe.season_number = "this".season_number
|
||||
and e.episode_number < "this".episode_number))
|
||||
order by
|
||||
pe.absolute_number desc nulls last,
|
||||
pe.season_number desc,
|
||||
pe.episode_number desc
|
||||
limit 1
|
||||
"""
|
||||
)]
|
||||
public Episode? PreviousEpisode { get; set; }
|
||||
|
||||
private Episode? _PreviousEpisode =>
|
||||
Show!
|
||||
.Episodes!.OrderBy(x => x.AbsoluteNumber == null)
|
||||
.ThenByDescending(x => x.AbsoluteNumber)
|
||||
.ThenByDescending(x => x.SeasonNumber)
|
||||
.ThenByDescending(x => x.EpisodeNumber)
|
||||
.FirstOrDefault(x =>
|
||||
x.AbsoluteNumber < AbsoluteNumber
|
||||
|| x.SeasonNumber < SeasonNumber
|
||||
|| (x.SeasonNumber == SeasonNumber && x.EpisodeNumber < EpisodeNumber)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// The next episode to watch after this one.
|
||||
/// </summary>
|
||||
[Projectable(UseMemberBody = nameof(_NextEpisode), OnlyOnInclude = true)]
|
||||
[LoadableRelation(
|
||||
// language=PostgreSQL
|
||||
Sql = """
|
||||
select
|
||||
ne.* -- Episode as ne
|
||||
from
|
||||
episodes as "ne"
|
||||
where
|
||||
ne.show_id = "this".show_id
|
||||
and (ne.absolute_number > "this".absolute_number
|
||||
or ne.season_number > "this".season_number
|
||||
or (ne.season_number = "this".season_number
|
||||
and e.episode_number > "this".episode_number))
|
||||
order by
|
||||
ne.absolute_number,
|
||||
ne.season_number,
|
||||
ne.episode_number
|
||||
limit 1
|
||||
"""
|
||||
)]
|
||||
public Episode? NextEpisode { get; set; }
|
||||
|
||||
private Episode? _NextEpisode =>
|
||||
Show!
|
||||
.Episodes!.OrderBy(x => x.AbsoluteNumber)
|
||||
.ThenBy(x => x.SeasonNumber)
|
||||
.ThenBy(x => x.EpisodeNumber)
|
||||
.FirstOrDefault(x =>
|
||||
x.AbsoluteNumber > AbsoluteNumber
|
||||
|| x.SeasonNumber > SeasonNumber
|
||||
|| (x.SeasonNumber == SeasonNumber && x.EpisodeNumber > EpisodeNumber)
|
||||
);
|
||||
|
||||
[JsonIgnore]
|
||||
public ICollection<EpisodeWatchStatus>? Watched { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metadata of what an user as started/planned to watch.
|
||||
/// </summary>
|
||||
[Projectable(UseMemberBody = nameof(_WatchStatus), OnlyOnInclude = true)]
|
||||
[LoadableRelation(
|
||||
Sql = "episode_watch_status",
|
||||
On = "episode_id = \"this\".id and \"relation\".user_id = [current_user]"
|
||||
)]
|
||||
public EpisodeWatchStatus? WatchStatus { get; set; }
|
||||
|
||||
// There is a global query filter to filter by user so we just need to do single.
|
||||
private EpisodeWatchStatus? _WatchStatus => Watched!.FirstOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Links to watch this episode.
|
||||
/// </summary>
|
||||
public VideoLinks Links =>
|
||||
new() { Direct = $"/episode/{Slug}/direct", Hls = $"/episode/{Slug}/master.m3u8", };
|
||||
|
||||
/// <summary>
|
||||
/// Get the slug of an episode.
|
||||
/// </summary>
|
||||
/// <param name="showSlug">The slug of the show. It can't be null.</param>
|
||||
/// <param name="seasonNumber">
|
||||
/// The season in which the episode is.
|
||||
/// If this is a movie or if the episode should be referred by it's absolute number, set this to null.
|
||||
/// </param>
|
||||
/// <param name="episodeNumber">
|
||||
/// The number of the episode in it's season.
|
||||
/// If this is a movie or if the episode should be referred by it's absolute number, set this to null.
|
||||
/// </param>
|
||||
/// <param name="absoluteNumber">
|
||||
/// The absolute number of this show.
|
||||
/// If you don't know it or this is a movie, use null
|
||||
/// </param>
|
||||
/// <returns>The slug corresponding to the given arguments</returns>
|
||||
public static string GetSlug(
|
||||
string showSlug,
|
||||
int? seasonNumber,
|
||||
int? episodeNumber,
|
||||
int? absoluteNumber = null
|
||||
)
|
||||
{
|
||||
return seasonNumber switch
|
||||
{
|
||||
null when absoluteNumber == null => showSlug,
|
||||
null => $"{showSlug}-{absoluteNumber}",
|
||||
_ => $"{showSlug}-s{seasonNumber}e{episodeNumber}"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,15 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An interface applied to resources.
|
||||
/// </summary>
|
||||
public interface IAddedDate
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform that the property is computed automatically and can't be assigned manually.
|
||||
/// The date at which this resource was added to kyoo.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ComputedAttribute : NotMergeableAttribute { }
|
||||
public DateTime AddedDate { get; set; }
|
||||
}
|
||||
@@ -16,21 +16,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Kyoo.TheMovieDb.Models
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An interface applied to resources containing external metadata.
|
||||
/// </summary>
|
||||
public interface IMetadata
|
||||
{
|
||||
/// <summary>
|
||||
/// The option containing the api key for TheMovieDb.
|
||||
/// The link to metadata providers that this show has. See <see cref="MetadataId"/> for more information.
|
||||
/// </summary>
|
||||
public class TheMovieDbOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to get this option from the root configuration.
|
||||
/// </summary>
|
||||
public const string Path = "the-moviedb";
|
||||
|
||||
/// <summary>
|
||||
/// The api key of TheMovieDb.
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; }
|
||||
}
|
||||
public Dictionary<string, MetadataId> ExternalId { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
@@ -19,11 +19,12 @@
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Attributes
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
public interface IQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// The targeted relation can be edited via calls to the repository's <see cref="IRepository{T}.Edit"/> method.
|
||||
/// The sorting that will be used when no user defined one is present.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class EditableRelationAttribute : Attribute { }
|
||||
public static virtual Sort DefaultSort => throw new NotImplementedException();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
public interface IRefreshable
|
||||
{
|
||||
/// <summary>
|
||||
/// The date of the next metadata refresh. Null if auto-refresh is disabled.
|
||||
/// </summary>
|
||||
public DateTime? NextMetadataRefresh { get; set; }
|
||||
|
||||
public static DateTime ComputeNextRefreshDate(DateOnly airDate)
|
||||
{
|
||||
int days = DateOnly.FromDateTime(DateTime.UtcNow).DayNumber - airDate.DayNumber;
|
||||
return days switch
|
||||
{
|
||||
<= 4 => DateTime.UtcNow.AddDays(1),
|
||||
<= 21 => DateTime.UtcNow.AddDays(14),
|
||||
_ => DateTime.UtcNow.AddMonths(2)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An interface to represent a resource that can be retrieved from the database.
|
||||
/// </summary>
|
||||
public interface IResource : IQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// A unique ID for this type of resource. This can't be changed and duplicates are not allowed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You don't need to specify an ID manually when creating a new resource,
|
||||
/// this field is automatically assigned by the <see cref="IRepository{T}"/>.
|
||||
/// </remarks>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A human-readable identifier that can be used instead of an ID.
|
||||
/// A slug must be unique for a type of resource but it can be changed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There is no setter for a slug since it can be computed from other fields.
|
||||
/// For example, a season slug is {ShowSlug}-s{SeasonNumber}.
|
||||
/// </remarks>
|
||||
[MaxLength(256)]
|
||||
public string Slug { get; }
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An interface representing items that contains images (like posters, thumbnails, logo, banners...)
|
||||
/// </summary>
|
||||
public interface IThumbnails
|
||||
{
|
||||
/// <summary>
|
||||
/// A poster is a 2/3 format image with the cover of the resource.
|
||||
/// </summary>
|
||||
public Image? Poster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A thumbnail is a 16/9 format image, it could ether be used as a background or as a preview but it usually
|
||||
/// is not an official image.
|
||||
/// </summary>
|
||||
public Image? Thumbnail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A logo is a small image representing the resource.
|
||||
/// </summary>
|
||||
public Image? Logo { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(ImageConvertor))]
|
||||
public class Image
|
||||
{
|
||||
/// <summary>
|
||||
/// A unique identifier for the image. Used for proper http caches.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The original image from another server.
|
||||
/// </summary>
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A hash to display as placeholder while the image is loading.
|
||||
/// </summary>
|
||||
[MaxLength(32)]
|
||||
public string Blurhash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The url to access the image in low quality.
|
||||
/// </summary>
|
||||
public string Low => $"/thumbnails/{Id}?quality=low";
|
||||
|
||||
/// <summary>
|
||||
/// The url to access the image in medium quality.
|
||||
/// </summary>
|
||||
public string Medium => $"/thumbnails/{Id}?quality=medium";
|
||||
|
||||
/// <summary>
|
||||
/// The url to access the image in high quality.
|
||||
/// </summary>
|
||||
public string High => $"/thumbnails/{Id}?quality=high";
|
||||
|
||||
public Image() { }
|
||||
|
||||
[JsonConstructor]
|
||||
public Image(string source, string? blurhash = null)
|
||||
{
|
||||
Source = source;
|
||||
Blurhash = blurhash ?? "000000";
|
||||
}
|
||||
|
||||
//
|
||||
public class ImageConvertor : JsonConverter<Image>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override Image? Read(
|
||||
ref Utf8JsonReader reader,
|
||||
Type typeToConvert,
|
||||
JsonSerializerOptions options
|
||||
)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.String && reader.GetString() is string source)
|
||||
return new Image(source);
|
||||
using JsonDocument document = JsonDocument.ParseValue(ref reader);
|
||||
string? src = document.RootElement.GetProperty("Source").GetString();
|
||||
string? blurhash = document.RootElement.GetProperty("Blurhash").GetString();
|
||||
Guid? id = document.RootElement.GetProperty("Id").GetGuid();
|
||||
return new Image(src ?? string.Empty, blurhash) { Id = id ?? Guid.Empty };
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(
|
||||
Utf8JsonWriter writer,
|
||||
Image value,
|
||||
JsonSerializerOptions options
|
||||
)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer.WriteString("source", value.Source);
|
||||
writer.WriteString("blurhash", value.Blurhash);
|
||||
writer.WriteString("low", value.Low);
|
||||
writer.WriteString("medium", value.Medium);
|
||||
writer.WriteString("high", value.High);
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The quality of an image
|
||||
/// </summary>
|
||||
public enum ImageQuality
|
||||
{
|
||||
/// <summary>
|
||||
/// Small
|
||||
/// </summary>
|
||||
Low,
|
||||
|
||||
/// <summary>
|
||||
/// Medium
|
||||
/// </summary>
|
||||
Medium,
|
||||
|
||||
/// <summary>
|
||||
/// Large
|
||||
/// </summary>
|
||||
High,
|
||||
}
|
||||
65
back/src/Kyoo.Abstractions/Models/Resources/JwtToken.cs
Normal file
65
back/src/Kyoo.Abstractions/Models/Resources/JwtToken.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Kyoo.Abstractions.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A container representing the response of a login or token refresh.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of the <see cref="JwtToken"/> class.
|
||||
/// </remarks>
|
||||
/// <param name="accessToken">The access token used to authorize requests.</param>
|
||||
/// <param name="refreshToken">The refresh token to retrieve a new access token.</param>
|
||||
/// <param name="expireIn">When the access token will expire.</param>
|
||||
public class JwtToken(string accessToken, string refreshToken, TimeSpan expireIn)
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of this token (always a Bearer).
|
||||
/// </summary>
|
||||
[JsonPropertyName("token_type")]
|
||||
public string TokenType => "Bearer";
|
||||
|
||||
/// <summary>
|
||||
/// The access token used to authorize requests.
|
||||
/// </summary>
|
||||
[JsonPropertyName("access_token")]
|
||||
public string AccessToken { get; set; } = accessToken;
|
||||
|
||||
/// <summary>
|
||||
/// The refresh token used to retrieve a new access/refresh token when the access token has expired.
|
||||
/// </summary>
|
||||
[JsonPropertyName("refresh_token")]
|
||||
public string RefreshToken { get; set; } = refreshToken;
|
||||
|
||||
/// <summary>
|
||||
/// When the access token will expire. After this time, the refresh token should be used to retrieve.
|
||||
/// a new token.cs
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire_in")]
|
||||
public TimeSpan ExpireIn => ExpireAt.Subtract(DateTime.UtcNow);
|
||||
|
||||
/// <summary>
|
||||
/// The exact date at which the access token will expire.
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire_at")]
|
||||
public DateTime ExpireAt { get; set; } = DateTime.UtcNow + expireIn;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user