В первой части мы прошли аутентификацию и получили токен. Теперь настало время перейти к следующей части - загрузке файлов на ЯндексДиск посредством REST API с использованием RESTClient и RESTRequest. В интернете много публикаций, в которых рассматривается чтение с Диска, но про загрузку что-то не встречал. Хотя все не просто, а очень просто ))
Берем предыдущий проект и добавляем на форму RESTClient и RESTRequest. В uses добавляем REST.Types, System.JSON.
RESTClient.BaseURL выставляем в https://cloud-api.yandex.net/v1 и удостоверяемся, что Authenticator подхватил OAuth2Authenticator1 с которым мы эксперементировали до этого.
Теперь - ВНИМАНИЕ!!! Очищаем свойство Authenticator у компонена RESTClient. Почему? Потому что эта [censored] подставляет токен в виде параметра access_token даже если ее не просят и при некоторых видах запросов портит Body.
В принципе, больше с ними ничего делать не надо, все остальное будем менять программно.
Так же можно добавить на форму Edit, SpeedButton и OpenDialog - для простоты выбора файла. На SpeedButton вешаем обработчик
и собственно, процедура UploadFile, которая, используя полученный токен в два захода отправляет файл на Диск. Почему в два захода? Потому что первым заходом получает ссылку для загрузки, время жизни которой ограничено 30 минутами и для которой не требуется токен.
UPD. Забыл! Для того, чтобы не спотыкаться об "401 UNAUTHORIZED", крайне важно у компонента OAuth2Authenticator свойство TokenType выставить в ttNONE, иначе при запросах в заголовке Authorization подставляется Bearer, из-за чего система и дает отлуп.
Берем предыдущий проект и добавляем на форму RESTClient и RESTRequest. В uses добавляем REST.Types, System.JSON.
RESTClient.BaseURL выставляем в https://cloud-api.yandex.net/v1 и удостоверяемся, что Authenticator подхватил OAuth2Authenticator1 с которым мы эксперементировали до этого.
Теперь - ВНИМАНИЕ!!! Очищаем свойство Authenticator у компонена RESTClient. Почему? Потому что эта [censored] подставляет токен в виде параметра access_token даже если ее не просят и при некоторых видах запросов портит Body.
В принципе, больше с ними ничего делать не надо, все остальное будем менять программно.
Так же можно добавить на форму Edit, SpeedButton и OpenDialog - для простоты выбора файла. На SpeedButton вешаем обработчик
procedure TForm3.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then begin
Edit1.Text:=OpenDialog1.FileName;
UploadFile(Edit1.Text);
end;
end;
и собственно, процедура UploadFile, которая, используя полученный токен в два захода отправляет файл на Диск. Почему в два захода? Потому что первым заходом получает ссылку для загрузки, время жизни которой ограничено 30 минутами и для которой не требуется токен.
Вот и все! Для использования в реальных условиях, конечно, надо оборачивать вызов UploadFile в try..except, поскольку даже при написании этой статьи я словил таймаут, не говоря уж о прочих возможных ошибках.
procedure TForm3.UploadFile(FileName: String);
var SFileName,Link,Mem:String;
Code:Integer;
begin
//выделяем только имя файла, без путей
SFileName:=ExtractFileName(FileName);
memo1.Lines.Add('uploading '+SFileName);
//подготавливаем параметры
RESTRequest1.Params.Clear;
RESTRequest1.Params.Add;
//в первую очередь дополнительный заголовок в запрос
//с токеном, иначе будет 401 UNAUTHORIZED
RESTRequest1.Params[0].Kind:=TRESTRequestParameterKind.pkHTTPHEADER;
RESTRequest1.Params[0].name:='Authorization';
RESTRequest1.Params[0].Options:=[poDoNotEncode];
RESTRequest1.Params[0].Value:='OAuth ' + OAuth2Authenticator1.AccessToken;
//далее - путь загрузки
//делаем просто в папку приложения
RESTRequest1.Params.Add;
RESTRequest1.Params[1].name:='path';
RESTRequest1.Params[1].Value:='app:/'+SFilename;
//перезапишем без вопросов
RESTRequest1.Params.Add;
RESTRequest1.Params[2].name:='overwrite';
RESTRequest1.Params[2].Value:='true';
RESTRequest1.Resource:='/disk/resources/upload';
RESTRequest1.Method:=rmGet;
//ну и собственно запрос ссылки на загрузк
RESTRequest1.Execute;
if RESTRequest1.Response.StatusCode=200 then begin
//все нормально, для отладки выведем полученный JSON
Memo1.Lines.Add(RESTRequest1.Response.Content);
//выделяем ссылку на загрузку
Link:=TJSONObject(RESTRequest1.Response.JSONValue).GetValue('href').Value;
Memo1.lines.add(Link); //запоминаем базовый путь
Mem:=RESTClient1.BaseURL;
try //прописываем ссылку на загрузку
RESTClient1.BaseURL:=Link;
//очищаем параметры, токен при это не нужен RESTRequest1.Params.Clear;
RESTRequest1.Resource:='';
//добавляем файл в запрос
RESTRequest1.AddFile(FileName);
//метод - PUT
RESTRequest1.Method:=rmPUT; //ну и отправляем файл на сервер
RESTRequest1.Execute;
finally
//после чего восстанавливаем ссылку на API
RESTClient1.BaseURL:=Mem;
end;
Code:=RESTRequest1.Response.StatusCode;
if Code=201 then Memo1.Lines.Add('файл успешно загружен');
if Code=202 then Memo1.Lines.Add('файл загружен на сервер, но пока не передан в папку назначения');
if Code=412 then Memo1.Lines.Add('при дозагрузке файла был передан неверный диапазон в заголовке Content-Range');
if Code=413 then Memo1.Lines.Add('размер файла превышает 10Гб');
if Code=500 then Memo1.Lines.Add('внутренняя ошибка сервера, попробуйте позже');
if Code=503 then Memo1.Lines.Add('сервис недоступен, попробуйте позже');
if Code=507 then Memo1.Lines.Add('исчерпано место на Диске');
end else Memo1.Lines.Add('запрос ссылки - ошибка '+RESTRequest1.Response.StatusCode.ToString);
end;
UPD. Забыл! Для того, чтобы не спотыкаться об "401 UNAUTHORIZED", крайне важно у компонента OAuth2Authenticator свойство TokenType выставить в ttNONE, иначе при запросах в заголовке Authorization подставляется Bearer, из-за чего система и дает отлуп.
Как скачать файл с ЯДиска?
ОтветитьУдалить