Изменения для уточнения возможности кэширования ответов yad.
* Добавлены raw-функции, которые возвращают и http-заголовки ответа yad-а тоже * Уточнения в README.md и TODO * Мелкие косметические исправления.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,7 @@
|
||||
.idea/**
|
||||
_Deparsed_XSubs.pm
|
||||
data/oauth/**
|
||||
data/cache/**
|
||||
data/config.json
|
||||
data/fileindex/**
|
||||
vendor_perl/**
|
||||
|
||||
40
README.md
40
README.md
@@ -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, через который это всё будет работать
|
||||
* uwsgi версии 2.0.15 или новее с поддержкой psgi
|
||||
* perl-5.18 или новее (вплоть до 5.32.x)
|
||||
* perl-5.18 или новее (вплоть до 5.32.x, дальше не тестировал)
|
||||
* пакеты perl-App-cpanminus и perl-local-lib
|
||||
|
||||
Предполагается, что придётся подтянуть модули из CPAN-а с помощью [cpanm][4]. Для этого есть скрипт **bootstrap.sh**
|
||||
|
||||
Как только всё вышеописанное в арсенале появится, можно переходить к [регистрации][1] приложения. Для работы понадобятся
|
||||
все привилегии в разделе **Яндекс.Диск REST API**. Полученные ID и Пароль надо вписать в **data/config.json**, пример
|
||||
все привилегии в разделе **Яндекс.Диск REST API**. Полученные **ID** и **Пароль** надо вписать в **data/config.json**, пример
|
||||
конфига **data/sample_config.json**. Также надо убедиться, что параметр "Код подтверждения" либо отсутствует в конфиге,
|
||||
либо закоментирован.
|
||||
|
||||
@@ -42,21 +60,25 @@
|
||||
|
||||
## Статус пректа
|
||||
|
||||
RC. Пока он *не готов*, хотя в принципе работает. Формально, он выйдет в релиз, как только закончатся пункты из файла
|
||||
TODO. :)
|
||||
|
||||
Ясное дело, что для серьёзного prodution-а это приложение не годится, во всяком случае в таком виде, как оно есть.
|
||||
Как минимум необходимо организовать кэширование. Соответственно, корректно выдавать expires со стороны приложения,
|
||||
чтобы, например, nginx мог без проблем кэшировать контент через proxy_cache.
|
||||
Beta. Пока он *не готов*, хотя в принципе, как PoC, работает. Формально, он выйдет в релиз, как только закончатся пункты
|
||||
из файла TODO. :) Планов и сроков нет, возможно через год, когда в нём появится необходимость.
|
||||
|
||||
## Завендоренные библиотеки
|
||||
|
||||
1. [Yandex::OAuth][5]
|
||||
2. [Yandex::Disk][6]
|
||||
|
||||
## Справочная литература
|
||||
1. [Yandex OAuth2 Reference][7] (FYI, для бОльшего понимания, как это работает, можно почитать документацию [imgur][8] на
|
||||
эту тематику)
|
||||
2. [Yandex Disk API reference][9]
|
||||
|
||||
[1]: https://oauth.yandex.ru/
|
||||
[2]: https://uwsgi-docs.readthedocs.io/en/latest/Perl.html
|
||||
[3]: https://github.com/unbit/uwsgi
|
||||
[4]: https://github.com/miyagawa/cpanminus
|
||||
[5]: https://metacpan.org/pod/Yandex::OAuth
|
||||
[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
39
TODO
@@ -1,19 +1,26 @@
|
||||
* Реализовать проверку кэша на тухлость (Yandex.Диск зачем-то регулярно
|
||||
обновляет ссылки, период обновления я пока не выявил). Делать по приходу
|
||||
клиента.
|
||||
* Из вышележащего следует, что можно пред-генерировать практически всё. Ибо
|
||||
оно зависит целиком и полностью от полного списка, который нам выдаёт yad и
|
||||
по факту является статическим контентом. То есть вполне можно полностью
|
||||
пред-генерировать все страницы и все редиректы. И по-хорошему так и надо
|
||||
делать.
|
||||
* Не аплодить файлы, которые уже есть в диске (проверка по длине + md5 или sha).
|
||||
* Реализовать проверку кэша на тухлость (Yandex.Диск зачем-то регулярно обновляет ссылки, период обновления я пока не
|
||||
выявил). Делать по приходу клиента. In fact, придётся делать запрос в yad на каждый redirect. Т.к. у yad выставлен
|
||||
заголовок Сache-Сontrol в значение no-cache, иными словами время жизни ссылки на файл не регламентировано. То есть от
|
||||
идеи построения file index и вписывания в него ссылок прямо на yad придётся отказаться и на каждый запрос на файл
|
||||
генерировать 302, делая подзапрос в yad.
|
||||
|
||||
* Не аплодить файлы, которые уже есть в диске (проверка по длине + md5 или sha). (Утилита yad_upload_dir.pl)
|
||||
|
||||
* Нужна утилита, которая синкает файлы из локального каталога в каталог на yad, удаляя в целевом каталоге всё лишнее.
|
||||
|
||||
* Исправить листинг каталогов, чтобы без слеша был 301-й редирект.
|
||||
* Исправить листинг файлов, чтобы по ссылке на файл отображался локальный урл,
|
||||
а при переходе на него происходил 302-й редирект.
|
||||
* Добавить режим *настоящего* проксирования, а не редиректа. До кучи. Но это
|
||||
опционально, факультативно, так редиректы работают нормально сами по себе.
|
||||
|
||||
* Исправить листинг файлов, чтобы по ссылке на файл отображался локальный урл, а при переходе на него происходил 302-й
|
||||
редирект в yad.
|
||||
|
||||
* Добавить режим *настоящего* проксирования, а не редиректа. До кучи. Но это опционально, факультативно, так редиректы
|
||||
работают нормально сами по себе.
|
||||
|
||||
* Добавить проверки corner-case-ов.
|
||||
|
||||
* Описать утилиты.
|
||||
* Организовать многопоточную загрузку файлов на Yandex.Disk, вероятно, через
|
||||
AnyEvent::HTTP, т.к. у него есть встроенное огранчение на количество
|
||||
подключений к одному серверу, либо через CORO::LWP.
|
||||
|
||||
* Организовать многопоточную загрузку файлов на Yandex.Disk, вероятно, через AnyEvent::HTTP, т.к. у него есть встроенное
|
||||
огранчение на количество подключений к одному серверу, либо через CORO::LWP.
|
||||
|
||||
* Хранить данные об oauth на в data/cache, а в data/oauth
|
||||
|
||||
0
bootstrap.sh
Normal file → Executable file
0
bootstrap.sh
Normal file → Executable file
@@ -19,6 +19,6 @@
|
||||
|
||||
# Всё что относится к работе с yandex.api
|
||||
"ID" : "ID полученный при регистрации прилодения на oauth.yandex.ru",
|
||||
"Пароль" : "Пароль полученный при регистрации прилодения на oauth.yandex.ru",
|
||||
"Код подтверждения" : "Циферьки из браузера - код подтверждения",
|
||||
"Пароль" : "Пароль полученный при регистрации приложения на oauth.yandex.ru",
|
||||
"Код подтверждения" : "Циферьки из браузера - код подтверждения"
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ sub GetAccessToken {
|
||||
}
|
||||
|
||||
my $token = RefreshAccessToken ($refresh_token);
|
||||
# yad обычно выдаёт токен на год, скинем с этого 1 минуту :) чтобы уж точно
|
||||
# yad обычно выдаёт токен на год, скинем с этого 1 минуту :) чтобы уж точно
|
||||
$cache->set ('refresh_token', $token->{refresh_token}, 'never');
|
||||
$cache->set ('access_token', $token->{access_token}, $token->{expires_in} - 60);
|
||||
$access_token = $token->{access_token};
|
||||
|
||||
@@ -225,6 +225,22 @@ sub fileInfo {
|
||||
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 {
|
||||
my $self = shift;
|
||||
my %opt = @_;
|
||||
@@ -265,6 +281,26 @@ sub listAllFiles {
|
||||
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 {
|
||||
my $self = shift;
|
||||
my %opt = @_;
|
||||
|
||||
@@ -8,6 +8,8 @@ use open qw (:std :utf8);
|
||||
use English qw ( -no_match_vars );
|
||||
use version; our $VERSION = qw (1.0);
|
||||
|
||||
use Carp qw (croak);
|
||||
|
||||
my $workdir;
|
||||
|
||||
# сменим рабочий каталог
|
||||
|
||||
42
test/yad_file_info_raw.pl
Executable file
42
test/yad_file_info_raw.pl
Executable 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
31
test/yad_list_all_files_raw.pl
Executable 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:
|
||||
@@ -25,6 +25,7 @@ use YadProxy::Conf qw (LoadConf);
|
||||
use YadProxy::Lib qw (GetAccessToken);
|
||||
use Yandex::Disk;
|
||||
use Data::Dumper;
|
||||
use Carp qw (croak);
|
||||
|
||||
my $c = LoadConf ();
|
||||
my $remote_dir = '/';
|
||||
|
||||
Reference in New Issue
Block a user