├── api.md ├── api_v2.md ├── api_v3.md ├── install ├── README.md ├── autoupdate.md ├── conf │ ├── default │ ├── filter.lua │ └── nginx.conf ├── exim.md ├── fail2ban.md ├── mariadb.md ├── memcached.md ├── munin.md ├── munin │ ├── xbt_torrents │ └── xbt_users ├── nginx.md ├── php73.md ├── phpmyadmin.md ├── pure-ftpd.md ├── sphinx.md ├── sysctl.md ├── timezone.md └── xbt_tracker.md ├── other ├── 17-02-2019.md ├── 18-02-2019.md ├── simple_http_filer.md └── transmission-daemon.md ├── todo └── site.md ├── video ├── index.php └── nginx_caching_proxy.md └── win10-install.md /api.md: -------------------------------------------------------------------------------- 1 | ### Примечание. 2 | * Тип поля указывается в [ ] 3 | * **?** – Обозначает Nullable или необязательное поле 4 | 5 | Оглавление: 6 | * ["Отправка запросов"](#user-content-отправка-запросов) 7 | * ["Авторизация"](#user-content-авторизация) 8 | * ["Релизы"](#user-content-релизы) 9 | * ["Лента"](#user-content-лента) 10 | * ["Расписание"](#user-content-расписание) 11 | * ["Случайный релиз"](#user-content-случайный-релиз) 12 | * ["Избранное"](#user-content-избранное) 13 | * ["Жанры"](#user-content-жанры) 14 | * ["Года"](#user-content-года) 15 | * ["Каталог"](#user-content-каталог) 16 | * ["Поиск по названию"](#user-content-поиск-по-названию) 17 | * ["YouTube"](#user-content-youtube) 18 | * ["Пользователь"](#user-content-пользователь) 19 | * ["Комментарии ВКонтакте"](#user-content-комментарии-вконтакте) 20 | * ["Модели данных"](#user-content-модели-данных) 21 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 22 | * ["Модель пагинации"](#user-content-модель-пагинации) 23 | * ["Модель релиза"](#user-content-модель-релиза) 24 | * ["Модель серии"](#user-content-модель-серии) 25 | * ["Модель торрента"](#user-content-модель-торрента) 26 | * ["Модель блокировки"](#user-content-модель-релиза) 27 | * ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 28 | * ["Модель ленты"](#user-content-модель-ленты) 29 | * ["Модель расписания"](#user-content-модель-расписания) 30 | * ["Модель случайного релиза"](#user-content-модель-случайного-релиза) 31 | * ["Модель жанра"](#user-content-модель-жанра) 32 | * ["Модель года"](#user-content-модель-года) 33 | * ["Модель пользователя"](#user-content-пользователя) 34 | * ["Модель YouTube"](#user-content-модель-youtube) 35 | * ["Модель комментариев ВКонтакте"](#user-content-модель-комментариев-вконтакте) 36 | 37 | 38 | ### Отправка запросов 39 | Для отправки запросов нужно использовать не JSON файл, а форму. В противном случае, Вы получите ["Базовую модель ответа"](#user-content-базовая-модель-ответа). 40 | 41 | Пример отправки запроса ["Случайный релиз"](#user-content-случайный-релиз) на языке программирования Go 42 | ``` 43 | resp, err := http.PostForm("https://www.anilibria.tv/public/api/index.php", 44 | url.Values{"query": {"random_release"}}) 45 | ``` 46 | Пример отправки запроса ["Релизы"](#user-content-релизы) на языке программирования Go 47 | ``` 48 | resp, err := http.PostForm("https://www.anilibria.tv/public/api/index.php", 49 | url.Values{"query": {"release"}, "code": {"rdg-red-data-girl"}}) 50 | ``` 51 | 52 | 53 | ### Авторизация 54 | Примечания: 55 | * Авторизация может пропасть в любой момент, т.к. время жизни сессии ограничено 56 | 57 | 58 | ##### Залогиниться 59 | URL 60 | ``` 61 | /public/login.php 62 | ``` 63 | 64 | Все параметры запроса 65 | ``` 66 | mail, passwd 67 | ``` 68 | * mail [string] – Логин или электронная почта от аккаунта 69 | * passwd [string] – Пароль от аккаунта 70 | 71 |
Пример запроса 72 | ``` 73 | {"mail":"testuser", "passwd":"testpass"} 74 | {"mail":"testuser@test.user", "passwd":"testpass"} 75 | Ответ: Тело не важно 76 | В хедере будет кука PHPSESSID - её нужно сохранить и использовать в следующих запросах 77 | ``` 78 | 79 | ##### Разлогиниться 80 | URL 81 | ``` 82 | /public/logout.php 83 | ``` 84 | 85 | Все параметры запроса 86 | ``` 87 | Нет 88 | ``` 89 | 90 |
Пример запроса 91 | ``` 92 | {} 93 | Ответ: Тело не важно 94 | В хедере кука PHPSESSID должна быть со значением "deleted" – удаляем её из клиента 95 | ``` 96 | 97 | ### Релизы 98 | URL 99 | ``` 100 | /public/api/index.php 101 | ``` 102 | 103 | Все параметры запроса 104 | ``` 105 | query, id, code, filter, rm, page, perPage 106 | ``` 107 | * query [string] – Что именно нужно вывести. 108 | * "release" - Вывод одного релизы, доступно [id, code, filter, rm] 109 | * "list" – Вывод списка всех релизов, есть пагинация, доступно [filter, rm, page, perPage] 110 | * "info" - Вывод необходимы релизов, доступно [id, filter, rm] 111 | * id [int/string]**?** – "id" релиза, обязателен для [info, release*] 112 | * code [string]**?** – "code" релиза, обазателен для [release*] 113 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 114 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 115 | * page [int/string]**?** – Номер страницы для списка релизов 116 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 117 | 118 | Используемые модели: 119 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 120 | * ["Модель пагинации"](#user-content-модель-пагинации) 121 | * ["Модель релиза"](#user-content-модель-релиза) 122 | * ["Модель серии"](#user-content-модель-серии) 123 | * ["Модель торрента"](#user-content-модель-торрента) 124 | * ["Модель блокировки"](#user-content-модель-релиза) 125 | * ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 126 | 127 |
Примеры запросов: 128 | 129 | Релиз 130 | ``` 131 | {"query":"release"} – будет ошибка 400, т.к. нет id и code 132 | {"query":"release","id":"120211111"} – будет ошибка, 404 133 | {"query":"release","id":"1202"} – релиз по id 134 | {"query":"release","code":"sakurako-san-no-ashimoto-ni-wa-shitai-ga-umatteiru"} – релиз по code 135 | Ответ: 136 | { 137 | "status": true|false, 138 | "data": {МОДЕЛЬ РЕЛИЗА}, 139 | "error": null|{} 140 | } 141 | ``` 142 | 143 |
Нужные релизы 144 | ``` 145 | {"query":"info","id":"1202, 473"} - выведет два релиза, если найдёт 146 | {"query":"info","id":"1202, 473","filter":"description,torrent"} - будут только поля descriptin и torrent 147 | {"query":"info","id":"1202, 473","filter":"description,torrent","rm":""} - исключит поля descriptin и torrent 148 | Ответ: 149 | { 150 | "status": true, 151 | "data": [МОДЕЛИ РЕЛИЗА], 152 | "error": null 153 | } 154 | ``` 155 | 156 |
Список релизов 157 | ``` 158 | {"query":"list","page":"1","perPage":"3"} - выведет 1 страницу с 3 релизами 159 | Ответ: 160 | { 161 | "status": true, 162 | "data": { 163 | "items": [МОДЕЛИ РЕЛИЗА], 164 | "pagination": {МОДЕЛЬ ПАГИНАЦИИ} 165 | }, 166 | "error": null 167 | } 168 | ``` 169 | 170 | ### Лента 171 | URL 172 | ``` 173 | /public/api/index.php 174 | ``` 175 | Параметры запроса 176 | ``` 177 | query, id, action, filter, rm, page, perPage 178 | ``` 179 | * query [string] = "feed" 180 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 181 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 182 | * page [int/string]**?** – Номер страницы для списка релизов 183 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 184 | 185 | Примечания: 186 | * filter действует только на поля в модели релиза 187 | 188 | Используемые модели: 189 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 190 | * ["Модель ленты"](#user-content-модель-ленты) 191 | * ["Модель релиза"](#user-content-модель-релиза) 192 | * ["Модель YouTube"](#user-content-модель-youtube) 193 | 194 |
Пример запроса: 195 | ``` 196 | {{"query":"feed","page":"1","perPage":"3"} - выведет 1 страницу с 3 элементами ленты 197 | Ответ: 198 | { 199 | "status": true, 200 | "data": [МОДЕЛИ ЛЕНТЫ], 201 | "error": null 202 | } 203 | ``` 204 | 205 | ### Расписание 206 | URL 207 | ``` 208 | /public/api/index.php 209 | ``` 210 | Параметры запроса 211 | ``` 212 | query, id, action, filter, rm, page, perPage 213 | ``` 214 | * query [string] = "schedule" 215 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 216 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 217 | 218 | 219 | Используемые модели: 220 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 221 | * ["Модель расписания"](#user-content-модель-расписания) 222 | * ["Модель релиза"](#user-content-модель-релиза) 223 | 224 |
Пример запроса: 225 | ``` 226 | {"query":"schedule"} 227 | Ответ: 228 | { 229 | "status": true, 230 | "data": [МОДЕЛИ РАСПИСАНИЯ], 231 | "error": null 232 | } 233 | ``` 234 | 235 | ### Случайный релиз 236 | URL 237 | ``` 238 | /public/api/index.php 239 | ``` 240 | Параметры запроса 241 | ``` 242 | query, id, action, filter, rm, page, perPage 243 | ``` 244 | * query [string] = "random_release" 245 | 246 | 247 | Используемые модели: 248 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 249 | * ["Модель случайного релиза"](#user-content-модель-случайного-релиза) 250 | 251 |
Пример запроса: 252 | ``` 253 | {"query":"random_release"} 254 | Ответ: 255 | { 256 | "status": true, 257 | "data": {МОДЕЛЬ СЛУЧАЙНОГО РЕЛИЗА}, 258 | "error": null 259 | } 260 | ``` 261 | 262 | ### Избранное 263 | URL 264 | ``` 265 | /public/api/index.php 266 | ``` 267 | Параметры запроса 268 | ``` 269 | query, id, action, filter, rm, page, perPage 270 | ``` 271 | * query [string] = "favorites" 272 | * id [string]**?** – ID релиза, который нужно добавить/удалить 273 | * action [string]**?** – Действие, которое нужно выполнить 274 | * "delete" – Удалить 275 | * "add" – Добавить 276 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 277 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 278 | * page [int/string]**?** – Номер страницы для списка релизов 279 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 280 | 281 | Примечания: 282 | * Необходима авторизация 283 | * action и id обязательные поля при удалении/добавлении 284 | * Если релиз уже был добавлен или уже был удалён из списка избранного, то вернётся ошибка 285 | 286 | Используемые модели: 287 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 288 | * ["Модель пагинации"](#user-content-модель-пагинации) 289 | * ["Модель релиза"](#user-content-модель-релиза) 290 | * ["Модель серии"](#user-content-модель-серии) 291 | * ["Модель торрента"](#user-content-модель-торрента) 292 | * ["Модель блокировки"](#user-content-модель-релиза) 293 | * ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 294 | 295 |
Примеры запросов 296 | 297 | Список избранного 298 | ``` 299 | {"query":"favorites","filter":"torrents","rm":""} 300 | {"query":"favorites","page":"4"} 301 | Ответ: 302 | { 303 | "status": true, 304 | "data": [МОДЕЛИ РЕЛИЗОВ], 305 | "error": null 306 | } 307 | ``` 308 |
Действие с избранным 309 | ``` 310 | {"query":"favorites","action":"add"} - Ошибка, не передан id 311 | {"query":"favorites","id":"4","action":"add"} 312 | {"query":"favorites","id":"4","action":"delete"} 313 | Ответ: 314 | { 315 | "status": true, 316 | "data": {МОДЕЛЬ РЕЛИЗА}, 317 | "error": null 318 | } 319 | ``` 320 | 321 | ### Жанры 322 | URL 323 | ``` 324 | /public/api/index.php 325 | ``` 326 | Параметры запроса 327 | ``` 328 | query 329 | ``` 330 | * query [string] = "genres" 331 | 332 | Используемые модели: 333 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 334 | * ["Модель жанра"](#user-content-модель-жанра) 335 | 336 |
Пример запроса 337 | ``` 338 | {"query":"genres"} 339 | Ответ: 340 | { 341 | "status": true, 342 | "data": [МОДЕЛИ ЖАНРА], 343 | "error": null 344 | } 345 | ``` 346 | 347 | ### Года 348 | URL 349 | ``` 350 | /public/api/index.php 351 | ``` 352 | Параметры запроса 353 | ``` 354 | query 355 | ``` 356 | * query [string] = "years" 357 | 358 | Используемые модели: 359 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 360 | * ["Модель года"](#user-content-модель-года) 361 | 362 |
Пример запроса 363 | ``` 364 | {"query":"years"} 365 | Ответ: 366 | { 367 | "status": true, 368 | "data": [МОДЕЛИ ГОДА], 369 | "error": null 370 | } 371 | ``` 372 | 373 | ### Каталог 374 | URL 375 | ``` 376 | /public/api/index.php 377 | ``` 378 | 379 | Все параметры запроса 380 | ``` 381 | query, search, xpage, sort, filter, rm, page, perPage 382 | ``` 383 | * query [string] = "catalog" 384 | * search [object]**?** = {genre:"genre1,genre2,genre3", year:"2017,2018"} 385 | * поле genre [string] – Список жанров разделенных через запятую 386 | * поле year [string] – Список годов разделенных через запятую 387 | * xpage [string]**?** – Где искать 388 | * "catalog" – В каталоге 389 | * sort [string]**?** – Сортировка 390 | * "1" – По популярности 391 | * "2" – По новизне 392 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 393 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 394 | * page [int/string]**?** – Номер страницы для списка релизов 395 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 396 | 397 | Используемые модели: 398 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 399 | * ["Модель пагинации"](#user-content-модель-пагинации) 400 | * ["Модель релиза"](#user-content-модель-релиза) 401 | * ["Модель серии"](#user-content-модель-серии) 402 | * ["Модель торрента"](#user-content-модель-торрента) 403 | * ["Модель блокировки"](#user-content-модель-релиза) 404 | * ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 405 | 406 |
Пример запроса 407 | ``` 408 | {"query":"catalog","page":"1","search":{"genre":"","year":"2019"},"xpage":"catalog","sort":"2"} - выведет 1 страницу с 3 релизами за 2019 года с сортировкой по новизне 409 | Ответ: 410 | { 411 | "status": true, 412 | "data": { 413 | "items": [МОДЕЛИ РЕЛИЗА], 414 | "pagination": {МОДЕЛЬ ПАГИНАЦИИ} 415 | }, 416 | "error": null 417 | } 418 | ``` 419 | 420 | ### Поиск по названию 421 | URL 422 | ``` 423 | /public/api/index.php 424 | ``` 425 | 426 | Все параметры запроса 427 | ``` 428 | query, search, filter, rm, page, perPage 429 | ``` 430 | * query [string] = "search" 431 | * search [string] – Название релиза 432 | * filter [string]**?** – Фильтрация выводимых полей, нужно передать строку с полями через сепаратор (пример: "id, names, description"). 433 | * rm [string]**?** – Если передать это поле, фильтр будет ИСКЛЮЧАТЬ поля 434 | * page [int/string]**?** – Номер страницы для списка релизов 435 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 436 | 437 | Используемые модели: 438 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 439 | * ["Модель пагинации"](#user-content-модель-пагинации) 440 | * ["Модель релиза"](#user-content-модель-релиза) 441 | * ["Модель серии"](#user-content-модель-серии) 442 | * ["Модель торрента"](#user-content-модель-торрента) 443 | * ["Модель блокировки"](#user-content-модель-релиза) 444 | * ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 445 | * ["Модель комментариев ВКонтакте"](#user-content-модель-комментариев-вконтакте) 446 | 447 |
Пример запроса 448 | ``` 449 | {"query":"search","search":"boruto"} 450 | Ответ: 451 | { 452 | "status": true, 453 | "data": { 454 | "items": [МОДЕЛИ РЕЛИЗА], 455 | "pagination": {МОДЕЛЬ ПАГИНАЦИИ} 456 | }, 457 | "error": null 458 | } 459 | ``` 460 | 461 | ### YouTube 462 | URL 463 | ``` 464 | /public/api/index.php 465 | ``` 466 | Параметры запроса 467 | ``` 468 | query, page, perPage 469 | ``` 470 | * query [string] = "youtube" 471 | * page [int/string]**?** – Номер страницы для списка релизов 472 | * perPage [int/string]**?** – Кол-во релизов на одну страницу 473 | 474 | Используемые модели: 475 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 476 | * ["Модель пагинации"](#user-content-модель-пагинации) 477 | * ["Модель YouTube"](#user-content-модель-youtube) 478 | 479 |
Пример запроса 480 | ``` 481 | {"query":"youtube"} 482 | Ответ: 483 | { 484 | "status": true, 485 | "data": [МОДЕЛИ YOUTUBE], 486 | "error": null 487 | } 488 | ``` 489 | 490 | ### Пользователь 491 | URL 492 | ``` 493 | /public/api/index.php 494 | ``` 495 | Параметры запроса 496 | ``` 497 | query 498 | ``` 499 | * query [string] = "user" 500 | 501 | Примечания: 502 | * Необходима авторизация 503 | 504 | Используемые модели: 505 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 506 | * ["Модель пользователя"](#user-content-пользователя) 507 | 508 |
Пример запроса 509 | ``` 510 | {"query":"user"} 511 | Ответ: 512 | { 513 | "status": true, 514 | "data": {МОДЕЛЬ ПОЛЬЗОВАТЕЛЯ}, 515 | "error": null 516 | } 517 | ``` 518 | 519 | ### Комментарии ВКонтакте 520 | URL 521 | ``` 522 | /public/api/index.php 523 | ``` 524 | Параметры запроса 525 | ``` 526 | query 527 | ``` 528 | * query [string] = "vkcomments" 529 | 530 | Используемые модели: 531 | * ["Базовая модель ответа"](#user-content-базовая-модель-ответа) 532 | * ["Модель комментариев ВКонтакте"](#user-content-модель-комментариев-вконтакте) 533 | 534 |
Пример запроса 535 | ``` 536 | {"query":"vkcomments"} 537 | Ответ: 538 | { 539 | "status": true, 540 | "data": {МОДЕЛЬ КОММЕНТАРИЕВ ВКОНТАКТЕ}, 541 | "error": null 542 | } 543 | ``` 544 | 545 | --- 546 | ### Модели данных 547 | 548 | ##### Базовая модель ответа 549 | ``` 550 | { 551 | "status": false, 552 | "data": null, 553 | "error": { 554 | "code": 400, 555 | "message": null, 556 | "description": null 557 | } 558 | } 559 | ``` 560 | * status [boolean] – true если запрос успешно выполнился, false - если произошла ошибка 561 | * data [object/array/any]**?** – Нужные данные 562 | * error [object]**?** – Объект ошибка 563 | * code [int] – Код ошибки, http код, либо специальный 564 | * message [string]**?** – Сообщение ошибки 565 | * description [string]**?** – Дополнительная информация, описание ошибки 566 | 567 | ##### Модель пагинации 568 | ``` 569 | { 570 | "page":0, 571 | "perPage":3, 572 | "allPages":211, 573 | "allItems":634 574 | } 575 | ``` 576 | * page [int] – Текущая страница 577 | * perPage [int] – Кол-во элементов на страница 578 | * allPages [int] – Кол-во всех страниц 579 | * allItems [int] – Кол-во всех элементов 580 | 581 | ##### Модель релиза 582 | ``` 583 | { 584 | "id":1202, 585 | "code":"sakurako-san-no-ashimoto-ni-wa-shitai-ga-umatteiru", 586 | "names":[ 587 | "Труп под ногами Сакурако", 588 | "Sakurako-san no Ashimoto ni wa Shitai ga Umatteiru" 589 | ], 590 | "series":"1-12", 591 | "poster":"/upload/release/350x500/default.jpg", 592 | "favorite": МОДЕЛЬ ИЗБРАННОГО В РЕЛИЗЕ, 593 | "last":"1202", 594 | "moon":"https://streamguard.cc/serial/f9f3c92e182de8c722ed0c13e8087558/iframe?nocontrols_translations=1", 595 | "status":"Завершен", 596 | "type":"ТВ (>12 эп.), 25 мин.", 597 | "genres":[ 598 | "приключения", 599 | "мистика", 600 | "детектив" 601 | ], 602 | "voices":[ 603 | "Mikrobelka", 604 | "HectoR", 605 | "Aemi" 606 | ], 607 | "year":"0", 608 | "day":"1", 609 | "description":"Описание релиза которое может содержать html", 610 | "blockedInfo": МОДЕЛЬ БЛОКИРОВКИ, 611 | "playlist":[ МОДЕЛЬ СЕРИИ ], 612 | "torrents":[ МОДЕЛЬ ТОРРЕНТА] 613 | } 614 | ``` 615 | Все поля Nullable, т.к. можно убрать их фильтром 616 | * id [int]**?** – ID релиза 617 | * code [string]**?** – Код релиза, используется для создания ссылки 618 | * names [array[string]]**?** – Список названий релиза. Пока-что максимум 2 названия может быть. Первое - Русское, второе - Английское. 619 | * series [string]**?** – Кол-во серий в релизе, используется при выводе списка релизов 620 | * poster [string]**?** – Относительны url на постер для списка 621 | * favorite [object]**?** – ["Модель избранного в релизе"](#user-content-модель-избранного-в-релизе) 622 | * last [???]**?** – По идеи должен быть timestamp последнего обновления релиза, но пока-что выводится его id и пока непонятно какого типа будет 623 | * moon [string]**?** – Ссылка на веб-плеер 624 | * status [string]**?** – Статус релиза текстом 625 | * type [string]**?** – Типа релиза 626 | * genres [array[string]]**?** – Список жанров 627 | * voices [array[string]]**?** – Список людей, которые озвучивали релиз 628 | * year [string]**?** – Год выпуска релиза 629 | * day [string]**?** – День недели, когда выходят новые серии 630 | * description [string]**?** – Описание релиза, может содержать html код 631 | * blockedInfo [object]**?** – ["Модель блокировки"](#user-content-модель-релиза) 632 | * playlist [array[object]]**?** – Список из ["Модель серии"](#user-content-модель-серии) 633 | * torrents [array[object]]**?** – Список из ["Модель торрента"](#user-content-модель-торрента) 634 | 635 | ##### Модель серии 636 | ``` 637 | { 638 | "id":1, 639 | "title":"Серия 1", 640 | "sd":"https:\/\/host.anilibria.tv\/videos\/ts\/0000\/0001-sd\/playlist.m3u8", 641 | "hd":"https:\/\/host.anilibria.tv\/videos\/ts\/0000\/0001\/playlist.m3u8", 642 | "fullhd":"https:\/\/host.anilibria.tv\/videos\/ts\/0000\/0001-hd\/playlist.m3u8", 643 | "srcSd":"https:\/\/host.anilibria.tv\/get\/somestring\/somenumber\/mp4\/0000\/0001-sd.mp4?download=Release Name-1-sd.mp4", 644 | "srcHd":"https:\/\/host.anilibria.tv\/get\/somestring\/somenumber\/mp4\/0000\/0001.mp4?download=Release Name-1-hd.mp4" 645 | } 646 | ``` 647 | * id [int] – ID серии, по сути это номер серии 648 | * title [string] – Название для отображения в списке серий 649 | * sd [string] – Ссылка на SD плейлист для онлайн плеера 650 | * hd [string] – Ссылка на HD плейлист для онлайн плеера 651 | * fullhd [string]**?** – Ссылка на FullHD плейлист для онлайн плеера (поле опциональное) 652 | * srcSd [string]**?** - Ссылка на SD файл для скачивания 653 | * srcHd [string]**?** - Ссылка на HD файл для скачивания 654 | 655 | ##### Модель торрента 656 | ``` 657 | { 658 | "id":977, 659 | "hash":"99b8dff0ce599c463f84ce23896fc285c892cfad", 660 | "leechers":0, 661 | "seeders":0, 662 | "completed":3845, 663 | "quality":"HDTV-Rip 720p", 664 | "series":"1-12", 665 | "size":3938641843, 666 | "url":"/upload/torrents/977.torrent" 667 | } 668 | ``` 669 | * id [int] – ID торрента 670 | * hash [string] – Хеш 671 | * leechers [int] – Скачивающие 672 | * seeders [int] – Раздающие 673 | * completed [int] – Возможно кол-во загрузок торрента 674 | * quality [string] – Качество 675 | * series [string] – Кол-во серий 676 | * size [long] – Размер файлов торрента, в байтах 677 | * url [string] – относительный путь до торрента. Вид ссылки может меняться 678 | 679 | ##### Модель блокировки 680 | ``` 681 | { 682 | "blocked":false, 683 | "reason":null 684 | } 685 | ``` 686 | * blocked [boolean] – Релиз заблокирован (по авторскому праву или еще что, разные ситуации бывают) 687 | * reason [string]**?** – Причина блокировки 688 | 689 | ##### Модель избранного в релизе 690 | ``` 691 | { 692 | "rating":421, 693 | "added":false 694 | } 695 | ``` 696 | * rating [int] – Рейтинг релиза (кол-во пользователей, которые добавили его в избранное) 697 | * added [boolean] – Флаг того, что добавлен релиз в твоё избранное 698 | 699 | ##### Модель ленты 700 | ``` 701 | { 702 | "release": {МОДЕЛЬ РЕЛИЗА}, 703 | "youtube": {МОДЕЛЬ YOUTUBE} 704 | } 705 | ``` 706 | * release [object]**?** – ["Модель релиза"](#user-content-модель-релиза) 707 | * youtube [object]**?** – ["Модель YouTube"](#user-content-модель-youtube) 708 | 709 | ##### Модель расписания 710 | ``` 711 | { 712 | "day": "1", 713 | "items": [МОДЕЛИ РЕЛИЗА] 714 | } 715 | ``` 716 | * day [string] – День недели. (1 - понедельник, 7 - воскресенье). 717 | * items [array[object]] – Массив ["Модель релиза"](#user-content-модель-релиза) 718 | 719 | ##### Модель случайного релиза 720 | ``` 721 | { 722 | "code": "boruto-naruto-next-generations" 723 | } 724 | ``` 725 | * code [string] – Код релиза 726 | 727 | ##### Модель жанра 728 | ``` 729 | "genre1" 730 | ``` 731 | * Просто строка 732 | 733 | ##### Модель года 734 | ``` 735 | "2019" 736 | ``` 737 | * Просто строка 738 | 739 | ##### Модель пользователя 740 | ``` 741 | { 742 | "id":0, 743 | "login":"testuser", 744 | "avatar":"/upload/avatars/img.jpg" 745 | } 746 | ``` 747 | * id [int] – ID пользователя 748 | * login [string] – Логин пользователя 749 | * avatar [string] – Ссылка на аватар пользователя 750 | 751 | ##### Модель YouTube 752 | ``` 753 | { 754 | "id":64, 755 | "title":"С АНИДАБОМ ЧТО-ТО НЕ ТАК \/ +СТРАЙК КАНАЛУ | ЛЛН", 756 | "image":"\/upload\/youtube\/a73cc011.jpg", 757 | "vid":"zeQtOtNad7o", 758 | "views":19966, 759 | "comments":690, 760 | "timestamp":1549102230 761 | } 762 | ``` 763 | * id [int] – ID айтема 764 | * title [string] – Заголовок 765 | * image [string] – Ссылка на превью видео 766 | * vid [string] – ID на youtube 767 | * views [int] – Кол-во просмотров на youtube 768 | * comments [int] – Кол-во комментариев на youtube 769 | * timestamp [int] – Timestamp создания айтема в секундах 770 | 771 | ##### Модель комментариев ВКонтакте 772 | ``` 773 | { 774 | "baseUrl":"https://dev.anilibria.tv/", 775 | "script":"
" 776 | } 777 | ``` 778 | * baseUrl [string] – Базовый урл для webview, чтобы виджет думал, что он на реальном сайте 779 | * script [string] – Необходимый HTML для работы виджета комментариев 780 | 781 | -------------------------------------------------------------------------------- /api_v2.md: -------------------------------------------------------------------------------- 1 | # AniLibria API – v2.13.18 2 | 3 | > :warning: **Внимание**: 4 | > 5 | > **После выхода версии v2.13.0 поддержка всех предыдущих версий API до v2.12.0 была прекращена!** 6 | > 7 | >В связи с переходом на новый бэкэнд сайта с существенными изменениями в архитектуре проекта. 8 | 9 | - [**RestAPI**](#restapi) – *Документация по RestAPI* 10 | - [**WebSocket**](#websocket) – *Документация по WebSocket* 11 | 12 | ## RestAPI 13 | ``` 14 | http(s)://api.anilibria.tv/v2/ 15 | ``` 16 | 17 | # Список методов: 18 | 19 | ## Открытые методы 20 | - [**getTitle**](#-gettitle) – *Получить информацию о тайтле* 21 | - [**getTitles**](#-gettitles) – *Получить информацию о нескольких тайтлах сразу* 22 | - [**getUpdates**](#-getupdates) – *Список тайтлов, отсортированные по времени добавления нового релиза* 23 | - [**getChanges**](#-getchanges) – *Список тайтлов, отсортированные по времени изменения* 24 | - [**getSchedule**](#-getschedule) – *Расписание выхода тайтлов, отсортированное по дням недели* 25 | - [**getRandomTitle**](#-getrandomtitle) – *Возвращает случайный тайтл из базы* 26 | - [**getYouTube**](#-getyoutube) – *Информация о вышедших роликах на наших YouTube каналах в хронологическом порядке* 27 | - [**getFeed**](#-getfeed) – *Список обновлений тайтлов и роликов на наших YouTube каналах в хронологическом порядке* 28 | - [**getYears**](#-getyears) – *Возвращает список годов выхода доступных тайтлов по возрастанию* 29 | - [**getGenres**](#-getgenres) – *Возвращает список всех жанров по алфавиту* 30 | - [**getCachingNodes**](#-getcachingnodes) – *Возвращает список кеш серверов, с которых можно брать данные* 31 | - [**getTeam**](#-getteam) – *Возвращает список участников команды, когда-либо существовавших на проекте.* 32 | - [**getSeedStats**](#-getseedstats) – *Возвращает список пользователей и их статистику на трекере.* 33 | - [**getRSS**](#-getrss) – *Возвращает список обновлений на сайте в одном из форматов RSS ленты* 34 | - [**searchTitles**](#-searchtitles) – *Возвращает список найденных по фильтрам тайтлов* 35 | - [**advancedSearch**](#-advancedsearch) – *Поиск информации по продвинутым фильтрам с поддержкой сортировки* 36 | 37 | ## Пользовательские методы, требующие авторизации 38 | - [**getFavorites**](#-getfavorites) – *Возвращает список избранных тайтлов пользователя* 39 | - [**addFavorite**](#-addfavorite) – *Добавляет тайтл в список избранных* 40 | - [**delFavorite**](#-delfavorite) – *Удаляет тайтл из списка избранных* 41 | 42 | # Описание методов: 43 | 44 | ## • getTitle 45 | Получить информацию о тайтле по id или коду 46 | 47 | ```js 48 | GET /v2/getTitle 49 | ``` 50 | 51 | ### Все доступные параметры 52 | | Параметр | Тип | Описание | По умолчанию | 53 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 54 | | id | int | ID тайтла | | 55 | | code | string | Код тайтла | | 56 | | torrent_id | int | ID торрент файла | | 57 | | filter | string, ... | Список значений, которые будут в ответе | | 58 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 59 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 60 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 61 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 62 | 63 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 64 | 65 | ### Примеры запросов 66 | ```js 67 | /v2/getTitle?id=8500&filter=posters,type,status,player.playlist.24 68 | ``` 69 | ```js 70 | /v2/getTitle?code=nanatsu-no-taizai-kamigami-no-gekirin 71 | ``` 72 | 73 | ### Пример ответа 74 | ```json 75 | { 76 | "id": 8500, 77 | "code": "nanatsu-no-taizai-kamigami-no-gekirin", 78 | "names": { 79 | "ru": "Семь смертных грехов: Гнев богов ТВ-3", 80 | "en": "Nanatsu no Taizai: Kamigami no Gekirin TV-3", 81 | "alternative": null 82 | }, 83 | "announce": "В 24 серии замена войсера. В течение недели будет исправление.", 84 | "status": { 85 | "string": "Завершен", 86 | "code": 2 87 | }, 88 | "posters": { 89 | "small": { 90 | "url": "/storage/releases/posters/8500/W4Q1mG49XVQnOUnc.jpg", 91 | "raw_base64_file": null 92 | }, 93 | "medium": { 94 | "url": "/storage/releases/posters/8500/W4Q1mG49XVQnOUnc.jpg", 95 | "raw_base64_file": null 96 | }, 97 | "original": { 98 | "url": "/storage/releases/posters/8500/W4Q1mG49XVQnOUnc.jpg", 99 | "raw_base64_file": null 100 | } 101 | }, 102 | "updated": 1585249972, 103 | "last_change": 1642539074, 104 | "type": { 105 | "full_string": "ТВ (24 эп.), 25 мин.", 106 | "code": 1, 107 | "string": "TV", 108 | "series": 24, 109 | "length": 25 110 | }, 111 | "genres": [ 112 | "Магия", 113 | "Приключения", 114 | "Сверхъестественное", 115 | "Сёнен", 116 | "Экшен" 117 | ], 118 | "team": { 119 | "voice": [ 120 | "Anzen", 121 | "Cleo-chan", 122 | "Hekomi", 123 | "Kari", 124 | "Sharon" 125 | ], 126 | "translator": [ 127 | "Anku" 128 | ], 129 | "editing": [ 130 | "mutagenb" 131 | ], 132 | "decor": [], 133 | "timing": [ 134 | "Alkhorus" 135 | ] 136 | }, 137 | "season": { 138 | "string": "осень", 139 | "code": 4, 140 | "year": 2019, 141 | "week_day": 4 142 | }, 143 | "description": "Продолжение аниме «Семь смертных грехов» расскажет нам о том, как Грехи продолжают противостояние с Десятью Заповедями. Мелиодасу и Элизабет предстоит вновь испытать свою судьбу в новых приключениях и сражениях, а также открыть секрет этого мира.", 144 | "in_favorites": 10333, 145 | "blocked": { 146 | "blocked": false, 147 | "bakanim": false 148 | }, 149 | "player": { 150 | "alternative_player": "//kodik.info/serial/19248/803944eb832adacd4d4bec7d4221f941/720p?translations=false", 151 | "host": "de4.libria.fun", 152 | "series": { 153 | "first": 1, 154 | "last": 24, 155 | "string": "1-24" 156 | }, 157 | "playlist": { 158 | "1": { 159 | "serie": 1, 160 | "created_timestamp": 1570809272, 161 | "preview": null, 162 | "skips": { 163 | "opening": [], 164 | "ending": [] 165 | }, 166 | "hls": { 167 | "fhd": "/videos/media/ts/8500/1/1080/6a6fc29f9428b2dcc8ce74ad21bb1cca.m3u8", 168 | "hd": "/videos/media/ts/8500/1/720/8e5d9ba9e79d80ca6b6db6e6e375b4bb.m3u8", 169 | "sd": "/videos/media/ts/8500/1/480/93048587fb765c9f2077ca7adad9457e.m3u8" 170 | } 171 | }, 172 | ... 173 | }, 174 | "torrents": { 175 | "series": { 176 | "first": 1, 177 | "last": 24, 178 | "string": "1-24" 179 | }, 180 | "list": [ 181 | { 182 | "torrent_id": 10725, 183 | "series": { 184 | "first": 1, 185 | "last": 24, 186 | "string": "1-24" 187 | }, 188 | "quality": { 189 | "string": "WEBRip 1080p", 190 | "type": "WEBRip", 191 | "resolution": "1080p", 192 | "encoder": "h264", 193 | "lq_audio": null 194 | }, 195 | "leechers": 1, 196 | "seeders": 17, 197 | "downloads": 10692, 198 | "total_size": 35521275317, 199 | "url": "/public/torrent/download.php?id=10725", 200 | "uploaded_timestamp": 1590483840, 201 | "hash": "e45884bf43636bf61512a6c5eb1b7b9b0e84a925", 202 | "metadata": null, 203 | "raw_base64_file": null 204 | }, 205 | ... 206 | ] 207 | } 208 | } 209 | ``` 210 | *** 211 | 212 | ## • getTitles 213 | Получить информацию о тайтле по id или коду 214 | ```js 215 | GET /v2/getTitles 216 | ``` 217 | 218 | ### Все доступные параметры 219 | | Параметр | Тип | Описание | По умолчанию | 220 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 221 | | id_list | string, ... | Список ID тайтлов | | 222 | | code_list | string, ... | Список кодов тайтла | | 223 | | filter | string, ... | Список значений, которые будут в ответе | | 224 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 225 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 226 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 227 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 228 | 229 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 230 | 231 | ### Примеры запросов 232 | ```js 233 | /v2/getTitles?id_list=8500,8644&filter=posters,type,status,player.playlist.24 234 | ``` 235 | ```js 236 | /v2/getTitles?code_list=nanatsu-no-taizai-kamigami-no-gekirin 237 | ``` 238 | 239 | ### Пример ответа 240 | ```json 241 | [ 242 | [Возвращаемые поля идентичны /getTitle], 243 | ... 244 | ] 245 | ``` 246 | *** 247 | 248 | 249 | ## • getUpdates 250 | Получить список последних обновлений тайтлов 251 | 252 | ```js 253 | GET /v2/getUpdates 254 | ``` 255 | 256 | ### Все доступные параметры 257 | 258 | | Параметр | Тип | Описание | По умолчанию | 259 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 260 | | filter | string, ... | Список значений, которые будут в ответе | | 261 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 262 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 263 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 264 | | since | int | Список тайтлов, у которых время обновления больше указанного timestamp | | 265 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 266 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 267 | | after | int | Удаляет первые n записей из выдачи | 268 | 269 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 270 | 271 | ### Примеры запросов 272 | ```js 273 | /api/v2/getUpdates?filter=posters,type,status&limit=5 274 | ``` 275 | ```js 276 | /api/v2/getUpdates?since=1590233417 277 | ``` 278 | ### Пример ответа 279 | 280 | ```json 281 | [ 282 | [Возвращаемые поля идентичны /getTitle], 283 | ... 284 | ] 285 | ``` 286 | *** 287 | 288 | ## • getChanges 289 | Получить список последних обновлений тайтлов 290 | 291 | ```js 292 | GET /v2/getChanges 293 | ``` 294 | 295 | ### Все доступные параметры 296 | | Параметр | Тип | Описание | По умолчанию | 297 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 298 | | filter | string, ... | Список значений, которые будут в ответе | | 299 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 300 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 301 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 302 | | since | int | Список тайтлов, у которых время обновления больше указанного timestamp | | 303 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 304 | | after | int | Удаляет первые n записей из выдачи | | 305 | 306 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 307 | 308 | ### Примеры запросов 309 | ```js 310 | /v2/getChanges?filter=posters,type,status&limit=5 311 | ``` 312 | ```js 313 | /v2/getChanges?since=1590233417 314 | ``` 315 | ### Пример ответа 316 | 317 | ```json 318 | [ 319 | [Возвращаемые поля идентичны /getTitle], 320 | ... 321 | ] 322 | ``` 323 | *** 324 | 325 | 326 | ## • getSchedule 327 | Получить список последних обновлений тайтлов 328 | 329 | ```js 330 | GET /v2/getSchedule 331 | ``` 332 | 333 | ### Все доступные параметры 334 | | Параметр | Тип | Описание | По умолчанию | 335 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 336 | | filter | string, ... | Список значений, которые будут в ответе | | 337 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 338 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 339 | | days | string, ... | Список дней недели на которые нужно расписание | | 340 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 341 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 342 | 343 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 344 | 345 | > Счет дней недели идет с понедельника, где 0 - Понедельник, а 6 - Воскресенье. 346 | 347 | ### Примеры запросов 348 | ```js 349 | /v2/getSchedule?filter=posters,type,status 350 | ``` 351 | ```js 352 | /v2/getSchedule?days=5,6 353 | ``` 354 | ### Пример ответа 355 | 356 | ```json 357 | [ 358 | { 359 | "day": 5, 360 | "list": [ 361 | [Возвращаемые поля идентичны /getTitle], 362 | ... 363 | ] 364 | },{ 365 | "day": 6, 366 | "list": [ 367 | [Возвращаемые поля идентичны /getTitle], 368 | ... 369 | ] 370 | } 371 | ] 372 | ``` 373 | *** 374 | 375 | 376 | ## • getCachingNodes 377 | Список кеш серверов с которых можно брать данные отсортированные по нагрузке 378 | Севера сортируются в реальном времени, по этому рекомендуется для каждого сервера использовать один из самых верхних серверов. 379 | 380 | ```js 381 | GET /v2/getCachingNodes 382 | ``` 383 | 384 | ### Примеры запросов 385 | ```js 386 | /v2/getCachingNodes 387 | ``` 388 | ### Пример ответа 389 | 390 | ```json 391 | [ 392 | "de3.libria.fun", 393 | "de2.libria.fun", 394 | "de8.libria.fun", 395 | "de1.libria.fun", 396 | "de6.libria.fun" 397 | ] 398 | ``` 399 | *** 400 | 401 | 402 | ## • getRandomTitle 403 | Возвращает случайный тайтл из базы 404 | 405 | ```js 406 | GET /v2/getRandomTitle 407 | ``` 408 | 409 | ### Все доступные параметры 410 | | Параметр | Тип | Описание | По умолчанию | 411 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 412 | | filter | string, ... | Список значений, которые будут в ответе | | 413 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 414 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 415 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 416 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 417 | 418 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 419 | 420 | ### Примеры запросов 421 | ```js 422 | /v2/getRandomTitle 423 | ``` 424 | ### Пример ответа 425 | 426 | ```json 427 | { 428 | [Возвращаемые поля идентичны /getTitle], 429 | } 430 | ``` 431 | *** 432 | 433 | 434 | ## • getYouTube 435 | Информация о вышедших роликах на наших YouTube каналах в хронологическом порядке 436 | 437 | ```js 438 | GET /v2/getYouTube 439 | ``` 440 | 441 | ### Все доступные параметры 442 | | Параметр | Тип | Описание | По умолчанию | 443 | | --------------- | ----------- | --------------------------------------------------------------------------- | ------------ | 444 | | filter | string, ... | Список значений, которые будут в ответе | | 445 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 446 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 447 | | since | int | Список видеороликов, у которых время обновления больше указанного timestamp | | 448 | | after | int | Удаляет первые n записей из выдачи | | 449 | 450 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 451 | 452 | ### Примеры запросов 453 | ```js 454 | /v2/getYouTube?limit=10 455 | ``` 456 | ### Пример ответа 457 | 458 | ```json 459 | [ 460 | { 461 | "id": 10861, 462 | "title": "АНИМЕ Своя игра с АниЛибрией (Люпин, Шарон, Зозя, Сахарочек, Рокетту, Никанор47)", 463 | "image": "https://img.youtube.com/vi/rvhfqzXXZaU/0.jpg", 464 | "youtube_id": "rvhfqzXXZaU", 465 | "comments": 29, 466 | "views": 7911, 467 | "timestamp": 1656844874 468 | }, 469 | ... 470 | } 471 | ``` 472 | *** 473 | 474 | 475 | ## • getFeed 476 | Список обновлений тайтлов и роликов на наших YouTube каналах в хронологическом порядке 477 | 478 | ```js 479 | GET /v2/getFeed?filter= 480 | ``` 481 | 482 | ### Все доступные параметры 483 | | Параметр | Тип | Описание | По умолчанию | 484 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 485 | | filter | string, ... | Список значений, которые будут в ответе | | 486 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 487 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 488 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 489 | | since | int | Список тайтлов, у которых время обновления больше указанного timestamp | | 490 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 491 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 492 | | after | int | Удаляет первые n записей из выдачи | | 493 | 494 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 495 | 496 | ### Примеры запросов 497 | ```js 498 | /v2/getFeed?limit=10 499 | ``` 500 | ### Пример ответа 501 | 502 | ```json 503 | [ 504 | { 505 | "youtube": { 506 | [Возвращаемые поля идентичны /getYouTube] 507 | } 508 | }, 509 | { 510 | "youtube": { 511 | [Возвращаемые поля идентичны /getYouTube] 512 | } 513 | }, 514 | { 515 | "title": { 516 | [Возвращаемые поля идентичны /getTitle] 517 | } 518 | }, 519 | ... 520 | ] 521 | ``` 522 | *** 523 | 524 | 525 | ## • getYears 526 | Возвращает список годов выхода доступных тайтлов отсортированный по возрастанию 527 | 528 | ```js 529 | GET /v2/getYears 530 | ``` 531 | 532 | ### Примеры запросов 533 | ```js 534 | /v2/getYears 535 | ``` 536 | ### Пример ответа 537 | 538 | ```json 539 | [ 540 | 1996, 541 | 1998, 542 | 2001, 543 | 2003, 544 | ... 545 | ] 546 | ``` 547 | *** 548 | 549 | 550 | ## • getGenres 551 | Возвращает список жанров доступных тайтлов отсортированный по алфавиту 552 | 553 | ```js 554 | GET /v2/getGenres 555 | ``` 556 | 557 | ### Все доступные параметры 558 | | Параметр | Тип | Описание | По умолчанию | 559 | | ------------ | ---------------------------- | ------------------------ | ------------ | 560 | | sorting_type | int | Тип сортировки элементов | 0 | 561 | | | `0 - Сортировка по алфавиту` | | | 562 | | | `1 - Сортировка по рейтингу` | | | 563 | 564 | ### Примеры запросов 565 | ```js 566 | /v2/getGenres 567 | ``` 568 | 569 | ### Пример ответа 570 | 571 | ```json 572 | [ 573 | "боевые искусства", 574 | "вампиры", 575 | "демоны", 576 | ... 577 | ] 578 | ``` 579 | *** 580 | 581 | 582 | ## • searchTitles 583 | Возвращает список найденных по фильтрам тайтлов 584 | 585 | ```js 586 | GET /v2/searchTitles 587 | ``` 588 | 589 | ### Все доступные параметры 590 | | Параметр | Тип | Описание | По умолчанию | 591 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 592 | | search | string, ... | Поиск по именам и описанию | | 593 | | year | string, ... | Список годов выхода | | 594 | | season_code | string, ... | Список сезонов, [подробнее](#season) | | 595 | | genres | string, ... | Список жанров | | 596 | | voice | string, ... | Список войсеров через запятую | | 597 | | translator | string, ... | Список переводчиков | | 598 | | editing | string, ... | Список сабберов | | 599 | | decor | string, ... | Список оформителей | | 600 | | timing | string, ... | Список таймеров | | 601 | | filter | string, ... | Список значений, которые будут в ответе | | 602 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 603 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 604 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 605 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 606 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 607 | | after | int | Удаляет первые n записей из выдачи | | 608 | 609 | ### Примеры запросов 610 | ```js 611 | /v2/searchTitles?search=cудьба апокреф&voice=Amikiri,Silv,Hekomi&filter=id,names,team,genres[0]&limit=10 612 | ``` 613 | > Поиск идет по неточному совпадению, так что опечатки допустимы. 614 | 615 | ### Пример ответа 616 | 617 | ```json 618 | { 619 | [Возвращаемые поля идентичны /getTitle] 620 | } 621 | ``` 622 | *** 623 | 624 | ## • advancedSearch 625 | Возвращает список найденных по фильтрам тайтлов 626 | 627 | ```js 628 | GET /v2/advancedSearch 629 | ``` 630 | 631 | ### Все доступные параметры 632 | | Параметр | Тип | Описание | По умолчанию | 633 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 634 | | [query](#query) | string | **Обязательный параметр** Фильтр, по которому будет идти выборка, [подробнее](#query) | | 635 | | filter | string, ... | Список значений, которые будут в ответе | | 636 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 637 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 638 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 639 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 640 | | [limit](#limit) | int | Количество объектов в ответе, [подробнее](#limit) | 5 | 641 | | after | int | Удаляет первые n записей из выдачи | | 642 | | order_by | string | Ключ, по которому будет происходить сортировка результатов | | 643 | | sort_direction | int | Направление сортировки. 0 - По возрастанию, 1 - По убыванию | 0 | 644 | 645 | ### Примеры запросов 646 | ```js 647 | /v2/advancedSearch?query={season.code} == 1 and {season.year} == 2020&filter=id,names,in_favorites&order_by=in_favorites&sort_direction=0 648 | ``` 649 | 650 | ### Пример ответа 651 | 652 | ```json 653 | { 654 | [Возвращаемые поля идентичны /getTitle] 655 | } 656 | ``` 657 | *** 658 | 659 | 660 | ## • getTeam 661 | Возвращает список участников команды когда-либо существовавших на проекте. 662 | 663 | ```js 664 | GET /v2/getTeam 665 | ``` 666 | 667 | ### Примеры запросов 668 | ```js 669 | /v2/getTeam 670 | ``` 671 | 672 | ### Пример ответа 673 | 674 | ```json 675 | { 676 | "team": { 677 | "voice": [...], 678 | "translator": [...], 679 | "editing": [...], 680 | "decor": [...], 681 | "timing": [...] 682 | } 683 | } 684 | ``` 685 | 686 | 687 | ## • getSeedStats 688 | Возвращает топ пользователей по количеству загруженного и скачанного через наш торрент трекер. 689 | 690 | ```js 691 | GET /v2/getSeedStats 692 | ``` 693 | 694 | ### Все доступные параметры 695 | | Параметр | Тип | Описание | По умолчанию | 696 | | --------------- | ----------- | -------------------------------------------------------------------------------------- | ------------ | 697 | | users | string, ... | Статистика по имени пользователя | | 698 | | filter | string, ... | Список значений, которые будут в ответе | | 699 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 700 | | [limit](#limit) | int | Количество объектов в ответе | 5 | 701 | | after | int | Удаляет первые n записей из выдачи | | 702 | | sort_by | string | По какому полю производить сортировку, допустимые значения: downloaded, uploaded, user | | 703 | | order | int | Направление сортировки 0 - DESC, 1 - ASC | | 704 | 705 | ### Примеры запросов 706 | ```js 707 | /v2/getSeedStats?users=T1MOX4 708 | ``` 709 | 710 | ### Пример ответа 711 | 712 | ```json 713 | [ 714 | { 715 | "downloaded": 72110162198, 716 | "uploaded": 1163165762554, 717 | "user": "T1MOX4" 718 | } 719 | ] 720 | ``` 721 | 722 | ## • getRSS 723 | Возвращает список обновлений на сайте в одном из форматов RSS ленты 724 | 725 | ```js 726 | GET /v2/getRSS 727 | ``` 728 | 729 | ### Все доступные параметры 730 | | Параметр | Тип | Описание | По умолчанию | 731 | | --------------------- | ------ | ---------------------------------------------------------------------- | ------------ | 732 | | [rss_type](#rss_type) | string | Предпочитаемый формат вывода | rss | 733 | | [session](#session) | string | Уникальный идентификатор сессии пользователя | | 734 | | [limit](#limit) | int | Количество объектов в ответе | 10 | 735 | | since | int | Список тайтлов, у которых время обновления больше указанного timestamp | | 736 | | after | int | Удаляет первые n записей из выдачи | | 737 | 738 | * Если указан верный параметр session, то загрузка торрентов будет происходить от имени вашего аккаунта, и вам будет начисляться статистика. 739 | * В случае если ключ указан неверно торрент клинт будет возвращать ошибку о неправильном формате торрента. 740 | 741 | ### Примеры запросов 742 | ```js 743 | /v2/getRSS?rss_type=atom&limit=5 744 | ``` 745 | 746 | ### Пример ответа 747 | 748 | ```xml 749 | 750 | 751 | Самое свежее на AniLibria.TV 752 | https://anilibria.tv/ 753 | Самое свежие релизы AniLibria.TV 754 | Wed, 07 Apr 2021 17:59:24 GMT 755 | https://validator.w3.org/feed/docs/rss2.html 756 | AniLibria API v2.11.2 757 | ru 758 | 759 | 760 | <![CDATA[ Золотое божество 3 / Golden Kamuy 3 | 1-8 [WEBRip 1080p HEVC] ]]> 761 | 762 | https://www.anilibria.tv/release/golden-kamuy-3.html 763 | 12848 764 | Tue, 08 Dec 2020 13:50:54 GMT 765 | 766 | 767 | 768 | 769 | 770 | ... 771 | 772 | 773 | ``` 774 | 775 | ## Пользовательские методы, для которых нужна авторизация 776 | 777 | ## • getFavorites 778 | Возвращает список избранных тайтлов пользователя 779 | 780 | ```js 781 | GET /v2/getFavorites 782 | ``` 783 | 784 | ### Все доступные параметры 785 | | Параметр | Тип | Описание | Обязательный | 786 | | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------- | ------------ | 787 | | [session](#session) | string | Уникальный идентификатор сессии пользователя | + | 788 | | filter | string, ... | Список значений, которые будут в ответе | | 789 | | remove | string, ... | Список значений, которые будут удалены из ответа | | 790 | | [include](#include) | string, ... | Список типов файлов, которые будут возвращены в виде base64 строки [подробнее](#include) | | 791 | | [description_type](#description_type) | string | Тип получаемого описания, [подробнее](#description_type) | plain | 792 | | playlist_type | string | Формат получаемого списка серий, `object` или `array` | object | 793 | 794 | *В параметрах `filter` и `remove` можно указать полный путь до ключа, который вы хотите оставить или удалить, например: `names.alternative` или `team.voice[0]`. С версии 2.8 появилась возможность получать значения одного ключа во всех объектах в массиве, например: torrents.list[\*].torrent_id* 795 | 796 | ### Примеры запросов 797 | ```js 798 | /v2/getFavorites?session=qwertyqwertyqwerty1234567890 799 | ``` 800 | 801 | ### Пример ответа 802 | 803 | ```json 804 | [ 805 | [Возвращаемые поля идентичны /getTitle], 806 | ... 807 | ] 808 | ``` 809 | 810 | ## • addFavorite 811 | Добавить тайтл в список избранных 812 | 813 | ```js 814 | PUT /v2/addFavorite 815 | ``` 816 | 817 | ### Все доступные параметры 818 | | Параметр | Тип | Описание | Обязательный | 819 | | ------------------- | ------ | -------------------------------------------- | ------------ | 820 | | [session](#session) | string | Уникальный идентификатор сессии пользователя | + | 821 | | title_id | int | ID тайтла который вы хотите добавить | + | 822 | 823 | 824 | ### Примеры запросов 825 | ```js 826 | /v2/addFavorite?session=qwertyqwertyqwerty1234567890&title_id=8500 827 | ``` 828 | 829 | ### Пример ответа 830 | 831 | ```json 832 | { 833 | "success": true 834 | } 835 | ``` 836 | 837 | ## • delFavorite 838 | Удалить тайтл из списка избранных 839 | 840 | ```js 841 | DELETE /v2/delFavorite 842 | ``` 843 | 844 | ### Все доступные параметры 845 | | Параметр | Тип | Описание | Обязательный | 846 | | ------------------- | ------ | -------------------------------------------- | ------------ | 847 | | [session](#session) | string | Уникальный идентификатор сессии пользователя | + | 848 | | title_id | int | ID тайтла который вы хотите удалить | + | 849 | 850 | 851 | ### Примеры запросов 852 | ```js 853 | /v2/delFavorite?session=qwertyqwertyqwerty1234567890&title_id=8500 854 | ``` 855 | 856 | ### Пример ответа 857 | 858 | ```json 859 | { 860 | "success": true 861 | } 862 | ``` 863 | 864 | ### Возвращаемые значения при запросе информации о тайтле 865 | 866 | id **int** – ID тайтла 867 | code **string** – Код тайтла, используется для создания ссылки 868 | [names](#names) **object** – Названия тайтла. 869 | [posters](#posters) **object** – Информация о постере 870 | updated **int** – Timestamp последнего обновления тайтла (обычно тайтл обновляют при выходе новых релизов) 871 | last_change **int** – Timestamp последнего изменения тайтла (Например описания, или анонса) 872 | [status](#status) **object** – Статус тайтла 873 | [type](#type) **object** – Типа тайтла 874 | genres **array[string]** – Список жанров 875 | [team](#team) **object** – Ники членов команды работавших над тайтлом 876 | [season](#season) **object** – Сезон, год выхода, и день недели из расписания когда выходят новые серии 877 | year **int** – Год выпуска тайтла 878 | week_day **int** – День недели, когда выходят новые релизы 879 | description **string** – Описание тайтла в указанном в [description_type](#description_type) формате 880 | [blocked](#blocked) **object** – Информация о блокировках тайтла 881 | [player](#player) **object** – Информация о сериях в плеере 882 | [torrents](#torrents) **object** – Информация о торрент файлах 883 | 884 | ### Возвращаемые значения при запросе информации о youtube ролике 885 | 886 | id **int** – ID записи в базе 887 | title **string** – Название видео ролика 888 | image **string** – Ссылка на превью к ролику 889 | youtube_id **string** – ID видео на YouTube (Легко форматируется в https://youtu.be/{youtube_id}) 890 | timestamp **int** – Timestamp времени добавления в базу 891 | comments **int** - Количество комментариев у ролика 892 | views **int** - Количество просмотров у ролика 893 | 894 | >*В случае отсутствия какой-то информации значения поля будет `null` для строк, пустой массив для массивов, и 0 для чисел* 895 | >*Такое редко, но бывает.* 896 | 897 | ### Описание возвращаемых объектов 898 | 899 | #### names: 900 | > ru **string** – Русское название тайтла 901 | > en **string** – Английское название тайтла 902 | > alternative **string** – Альтернативное название 903 | 904 | #### posters: 905 | > [small](#poster) **object** – Постер маленького размера 906 | > [medium](#poster) **object** – Постер среднего размера 907 | > [original](#poster) **object** – Оригинальный и самый большой постер 908 | 909 | ##### poster: 910 | > url **string** – Относительный url на постер 911 | > raw_base64_file **string** – Постер в base64 формате (если запрошен в параметре [include](#include)) 912 | 913 | #### series: 914 | > string **string** – Количество серий в виде строки 915 | > first **int** – Первая серия 916 | > last **int** – Последняя серия 917 | 918 | #### status: 919 | > string **string** – Статус тайтла в виде строки 920 | > code **int** – Статус тайтла в виде числа 921 | >> 1 – В работе 922 | >> 2 – Завершен 923 | >> 3 – Скрыт 924 | >> 4 – Неонгоинг 925 | 926 | #### type: 927 | > full_string **string** – Тип тайтла целиком в виде строки (как это указано на сайте) 928 | > string **string** – Тип тайтла в виде строки 929 | > series **int** – Ожидаемое количество серий 930 | > length **string** – Длительность серий 931 | > code **int** – Тип тайтла в виде числа 932 | >> 0 – Фильм 933 | >> 1 – TV 934 | >> 2 – OVA 935 | >> 3 – ONA 936 | >> 4 – Спешл 937 | >> 5 - WEB 938 | 939 | #### team: 940 | > voice **array[string]** – Список войсеров работавших над озвучкой. 941 | > translator **array[string]** – Список участников команды работавших над переводом. 942 | > editing **array[string]** – Список участников команды работавших над субтитрами. 943 | > decor **array[string]** – Список участников команды работавших над оформлением. 944 | > timing **array[string]** – Список участников команды работавших над таймингом. 945 | 946 | #### season: 947 | > year **int** – Список войсеров работавших над озвучкой 948 | > week_day **int** – День недели. Счет дней недели идет с понедельника, где 0 - Понедельник, а 6 - Воскресенье. 949 | > string **string** – Название сезона в котором вышел тайтл. 950 | > code **int** – Код сезона в котором вышел тайтл. 951 | >> 1 - Зима 952 | >> 2 - Весна 953 | >> 3 - Лето 954 | >> 4 - Осень 955 | 956 | #### blocked: 957 | > blocked **bool** – Тайтл заблокирован на территории РФ. 958 | > bakanim **bool** – Тайтл заблокирован из-за жалобы Wakanim. 959 | 960 | *** 961 | 962 | #### player: 963 | > alternative_player **string** – Ссылка на альтернативный плеер. 964 | > [host](#host) **object** – Имена предпочитаемых серверов для построения ссылок на поток и скачивание. 965 | > [playlist](#playlist) **object** – Список релизов тайтла со ссылками на просмотр и загрузку. 966 | > [series](#series) **object** – Количество вышедших в плеере серий 967 | 968 | ##### host: 969 | > hls **string** – Ссылка без домена на альтернативный плеер 970 | Эти имена служат для того, чтобы использовать их как часть ссылки к файлу. 971 | Например: `http://de3.libria.fun/videos/ts/8500/0001/playlist.m3u8` позволит скачать указанный файл с сервера. 972 | 973 | ##### playlist: 974 | > serie **int** – Номер серии 975 | > created_timestamp **int** – Время создания/изменения плейлиста в формате unix timestamp 976 | > preview **str** - Ссылка без домена на превью серии 977 | > skips **array[int]** - Массив чисел с временем для пропуска опенинга и эндинга 978 | > [hls](#hls) **object** – Объект, содержащий ссылки на потоковое воспроизведение в разном качестве 979 | 980 | ###### hls: 981 | > fhd **string** – Ссылка без домена на потоковое воспроизведение в Full-HD качестве 982 | > hd **string** – Ссылка без домена на потоковое воспроизведение в HD качестве 983 | > sd **string** – Ссылка без домена на потоковое воспроизведение в SD качестве 984 | 985 | *** 986 | 987 | #### torrents: 988 | > [series](#series) **object** – Серии содержащиеся в файле 989 | > list **array[object]** – Массив объектов с информацией о торрент файлах 990 | 991 | ##### list: 992 | *Содержит массив объектов с информацией о торрент файлах.* 993 | > torrent_id **int** – ID торрент файла 994 | > [series](#series) **object** – Серии содержащиеся в файле 995 | > [quality](#quality) **object** – Информации о разрешении, кодировщике и типе релиза 996 | > leechers **int** – Количество личеров (личей) 997 | > seeders **int** – Количество сидеров (сидов) 998 | > downloads **int** – Количество загрузок файла 999 | > total_size **int** – Размер файлов в торренте в байтах 1000 | > url **string** – Ссылка на торрент файл без домена 1001 | > uploaded_timestamp **int** – Время загрузки торрента в формате unix timestamp 1002 | > raw_base64_file **string** – Торрент файл в base64 формате (если запрошен в параметре [include](#include)) 1003 | > [metadata](#metadata) **object** – Объект, содержащий метаданные торрент файла 1004 | > hash **string** - Хеш торрент файла 1005 | 1006 | ###### quality: 1007 | > string **string** – Полная строка с описание качества и типа релиза 1008 | > type **string** – Тип релиза WEBRip, HDRip и тд... 1009 | > resolution **int** – Разрешение одной стороны изображения. Например 720 1010 | > encoder **string** – Строка указывающая на кодировщик используемый для кодирования релиза, h264 или h265 1011 | > lq_audio **bool** – Используется ли аудио дорожка с пониженным битрейтом (Для экономии размера файла) 1012 | 1013 | ###### metadata: 1014 | > hash **string** – Хеш торрент файла 1015 | > name **string** – Имя тайтла в торрент файле 1016 | > announce **array[string]** – Массив строк содержащий список трекеров 1017 | > created_timestamp **int** – Время создания торрента в формате unix timestamp 1018 | > [files_list](#files_list) **array[object]** – Массив объектов содержащий список файлов в торренте 1019 | 1020 | ###### files_list: 1021 | > file **string** – Имя файла 1022 | > size **int** – Размер файла в байтах 1023 | > offset **int64** – Смещение в байтах относительно предыдущего файла 1024 | 1025 | *** 1026 | 1027 | #### description_type: 1028 | > html – Описание тайтла в виде html (в том виде в каком оно на сайте) 1029 | > plain – Описание тайтла в виде текста без дополнительного форматирования 1030 | > no_view_order – Описание тайтла в виде текста без дополнительного форматирования и порядка просмотра 1031 | 1032 | #### include: 1033 | *Это полезно в случае если вы не хотите делать много запросов, такая конструкция позволяет получить все необходимое в одном запросе* 1034 | > raw_poster – Добавить постер в base64 формате в ответ 1035 | > raw_torrent – Добавить торрент файлы в base64 формате в ответ 1036 | > torrent_meta - Добавить в ответ метаданные торрента (список файлов, их размер, трекер) 1037 | 1038 | #### limit: 1039 | *Количество объектов в ответе* 1040 | Любое положительное число, или -1, чтобы получить все результаты. 1041 | 1042 | #### rss_type: 1043 | Предпочитаемый формат вывода RSS ленты 1044 | 1045 | | Название | Описание | 1046 | | -------- | ---------------------- | 1047 | | rss | RSS 2.0 (По умолчанию) | 1048 | | atom | Atom 1.0 | 1049 | | json | JSON Feed 1.0 | 1050 | 1051 | #### query: 1052 | Ключи объектов должны быть закрыты в фигурные скобки, например `{names.ru}` 1053 | 1054 | ### Поддерживаемые операции 1055 | 1056 | #### Операции сравнения 1057 | 1058 | | Операция | Описание | 1059 | | -------------------- | ----------------------------------------- | 1060 | | `x == y` | Равно | 1061 | | `x != y` | Не равно | 1062 | | `x < y` | Меньше чем | 1063 | | `x <= y` | Меньше чем или равно | 1064 | | `x > y` | Больше чем | 1065 | | `x >= y` | Больше чем или равно | 1066 | | `x ~= y` | Регулярное выражение | 1067 | | `x in (a, b, c)` | Эквивалент (x == a or x == b or x == c) | 1068 | | `x not in (a, b, c)` | Эквивалент (x != a and x != b and x != c) | 1069 | 1070 | #### Логические операции 1071 | 1072 | | Операция | Описание | 1073 | | ----------- | --------------------------------------------------------- | 1074 | | `x and y` | Логическое И | 1075 | | `x or y` | Логическое ИЛИ | 1076 | | `not x` | Логическое НЕ | 1077 | | `x ? y : z` | Условие x, истина y, ложь z | 1078 | | `( x )` | Оператор приоритета, например `(x == y or y < 10) and z)` | 1079 | 1080 | #### Математические операции 1081 | 1082 | | Операция | Описание | 1083 | | -------- | --------- | 1084 | | `x + y` | Сложение | 1085 | | `x - y` | Вычитание | 1086 | | `x * y` | Умножение | 1087 | | `x / y` | Деление | 1088 | | `x % y` | Модуль | 1089 | | `x ^ y` | Степень | 1090 | 1091 | #### Операции с объектами и массивами 1092 | 1093 | | Операция | Описание | 1094 | | ----------- | ----------------------------------------- | 1095 | | `(a, b, c)` | Массив | 1096 | | `a in b` | Массив a является подмножеством массива b | 1097 | | `x of y` | Свойство x объекта y | 1098 | 1099 | #### Встроенные функции 1100 | 1101 | | Функция | Описание | 1102 | | --------------------- | ------------------------------------------------------------------- | 1103 | | `abs(x)` | Абсолютное значение | 1104 | | `ceil(x)` | Округление float числа вверх | 1105 | | `floor(x)` | Округление float числа вниз | 1106 | | `log(x)` | Натуральный логарифм | 1107 | | `max(a, b, c...)` | Максимальное число из указанных (число аргументов может быть любым) | 1108 | | `min(a, b, c...)` | Минимальное число из указанных (число аргументов может быть любым) | 1109 | | `random()` | Случайное float значение от 0.0 до 1.0 | 1110 | | `round(x)` | Простое округление float | 1111 | | `sqrt(x)` | Квадратный корень | 1112 | | `len(x)` | Длина массива или строки | 1113 | | `randomInt(min, max)` | Случайное число в указанном диапазоне | 1114 | 1115 | ### Получение session id: 1116 | 1117 | Для получения ключа, нужно отправить POST запрос на адрес 1118 | `https://www.anilibria.tv/public/login.php` 1119 | 1120 | | Параметр | Тип | Описание | Обязательный | 1121 | | -------- | ------ | --------------------------------------- | ------------ | 1122 | | mail | string | Логин или электронная почта от аккаунта | + | 1123 | | passwd | string | Пароль от аккаунта | + | 1124 | 1125 | После успешной авторизации в ответе будет значение с ключом `sessionId`, а в cookies `PHPSESSID`, оба значения одинаковы. 1126 | 1127 | Стоит помнить: 1128 | * Авторизация может пропасть в любой момент, т.к. время жизни сессии ограничено 1129 | 1130 | *** 1131 | 1132 | ### Возможные коды ошибок 1133 | ```json 1134 | { 1135 | "error": { "code": 500, "message": "Internal Server Error!" } 1136 | } 1137 | ``` 1138 | 1139 | Возникает в случае непредвиденной внутренней ошибки сервера. 1140 | > Все 5хх ошибки возвращают статус код 500, хотя в теле ответа будет указан настоящий код. 1141 | 1142 | ```json 1143 | { 1144 | "error": { "code": 412, "message": "Unknown parameters: code, id" } 1145 | } 1146 | ``` 1147 | 1148 | Возникает в случае если передать неизвестный параметр в запросе. 1149 | 1150 | ```json 1151 | { 1152 | "error": { "code": 404, "message": "Title "test" not found!" } 1153 | } 1154 | ``` 1155 | 1156 | Возникает в случае если запрошеный тайтл отсутствует в базе. 1157 | и другие... 1158 | 1159 | >В случае ошибки HTTP Status дублирует код из **error.code** (Исключение 5хх ошибки) 1160 | >В случае успешного выполнения запроса будет возвращен HTTP Status: **200** 1161 | *** 1162 | 1163 | ### Полезное 1164 | 1. Версию API можно узнать в заголовке `API-Version` и сравнить ее с версией документации, чтобы узнать актуальна ли документация. 1165 | 2. Версии меняются по принципу .. где Major обозначает очень крупные изменения в коде проекта без обратной совместимости, Minor обозначает существенные изменения в API с частичной обратной совместимостью, и Patch исправление различных ошибок, не влияет на совместимость. 1166 | 3. С версии 2.6.2. появилась поддержка старых версий api и был расширен функционал версионирования. 1167 | Таким образом теперь можно использовать либо последнюю версию с последними исправлениями, либо старую минорную со старой схемой которая не будет обновляться и меняться со временем. 1168 | Например, сейчас можно использовать ссылки следующего формата: 1169 | >Ссылка на актуальную мажорную версию API - https://api.anilibria.tv/v2/... 1170 | >Ссылка на минорный патч со всеми исправлениями - https://api.anilibria.tv/v2.13/... 1171 | >Ссылка на патч - https://api.anilibria.tv/v2.13.15/... 1172 | 4. Полезно использовать фильтры при запросе информации о множестве тайтлов, к примеру: исключив информацию о плеере, вы существенно сэкономите время ответа, если она вам не нужна. 1173 | 1174 | ## WebSocket 1175 | 1176 | ### Подключение 1177 | 1178 | ```js 1179 | ws(s)://api.anilibria.tv/v2/ws/ 1180 | ``` 1181 | 1182 | или 1183 | 1184 | ```js 1185 | ws(s)://api.anilibria.tv/v2/webSocket/ 1186 | ``` 1187 | 1188 | > **ВебСокет каждые 30 секунд отправляет ping пакет, который проверяет соединение.** 1189 | 1190 | ### Уведомления 1191 | 1192 | #### title_update 1193 | 1194 | При обновлении какой-либо информации о тайтле Веб Сокет отправляет всем клиентам строку в JSON формате: 1195 | 1196 | ```json 1197 | { 1198 | "type": "title_update", 1199 | "title_update": { 1200 | "hash": "c3499c2729730a7f807efb8676a92dcb6f8a3f8f", 1201 | "title": { 1202 | [Возвращаемые поля идентичны /getTitle] 1203 | }, 1204 | "diff": { 1205 | [Те ключи и значения, что были изменены, добавлены или удалены] 1206 | } 1207 | } 1208 | } 1209 | ``` 1210 | 1211 | ##### Возвращаемые значения 1212 | 1213 | type **string** - Тип уведомления. 1214 | hash **string** – Хеш уведомления, для проверки уникальности уведомления 1215 | title **object** – Объект, содержащий все поля из /getTitle 1216 | diff **object** – Объект, содержащий информацию о том, какие данные были изменены, добавлены или удалены. 1217 | 1218 | #### playlist_update 1219 | 1220 | При обновлении плейлиста тайтла, что происходит при добавлении или перезаливе релиза, ВебСокет отправляет всем клиентам строку в формате: 1221 | 1222 | ```json 1223 | { 1224 | "type": "playlist_update", 1225 | "playlist_update": { 1226 | "id": 8700, 1227 | "player": {объект плеера}, 1228 | "updated_episode": {объект плейлиста}, 1229 | "episode": "2", 1230 | "diff": {Те ключи и значения, что были изменены, добавлены или удалены}, 1231 | "reupload": false 1232 | } 1233 | } 1234 | ``` 1235 | 1236 | ##### Возвращаемые значения 1237 | 1238 | type **string** - Тип уведомления. 1239 | id **int** – ID обновленного тайтла. 1240 | [player](#player) **object** – Объект, содержащий информация о плеере. 1241 | updated_episode **object** - Объект, содержащий все поля из объекта [playlist](#playlist). 1242 | episode **int** – Номер вышедшего или перезалитого релиза. 1243 | diff **object** – Объект, содержащий информацию о том, какие данные были изменены, добавлены или удалены. 1244 | reupload **bool** - Означает, перезалив это или нет. 1245 | 1246 | #### encode_start 1247 | При начале кодирования серии в плеер, что происходит при добавлении или перезаливе релиза, ВебСокет отправляет всем клиентам строку в формате: 1248 | ```json 1249 | { 1250 | "type": "encode_start", 1251 | "encode_start": { 1252 | "id": "8700", 1253 | "episode": "4", 1254 | "resolution": "480", 1255 | "quality": "sd", 1256 | "isReupload": false 1257 | } 1258 | } 1259 | ``` 1260 | 1261 | ##### Возвращаемые значения 1262 | id **string** – ID обновленного тайтла. 1263 | episode **string** – Номер вышедшего или перезалитого релиза. 1264 | resolution **string** - Разрешение, в котором была скодирована серия. 1265 | quality **string** – Качество, в котором кодируется серия (одно из значений [hls](#hls)). 1266 | isReupload **bool** - Означает, перезалив это или нет. 1267 | 1268 | #### encode_end 1269 | 1270 | Когда серия успешно скодирована в определённом качестве, ВебСокет отправляет всем клиентам строку в формате: 1271 | 1272 | ```json 1273 | { 1274 | "type": "encode_end", 1275 | "encode_end": { 1276 | "id": "8700", 1277 | "episode": "4", 1278 | "resolution": "480", 1279 | "quality": "sd" 1280 | } 1281 | } 1282 | ``` 1283 | 1284 | ##### Возвращаемые значения 1285 | 1286 | id **string** – ID обновленного тайтла. 1287 | episode **string** – Номер вышедшего или перезалитого релиза. 1288 | resolution **string** - Разрешение, в котором была скодирована серия. 1289 | quality **string** – Качество, в котором стала доступна серия (одно из значений [hls](#hls)). 1290 | 1291 | #### encode_progress 1292 | 1293 | На каждые 5% кодирования в определённом качестве, Веб Сокет будет отправлять клиентам строку в формате: 1294 | 1295 | ```json 1296 | { 1297 | "type": "encode_progress", 1298 | "encode_progress": { 1299 | "id": "8700", 1300 | "episode": "4", 1301 | "resolution": "480", 1302 | "quality": "sd", 1303 | "encoded_percent": "25" 1304 | } 1305 | } 1306 | ``` 1307 | 1308 | ##### Возвращаемые значения 1309 | id **string** – ID обновленного тайтла. 1310 | episode **string** – Номер вышедшего или перезалитого релиза. 1311 | resolution **string** - Разрешение, в котором была скодирована серия. 1312 | quality **string** – Качество, в котором кодируется серия (одно из значений [hls](#hls)). 1313 | encoded_percent **string** – процент кодирования. 1314 | 1315 | 1316 | #### encode_finish 1317 | Когда серия успешно скодирована во всех качествах, ВебСокет отправляет клиентам строку в формате: 1318 | 1319 | ```json 1320 | { 1321 | "id": "8700", 1322 | "episode": "4" 1323 | } 1324 | ``` 1325 | 1326 | ##### Возвращаемые значения 1327 | 1328 | id **string** – ID обновленного тайтла. 1329 | episode **string** – Номер вышедшего или перезалитого релиза. 1330 | 1331 | #### torrent_update 1332 | 1333 | При обновлении информации о торренте, Веб Сокет будет отправлять клиентам строку в формате: 1334 | 1335 | ```json 1336 | { 1337 | "type": "torrent_update", 1338 | "torrent_update": { 1339 | "id": "9215", 1340 | "torrents": { 1341 | "series": { 1342 | "first": 1, 1343 | "last": 1, 1344 | "string": "1-1" 1345 | }, 1346 | "list": [ 1347 | { 1348 | "torrent_id": 19973, 1349 | "series": { 1350 | "first": 1, 1351 | "last": 1, 1352 | "string": "1" 1353 | }, 1354 | "quality": { 1355 | "string": "WEBRip 1080p", 1356 | "type": "WEBRip", 1357 | "resolution": "1080p", 1358 | "encoder": "h264", 1359 | "lq_audio": null 1360 | }, 1361 | "leechers": 2, 1362 | "seeders": 25, 1363 | "downloads": 32, 1364 | "total_size": 547428705, 1365 | "url": "/public/torrent/download.php?id=19973", 1366 | "uploaded_timestamp": 1657158936, 1367 | "hash": "51a8800ca1a6486b352227a37da0c5d3dbba59c7", 1368 | "metadata": null, 1369 | "raw_base64_file": null 1370 | }, 1371 | ... 1372 | ] 1373 | }, 1374 | "updated_torrent_id": 19973, 1375 | "diff": { 1376 | "list": { 1377 | "0": { 1378 | "torrent_id": 19972, 1379 | "leechers": 4, 1380 | "seeders": 18, 1381 | "downloads": 23, 1382 | "total_size": 547426413, 1383 | "url": "/public/torrent/download.php?id=19972", 1384 | "uploaded_timestamp": 1657156714, 1385 | "hash": "f3d72484bdc41265bd025dbbb24ea8bcb63a1abf" 1386 | } 1387 | } 1388 | }, 1389 | "hash": "81f7dbc27a1a445105b90c3096e3168008f2886e" 1390 | } 1391 | } 1392 | ``` 1393 | 1394 | ##### Возвращаемые значения 1395 | 1396 | id **string** – ID обновленного тайтла. 1397 | [torrents](#torrents) **object** – Информация о торрент файлах. 1398 | updated_torrent_id **int** - ID обновлённого торрента. 1399 | diff **object** – Объект, содержащий информацию о том, какие данные были изменены, добавлены или удалены. 1400 | hash **string** – Хеш уведомления, для проверки уникальности уведомления. 1401 | 1402 | ### Подписка на уведомления 1403 | 1404 | По умолчанию, при подключении, клиент подписывается на все уведомления сразу, но после добавления подписки, вебсокет будет отправлять только те уведомления, которые соответствуют заданым фильтрам. 1405 | 1406 | ```json 1407 | { 1408 | "subscribe": { 1409 | "title_update": { 1410 | "title": { 1411 | "season": { 1412 | "year": 2022 1413 | } 1414 | } 1415 | } 1416 | // Тут могут быть любые поля и значения, которые отправляет вебсокет. 1417 | } 1418 | } 1419 | ``` 1420 | 1421 | #### Пример ответа 1422 | 1423 | ```json 1424 | { 1425 | "subscribe": "success", 1426 | "subscription_id": 0 1427 | } 1428 | ``` 1429 | 1430 | Можно отправить несколько запросов с подпиской, тогда вебсокет будет отправлять уведомление при совпадении с одним из них. 1431 | 1432 | В качестве значения также можно указать `*`, что будет соответствовать любому значению указанного поля. 1433 | Таким образом, к примеру, можно подписаться на получение уведомлений только о выходе всех серий начиная с 12. 1434 | 1435 | ```json 1436 | { 1437 | "subscribe": { 1438 | "title_update": { 1439 | "title": { 1440 | "player": { 1441 | "playlist": { 1442 | "12": * 1443 | } 1444 | } 1445 | } 1446 | } 1447 | } 1448 | } 1449 | ``` 1450 | 1451 | #### Фильтры 1452 | 1453 | При добавлении подписки можно указать какие поля вебсокет будет вам отправлять. 1454 | Работает это так же, как и при указании фильтров к GET запросам. 1455 | Например: 1456 | 1457 | ```json 1458 | { 1459 | "subscribe": { 1460 | "title_update": { 1461 | "title": { 1462 | "season": { 1463 | "year": 2022 1464 | } 1465 | } 1466 | } 1467 | }, 1468 | "filter": "names,season", 1469 | "remove": "names.en" 1470 | } 1471 | ``` 1472 | 1473 | *** 1474 | -------------------------------------------------------------------------------- /install/README.md: -------------------------------------------------------------------------------- 1 | Все действия выполняются на Debian 9 minimal 64 bit.
2 | Конфиг сервера: 2x E5-2620 v4, 64GB DDR4, 2x 480GB SSD.
3 | 4 | ``` 5 | apt-get update 6 | apt-get upgrade 7 | apt-get install htop bwm-ng mc lsof fail2ban iotop sysstat net-tools curl 8 | 9 | cat </etc/rc.local 10 | #!/bin/sh -e 11 | # 12 | # rc.local 13 | # 14 | # This script is executed at the end of each multiuser runlevel. 15 | # Make sure that the script will "exit 0" on success or any other 16 | # value on error. 17 | # 18 | # In order to enable or disable this script just change the execution 19 | # bits. 20 | # 21 | # By default this script does nothing. 22 | 23 | exit 0 24 | EOF 25 | chmod +x /etc/rc.local 26 | systemctl daemon-reload 27 | systemctl start rc-local 28 | systemctl status rc-local 29 | ``` 30 | 31 | 1. Memcached 32 | 2. MariaDB 33 | 3. XBT Tracker 34 | ``` 35 | # adduser anilibria 36 | # nano /etc/ssh/sshd_config 37 | 38 | # override default of no subsystems 39 | Subsystem sftp /usr/lib/openssh/sftp-server 40 | 41 | # Disable ssh and sftp for users 42 | DenyUsers anilibria 43 | 44 | # systemctl restart sshd 45 | ``` 46 | 47 | 4. PHP 7.3 48 | 5. Nginx 49 | 50 | ``` 51 | mkdir /var/www/anilibria 52 | mkdir /var/www/anilibria/logs 53 | mkdir /var/www/anilibria/root 54 | usermod -a -G www-data anilibria 55 | chown -R anilibria:www-data /var/www/anilibria 56 | usermod -m -d /var/www/anilibria anilibria 57 | ``` 58 | 59 | 6. phpMyAdmin 60 | 7. Sphinx 61 | 8. Munin 62 | 9. Fail2Ban 63 | 10. AutoUpdate 64 | 11. Timezone 65 | 12. KernelCare 66 | 13. Onion 67 | 14. Sysctl 68 | 15. Exim 69 | 16. Pure-FTPd 70 | 17. ntpd 71 | -------------------------------------------------------------------------------- /install/autoupdate.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get update 3 | apt-get install unattended-upgrades cron-apt 4 | dpkg-reconfigure unattended-upgrades 5 | ``` 6 | Появится окно => выбираем Yes.
7 | 8 | 9 | 10 | Запустим автообновление в тестовом режиме. 11 | ``` 12 | # unattended-upgrade --debug --dry-run 13 | ... 14 | Allowed origins are: ['origin=Debian,codename=jessie,label=Debian-Security'] 15 | ... 16 | ``` 17 | Логи можно посмотреть в файле /var/log/unattended-upgrades/unattended-upgrades.log 18 | -------------------------------------------------------------------------------- /install/conf/default: -------------------------------------------------------------------------------- 1 | server { 2 | listen 443 ssl http2; 3 | server_name anilibria.tv www.anilibria.tv; 4 | ssl_certificate /etc/letsencrypt/live/anilibria.tv/fullchain.pem; 5 | ssl_certificate_key /etc/letsencrypt/live/anilibria.tv/privkey.pem; 6 | root /var/www/anilibria/root; 7 | index index.php index.html index.htm; 8 | 9 | error_page 403 /pages/error/403.php; 10 | error_page 404 /pages/error/404.php; 11 | error_page 502 /pages/error/502.html; 12 | 13 | location ^~ /phpmyadmin { 14 | auth_basic "Restricted Content"; 15 | auth_basic_user_file /etc/nginx/.htpasswd; 16 | root /usr/share; 17 | location ~ \.php$ { 18 | try_files $uri $uri/ =404; 19 | include fastcgi_params; 20 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 21 | fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name; 22 | fastcgi_pass unix:/var/run/anilibria.sock; 23 | } 24 | } 25 | 26 | location ^~ /munin-cgi/munin-cgi-graph/ { 27 | auth_basic "Restricted Content"; 28 | auth_basic_user_file /etc/nginx/.htpasswd; 29 | fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*); 30 | fastcgi_param PATH_INFO $fastcgi_path_info; 31 | fastcgi_pass unix:/var/run/munin/fastcgi-graph.sock; 32 | include fastcgi_params; 33 | } 34 | 35 | location /munin/static/ { 36 | auth_basic "Restricted Content"; 37 | auth_basic_user_file /etc/nginx/.htpasswd; 38 | alias /etc/munin/static/; 39 | } 40 | 41 | location /munin { 42 | auth_basic "Restricted Content"; 43 | auth_basic_user_file /etc/nginx/.htpasswd; 44 | alias /var/cache/munin/www/; 45 | } 46 | 47 | location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|ico|bmp|woff)$ { 48 | expires 30d; 49 | access_log off; 50 | } 51 | 52 | location ^~ /private/ { 53 | deny all; 54 | } 55 | 56 | location /upload/ { 57 | location ~* ^.+\.php { 58 | deny all; 59 | } 60 | } 61 | 62 | rewrite ^/release/(.*).html$ /pages/release.php?code=$1 last; 63 | rewrite ^/api/api_v2.php$ /other/old_api_placeholder/api_v2.php last; 64 | 65 | location ~ \.php$ { 66 | default_type 'text/plain'; 67 | access_by_lua_file /etc/nginx/lua/filter.lua; 68 | try_files $uri $uri/ =404; 69 | include fastcgi_params; 70 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 71 | fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name; 72 | fastcgi_pass unix:/var/run/anilibria.sock; 73 | } 74 | } 75 | 76 | server { 77 | listen 80 default_server; 78 | server_name anilibria.tv www.anilibria.tv; 79 | location ^~ /.well-known/ { 80 | root /var/www/html; 81 | default_type "text/plain"; 82 | } 83 | location /nginx_status { 84 | stub_status on; 85 | access_log off; 86 | allow 127.0.0.1; 87 | deny all; 88 | } 89 | location / { 90 | return 301 https://$server_name$request_uri; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /install/conf/filter.lua: -------------------------------------------------------------------------------- 1 | -- Simple filter 2 | 3 | local function isempty(s) 4 | return s == nil or s == '' 5 | end 6 | 7 | local function contains(table, val) 8 | for i=1,#table do 9 | if table[i] == val then 10 | return true 11 | end 12 | end 13 | return false 14 | end 15 | 16 | function split(s, delimiter) 17 | result = {}; 18 | for match in (s..delimiter):gmatch("(.-)"..delimiter) do 19 | table.insert(result, tonumber(match)); 20 | end 21 | return result; 22 | end 23 | 24 | function httpFloodStat(key, limit) 25 | xEnd = 60 26 | xTime = os.time() 27 | xStat = ngx.shared.stats:get(key) 28 | if isempty(xStat) then 29 | xCount = 1 30 | xStat = xCount .. "|" .. xTime+xEnd 31 | else 32 | xTmp = split(xStat, "|") 33 | if xTime > xTmp[2] then 34 | xTmp[1] = xTmp[1]-limit*(xTime-xTmp[2]) 35 | xTmp[2] = xTime+xEnd 36 | if xTmp[1] < 0 then 37 | xTmp[1] = 0 38 | end 39 | end 40 | xCount = xTmp[1]+1 41 | xStat = xCount .. "|" .. xTmp[2] 42 | end 43 | ngx.shared.stats:set(key, xStat) 44 | --ngx.say(ngx.shared.stats:get(key)) 45 | return xCount 46 | end 47 | 48 | function httpFilter(xStat, limit) 49 | if xStat == limit then 50 | ngx.log(ngx.ERR, "Warning " .. xData[1] .. " points " .. xStat) 51 | end 52 | if xStat > limit then 53 | ngx.status = 403 54 | xLog = "Banned " .. xData[1] .. " points " .. xStat 55 | ngx.say(xLog) 56 | if xStat > 10000 then 57 | ngx.log(ngx.ERR, xLog) -- for fail2ban 58 | end 59 | ngx.exit(ngx.HTTP_FORBIDDEN) 60 | end 61 | end 62 | 63 | wl = {"127.0.0.1", "37.1.217.18"} 64 | if not contains(wl, ngx.var.remote_addr) then 65 | xData = {ngx.var.remote_addr, ngx.md5(ngx.var.remote_addr)} 66 | --ngx.say('identify: ' .. xData[1] .. ', hash: ' .. xData[2]) 67 | xStat = httpFloodStat(xData[2], 20) -- 20 r/s per ip 68 | httpFilter(xStat, 1200) -- limit 1200 r/m 69 | if ngx.var.cookie_PHPSESSID then 70 | xData = {ngx.var.cookie_PHPSESSID, ngx.md5(ngx.var.cookie_PHPSESSID)} 71 | --ngx.say('identify: ' .. xData[1] .. ', hash: ' .. xData[2]) 72 | xStat = httpFloodStat(xData[2], 5) -- 5 r/s per sess 73 | httpFilter(xStat, 300) -- limit 300 r/m 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /install/conf/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes 8; 3 | pid /run/nginx.pid; 4 | include /etc/nginx/modules-enabled/*.conf; 5 | worker_rlimit_nofile 65535; 6 | 7 | events { 8 | worker_connections 32768; 9 | # multi_accept on; 10 | use epoll; 11 | } 12 | 13 | http { 14 | 15 | ## 16 | # Basic Settings 17 | ## 18 | 19 | sendfile on; 20 | tcp_nopush on; 21 | tcp_nodelay on; 22 | keepalive_timeout 65; 23 | types_hash_max_size 2048; 24 | server_tokens off; 25 | 26 | # server_names_hash_bucket_size 64; 27 | # server_name_in_redirect off; 28 | 29 | include /etc/nginx/mime.types; 30 | default_type application/octet-stream; 31 | 32 | ## 33 | # SSL Settings 34 | ## 35 | 36 | ssl_dhparam /etc/nginx/ssl/dhparam.pem; 37 | ssl_protocols TLSv1.2 TLSv1.1 TLSv1; 38 | ssl_prefer_server_ciphers on; 39 | ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA512:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:DH+AESGCM:DH+AES256:RSA+AESGCM:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS; 40 | ssl_session_cache shared:TLS:128m; 41 | ssl_session_timeout 1d; 42 | 43 | ## 44 | # Logging Settings 45 | ## 46 | 47 | access_log /var/log/nginx/access.log; 48 | error_log /var/log/nginx/error.log; 49 | 50 | ## 51 | # Gzip Settings 52 | ## 53 | 54 | gzip on; 55 | gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; 56 | 57 | ## 58 | # Lua 59 | ## 60 | 61 | lua_shared_dict stats 128m; 62 | 63 | ## 64 | # Other Settings 65 | ## 66 | 67 | #client_max_body_size 100m; 68 | #add_header X-Frame-Options SAMEORIGIN; 69 | 70 | ## 71 | # Virtual Host Configs 72 | ## 73 | 74 | include /etc/nginx/conf.d/*.conf; 75 | include /etc/nginx/sites-enabled/*; 76 | 77 | } 78 | -------------------------------------------------------------------------------- /install/exim.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get install exim4 3 | dpkg-reconfigure exim4-config 4 | 5 | > internet site; mail is send and received directly using SMTP 6 | > anilibria.tv 7 | > 127.0.0.1 8 | > anilibria.tv 9 | > empty 10 | > empty 11 | > No 12 | > mbox format in /var/mail/ 13 | > No 14 | > empty 15 | ``` 16 | 17 | Выключим ipv6. Открываем `/etc/exim4/exim4.conf.template` добавляем сразу перед `begin acl` добавляем. 18 | ``` 19 | disable_ipv6 = true 20 | ``` 21 | 22 | DKIM + SPF запись + яндекс почта. 23 | 24 | ``` 25 | apt-get install opendkim-tools 26 | mkdir /etc/exim4/dkim 27 | opendkim-genkey -D /etc/exim4/dkim/ -d anilibria.tv -s mail 28 | cd /etc/exim4/dkim/ 29 | mv mail.private example.com.key 30 | chown -R Debian-exim:Debian-exim /etc/exim4/dkim/ 31 | chmod 640 /etc/exim4/dkim/* 32 | ``` 33 | 34 | В конфиг `/etc/exim4/exim4.conf.template` или если он разделен,
35 | то `/etc/exim4/conf.d/transport/30_exim4-config_remote_smtp` добавляем 36 | 37 | ``` 38 | ### transport/30_exim4-config_remote_smtp 39 | DKIM_DOMAIN = ${lc:${domain:$h_from:}} 40 | DKIM_KEY_FILE = /etc/exim4/dkim/DKIM_DOMAIN.key 41 | DKIM_PRIVATE_KEY = ${if exists{DKIM_KEY_FILE}{DKIM_KEY_FILE}{0}} 42 | DKIM_SELECTOR = mail 43 | ``` 44 | 45 | ``` 46 | TXT mail._domainkey.anilibria.tv /etc/exim4/dkim/mail.txt 47 | TXT anilibria.tv v=spf1 ip4:37.1.217.18 include:_spf.yandex.net ~all 48 | MX anilibria.tv mx.yandex.net 10 49 | CNAME mail.anilibria.tv domain.mail.yandex.net 50 | ``` 51 | 52 | ``` 53 | /etc/init.d/exim4 restart 54 | ``` 55 | -------------------------------------------------------------------------------- /install/fail2ban.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get install fail2ban 3 | ``` 4 | 5 | Редактируем файл `/etc/fail2ban/jail.conf`, включаем мониторинг `ssh` и `pure-ftpd` 6 | 7 | ``` 8 | [ssh] 9 | 10 | enabled = true 11 | port = ssh 12 | filter = sshd 13 | logpath = /var/log/auth.log 14 | maxretry = 6 15 | 16 | [pure-ftpd] 17 | 18 | enabled = true 19 | port = ftp,ftp-data,ftps,ftps-data 20 | filter = pure-ftpd 21 | logpath = /var/log/syslog 22 | maxretry = 6 23 | ``` 24 | 25 | Ввожу шесть раз неверный пароль. 26 | ``` 27 | # ssh root@5.9.82.141 28 | root@5.9.82.141's password: 29 | Permission denied, please try again. 30 | root@5.9.82.141's password: 31 | Permission denied, please try again. 32 | root@5.9.82.141's password: 33 | Permission denied (publickey,password). 34 | 35 | # ssh root@5.9.82.141 36 | root@5.9.82.141's password: 37 | Permission denied, please try again. 38 | root@5.9.82.141's password: 39 | Permission denied, please try again. 40 | root@5.9.82.141's password: 41 | Permission denied (publickey,password). 42 | ``` 43 | 44 | Fail2ban блокирует подключение. 45 | ``` 46 | # ssh root@5.9.82.141 47 | ssh: connect to host 5.9.82.141 port 22: Connection refused 48 | ``` 49 | 50 | Проверяю логи, правила iptables. 51 | ``` 52 | # cat /var/log/auth.log | grep 5.39.64.7 53 | Feb 1 14:16:27 x sshd[29355]: Failed password for root from 5.39.64.7 port 60397 ssh2 54 | Feb 1 14:16:31 x sshd[29355]: Failed password for root from 5.39.64.7 port 60397 ssh2 55 | Feb 1 14:16:38 x sshd[29355]: Failed password for root from 5.39.64.7 port 60397 ssh2 56 | Feb 1 14:16:38 x sshd[29355]: Connection closed by 5.39.64.7 [preauth] 57 | Feb 1 14:16:42 x sshd[29360]: Failed password for root from 5.39.64.7 port 60931 ssh2 58 | Feb 1 14:16:45 x sshd[29360]: Failed password for root from 5.39.64.7 port 60931 ssh2 59 | Feb 1 14:16:48 x sshd[29360]: Failed password for root from 5.39.64.7 port 60931 ssh2 60 | Feb 1 14:16:48 x sshd[29360]: Connection closed by 5.39.64.7 [preauth] 61 | ``` 62 | ``` 63 | # cat /var/log/fail2ban.log | grep 5.39.64.7 64 | 2018-02-01 14:16:49,691 fail2ban.actions[1502]: WARNING [ssh] Ban 5.39.64.7 65 | ``` 66 | ``` 67 | # iptables -L fail2ban-ssh -v -n 68 | Chain fail2ban-ssh (1 references) 69 | pkts bytes target prot opt in out source destination 70 | 1 60 REJECT all -- * * 5.39.64.7 0.0.0.0/0 reject-with icmp-port-unreachable 71 | 14M 21G RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 72 | ``` 73 | -------------------------------------------------------------------------------- /install/mariadb.md: -------------------------------------------------------------------------------- 1 | Список реп доступен на сайте https://downloads.mariadb.org/mariadb/repositories/ 2 | 3 | ``` 4 | apt-get install software-properties-common dirmngr 5 | apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8 6 | add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://mirrors.n-ix.net/mariadb/repo/10.3/debian stretch main' 7 | 8 | apt-get update 9 | apt-get install mariadb-server 10 | ``` 11 | 12 | Редактируем конфиг. 13 | ``` 14 | # nano /etc/mysql/my.cnf 15 | 16 | ## MySQL config 17 | [client] 18 | port = 3306 19 | socket = /var/run/mysqld/mysqld.sock 20 | default-character-set = utf8 21 | 22 | [mysqld_safe] 23 | socket = /var/run/mysqld/mysqld.sock 24 | nice = 0 25 | malloc-lib = /usr/lib/x86_64-linux-gnu/libjemalloc.so.1 26 | 27 | [mysqld] 28 | user = mysql 29 | pid-file = /var/run/mysqld/mysqld.pid 30 | socket = /var/run/mysqld/mysqld.sock 31 | port = 3306 32 | basedir = /usr 33 | datadir = /var/lib/mysql 34 | tmpdir = /tmp 35 | skip-networking 36 | skip-name-resolve 37 | 38 | # XBT Tracker not displaying seeders/leechers 39 | # https://github.com/anilibria/docs/blob/master/install/xbt_tracker.md 40 | sql_mode="ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 41 | 42 | # Other 43 | default-storage-engine = INNODB 44 | character-set-server = utf8 45 | max_connections = 500 46 | wait_timeout = 7200 47 | max_allowed_packet = 16M 48 | skip-external-locking 49 | #memlock 50 | open_files_limit = 16000 51 | 52 | # MyISAM settings 53 | key_buffer_size = 256M 54 | 55 | # InnoDB settings 56 | innodb_buffer_pool_size = 16G 57 | innodb_buffer_pool_instances = 16 58 | innodb_log_file_size = 2G 59 | innodb_flush_log_at_trx_commit = 2 60 | innodb_log_buffer_size = 16M 61 | innodb_log_files_in_group = 2 62 | innodb_flush_method = O_DIRECT 63 | innodb_thread_concurrency = 16 64 | 65 | # Buffer settings 66 | join_buffer_size = 2M 67 | 68 | # TMP & memory settings 69 | tmp_table_size = 256M 70 | max_heap_table_size = 256M 71 | 72 | # Cache settings 73 | query_cache_type = 1 74 | query_cache_limit = 256K 75 | query_cache_size = 32M 76 | 77 | # Try off https://community.centminmod.com/threads/mysqltuner.6779/ 78 | #query_cache_type = 0 # for OFF 79 | #query_cache_size = 0 # to ensure QC is NOT USED 80 | 81 | 82 | # Slowlog settings 83 | slow_query_log = 1 84 | long_query_time = 5 85 | slow_query_log_file = /var/log/mysql/mariadb-slow.log 86 | 87 | #Set General Log 88 | #general_log = on 89 | #general_log_file = /var/log/mysql/full.log 90 | 91 | [mysqldump] 92 | # Do not buffer the whole result set in memory before writing it to 93 | # file. Required for dumping very large tables 94 | quick 95 | 96 | max_allowed_packet = 32M 97 | default-character-set = utf8 98 | 99 | [mysql] 100 | no-auto-rehash 101 | default-character-set = utf8 102 | 103 | [isamchk] 104 | key_buffer_size = 8M 105 | sort_buffer_size = 8M 106 | read_buffer = 8M 107 | write_buffer = 8M 108 | default-character-set = utf8 109 | 110 | # 111 | # * IMPORTANT: Additional settings that can override those from this file! 112 | # The files must end with '.cnf', otherwise they'll be ignored. 113 | # 114 | !includedir /etc/mysql/conf.d/ 115 | ``` 116 | -------------------------------------------------------------------------------- /install/memcached.md: -------------------------------------------------------------------------------- 1 | Установка. 2 | ``` 3 | apt-get install memcached 4 | ``` 5 | 6 | Редактируем `/etc/memcached.conf` 7 | ``` 8 | -d 9 | logfile /var/log/memcached.log 10 | -m 256 11 | -u nobody 12 | -s /tmp/memcached.socket 13 | -a 0777 14 | ``` 15 | 16 | Перезагружаем. 17 | ``` 18 | /etc/init.d/memcached restart 19 | ``` 20 | -------------------------------------------------------------------------------- /install/munin.md: -------------------------------------------------------------------------------- 1 | Установка. 2 | ``` 3 | apt-get install munin munin-node spawn-fcgi libcgi-fast-perl curl 4 | apt-get install libfile-readbackwards-perl liblwp-useragent-determined-perl libwww-perl 5 | ``` 6 | 7 | Скачиваем плагины. 8 | ``` 9 | cd /usr/share/munin/plugins 10 | 11 | # mysql 12 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_size_ondisk 13 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_size_all 14 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_connections_per_user 15 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_connections 16 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql-table-size 17 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql-schema-size 18 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_qcache_mem 19 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/mysql/mysql_qcache 20 | 21 | # memcached 22 | rm memcached_ 23 | wget https://raw.githubusercontent.com/mhwest13/Memcached-Munin-Plugin/master/memcached_ 24 | 25 | # nginx 26 | wget https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/nginx/nginx_memory 27 | 28 | # xbt_tracker 29 | wget https://raw.githubusercontent.com/anilibria/docs/master/install/munin/xbt_users 30 | wget https://raw.githubusercontent.com/anilibria/docs/master/install/munin/xbt_torrents 31 | ``` 32 | 33 | Выставляем права. 34 | ``` 35 | chmod -R 755 /usr/share/munin/plugins/* 36 | ``` 37 | 38 | Подключаем. 39 | ``` 40 | # mysql 41 | ln -s /usr/share/munin/plugins/mysql_bytes /etc/munin/plugins/ 42 | ln -s /usr/share/munin/plugins/mysql_connections /etc/munin/plugins/ 43 | ln -s /usr/share/munin/plugins/mysql_connections_per_user /etc/munin/plugins/ 44 | ln -s /usr/share/munin/plugins/mysql_size_all /etc/munin/plugins/ 45 | ln -s /usr/share/munin/plugins/mysql_innodb /etc/munin/plugins/ 46 | ln -s /usr/share/munin/plugins/mysql_size_ondisk /etc/munin/plugins/ 47 | ln -s /usr/share/munin/plugins/mysql_slowqueries /etc/munin/plugins/ 48 | ln -s /usr/share/munin/plugins/mysql_threads /etc/munin/plugins/ 49 | ln -s /usr/share/munin/plugins/mysql_queries /etc/munin/plugins/ 50 | ln -s /usr/share/munin/plugins/mysql_qcache /etc/munin/plugins/ 51 | ln -s /usr/share/munin/plugins/mysql_qcache_mem /etc/munin/plugins/ 52 | 53 | # memcached 54 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_bytes' 55 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_commands' 56 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_conns' 57 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_evictions' 58 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_items' 59 | ln -s '/usr/share/munin/plugins/memcached_' '/etc/munin/plugins/memcached_memory' 60 | 61 | # nginx 62 | ln -s /usr/share/munin/plugins/nginx_request /etc/munin/plugins/ 63 | ln -s /usr/share/munin/plugins/nginx_status /etc/munin/plugins/ 64 | ln -s /usr/share/munin/plugins/nginx_memory /etc/munin/plugins/ 65 | 66 | # xbt_tracker 67 | ln -s /usr/share/munin/plugins/xbt_users /etc/munin/plugins/ 68 | ln -s /usr/share/munin/plugins/xbt_torrents /etc/munin/plugins/ 69 | ``` 70 | 71 | ``` 72 | # nano /etc/munin/plugin-conf.d/munin-node 73 | [nginx*] 74 | env.url http://www.anilibria.tv/nginx_status 75 | env.ua nginx-status-verifier/0.1 76 | 77 | [memcached_*] 78 | env.host unix:///tmp/memcached.socket 79 | ``` 80 | 81 | Перезапускаем munin, nginx. Включаем spawn-fcgi. 82 | ``` 83 | /etc/init.d/nginx restart 84 | /etc/init.d/munin-node restart 85 | spawn-fcgi -s /var/run/munin/fcgi-graph.sock -U www-data -u www-data -g www-data /usr/lib/munin/cgi/munin-cgi-graph 86 | 87 | # nano /etc/rc.local 88 | spawn-fcgi -s /var/run/munin/fcgi-graph.sock -U www-data -u www-data -g www-data /usr/lib/munin/cgi/munin-cgi-graph 89 | ``` 90 | 91 | Проверяем статистику https://www.anilibria.tv/munin/ 92 | 93 | 94 | -------------------------------------------------------------------------------- /install/munin/xbt_torrents: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # XBT Tracker torrents, munin plugin by poiuty 3 | # Thanks Sanasol & cx https://www.linux.org.ru/forum/admin/9400654 4 | 5 | URL="http://anilibria.tv:2710/st" 6 | 7 | if [ "$1" = "config" ]; then 8 | echo 'graph_title XBT Tracker torrents' 9 | echo 'graph_args --base 1000' 10 | echo 'graph_category XBT Tracker' 11 | echo 'graph_info This graph shows the XBT Tracker torrents stat.' 12 | 13 | echo 'graph_vlabel torrents' 14 | 15 | echo 'torrents.label torrents' 16 | echo 'torrents.info torrents stats' 17 | 18 | exit 0 19 | fi 20 | 21 | curl -s --compressed $URL | sed -e 's,.*torrents\([^<]*\).*,\1,g' | xargs -r printf "torrents.value %s\n" 22 | -------------------------------------------------------------------------------- /install/munin/xbt_users: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # XBT Tracker users, munin plugin by poiuty 3 | # Thanks Sanasol & cx https://www.linux.org.ru/forum/admin/9400654 4 | 5 | URL="http://anilibria.tv:2710/st" 6 | 7 | if [ "$1" = "config" ]; then 8 | echo 'graph_title XBT Tracker user stats' 9 | echo 'graph_args --base 1000' 10 | echo 'graph_category XBT Tracker' 11 | echo 'graph_info This graph shows the XBT Tracker Stats.' 12 | 13 | echo 'graph_vlabel users' 14 | echo 'peers.label peers' 15 | echo 'peers.info peers stats' 16 | 17 | echo 'seeders.label seeders' 18 | echo 'seeders.info seeders stats' 19 | 20 | echo 'leechers.label leechers' 21 | echo 'leechers.info leechers stats' 22 | 23 | exit 0 24 | fi 25 | 26 | curl -s --compressed $URL | sed -e 's,.*peers\([^<]*\).*,\1,g' | xargs -r printf "peers.value %s\n" 27 | curl -s --compressed $URL | sed -e 's,.*seeders\([^<]*\).*,\1,g' | xargs -r printf "seeders.value %s\n" 28 | curl -s --compressed $URL | sed -e 's,.*leechers\([^<]*\).*,\1,g' | xargs -r printf "leechers.value %s\n" 29 | -------------------------------------------------------------------------------- /install/nginx.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get install nginx-extras certbot apache2-utils 3 | mkdir /etc/nginx/ssl/ 4 | openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 5 | chown www-data:www-data /etc/nginx/ssl/dhparam.pem 6 | chmod 400 /etc/nginx/ssl/dhparam.pem 7 | mkdir /etc/nginx/lua 8 | wget -O /etc/nginx/lua/filter.lua https://raw.githubusercontent.com/anilibria/docs/master/install/conf/filter.lua 9 | htpasswd -c /etc/nginx/.htpasswd user 10 | chmod 400 /etc/nginx/.htpasswd 11 | chown www-data:www-data /etc/nginx/.htpasswd 12 | ``` 13 | 14 | Получаем сертификат. Можно указать дополнительные поддомены `-d one.anilibria.tv`, `-d two.anilibria.tv` 15 | 16 | ``` 17 | certbot certonly --webroot -w /var/www/html -d anilibria.tv -d www.anilibria.tv -m admin@anilibria.tv --agree-tos 18 | ``` 19 | 20 | Обновляем конфиги. 21 | ``` 22 | wget -O /etc/nginx/nginx.conf https://raw.githubusercontent.com/anilibria/docs/master/install/conf/nginx.conf 23 | wget -O /etc/nginx/sites-available/default https://raw.githubusercontent.com/anilibria/docs/master/install/conf/default 24 | ``` 25 | -------------------------------------------------------------------------------- /install/php73.md: -------------------------------------------------------------------------------- 1 | debian 9 default php vesrion 7.0 2 | 3 | Содержимое файла. 4 | ``` 5 | {"382":{"rid":"382","name":["INCh0LLRj9GC0LDRjyDRgtGA0L7QuNGG0LA6INCc0LXRh9C4LCDQnNCw0LPQuNGPLCDQqNC60L7Qu9Cw","Seiken Tsukai no World Break "],"rating":"516","last":"382","moon":"https:\/\/streamguard.cc\/serial\/f07b9153c626fdd6c55e92b655d79b10\/iframe?nocontrols_translations=1&season=1","status":"2","type":"\u0422\u0412 (>12 \u044d\u043f.), 25 \u043c\u0438\u043d.","genre":"\u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f","year":"0","day":"1","description":"0JrRgtC+INCx0Ysg0L3QtSDRhdC+0YLQtdC7INC30L3QsNGC0YwsINC60LXQvCDQvtC9INCx0YvQuyDQsiDQv9GA0L7RiNC70L7QuSDQttC40LfQvdC4LiDQktC+0LfQvNC+0LbQvdC+LCDQutGC0L4t0YLQviDRhtCw0YDQtdC8LCDQutGC0L4t0YLQviDRgNGL0YbQsNGA0LXQvCwg0LAg0LzQvtC20LXRgiDQuCDQv9GA0L7RgdGC0L7QuSDQvNGD0YXQvtC5LiDQlNCwLCDQt9Cy0YPRh9C40YIg0Y3RgtC+INC90LUg0L7Rh9C10L3RjC4g0J3QuNC60YLQviDQsdGLINC90LUg0YXQvtGC0LXQuyDQsdGL0YLRjCDQvNGD0YXQvtC5LCDQvtC00L3QsNC60L4sINGB0YPRgtGMINC30LDQutC70Y7Rh9Cw0LXRgtGB0Y8g0L3QtSDQsiDRjdGC0L7QvC4g0KHRg9GC0Ywg0LIg0YLQvtC8LCDRh9GC0L4g0YLQtSDQutCw0YfQtdGB0YLQstCwLCDQutC+0YLQvtGA0YvQvNC4INGC0Ysg0L7QsdC70LDQtNCw0Lsg0LIg0L\/RgNC+0YjQu9C+0Lkg0LbQuNC30L3QuCwg0LzQvtCz0YPRgiDQv9C+0LzQvtGH0Ywg0YLQtdCx0LUg0LIg0L\/RgNC10L7QtNC+0LvQtdC90LjQuCDRgtGA0YPQtNC90L7RgdGC0LXQuS4g0J7QsdGA0LXRgtC10L3QuNC4INGB0LXQsdGPINCyINC20LjQt9C90Lgg0LrQsNC6LdC90LjQutCw0LouINCSINGN0YLQvtC8INC4INCx0YPQtNC10YIg0LfQsNC60LvRjtGH0LDRgtGM0YHRjyDRgdGD0YLRjCDRgdC10LPQviDQkNC90LjQvNC1LiDQm9C40YjRjCDQt9C90LDRjywg0LrQtdC8INGC0Ysg0LHRi9C7INCyINC\/0YDQvtGI0LvQvtC5INC20LjQt9C90LgsINGC0Ysg0LHRg9C00LXRiNGMINC30L3QsNGC0YwsINGB0LzQvtC20LXRiNGMINC70Lgg0YLRiyDQt9Cw0YnQuNGC0LjRgtGMINGH0LXQu9C+0LLQtdGH0LXRgdGC0LLQvuKApg0K0J3QsNGIINCz0LvQsNCy0L3Ri9C5INCz0LXRgNC+0Lkg0JzQvtGA0L7RhdCwINCl0LDQuNC80YPRgNCwLCDQutCw0Log0YDQsNC3LCDQttC40LLQtdGCINCyINGC0LDQutC+0Lwg0LzQuNGA0LUuINCSINC80LjRgNC1LCDQs9C00LUg0LzQvtC20L3QviDRg9C30L3QsNGC0YwsINC60LXQvCDRgtGLINCx0YvQuyDQsiDQv9GA0L7RiNC70L7QuSDQttC40LfQvdC4LiDQkdGL0LvQviDQsdGLINGF0L7RgNC+0YjQviDRg9GC0LLQtdGA0LbQtNCw0YLRjCwg0LXRgdC70Lgg0LHRiyDQstGB0LUg0LHRi9C70L4g0YLQsNC6INC\/0YDQvtGB0YLQvi4g0KPQt9C90LDQuyDQutC10Lwg0YLRiyDQsdGL0Lsg0Lgg0YLQtdCx0LUg0YHRgtCw0LvQviDQu9C10LPRh9C1LiDQndC+INC90LUg0YLRg9GCLdGC0L4g0LHRi9C70L4uINCt0YLQviDQvtGH0LXQvdGMINC+0L\/QsNGB0L3Ri9C5INC80LjRgCwg0YEg0YHQvtC30LTQsNC90LjRj9C80LgsINC40LvQuCDQutCw0Log0LjRhSDQtdGJ0LUg0L3QsNC30YvQstCw0Y7RgiDCq9Cc0LXRgtCw0YTQuNC30LjRh9C10YHQutC40LUg0YHQvtC30LTQsNC90LjRj8K7LCDQutC+0YLQvtGA0YvQuSDQvdC1INC00LDRgdGCINGC0LXQsdC1INGB0L\/QsNGC0Ywg0YHQv9C+0LrQvtC50L3Qviwg0LXRgdC70Lgg0YLRiyDRgtCw0Log0LbQtSwg0LrQsNC6INC4INCl0LDQuNC80YPRgNCwLCDQvtGC0L3QvtGB0LjRiNGM0YHRjyDQuiDRgtCw0Log0L3QsNC30YvQstCw0LXQvNGL0LwgwqvQodC\/0LDRgdC40YLQtdC70Y\/QvMK7LiDQntC90Lgg0LzQvtCz0YPRgiDQv9C+0LzQvdC40YLRjCDRgtC+LCDQutC10Lwg0L7QvdC4INCx0YvQu9C4INCyINC\/0YDQvtGI0LvQvtC5INC20LjQt9C90LguINCS0YHQtSDQvtC90Lgg0LzQvtCz0YPRgiDQv9C+0LvRjNC30L7QstCw0YLRjNGB0Y8g0LzQsNCz0LjQtdC5LiDQrdGC0LAg0LzQsNCz0LjRjyDQv9C+0LfQstC+0LvRj9C10YIg0LjQvCDRgdGA0LDQttCw0YLRjNGB0Y8g0Lgg0L\/QvtCx0LXQttC00LDRgtGMIMKr0KHQvtC30LTQsNC90LjQucK7LiDQlNC70Y8g0L\/QvtC00LPQvtGC0L7QstC60Lgg0YHQv9Cw0YHQuNGC0LXQu9C10LksINGB0YPRidC10YHRgtCy0YPQtdGCINGB0L\/QtdGG0LjQsNC70YzQvdCw0Y8g0YjQutC+0LvQsCwg0LIg0LrQvtGC0L7RgNC+0Lkg0LjRhSDRgtGA0LXQvdC40YDRg9GO0YIuINCi0YPRgiDRgtC+INC4INC90LDRh9C40L3QsNC10YLRgdGPINC40YHRgtC+0YDQuNGPINC90LDRiNC10LPQviDQs9C70LDQstC90L7Qs9C+INCz0LXRgNC+0Y8sINCwINC10YHQu9C4INCx0YvRgtGMINGC0L7Rh9C90LXQtSwg0YLQviDRgdC+INCy0YHRgtGD0L\/QuNGC0LXQu9GM0L3QvtCz0L4g0Y3QutC30LDQvNC10L3QsOKApiDQodC80L7RgtGA0LjQvCE=","code":"seiken-tsukai-no-world-break"}} 6 | ``` 7 | 8 | Записываем информацию из файлов в массив. 9 | ```php 10 | for($i=0; $i < 630; $i++){ 11 | $tmp = json_decode(file_get_contents("/var/www/test.anilibria.tv/upload/cache/info$i.json"), true); 12 | foreach($tmp as $k => $v){ 13 | $info["$k"] = $v; 14 | } 15 | } 16 | ``` 17 | 18 | PHP 7.0 19 | ``` 20 | PHP Fatal error: Allowed memory size of 2097152 bytes exhausted (tried to allocate 8192 bytes) 21 | ``` 22 | 23 | PHP 7.3 24 | ``` 25 | Page generated in 0.0584 seconds. Peak memory usage: 2.85 MB 26 | ``` 27 | 28 | Тоже происходит, если запустить в цикле `Memcached::get()` 29 | ```php 30 | $count = $cache->get('apiInfo'); 31 | for($i=0; $i < $count; $i++){ 32 | $tmp = json_decode($cache->get("apiInfo$i"), true); 33 | foreach($tmp as $k => $v){ 34 | $info["$k"] = $v; 35 | } 36 | } 37 | ``` 38 | 39 |
40 | 41 | Устанавливаем PHP 7.3 42 | 43 | ``` 44 | apt-get update 45 | apt-get upgrade 46 | apt-get install ca-certificates apt-transport-https 47 | wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add - 48 | echo "deb https://packages.sury.org/php/ stretch main" | tee /etc/apt/sources.list.d/php.list 49 | apt-get update 50 | apt-get install php7.3-fpm php7.3-cli php7.3-curl php7.3-mysql php7.3-mbstring php-memcached php-geoip php-imagick geoip-database imagemagick 51 | ``` 52 | 53 | Настраиваем fpm pool. 54 | ``` 55 | # nano /etc/php/7.3/fpm/pool.d/anilibria.conf 56 | 57 | [anilibria] 58 | listen = /var/run/anilibria.sock 59 | 60 | user = anilibria 61 | group = www-data 62 | 63 | listen.owner = anilibria 64 | listen.group = www-data 65 | 66 | pm = static 67 | pm.max_children = 100 68 | pm.max_requests = 1000 69 | 70 | chdir = / 71 | 72 | php_admin_value[memory_limit] = 32M 73 | php_admin_value[max_execution_time] = 5 74 | php_admin_value[date.timezone] = "Europe/Moscow" 75 | php_admin_value[upload_max_filesize] = 4M 76 | php_admin_value[post_max_size] = 4M 77 | php_admin_flag[display_errors] = Off 78 | php_admin_flag[expose_php] = Off 79 | 80 | php_admin_value[error_log] = /var/www/anilibria/logs/php_error.log 81 | php_admin_flag[log_errors] = On 82 | php_admin_flag[report_memleaks] = On 83 | 84 | php_admin_value[opcache.enable] = 1 85 | php_admin_value[opcache.interned_strings_buffer] = 8 86 | php_admin_value[opcache.max_accelerated_files] = 4000 87 | 88 | php_admin_value[session.gc_probability] = 1 89 | php_admin_value[session.gc_divisor] = 1000 90 | php_admin_value[session.gc_maxlifetime] = 2592000 91 | php_admin_value[session.use_only_cookies] = 1 92 | php_admin_value[session.save_handler] = memcached 93 | php_admin_value[session.save_path] = "/tmp/memcached.socket" 94 | 95 | php_admin_value[disable_functions] = "apache_setenv, chown, chgrp, closelog, define_syslog_variables, dl, exec, ftp_exec, openlog, passthru, pcntl_exec, popen, posix_getegid, posix_geteuid, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, syslog, system, pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, shell_exec" 96 | ``` 97 | -------------------------------------------------------------------------------- /install/phpmyadmin.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get --no-install-recommends install phpmyadmin 3 | ``` 4 | 5 | Доступен по ссылке https://www.anilibria.tv/phpmyadmin/ 6 | 7 |
8 | 9 | No activity within 1440 seconds; please log in again error. 10 | 11 | ``` 12 | # nano /etc/phpmyadmin/config.inc.php 13 | $cfg['LoginCookieValidity'] = 7200; 14 | ``` 15 | 16 |
17 | 18 | Если phpmyadmin 4.6.6 и php > 7.1 19 | ``` 20 | Warning in ./libraries/plugin_interface.lib.php#551 21 | count(): Parameter must be an array or an object that implements Countable 22 | ``` 23 | 24 | ```php 25 | if ($options != null && count($options) > 0) { 26 | ``` 27 | 28 | Fix 29 | ```php 30 | if ($options != null && count((array)$options) > 0) { 31 | ``` 32 | -------------------------------------------------------------------------------- /install/pure-ftpd.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get install pure-ftpd 3 | openssl req -new -newkey rsa:2048 -days 9999 -nodes -x509 -subj /C=EU/ST=Unknown/L=Unknown/O=AniLibria/CN=anilibria.tv -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem 4 | chmod 0600 /etc/ssl/private/pure-ftpd.pem 5 | chmod 0600 /etc/ssl/private/pure-ftpd.pem 6 | echo yes > /etc/pure-ftpd/conf/ChrootEveryone 7 | echo yes > /etc/pure-ftpd/conf/DontResolve 8 | echo 1 > /etc/pure-ftpd/conf/TLS 9 | /etc/init.d/pure-ftpd restart 10 | ``` 11 | -------------------------------------------------------------------------------- /install/sphinx.md: -------------------------------------------------------------------------------- 1 | ``` 2 | apt-get install sphinxsearch 3 | mkdir /etc/sphinxsearch/dicts 4 | wget http://sphinxsearch.com/files/dicts/en.pak -O /etc/sphinxsearch/dicts/en.pak 5 | wget http://sphinxsearch.com/files/dicts/ru.pak -O /etc/sphinxsearch/dicts/ru.pak 6 | ``` 7 | 8 | ``` 9 | # nano /etc/default/sphinxsearch 10 | START=yes 11 | ``` 12 | 13 | ``` 14 | # nano /etc/sphinxsearch/sphinx.conf 15 | 16 | common { 17 | lemmatizer_base = /etc/sphinxsearch/dicts 18 | } 19 | 20 | source mysql { 21 | type = mysql 22 | sql_host = localhost 23 | sql_user = anilibria 24 | sql_pass = anilibria 25 | sql_db = anilibria 26 | 27 | # Sphinx return empty result on cyrillic query 28 | # http://sphinxsearch.com/forum/view.html?id=11176 29 | sql_query_pre = SET NAMES utf8 30 | 31 | sql_query_range = select min(id), max(id) from `xrelease` 32 | sql_range_step = 2048 33 | 34 | sql_query = select id, name, ename, aname, genre, year, last, rating from `xrelease` where id >= $start and id <= $end 35 | 36 | # http://sphinxsearch.com/forum/view.html?id=15403 37 | sql_attr_uint = last 38 | sql_attr_uint = rating 39 | } 40 | 41 | index anilibria { 42 | source = mysql 43 | 44 | # ё => е, э => е 45 | # http://sphinxsearch.com/docs/current/conf-charset-table.html 46 | # http://sphinxsearch.com/forum/view.html?id=7280 47 | charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42C->U+430..U+44C, \ 48 | U+42E..U+42F->U+44E..U+44F, U+430..U+44C, U+44E..U+44F, \ 49 | U+0401->U+0435, U+0451->U+0435, U+042D->U+0435, U+044D->U+0435 50 | 51 | # https://habr.com/post/147745/ 52 | morphology = stem_enru, soundex 53 | ondisk_attrs=1 54 | min_word_len = 3 55 | min_infix_len = 3 56 | expand_keywords = 1 57 | index_exact_words = 1 58 | 59 | path = /var/lib/sphinxsearch/data/anilibria 60 | } 61 | 62 | searchd { 63 | listen = localhost:9312 64 | listen = localhost:9306:mysql41 65 | log = /var/log/sphinxsearch/searchd.log 66 | query_log = /var/log/sphinxsearch/query.log 67 | pid_file = /var/run/sphinxsearch/searchd.pid 68 | } 69 | ``` 70 | 71 | ``` 72 | # nano /etc/cron.d/sphinxsearch 73 | 74 | * * * * * sphinxsearch [ -x /usr/bin/indexer ] && /usr/bin/indexer --quiet --rotate --config /etc/sphinxsearch/sphinx.conf --all 75 | ``` 76 | 77 | ``` 78 | /etc/init.d/sphinxsearch start 79 | ``` 80 | -------------------------------------------------------------------------------- /install/sysctl.md: -------------------------------------------------------------------------------- 1 | ``` 2 | # nano /etc/sysctl.conf 3 | 4 | net.ipv4.ip_forward=0 5 | net.ipv4.tcp_syncookies=0 6 | 7 | net.ipv4.icmp_echo_ignore_all=1 8 | 9 | net.ipv6.conf.all.disable_ipv6 = 1 10 | net.ipv6.conf.default.disable_ipv6 = 1 11 | net.ipv6.conf.lo.disable_ipv6 = 1 12 | 13 | net.ipv4.ip_local_port_range = 10000 65535 14 | 15 | net.ipv4.tcp_fin_timeout = 4 16 | net.ipv4.tcp_keepalive_time = 60 17 | net.ipv4.tcp_max_syn_backlog = 10240 18 | net.core.somaxconn = 1024 19 | 20 | # sysctl -p 21 | ``` 22 | 23 | 24 | -------------------------------------------------------------------------------- /install/timezone.md: -------------------------------------------------------------------------------- 1 | Проверить время на сервере можно с помощью команды. 2 | ``` 3 | # date 4 | Sun Feb 3 01:18:09 CET 2019 5 | ``` 6 | Debian/ Ubuntu. 7 | ``` 8 | dpkg-reconfigure tzdata 9 | ``` 10 | 11 | 12 | -------------------------------------------------------------------------------- /install/xbt_tracker.md: -------------------------------------------------------------------------------- 1 | Устанавливаем пакеты. 2 | ``` 3 | apt-get install cmake default-libmysqlclient-dev libmariadb-dev-compat g++ git libboost-dev make zlib1g-dev 4 | ``` 5 | 6 | Скачиваем, компилируем. 7 | ``` 8 | git clone https://github.com/OlafvdSpek/xbt.git 9 | cd xbt/Tracker 10 | cmake . 11 | make 12 | cp xbt_tracker.conf.default xbt_tracker.conf 13 | ``` 14 | 15 | Создаем пользователя. Перемещаем файлы. 16 | ``` 17 | adduser --disabled-login xbt 18 | mkdir /home/xbt/bin 19 | cp xbt_tracker /home/xbt/bin 20 | cp xbt_tracker.conf /home/xbt/bin 21 | chown -R xbt:xbt /home/xbt/bin 22 | chmod 700 /home/xbt/bin/xbt_tracker.conf 23 | ``` 24 | 25 | Редактируем конфиг. SQL таблицы уже есть в базе. 26 | ``` 27 | # nano /home/xbt/bin/xbt_tracker.conf 28 | mysql_host = localhost 29 | mysql_user = xbt 30 | mysql_password = secret 31 | mysql_database = anilibria 32 | ``` 33 | 34 | Добавляем в автозагрузку. 35 | ``` 36 | # nano /root/xbt.bash 37 | #!/bin/bash -x 38 | sleep 60 39 | su - xbt -c "cd /home/xbt/bin && ./xbt_tracker > /dev/null 2>/dev/null &" 40 | 41 | # chmod 755 /root/xbt.bash 42 | 43 | # nano /etc/rc.local 44 | /root/xbt.bash & 45 | ``` 46 | 47 | Запускаем. 48 | ``` 49 | su - xbt -c "cd /home/xbt/bin && ./xbt_tracker > /dev/null 2>/dev/null &" 50 | ``` 51 | 52 | Проверяем http://anilibria.tv:2710/st 53 | ``` 54 | peers 7242 55 | seeders 6159 85 % 56 | leechers 1083 14 % 57 | torrents 708 58 | accepted tcp 8909520 12 /s 59 | slow tcp 7987727 10 /s 60 | rejected tcp 0 61 | accept errors 0 62 | received udp 232422 0 /s 63 | sent udp 232422 0 /s 64 | announced 5099797 57 % 65 | announced http 5003668 98 % 66 | announced udp 96129 1 % 67 | scraped full 0 68 | scraped multi 265767 69 | scraped 646429 7 % 70 | scraped http 635775 98 % 71 | scraped udp 10654 1 % 72 | up time 1.2 weeks 73 | anonymous announce 1 74 | anonymous scrape 1 75 | auto register 0 76 | full scrape 0 77 | read config time 167 / 180 78 | clean up time 18 / 60 79 | read db files time 6 / 10 80 | read db users time 5 / 10 81 | write db files time 1 / 10 82 | write db users time 4 / 10 83 | ``` 84 | 85 |
86 | 87 | Оптимальное значение `announce_interval`? Меньше интервал, больше запросов на сервер.
88 | Если клиент не отправил запрос, сервер удаляет его из списка. Установим `announce_interval 60`.
89 | Количество пиров падает до `~30`. Думаю, хорошее значение `900~1800`.
90 | 91 | Munin плагины: xbt_users, xbt_torrents. 92 | 93 |
94 | 95 | После обновления MariaDB (5.5 => 10.2) трекер перестал обновлять seeders/leechers.
96 | Посмотрел код, проверил, что xbt подключается к базе и выполняет запросы. 97 | 98 | Включил логирование всех запросов. 99 | ``` 100 | # nano /etc/my/my.cnf 101 | general_log = on 102 | general_log_file = /var/log/mysql/full.log 103 | ``` 104 | 105 | Выполняю запрос, получаю ошибку. 106 | ``` 107 | insert into xbt_files (leechers, seeders, completed, fid) values (54,108,1692,3299),(39,53,1375,3297),(1,51,301,3295),(6,35,618,3287),(18,26,3376,3271),(4,39,3687,3241),(12,64,6650,3217),(12,42,4857,3212),(19,71,7624,3207),(8,78,5786,3198),(7,32,3443,3175),(8,40,5437,2777),(7,31,826,3292),(4,8,1758,2395),(9,38,15151,1999),(9,19,3673,759),(1,7,5813,2013),(1,12,3170,2417),(0,3,1485,1331),(3,38,2659,3195),(3,8,1600,1046),(1,10,3939,987),(6,36,6547,2403),(2,10,9300,1691),(3,17,641,3236),(4,15,7386,974),(3,18,1530,3250),(1,16,245,3242),(0,49,1603,3130),(2,13,1335,835),(17,47,3594,3238),(3,7,4232,1356),(4,10,2936,1780),(3,39,1496,3243),(0,69,1000,3272),(2,13,4959,1714),(1,72,950,3276),(1,14,7164,983),(12,34,1691,3237),(41,84,1422,3296),(24,40,5354,3279) on duplicate key update leechers = values(leechers), seeders = values(seeders), completed = values(completed), mtime = unix_timestamp() 108 | 109 | Field 'info_hash' doesn't have a default value 110 | ``` 111 | 112 | Проверяю sql mode. 113 | ``` 114 | MariaDB [(none)]> SELECT @@sql_mode; 115 | +-------------------------------------------------------------------------------------------+ 116 | | @@sql_mode | 117 | +-------------------------------------------------------------------------------------------+ 118 | | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | 119 | +-------------------------------------------------------------------------------------------+ 120 | ``` 121 | 122 | Выключаю STRICT_TRANS_TABLES. 123 | ``` 124 | # nano /etc/my/my.cnf 125 | [mysqld] 126 | ... 127 | sql_mode="ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 128 | 129 | # /etc/init.d/mysql restart 130 | ``` 131 | -------------------------------------------------------------------------------- /other/17-02-2019.md: -------------------------------------------------------------------------------- 1 | Report info. Author https://vk.com/id4726782 2 | 3 | 4 | 5 |
6 | 7 | ```php 8 | '-1', 'search' => '{"year":"2019","genre":""}', 'xpage' => 'catalog', 'sort' => '2']; 17 | 18 | // broblem: offset=1321165980, max_matches=1000 19 | // $data = ['page' => '-1', 'search' => '{"year":"2019","genre":""}', 'xpage' => 'catalog', 'sort' => '2']; 20 | 21 | $options = [ 22 | 'http' => [ 23 | 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 24 | 'method' => 'POST', 25 | 'content' => http_build_query($data) 26 | ] 27 | ]; 28 | $context = stream_context_create($options); 29 | $result = file_get_contents($url, false, $context); 30 | 31 | var_dump($result); 32 | 33 | ?> 34 | ``` 35 | 36 | ``` 37 | if(!empty($_POST['page'])){ 38 | $page = intval($_POST['page']); // -1 39 | if(empty($page) || $page == 1){ 40 | $page = 0; 41 | }else{ 42 | $page = ($page-1) * 12; // -2 * 12 = -24 43 | } 44 | // page > 1000 but max_matches=1000 45 | } 46 | ``` 47 | 48 | https://github.com/anilibria/anilibria/blob/0114562159e4602ae9d072bb7e0d57815c62c60b/private/func.php#L1985-L1992 49 | 50 | 51 | 52 | ``` 53 | [16-Feb-2019 23:35:52 Europe/Moscow] PHP Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 sphinxql: syntax error, unexpected '-', expecting CONST_INT near '-24, 12' in /var/www/anilibria/root/private/func.php:1933 54 | Stack trace: 55 | #0 /var/www/anilibria/root/private/func.php(1933): PDOStatement->execute() 56 | #1 /var/www/anilibria/root/private/func.php(2005): bSearch(Object(PDO), -24, 'last') 57 | #2 /var/www/anilibria/root/public/catalog.php(11): showCatalog() 58 | #3 {main} 59 | thrown in /var/www/anilibria/root/private/func.php on line 1933 60 | ``` 61 | 62 | fix `$page = abs(intval($_POST['page']));` 63 | https://github.com/anilibria/anilibria/commit/49d8aa0ad56b1368b3d4284d05ac646371973f42 64 | 65 | ``` 66 | [17-Feb-2019 00:52:25 Europe/Moscow] PHP Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 offset out of bounds (offset=1321165980, max_matches=1000) in /var/www/anilibria/root/private/func.php:1933 67 | Stack trace: 68 | #0 /var/www/anilibria/root/private/func.php(1933): PDOStatement->execute() 69 | #1 /var/www/anilibria/root/private/func.php(2005): bSearch(Object(PDO), 1321165980, 'last') 70 | #2 /var/www/anilibria/root/public/catalog.php(11): showCatalog() 71 | #3 {main} 72 | thrown in /var/www/anilibria/root/private/func.php on line 1933 73 | ``` 74 | 75 | fix `if($page > 2000) $page = 2000;` 76 | https://github.com/anilibria/anilibria/commit/3d0bb96fcd69795522a99c1dfd03326232f9be11 77 | -------------------------------------------------------------------------------- /other/18-02-2019.md: -------------------------------------------------------------------------------- 1 | Report info. Author https://vk.com/lurkerspower 2 | ``` 3 | нет защиты от CSRF 4 | ``` 5 |
6 | 7 | fix https://github.com/anilibria/anilibria/commit/2b4b5f79d5d61b5a43b2b29a8425e59139306689 8 | -------------------------------------------------------------------------------- /other/simple_http_filer.md: -------------------------------------------------------------------------------- 1 | Не проверяем целевую аудиторию, поисковики (google, yandex) и если пользователь уже прошел проверку. 2 | ``` 3 | Россия 4 | Украина 5 | Беларусь 6 | Латвия 7 | Литва 8 | Туркменистан 9 | Эстония 10 | Киргизия 11 | Казахстан 12 | Молдавия 13 | Узбекистан 14 | Азербайджан 15 | Армения 16 | Грузия 17 | ``` 18 | ```php 19 | function xSpiderBot($name){ 20 | $arr = ['Google' => '/\.googlebot\.com$/i', 'Yandex' => '/\.spider\.yandex\.com$/i']; 21 | if(strpos($_SERVER['HTTP_USER_AGENT'], $name) !== false){ 22 | return preg_match($arr["$name"], gethostbyaddr($_SERVER['REMOTE_ADDR'])); 23 | } 24 | return false; 25 | } 26 | ``` 27 | ```php 28 | $xflag = false; 29 | if(!empty($_COOKIE['ani_test'])){ 30 | $xkey = 'secret'; 31 | $xstring = $_COOKIE['ani_test']; 32 | $xhash = substr($xstring, 0, 64); 33 | $xrand = substr($xstring, 64+strlen($_SERVER['REMOTE_ADDR'])); 34 | $xtest = hash('sha256', $_SERVER['REMOTE_ADDR'].$xrand.$xkey); 35 | if($xhash == $xtest){ 36 | $xflag = true; 37 | } 38 | } 39 | ``` 40 | 41 | https://developers.google.com/recaptcha/docs/v3
42 | ``` 43 | Проверка выполняется автоматически. 44 | Получаем score от 0.0 до 1.0 45 | Если score меньше 0.5 выводим coinhive 46 | ``` 47 | 48 | https://coinhive.com/documentation/captcha 49 | ``` 50 | Проверка выполняется автоматически. 51 | Необходимо решить несколько хэшей (js xmr miner). 52 | ``` 53 | 54 | 55 | Если пользователь прошел проверку - создадим cookie. 56 | ```php 57 | $xkey = 'secret'; 58 | $xrand = random_int(0, 1000000); 59 | $xhash = hash('sha256', $_SERVER['REMOTE_ADDR'].$xrand.$xkey); 60 | setcookie("ani_test", $xhash.$_SERVER['REMOTE_ADDR'].$xrand, time() + 86400, '/'); 61 | 62 | // sign[hash(IP.RAND)] IP RAND 63 | // d6f8e5c40add2a6883b4885a0ff391d29a85c630a23bc497b1269250d5b49a66 127.0.0.1 110654 64 | // d6f8e5c40add2a6883b4885a0ff391d29a85c630a23bc497b1269250d5b49a66127.0.0.1110654 65 | ``` 66 | 67 | Demo https://www.anilibria.tv/demo/filter_demo.mp4 68 | -------------------------------------------------------------------------------- /other/transmission-daemon.md: -------------------------------------------------------------------------------- 1 | Установка. 2 | ``` 3 | apt-get install transmission-daemon 4 | ``` 5 | 6 | Перед тем как редактировать `/etc/transmission-daemon/settings.json` - выключите `transmission`. 7 | ``` 8 | /etc/init.d/transmission-daemon stop 9 | ``` 10 | 11 | Поменяем папку. 12 | ``` 13 | # "download-dir": "/var/www/torrent", 14 | mkdir /var/www/torrent/ 15 | chown debian-transmission:debian-transmission /var/www/torrent/ 16 | ``` 17 | 18 | Поменяем логин и пароль. 19 | ``` 20 | "rpc-username": "login", 21 | "rpc-password": "passwd", 22 | ``` 23 | 24 | Доступ к rpc `http://IP:9091` 25 | ``` 26 | "rpc-whitelist": "127.0.0.1", 27 | "rpc-whitelist": "127.0.0.1, 127.0.0.50", 28 | "rpc-whitelist": "*", 29 | ``` 30 | 31 |
32 | 33 | Nginx proxy. 34 | ``` 35 | "rpc-bind-address": "127.0.0.1", 36 | "rpc-port": 9091, 37 | ``` 38 | ``` 39 | location ~ ^/transmission { 40 | proxy_pass http://127.0.0.1:9091; 41 | proxy_pass_header X-Transmission-Session-Id; 42 | proxy_set_header Host $host; 43 | proxy_set_header X-Real-IP $remote_addr; 44 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 45 | } 46 | ``` 47 | 48 |
49 | 50 | Auto upload torrents. 51 | ```bash 52 | mkdir /home/torrent 53 | mkdir /home/torrent/tmp 54 | cat </home/torrent/upload.bash 55 | #!/bin/bash 56 | cd /home/torrent/tmp 57 | wget --no-directories --content-disposition --restrict-file-names=nocontrol -e robots=off -A.torrent -r https://www.anilibria.tv/wget_torrents.php 58 | for f in /home/torrent/tmp/*.torrent; do 59 | transmission-remote --auth transmission:HuHacOmcass2 -a $f 60 | done 61 | rm /home/torrent/tmp/*.torrent 62 | EOF 63 | 64 | chmod 750 /home/torrent/upload.bash 65 | 66 | cat </etc/cron.d/torrent 67 | SHELL=/bin/sh 68 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 69 | MAILTO="" 70 | HOME=/ 71 | 72 | 10 15 */7 * * root /home/torrent/upload.bash >/dev/null 2>&1 73 | EOF 74 | 75 | /etc/init.d/crond restart 76 | ``` 77 | 78 |
79 | 80 | Auto upload and clean old torrents https://habr.com/post/135874/ 81 | 82 | ```php 83 | #!/usr/bin/php 84 | ['timeout' => 5 ]]); // timeout 5s for file_get_contents 102 | $dir = ['/var/lib/transmission-daemon/.config/transmission-daemon/torrents', '/home/torrent/tmp']; 103 | $files = array_slice(scandir($dir[0]), 2); 104 | foreach($files as $v){ 105 | if(pathinfo("$dir[0]/$v",PATHINFO_EXTENSION) == 'torrent'){ 106 | $info = $torrent->decodeFile("$dir[0]/$v"); 107 | $info_hash = pack('H*',$info["info_hash"]); 108 | if(!checkTorrent(urlencode($info_hash))){ 109 | echo "Try remove $v ... "; 110 | $id = intval(shell_exec("transmission-remote --auth $login:$passwd -t ".escapeshellarg($info['info_hash'])." --info | grep \"Id:\" | sed -e 's/[^0-9]*//g'")); 111 | if(is_numeric($id) && $id != 0){ 112 | echo "OK!"; 113 | shell_exec("transmission-remote --auth $login:$passwd --torrent $id --remove-and-delete"); 114 | } 115 | echo "\n"; 116 | } 117 | } 118 | } 119 | 120 | // clean https://habr.com/post/135874/ 121 | $bl = false; // true - use blacklist, false - dont use. 122 | $blacklist = explode("\n", file_get_contents('/var/www/anilibria/root/tracker/torrents/blacklist.txt', false, $ctx)); 123 | shell_exec("cd $dir[1] && wget -q --no-directories --content-disposition --restrict-file-names=nocontrol -e robots=off -A.torrent -r https://www.anilibria.tv/tracker/torrents/wget_torrents.php"); 124 | $files = array_slice(scandir($dir[1]), 2); 125 | foreach($files as $v){ 126 | if(pathinfo("$dir[1]/$v",PATHINFO_EXTENSION) == 'torrent'){ 127 | $info = $torrent->decodeFile("$dir[1]/$v"); 128 | if($bl && in_array($info['info_hash'], $blacklist)){ 129 | echo "Blacklist {$info['info_hash']} $v\n"; 130 | continue; 131 | } 132 | echo "Upload $v\n"; 133 | shell_exec("transmission-remote --auth $login:$passwd -a ".escapeshellarg("$dir[1]/$v")); 134 | } 135 | } 136 | shell_exec("rm /home/torrent/tmp/*.torrent"); 137 | ``` 138 | 139 |
140 | 141 | 142 | -------------------------------------------------------------------------------- /todo/site.md: -------------------------------------------------------------------------------- 1 | ``` 2 | [-] авторизация vk 3 | [-] возможность установить свой пароль 4 | [-] поиск, скрыть where status = скрыт 5 | [-] заявки в команду, поменять почту 6 | [-] исправление notice/ warning (php_error.log) 7 | [-] описать проблему stat.go 8 | [-] монетизация (плеер + шапка) 9 | [-] kernelcare, установка + документация 10 | [-] удалить чат, вместо него картинка + спасибо что выбираете нас 11 | [-] удалить sanasol announce, добавить через своего бота 12 | [-] страницы 404 и 403, same PageURL 13 | [-] удалить страницу ссылки, перенести ссылки в футер (слева) 14 | [-] добавить страницу алфавитный указатель (вывести все релизы на одной странице) 15 | [-] страница релизы, автосохранение популярное/ новое 16 | ``` 17 | 18 | ``` 19 | [+] альтернативное название релиза 20 | [+] if access < 2 hide edit announce 21 | [+] поля тайминг, оформление, перевод 22 | [+] работа над релизом link => open modal window 23 | [-] push if new youtube video 24 | [-] og tags + desc + img 25 | [+] remove download from playerjs (we have torrent for download on site) 26 | [+] if access > 1 bind session to ip 27 | [+] video links 28 | [+] block by country 29 | [-] алфавитный указатель 30 | [-] порядок просмотра 31 | [+] upload avatar show error 32 | [-] add message change email, passwd 33 | ``` 34 | 35 | ``` 36 | Есть проблемы с отображением, если в поиске ввести Игры/2018, то видно 3 аниме, а рамку четвертого видно только когда наводишь мышку под первое аниме "Повелитель" . 37 | 38 | при попытке удаления 2х торрентов удалаяет все торренты (их было 3) 39 | ``` 40 | -------------------------------------------------------------------------------- /video/index.php: -------------------------------------------------------------------------------- 1 | addServer('/tmp/memcached.socket', 0) or die('memcache not work'); 4 | $bl = $cache->get('anilibria_bl'); 5 | $id = false; 6 | $path = '/var/www/video/ftp/videos/mp4/'; 7 | 8 | $hosts = [ 9 | 'de1' => '10', 10 | 'de2' => '10', 11 | 'de3' => '10', 12 | 'de4' => '10', 13 | 'de5' => '10', 14 | 'de6' => '10', 15 | 'de7' => '10', 16 | 'de8' => '10', 17 | ]; 18 | 19 | function anilibria_getHost(){ 20 | global $hosts; $host = []; 21 | foreach($hosts as $key => $val){ 22 | $host = array_merge($host, array_fill(0, $val, $key)); 23 | } 24 | shuffle($host); 25 | if(count($host) == 1){ 26 | return $host[0].".anilibria.tv"; 27 | } 28 | return $host[random_int(0, count($host) - 1)].".anilibria.tv"; 29 | } 30 | 31 | function testCDN($arr){ 32 | global $cache; 33 | foreach($arr as $host => $val){ 34 | if($host == 'x') continue; 35 | $ch = curl_init(); 36 | curl_setopt($ch, CURLOPT_URL, "https://$host.anilibria.tv/videos/dont_delete_this_fucking_file.ts"); 37 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 38 | curl_setopt($ch, CURLOPT_HEADER, 1); 39 | curl_setopt($ch, CURLOPT_NOBODY, 1); 40 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,5); 41 | curl_setopt($ch, CURLOPT_TIMEOUT, 5); 42 | $result = curl_exec($ch); 43 | curl_close($ch); 44 | $bl = $cache->get('anilibria_bl'); 45 | if(!empty($bl)){ 46 | $bl = json_decode($bl, TRUE); 47 | foreach($bl as $h => $v){ // clean if host not exist 48 | if(!array_key_exists($h, $arr)){ 49 | unset($bl[$h]); 50 | } 51 | } 52 | }else{ 53 | $bl = []; 54 | } 55 | if($result && strpos($result, '200 OK') !== false){ 56 | unset($bl[$host]); 57 | }else{ 58 | $bl[$host] = $host; 59 | } 60 | $cache->set('anilibria_bl', json_encode($bl), 0); 61 | } 62 | return $bl = $cache->get('anilibria_bl'); 63 | } 64 | 65 | if(isset($_GET['testCDN'])){ 66 | die(testCDN($hosts)); 67 | } 68 | 69 | if(!empty($bl)){ 70 | $bl = json_decode($bl, true); 71 | foreach($hosts as $h => $v){ 72 | if(in_array($h, $bl)){ 73 | unset($hosts[$h]); 74 | } 75 | } 76 | if(empty($hosts)){ // if all cdn down 77 | die('all hosts down'); 78 | } 79 | } 80 | 81 | if(isset($_GET['id'])){ 82 | $id = intval($_GET['id']); 83 | } 84 | 85 | if(!$id){ 86 | die('403'); 87 | } 88 | 89 | if(!file_exists($path.$id)){ 90 | die('404'); 91 | } 92 | 93 | $i = 0; 94 | $links = []; 95 | $episodeNum = 0; 96 | $host = anilibria_getHost(); 97 | $files = glob("/var/www/video/ftp/videos/ts/{$id}/*"); 98 | foreach($files as $file){ 99 | if(is_dir($file)){ 100 | if(strpos($file, '-sd') !== false){ 101 | continue; 102 | } 103 | $file = str_replace('/var/www/video/ftp/', '', $file); 104 | preg_match('/\/\d+\/0*(\d+)/', $file, $matches); 105 | $i++; 106 | $episodeNum = intval($matches[1]); 107 | $links[$episodeNum] = [ 108 | 'file' => str_replace(['ts', 'videos/'], ['mp4', ''], $file), 109 | 'hd' => '//'.$host.'/'.$file.'/playlist.m3u8', 110 | 'sd' => '//'.$host.'/'.$file.'-sd/playlist.m3u8', 111 | 'new' => "[720p]//$host/$file/playlist.m3u8,[480p]//$host/$file-sd/playlist.m3u8", 112 | 'new2' => "[720p]//{host}/$file/playlist.m3u8,[480p]//{host}/$file-sd/playlist.m3u8", 113 | ]; 114 | } 115 | } 116 | $links['updated'] = true; 117 | if(isset($_GET['v2'])){ 118 | $links['online'] = $hosts; 119 | } 120 | echo json_encode(array_reverse($links, true)); 121 | -------------------------------------------------------------------------------- /video/nginx_caching_proxy.md: -------------------------------------------------------------------------------- 1 | В 2016 году Sanasol предложил кешировать видео с помощью cloudflare (бесплатный тариф).
2 | Статистика cloudflare за последний месяц (август 2017). 3 | ``` 4 | Total Bandwidth 205.71 TB 5 | Cached Bandwidth 170.13 TB 6 | Uncached Bandwidth 35.58 TB 7 | ``` 8 | 9 | Халява закончилась в октябре. Cloudflare отключил cache.
10 | 11 |
12 | 13 | Создаем поддомен. 14 | 15 | ``` 16 | xakep1 A 109.248.206.13 # YALOCO [PROXY] 17 | x A 5.9.82.141 # HETZNER [MAIN] 18 | ``` 19 | 20 | Действия выполняются на Debian 9, устанавливаем пакеты. 21 | ``` 22 | apt-get update && apt-get upgrade -y 23 | apt-get install nginx munin munin-node certbot spawn-fcgi libcgi-fast-perl htop bwm-ng strace lsof libfile-readbackwards-perl 24 | ``` 25 | 26 | Устанавливаем munin плагин nginx-cache-hit-rate 27 | ``` 28 | # wget -O /usr/share/munin/plugins/nginx-cache-hit-rate https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/nginx/nginx-cache-hit-rate 29 | # chmod 755 /usr/share/munin/plugins/nginx-cache-hit-rate 30 | # ln -s /usr/share/munin/plugins/nginx-cache-hit-rate /etc/munin/plugins/ 31 | 32 | # nano /etc/munin/plugin-conf.d/munin-node 33 | ... 34 | [nginx-cache-hit-rate] 35 | user www-data 36 | 37 | # /etc/init.d/munin-node restart 38 | ``` 39 | 40 | Генерируем dhparam. Получаем letsencrypt сертификат. 41 | ``` 42 | mkdir /etc/nginx/ssl/ 43 | openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 44 | chown www-data:www-data /etc/nginx/ssl/dhparam.pem 45 | chmod 400 /etc/nginx/ssl/dhparam.pem 46 | certbot certonly --webroot -w /var/www/html -d xakep1.anilibria.tv -m admin@anilibria.tv --agree-tos 47 | ``` 48 | 49 | Настраиваем автопродление сертификата, добавляем renew-hook, перезагружаем cron. 50 | ``` 51 | # nano /etc/cron.d/certbot 52 | ... 53 | 0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "/etc/init.d/nginx restart" 54 | 55 | # /etc/init.d/cron restart 56 | ``` 57 | 58 | Скачиваем конфиг /etc/nginx/nginx.conf, перезагружаем nginx. 59 | ``` 60 | wget https://raw.githubusercontent.com/icantbelieveitworks/docs/master/lepus/conf/nginx_caching_proxy.conf -O /etc/nginx/nginx.conf 61 | /etc/init.d/nginx restart 62 | ``` 63 | 64 | Проверим что cache работает. 65 | ``` 66 | # после трех запросов => файл попадает в cache 67 | # curl https://xakep1.anilibria.tv/videos/ts/5223/0001/fff31.ts -s -I | grep x-cache-status 68 | x-cache-status: MISS 69 | 70 | # HIT => кеш работает. 71 | # curl https://xakep1.anilibria.tv/videos/ts/5223/0001/fff31.ts -s -I | grep x-cache-status 72 | x-cache-status: HIT 73 | ``` 74 | 75 | За удаление файла из кеша - отвечает настройка proxy_cache_bypass в конфиге nginx.
76 | Чтобы удалить - отправим запрос => `ded334209c901fe8c90c9ca08c8aa86c` secret cookie. 77 | ``` 78 | curl https://xakep1.anilibria.tv/videos/ts/4576/0001/fff1.ts -s -I -H "ded334209c901fe8c90c9ca08c8aa86c:true" 79 | ``` 80 | 81 |
82 | 83 | `proxy_cache_min_uses` задаёт число запросов, после которого ответ будет закэширован. Временное окно зависит от настройки proxy_cache_path `keys_zone`, `max_size` и `inactive`. Вытесняются из кеша, если нет обращений > `inactive time` или когда размер кеша превышает максимальное значение (алгоритм LRU). 84 | 85 | Позволяет значительно снизить нагрузку на диск. 86 | 87 | 88 | ``` 89 | proxy_cache_min_uses 1; 90 | iostat -xk -t 10 91 | Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util 92 | nvme0n1 0.00 99.20 351.80 96.90 36560.40 8809.20 202.23 40.22 89.64 8.12 385.62 0.46 20.64 93 | nvme0n1 0.00 53.20 341.60 15.60 35042.40 8408.00 243.28 5.71 15.97 7.35 204.74 0.54 19.32 94 | nvme0n1 0.00 42.90 318.80 17.50 32736.80 10322.40 256.08 6.68 19.88 9.21 214.17 0.67 22.64 95 | nvme0n1 0.00 90.70 388.30 100.20 40371.20 11722.00 213.28 41.87 85.70 15.70 357.00 0.53 26.04 96 | nvme0n1 0.00 51.90 297.40 15.60 30661.60 9576.00 257.11 7.03 22.48 10.67 247.59 0.66 20.64 97 | 98 | AVG %util (20.64+19.32+22.64+26.04+20.64)/5 = 21.856 99 | ``` 100 | ``` 101 | proxy_cache_min_uses 3; 102 | iostat -xk -t 10 103 | Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util 104 | nvme0n1 0.00 20.00 316.80 3.20 32999.20 2244.80 220.28 0.38 1.20 0.88 33.00 0.35 11.08 105 | nvme0n1 0.00 47.30 340.80 52.40 35730.80 2792.40 195.95 1.42 3.61 0.90 21.22 0.31 12.28 106 | nvme0n1 0.00 22.50 298.20 5.00 31284.40 3541.20 229.72 0.92 3.04 1.96 68.00 0.38 11.64 107 | nvme0n1 0.00 25.40 337.60 3.70 35014.00 2290.00 218.60 0.42 1.24 0.88 33.84 0.29 9.96 108 | nvme0n1 0.00 41.20 322.90 42.20 33559.60 3074.80 200.68 2.77 7.59 1.16 56.80 0.33 12.08 109 | 110 | AVG %util (11.08+12.28+11.64+9.96+12.08)/5 = 11.408 111 | ``` 112 |
113 | 114 | Если `proxy_temp_path` и `proxy_cache_path` располагаются на разных файловых системах, то вместо дешёвой операции переименовывания в пределах одной файловой системы файл копируется с одной файловой системы на другую. Поэтому лучше, если кэш будет находиться на той же файловой системе, что и каталог с временными файлами. Если параметр `use_temp_path` установлен в значение “off”, то временные файлы будут располагаться непосредственно в каталоге кэша. 115 | 116 | ``` 117 | # df -h 118 | /dev/md0 92G 15G 73G 17% / 119 | /dev/nvme0n1p1 459G 406G 30G 94% /var/www/cache 120 | ``` 121 | ``` 122 | proxy_cache_path /var/www/cache use_temp_path=off levels=1:2 keys_zone=STATIC:125m inactive=1d max_size=430g; 123 | ``` 124 |
125 | 126 | `reuseport` этот параметр (1.9.1) указывает, что нужно создавать отдельный слушающий сокет для каждого рабочего процесса (через параметр сокета SO_REUSEPORT), позволяя ядру распределять входящие соединения между рабочими процессами. В настоящий момент это работает только на Linux 3.9+ и DragonFly BSD. 127 | 128 | Nginx использует 2-3 воркера. 129 | ``` 130 | server { # caching reverse proxy 131 | listen 80; 132 | listen 443 ssl http2; 133 | ``` 134 | 135 | 136 | 137 | Включаем `reuseport`, нагрузка распределяется между всеми воркерами. 138 | 139 | ``` 140 | server { # caching reverse proxy 141 | listen 80 reuseport; 142 | listen 443 ssl http2 reuseport; 143 | ``` 144 | 145 | 146 | 147 | Проверяем скорость. 148 | 149 | ``` 150 | # reuseport off 151 | # siege -t60S http://xakep1.anilibria.tv/videos/ts/5614/0001/fff3.ts 152 | Transactions: 4758 hits 153 | Availability: 100.00 % 154 | Elapsed time: 59.42 secs 155 | Data transferred: 5323.13 MB 156 | Response time: 0.06 secs 157 | Transaction rate: 80.07 trans/sec 158 | Throughput: 89.58 MB/sec 159 | Concurrency: 4.93 160 | Successful transactions: 4758 161 | Failed transactions: 0 162 | Longest transaction: 5.06 163 | Shortest transaction: 0.05 164 | ``` 165 | ``` 166 | # reuseport on 167 | # siege -t60S http://xakep1.anilibria.tv/videos/ts/5614/0001/fff3.ts 168 | Transactions: 4754 hits 169 | Availability: 100.00 % 170 | Elapsed time: 59.26 secs 171 | Data transferred: 5318.65 MB 172 | Response time: 0.06 secs 173 | Transaction rate: 80.22 trans/sec 174 | Throughput: 89.75 MB/sec 175 | Concurrency: 4.97 176 | Successful transactions: 4754 177 | Failed transactions: 0 178 | Longest transaction: 5.06 179 | Shortest transaction: 0.05 180 | ``` 181 | 182 |
183 | 184 | Каждый новый запроc nginx записывает в `access.log` => много мелких операций. 185 | 186 | ``` 187 | request <==> nginx <==> write log 188 | request <==> nginx <==> write log 189 | request <==> nginx <==> write log 190 | ``` 191 | 192 | Выгоднее записать данные в `buffer`. Потом, за одну операцию, сохранить в `access.log`.
193 | Если установить `flush=5s`, то запись в файл будет происходить каждые пять секунд или когда `buffer > size`. 194 | 195 | ``` 196 | access_log /var/log/nginx/cache-access.log cache buffer=16k; 197 | ``` 198 | 199 | ``` 200 | request <==> nginx <==> write buffer 201 | request <==> nginx <==> write buffer 202 | request <==> nginx <==> write buffer 203 | 204 | ========= if buffer > size ========= 205 | buffer ==> write log ==> clean buffer 206 | ``` 207 | 208 | Если вам не нужны логи/ статистика - отключите `access.log`. 209 | ``` 210 | access_log off; 211 | ``` 212 | 213 |
214 | 215 | `Keepalive connections` can have a major impact on performance by reducing the CPU and network overhead needed to open and close connections. NGINX terminates all client connections and creates separate and independent connections to the upstream servers. NGINX supports keepalives for both clients and upstream servers. 216 | 217 | ``` 218 | # netstat -tupan | grep 5.9.82.141 219 | tcp 0 0 109.248.206.13:34834 5.9.82.141:80 ESTABLISHED 15062/nginx: worker 220 | tcp 0 0 109.248.206.13:34838 5.9.82.141:80 ESTABLISHED 15059/nginx: worker 221 | tcp 0 564 109.248.206.13:34842 5.9.82.141:80 ESTABLISHED 15058/nginx: worker 222 | tcp 0 0 109.248.206.13:34826 5.9.82.141:80 ESTABLISHED 15063/nginx: worker 223 | tcp 0 0 109.248.206.13:34830 5.9.82.141:80 ESTABLISHED 15058/nginx: worker 224 | tcp 0 0 109.248.206.13:34828 5.9.82.141:80 ESTABLISHED 15057/nginx: worker 225 | tcp 0 1 109.248.206.13:34844 5.9.82.141:80 SYN_SENT 15059/nginx: worker 226 | tcp 0 0 109.248.206.13:34786 5.9.82.141:80 ESTABLISHED 15061/nginx: worker 227 | tcp 0 0 109.248.206.13:34840 5.9.82.141:80 ESTABLISHED 15061/nginx: worker 228 | tcp 0 0 109.248.206.13:34764 5.9.82.141:80 ESTABLISHED 15061/nginx: worker 229 | ``` 230 | 231 | Включаем. 232 | ``` 233 | proxy_http_version 1.1; 234 | proxy_set_header Connection ""; 235 | ``` 236 | ``` 237 | # netstat -tupan | grep 5.9.82.141 238 | tcp 0 0 109.248.206.13:36958 5.9.82.141:80 TIME_WAIT - 239 | tcp 0 0 109.248.206.13:36930 5.9.82.141:80 TIME_WAIT - 240 | tcp 0 0 109.248.206.13:37156 5.9.82.141:80 TIME_WAIT - 241 | tcp 0 0 109.248.206.13:37412 5.9.82.141:80 TIME_WAIT - 242 | tcp 0 0 109.248.206.13:37458 5.9.82.141:80 ESTABLISHED 32043/nginx: worker 243 | tcp 0 0 109.248.206.13:37250 5.9.82.141:80 TIME_WAIT - 244 | tcp 0 0 109.248.206.13:37510 5.9.82.141:80 TIME_WAIT - 245 | tcp 0 0 109.248.206.13:37076 5.9.82.141:80 TIME_WAIT - 246 | tcp 0 0 109.248.206.13:37252 5.9.82.141:80 TIME_WAIT - 247 | tcp 0 0 109.248.206.13:37316 5.9.82.141:80 TIME_WAIT - 248 | tcp 0 0 109.248.206.13:37494 5.9.82.141:80 TIME_WAIT - 249 | tcp 0 0 109.248.206.13:37176 5.9.82.141:80 TIME_WAIT - 250 | tcp 0 0 109.248.206.13:37474 5.9.82.141:80 TIME_WAIT - 251 | tcp 0 0 109.248.206.13:37448 5.9.82.141:80 TIME_WAIT - 252 | tcp 0 0 109.248.206.13:37578 5.9.82.141:80 ESTABLISHED 32042/nginx: worker 253 | ``` 254 | 255 |
256 | 257 | Несколько `proxy_cache_path`. 258 | ``` 259 | proxy_cache_path /var/www/cache use_temp_path=off levels=1:2 keys_zone=cache:125m inactive=1d max_size=450g; 260 | proxy_cache_path /var/www/test use_temp_path=off levels=1:2 keys_zone=test:125m inactive=1d max_size=1000g; 261 | 262 | split_clients $request_uri $cachedisk { 263 | 50% "cache"; 264 | 50% "test"; 265 | } 266 | 267 | server { 268 | ... 269 | proxy_cache $cachedisk; 270 | ... 271 | ``` 272 | 273 |
274 | 275 | `proxy_cache_lock` если включено, одновременно только одному запросу будет позволено заполнить новый элемент кэша, идентифицируемый согласно директиве `proxy_cache_key`, передав запрос на проксируемый сервер. Остальные запросы этого же элемента будут либо ожидать появления ответа в кэше, либо освобождения блокировки этого элемента, в течение времени, заданного директивой `proxy_cache_lock_timeout`. 276 | 277 | ``` 278 | proxy_cache_lock on; 279 | proxy_cache_min_uses 3; 280 | ``` 281 | 282 | Делает три запроса на сервер. Последний - записывает в кэш. 283 | ``` 284 | # siege -t60S http://192.168.0.92/test.ts 285 | ** Preparing 25 concurrent users for battle 286 | 287 | 192.168.0.92 - - [03/Feb/2018:10:52:26 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 288 | 192.168.0.92 - - [03/Feb/2018:10:52:26 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 289 | 192.168.0.92 - - [03/Feb/2018:10:52:26 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 290 | ``` 291 | 292 | Выключим. Двадцать пять запросов. 293 | ``` 294 | proxy_cache_lock off; 295 | proxy_cache_min_uses 3; 296 | ``` 297 | 298 | ``` 299 | # siege -t60S http://192.168.0.92/test.ts 300 | ** Preparing 25 concurrent users for battle 301 | 302 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 303 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 304 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 305 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 306 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 307 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 308 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 309 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 310 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 311 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 312 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 313 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 314 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 315 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 316 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 317 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 318 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 319 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 320 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 321 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 322 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 323 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 324 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 325 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 326 | 192.168.0.92 - - [03/Feb/2018:10:56:32 -0500] "GET /test.ts HTTP/1.0" 200 5242880 "-" "Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.0.2" 327 | ``` 328 | 329 |
330 | 331 | Конфиг сервера. 332 | 333 | ``` 334 | CPU E3-1245 v5 335 | RAM 32 GB DDR4 336 | Samsung SSD 960 EVO 500GB 337 | I210 Gigabit Network Connection 338 | ``` 339 | 340 | Так как файлы не изменяются, задаем время кэширования один год.
341 | Если в течении дня, нет запросов `inactive=1d` - убираем из кеша.
342 | 343 | Все активные ключи и информация о данных хранятся в зоне разделяемой памяти, имя и размер которой задаются параметром `keys_zone`. Зоны размером в 1 мегабайт достаточно для хранения около 8 тысяч ключей.
344 | 345 | Думаю, можно посчитать так: средний размер файла `1MB => 420GB => 420000 файлов / 8000 => keys_zone 52.5M` 346 | Чтобы точно хватило сделал 2x => 125M. 347 | 348 | ``` 349 | proxy_cache_path /var/www/cache levels=1:2 keys_zone=STATIC:125m inactive=1d max_size=420g; 350 | proxy_cache_valid 200 1y; 351 | ``` 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 |
360 | 361 | Nginx: документация.
362 | Reverse Proxy with Caching.
363 | A Guide to Caching with NGINX and NGINX Plus.
364 | Пулы потоков: ускоряем NGINX в 9 и более раз.
365 | Увеличиваем производительность с помощью SO_REUSEPORT в NGINX 1.9.1
366 | 367 | -------------------------------------------------------------------------------- /win10-install.md: -------------------------------------------------------------------------------- 1 | ## Инструкция по установке тестовых версий (без использования Windows Store) на компьютер с windows 10. 2 | 3 | К сожалению Майрософт не сделала процесс установки такого типа приложений без Windows Store проще поэтому прийдется следовать их правилам. 4 | Я заранее извиняюсь за очень сложный процесс установки. Позже попробую избавиться от шага **Установка зависимостей**. 5 | 6 | ### Системные требования 7 | 8 | Windows 10 версии 17134 и выше 9 | 10 | ### Как посмотреть Версию системы и Тип системы? 11 | 12 | Для этого необходимо в меню пуск нажать на шестеренку в левом нижнем углу далее перейти в Система -> О системе. 13 | В разделе **Характеристики Windows** будет пункт **Сборка ОС**. И еще сразу посмотрите на пункт **Тип сиcтемы**, он нам тоже понадобится. 14 | 15 | ![Версия системы](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/systemversion.jpg?raw=true) 16 | 17 | ### Проверка наличия App Installer 18 | 19 | Для того чтобы убедиться что приложение **App Installer** установлено (на некоторых не стоковых версих Windows 10 они могут не стоять) перейдите в меню пуск нажмите на шестеренку в левом нижнем углу и перейдите в Приложения -> Приложения и возможности. Далее просто введите в строке поиска **App in**. После этого приложение должно появиться в списке как на скриншоте ниже. 20 | ![Версия системы](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/appinstaller.jpg?raw=true) 21 | Если приложения там нет то перейдите в Windows Store и установите его по [этой ссылке](https://www.microsoft.com/en-us/p/app-installer/9nblggh4nns1). 22 | 23 | ### Включение возможности установки приложений из любых источников (sideloading) 24 | 25 | Для этого необходимо в меню пуск нажать на шестеренку в левом нижнем углу далее перейти в **Обновление и безопастность** -> **Для разработчиков**. Выбрать в разделе **Использование функций разработчика** опцию **Неопубликованные приложения**. 26 | ![Настройка](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/settingssideload.jpg?raw=true) 27 | 28 | ### Скачивание версии 29 | 30 | Переходим на страницу с релизами https://github.com/anilibria/anilibria-win/releases 31 | 32 | На этой странице представлены все тестовые версии приложения. 33 | Все версии маркируются префиксами prealpha/alpha/beta/stable. 34 | Ниже описаны что они означают. Обычно лучше брать последнюю версию (в списке они от старшей к младшей расположены т.е. самая последняя вначале), 35 | стоит также обращать внимание на префиксы. 36 | 37 | * **prealpha** содержит новый функционал который не доработан или только в процессе доработки. 38 | * **alpha** содержит новый функционал в каком-то плюс минус законченном виде но нет гарантий что он работает стабильно. 39 | * **beta** содержит новый функционал в уже финальном виде но опять же не факт что оно работает стабильно. 40 | * **stable** это релизная версия которая отправиться в Windows Store или на сайт и будет доступна широкому кругу пользователей. 41 | 42 | ## Первоначальная установка версии 43 | 44 | Данные шаги необходимы если Вы в первый раз ставите на конкретной машине приложение. 45 | Возможно выполнение некоторых из этих шагов понадобиться и в дальнейшем, но не при каждой установке. 46 | 47 | Все манипуляции ниже требуют наличия администраторских прав, поэтому если у Вас нет таковых то попросите у кого есть. 48 | 49 | ### Установка сертификата 50 | 51 | Распакуйте скачанный в разделе **Скачивание версии** архив в любую папку на диске. 52 | Далее в корне распакованной папки будет находиться файл с расширением .cer 53 | Выполните его (кликните дважды мышкой) и затем нажмите на кнопку **Установить сертификат**. 54 | ![Установка сертификата](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/installcertificate.jpg?raw=true) 55 | Выберите **Локальный компьютер**, и далее **Поместить все сертификаты в следующее хранилище**. 56 | ![Установка расположения сертификата](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/certifilocation.jpg?raw=true) 57 | Нажмите на кнопку **Обзор** рядом с полем **Хранилище сертификатов** и в открывшимся диалоге выберите **Доверенные корневые центры сертификации** и нажмите **ОК**. 58 | 59 | ### Установка зависимостей 60 | 61 | Когда установка происходит из Windows Store механизм установки сам поставит все зависимости но к сожалению в нашем случае нам прийдется самим этим заняться. 62 | В корне распакованной папки из шага **Скачивание версии** зайдите в папку Dependencies. Далее Вам надо зайти в папку в зависимости от **Типа системы**. 63 | Как узнать какой у Вас тип системы я описал в разделе **Как посмотреть версию системы и Тип системы**. 64 | Далее переходим в папку соответственно Вашему типу системы: 65 | - Если в типе системы написано **64-разрядная операционная система, процессор x64** то значит переходим в папку x64 66 | - Если в типе системы написано **32-разрядная операционная система, процессор x86** то значит переходим в папку x86 67 | - Если в типе системы написано **32-разрядная операционная система, процессор ARM** то значит переходим в папку arm 68 | - Если в типе системы написано **64-разрядная операционная система, процессор ARM** то значит переходим в папку arm64 69 | 70 | После перехода в папку запустите (дважды щелкните) на каждый файл с расширением **.appx** а в открывшихся окнах нажмайте **Install**. 71 | 72 | ### Установка приложения 73 | 74 | После выполнения всех вышеупомянутых шагов можно вернуться в корень папки из раздела **Скачивание версии** и выполнить (дважды кликнуть) на файл 75 | с расширением **.appxbundle** (он будет называться Anilibria_0.0.2.0_x86_x64_arm_Debug или похоже). 76 | Откроется окно в котором достаточно нажать на кнопку **Install/Update**. Галочка **Launch when ready** если стоит означает что приложение запустится сразу после установки. 77 | ![Установка приложения](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/installer.jpg?raw=true) 78 | 79 | ## Обновление приложения 80 | 81 | Для обновления приложения Вам достаточно скачать новую версию и выполнить действия из раздела **Установка приложения** повторно. 82 | 83 | ## Известные ошибки при установке версии 84 | 85 | ### Проблема с сертификатом 86 | 87 | Если на шаге **Установка приложения** у Вас окно установки похоже на это: 88 | ![Проблема с сертификатом](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/certificatefailedinstall.jpg?raw=true) 89 | Убедитесь что Вы корректно выполнили установку сертификата из шага **Установка сертификата**, от неправильно указанного расположения и/или распределения прав сертификат может не работать. 90 | 91 | ### Проблема с зависимостями 92 | 93 | Если на шаге **Установка приложения** у Вас окно установки похоже на это: 94 | 95 | ![Проблемы с зависимостями](https://github.com/anilibria/anilibria-win/blob/master/doc/assets/dependencieserror.jpg?raw=true) 96 | Убедитесь что Вы корректно установили зависимости из шага **Установка зависимостей**. Обратите внимание возможно Вы установили зависимости из папки которая не соответствует Вашему **Типу системы**. 97 | --------------------------------------------------------------------------------