0

Изменения для уточнения возможности кэширования ответов yad.

* Добавлены raw-функции, которые возвращают и http-заголовки ответа
yad-а тоже
* Уточнения в README.md и TODO
* Мелкие косметические исправления.
This commit is contained in:
eleksir
2021-08-28 13:19:31 +03:00
parent e655c11e0b
commit cd4a0f5cb4
11 changed files with 172 additions and 28 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,7 @@
.idea/**
_Deparsed_XSubs.pm
data/oauth/** data/oauth/**
data/cache/**
data/config.json data/config.json
data/fileindex/** data/fileindex/**
vendor_perl/** vendor_perl/**

View File

@@ -2,7 +2,8 @@
## Что это? ## Что это?
Своего рода API, делающий запросы в Yandex.Disk и выставляющий наружу листинг публично доступных файлов. Своего рода API, делающий запросы в Yandex.Disk и выставляющий наружу листинг публично доступных файлов. Так же есть
утилитка, которая заливает каталог с файлами на yad.
## Зачем это нужно? ## Зачем это нужно?
@@ -11,21 +12,38 @@
## Как это работает? ## Как это работает?
### Немного лирики
YaD использует в своей работе т.н. "публичные ссылки". Это ссылки на страничку где предлагается указанный файл
сохранить либо к себе на yad, чтобы оно засинкалось на комп через штатного клиента yad, либо скачать через браузер.
Нам такой вариант никак не подходит по понятным причинам.
Но есть хорошие новости: в YaD есть прямые ссылки на файлы и эти ссылки "работают" напрямую, без дополнительных
http-заголовков. Но ту тже огорчу - время жизни таких ссылок ограничено и не регламентировано. Иными словами,
ссылку на объект хорошо бы каждый раз перед скачиванием запрашивать с yad.
### В общих чертах
При загрузке файлов на диск сохраняется список урлов, по которым эти файлы будут доступны через веб-часть. При загрузке файлов на диск сохраняется список урлов, по которым эти файлы будут доступны через веб-часть.
Как приятный бонус мы имеем dirlist в стиле nginx-а - со списком каталогов и файлов - в котором файлы - это по сути
ссылки на YaD, а каталоги... ну это каталоги :) Если обратиться к файлу напрямую, в веб-часть, то мы получаем редирект
на YaD.
Также предполагается к использованию утилита **yad_upload_dir.pl**. Она аплодит каталог с файлами в YaD.
## Как это запустить? ## Как это запустить?
Для запуска понадобятся: Для запуска понадобятся:
* Аккаунт @yandex.ru, через который это всё будет работать * Аккаунт @yandex.ru, через который это всё будет работать
* uwsgi версии 2.0.15 или новее с поддержкой psgi * uwsgi версии 2.0.15 или новее с поддержкой psgi
* perl-5.18 или новее (вплоть до 5.32.x) * perl-5.18 или новее (вплоть до 5.32.x, дальше не тестировал)
* пакеты perl-App-cpanminus и perl-local-lib * пакеты perl-App-cpanminus и perl-local-lib
Предполагается, что придётся подтянуть модули из CPAN-а с помощью [cpanm][4]. Для этого есть скрипт **bootstrap.sh** Предполагается, что придётся подтянуть модули из CPAN-а с помощью [cpanm][4]. Для этого есть скрипт **bootstrap.sh**
Как только всё вышеописанное в арсенале появится, можно переходить к [регистрации][1] приложения. Для работы понадобятся Как только всё вышеописанное в арсенале появится, можно переходить к [регистрации][1] приложения. Для работы понадобятся
все привилегии в разделе **Яндекс.Диск REST API**. Полученные ID и Пароль надо вписать в **data/config.json**, пример все привилегии в разделе **Яндекс.Диск REST API**. Полученные **ID** и **Пароль** надо вписать в **data/config.json**, пример
конфига **data/sample_config.json**. Также надо убедиться, что параметр "Код подтверждения" либо отсутствует в конфиге, конфига **data/sample_config.json**. Также надо убедиться, что параметр "Код подтверждения" либо отсутствует в конфиге,
либо закоментирован. либо закоментирован.
@@ -42,21 +60,25 @@
## Статус пректа ## Статус пректа
RC. Пока он *не готов*, хотя в принципе работает. Формально, он выйдет в релиз, как только закончатся пункты из файла Beta. Пока он *не готов*, хотя в принципе, как PoC, работает. Формально, он выйдет в релиз, как только закончатся пункты
TODO. :) из файла TODO. :) Планов и сроков нет, возможно через год, когда в нём появится необходимость.
Ясное дело, что для серьёзного prodution-а это приложение не годится, во всяком случае в таком виде, как оно есть.
Как минимум необходимо организовать кэширование. Соответственно, корректно выдавать expires со стороны приложения,
чтобы, например, nginx мог без проблем кэшировать контент через proxy_cache.
## Завендоренные библиотеки ## Завендоренные библиотеки
1. [Yandex::OAuth][5] 1. [Yandex::OAuth][5]
2. [Yandex::Disk][6] 2. [Yandex::Disk][6]
## Справочная литература
1. [Yandex OAuth2 Reference][7] (FYI, для бОльшего понимания, как это работает, можно почитать документацию [imgur][8] на
эту тематику)
2. [Yandex Disk API reference][9]
[1]: https://oauth.yandex.ru/ [1]: https://oauth.yandex.ru/
[2]: https://uwsgi-docs.readthedocs.io/en/latest/Perl.html [2]: https://uwsgi-docs.readthedocs.io/en/latest/Perl.html
[3]: https://github.com/unbit/uwsgi [3]: https://github.com/unbit/uwsgi
[4]: https://github.com/miyagawa/cpanminus [4]: https://github.com/miyagawa/cpanminus
[5]: https://metacpan.org/pod/Yandex::OAuth [5]: https://metacpan.org/pod/Yandex::OAuth
[6]: https://metacpan.org/pod/Yandex::Disk [6]: https://metacpan.org/pod/Yandex::Disk
[7]: https://yandex.com/dev/oauth/doc/dg/concepts/about.html
[8]: https://api.imgur.com/oauth2
[9]: https://yandex.com/dev/disk/api/concepts/about.html

39
TODO
View File

@@ -1,19 +1,26 @@
* Реализовать проверку кэша на тухлость (Yandex.Диск зачем-то регулярно * Реализовать проверку кэша на тухлость (Yandex.Диск зачем-то регулярно обновляет ссылки, период обновления я пока не
обновляет ссылки, период обновления я пока не выявил). Делать по приходу выявил). Делать по приходу клиента. In fact, придётся делать запрос в yad на каждый redirect. Т.к. у yad выставлен
клиента. заголовок Сache-Сontrol в значение no-cache, иными словами время жизни ссылки на файл не регламентировано. То есть от
* Из вышележащего следует, что можно пред-генерировать практически всё. Ибо идеи построения file index и вписывания в него ссылок прямо на yad придётся отказаться и на каждый запрос на файл
оно зависит целиком и полностью от полного списка, который нам выдаёт yad и генерировать 302, делая подзапрос в yad.
по факту является статическим контентом. То есть вполне можно полностью
пред-генерировать все страницы и все редиректы. И по-хорошему так и надо * Не аплодить файлы, которые уже есть в диске (проверка по длине + md5 или sha). (Утилита yad_upload_dir.pl)
делать.
* Не аплодить файлы, которые уже есть в диске (проверка по длине + md5 или sha). * Нужна утилита, которая синкает файлы из локального каталога в каталог на yad, удаляя в целевом каталоге всё лишнее.
* Исправить листинг каталогов, чтобы без слеша был 301-й редирект. * Исправить листинг каталогов, чтобы без слеша был 301-й редирект.
* Исправить листинг файлов, чтобы по ссылке на файл отображался локальный урл,
а при переходе на него происходил 302-й редирект. * Исправить листинг файлов, чтобы по ссылке на файл отображался локальный урл, а при переходе на него происходил 302-й
* Добавить режим *настоящего* проксирования, а не редиректа. До кучи. Но это редирект в yad.
опционально, факультативно, так редиректы работают нормально сами по себе.
* Добавить режим *настоящего* проксирования, а не редиректа. До кучи. Но это опционально, факультативно, так редиректы
работают нормально сами по себе.
* Добавить проверки corner-case-ов. * Добавить проверки corner-case-ов.
* Описать утилиты. * Описать утилиты.
* Организовать многопоточную загрузку файлов на Yandex.Disk, вероятно, через
AnyEvent::HTTP, т.к. у него есть встроенное огранчение на количество * Организовать многопоточную загрузку файлов на Yandex.Disk, вероятно, через AnyEvent::HTTP, т.к. у него есть встроенное
подключений к одному серверу, либо через CORO::LWP. огранчение на количество подключений к одному серверу, либо через CORO::LWP.
* Хранить данные об oauth на в data/cache, а в data/oauth

0
bootstrap.sh Normal file → Executable file
View File

View File

@@ -19,6 +19,6 @@
# Всё что относится к работе с yandex.api # Всё что относится к работе с yandex.api
"ID" : "ID полученный при регистрации прилодения на oauth.yandex.ru", "ID" : "ID полученный при регистрации прилодения на oauth.yandex.ru",
"Пароль" : "Пароль полученный при регистрации прилодения на oauth.yandex.ru", "Пароль" : "Пароль полученный при регистрации приложения на oauth.yandex.ru",
"Код подтверждения" : "Циферьки из браузера - код подтверждения", "Код подтверждения" : "Циферьки из браузера - код подтверждения"
} }

View File

@@ -225,6 +225,22 @@ sub fileInfo {
return $json_res; return $json_res;
} }
sub fileInfoRaw {
my $self = shift;
my %opt = @_;
my $path = $opt{-path} || croak "Specify -path param";
my $param = '?path=' . uri_escape($path);
my $res = $self->__request('https://cloud-api.yandex.net/v1/disk/resources' . $param, 'GET');
my $code = $res->code;
if ($code ne '200') {
croak "Error on fileInfo. Error: " . $res->status_line;
}
return $res;
}
sub listFiles { sub listFiles {
my $self = shift; my $self = shift;
my %opt = @_; my %opt = @_;
@@ -265,6 +281,26 @@ sub listAllFiles {
return $json_res->{items}; return $json_res->{items};
} }
sub listAllFilesRaw {
my $self = shift;
my %opt = @_;
my $limit = $opt{-limit} || 999999;
my $media_type = $opt{-media_type};
my $offset = $opt{-offset};
$offset = 0 if not $offset;
my $param = "?limit=$limit&offset=$offset";
$param .= '&media_type=' . $media_type if $media_type;
my $res = $self->__request('https://cloud-api.yandex.net/v1/disk/resources/files' . $param, 'GET');
my $code = $res->code;
if ($code ne '200') {
croak "Error on listFiles. Error: " . $res->status_line;
}
return $res;
}
sub lastUploadedFiles { sub lastUploadedFiles {
my $self = shift; my $self = shift;
my %opt = @_; my %opt = @_;

View File

@@ -8,6 +8,8 @@ use open qw (:std :utf8);
use English qw ( -no_match_vars ); use English qw ( -no_match_vars );
use version; our $VERSION = qw (1.0); use version; our $VERSION = qw (1.0);
use Carp qw (croak);
my $workdir; my $workdir;
# сменим рабочий каталог # сменим рабочий каталог

42
test/yad_file_info_raw.pl Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/perl
use 5.018;
use strict;
use warnings;
use utf8;
use open qw (:std :utf8);
use English qw ( -no_match_vars );
use version; our $VERSION = qw (1.0);
use Carp qw (croak);
my $workdir;
# сменим рабочий каталог
BEGIN {
use Cwd qw (chdir abs_path);
my @CWD = split /\//xms, abs_path ($PROGRAM_NAME);
if ($#CWD > 1) { $#CWD = $#CWD - 2; }
$workdir = join '/', @CWD;
chdir $workdir;
}
use lib ("$workdir/lib", "$workdir/vendor_perl", "$workdir/vendor_perl/lib/perl5");
use YadProxy::Conf qw (LoadConf);
use YadProxy::Lib qw (GetAccessToken);
use Yandex::Disk;
use Data::Dumper;
my $c = LoadConf ();
my $remote_dir = '';
my $file = 'test_file.txt';
if ($c->{remote_dir} && $c->{remote_dir} ne '') {
$remote_dir = $c->{remote_dir};
}
my $disk = Yandex::Disk->new ( -token => GetAccessToken );
say Dumper $disk->fileInfoRaw ( -path => sprintf ('%s/%s', $remote_dir, $file));
__END__
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:

31
test/yad_list_all_files_raw.pl Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/perl
use 5.018;
use strict;
use warnings;
use utf8;
use open qw (:std :utf8);
use English qw ( -no_match_vars );
use version; our $VERSION = qw (1.0);
my $workdir;
# сменим рабочий каталог
BEGIN {
use Cwd qw (chdir abs_path);
my @CWD = split /\//xms, abs_path ($PROGRAM_NAME);
if ($#CWD > 1) { $#CWD = $#CWD - 2; }
$workdir = join '/', @CWD;
chdir $workdir;
}
use lib ("$workdir/lib", "$workdir/vendor_perl", "$workdir/vendor_perl/lib/perl5");
use YadProxy::Lib qw (GetAccessToken);
use Yandex::Disk;
use Data::Dumper;
my $disk = Yandex::Disk->new ( -token => GetAccessToken );
say Dumper $disk->listAllFilesRaw ();
__END__
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:

View File

@@ -25,6 +25,7 @@ use YadProxy::Conf qw (LoadConf);
use YadProxy::Lib qw (GetAccessToken); use YadProxy::Lib qw (GetAccessToken);
use Yandex::Disk; use Yandex::Disk;
use Data::Dumper; use Data::Dumper;
use Carp qw (croak);
my $c = LoadConf (); my $c = LoadConf ();
my $remote_dir = '/'; my $remote_dir = '/';