Quick.Amazon.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. { ***************************************************************************
  2. Copyright (c) 2015-2017 Kike Pérez
  3. Unit : Quick.Amazon
  4. Description : Amazon object operations
  5. Author : Kike Pérez
  6. Version : 1.2
  7. Created : 18/11/2016
  8. Modified : 20/11/2016
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Amazon;
  22. interface
  23. uses
  24. Classes,
  25. System.SysUtils,
  26. System.Generics.Collections,
  27. IPPeerClient,
  28. Data.Cloud.CloudAPI,
  29. Data.Cloud.AmazonAPI;
  30. type
  31. TAmazonProtocol = (amHTTP,amHTTPS);
  32. TAmazonStorage = TAmazonStorageService;
  33. TAmazonACLAccess = TAmazonACLType;
  34. TAmazonRegion = Data.Cloud.AmazonAPI.TAmazonRegion;
  35. TAmazonObject = class
  36. Name : string;
  37. Modified : TDateTime;
  38. Size : Int64;
  39. IsDeleted : Boolean;
  40. end;
  41. TAmazonObjects = class(TObjectList<TAmazonObject>);
  42. TAmazonResponseInfo = record
  43. StatusCode : Integer;
  44. StatusMsg : string;
  45. end;
  46. TQuickAmazon = class
  47. private
  48. fconAmazon : TAmazonConnectionInfo;
  49. fAccountName : string;
  50. fAccountKey : string;
  51. fAmazonProtocol : TAmazonProtocol;
  52. procedure SetAccountName(amAccountName : string);
  53. procedure SetAccountKey(amAccountKey : string);
  54. procedure SetAmazonProtocol(amProtocol : TAmazonProtocol);
  55. function FileToArray(cFilename : string) : TArray<Byte>;
  56. function StreamToArray(cStream : TStream) : TArray<Byte>;
  57. public
  58. constructor Create; overload;
  59. constructor Create(amAccountName, amAccountKey : string); overload;
  60. destructor Destroy; override;
  61. property AccountName : string read fAccountName write SetAccountName;
  62. property AccountKey : string read fAccountKey write SetAccountKey;
  63. property AmazonProtocol : TAmazonProtocol read fAmazonProtocol write SetAmazonProtocol;
  64. function StorageURL(amBucket : string) : string;
  65. function PutObject(amBucket, cFilename, amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  66. function PutObject(amBucket : string; cStream : TStream; amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  67. function GetObject(amBucket, amObjectName, cFilenameTo : string; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  68. function GetObject(amBucket, amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : TMemoryStream; overload;
  69. function ExistsObject(amBucket, amObjectName : string; amRegion : TAmazonRegion) : Boolean;
  70. function DeleteObject(amBucket,amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  71. function ListObjects(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TAmazonObjects;
  72. function ListObjectsNames(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TStrings;
  73. function ExistsBucket(amBucketName : string) : Boolean;
  74. function ListBuckets(var amResponseInfo : TAmazonResponseInfo) : TStrings;
  75. function CreateBucket(amBucket : string; amBucketRegion : TAmazonRegion; amACLType : TAmazonACLAccess; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  76. function DeleteBucket(amBucket : string; amBucketRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  77. end;
  78. implementation
  79. constructor TQuickAmazon.Create;
  80. begin
  81. inherited;
  82. fconAmazon := TAmazonConnectionInfo.Create(nil);
  83. fAmazonProtocol := amHTTP;
  84. end;
  85. constructor TQuickAmazon.Create(amAccountName, amAccountKey : string);
  86. begin
  87. Create;
  88. SetAccountName(amAccountName);
  89. SetAccountKey(amAccountKey);
  90. end;
  91. destructor TQuickAmazon.Destroy;
  92. begin
  93. if Assigned(fconAmazon) then fconAmazon.Free;
  94. inherited;
  95. end;
  96. procedure TQuickAmazon.SetAccountName(amAccountName : string);
  97. begin
  98. if fAccountName <> amAccountName then
  99. begin
  100. fAccountName := amAccountName;
  101. fconAmazon.AccountName := amAccountName;
  102. end;
  103. end;
  104. procedure TQuickAmazon.SetAccountKey(amAccountKey : string);
  105. begin
  106. if fAccountKey <> amAccountKey then
  107. begin
  108. fAccountKey := amAccountKey ;
  109. fconAmazon.AccountKey := amAccountKey;
  110. end;
  111. end;
  112. procedure TQuickAmazon.SetAmazonProtocol(amProtocol: TAmazonProtocol);
  113. begin
  114. if fAmazonProtocol <> amProtocol then
  115. begin
  116. fAmazonProtocol := amProtocol;
  117. if amProtocol = amHTTP then fconAmazon.Protocol := 'http'
  118. else fconAmazon.Protocol := 'https';
  119. end;
  120. end;
  121. function TQuickAmazon.FileToArray(cFilename : string) : TArray<Byte>;
  122. var
  123. fs : TFileStream;
  124. bs : TBytesStream;
  125. begin
  126. fs := TFileStream.Create(cFilename, fmOpenRead);
  127. try
  128. bs := TBytesStream.Create(Result);
  129. try
  130. bs.LoadFromStream(fs);
  131. Result := bs.Bytes;
  132. finally
  133. bs.Free
  134. end;
  135. finally
  136. fs.Free;
  137. end;
  138. end;
  139. function TQuickAmazon.StreamToArray(cStream : TStream) : TArray<Byte>;
  140. var
  141. bs : TBytesStream;
  142. begin
  143. bs := TBytesStream.Create(Result);
  144. try
  145. bs.LoadFromStream(cStream);
  146. Result := bs.Bytes;
  147. finally
  148. bs.Free
  149. end;
  150. end;
  151. function GetResponseInfo(amResponseInfo : TCloudResponseInfo) : TAmazonResponseInfo;
  152. begin
  153. Result.StatusCode := amResponseInfo.StatusCode;
  154. Result.StatusMsg := amResponseInfo.StatusMessage;
  155. end;
  156. function TQuickAmazon.StorageURL(amBucket : string) : string;
  157. begin
  158. Result := fconAmazon.StorageURL(amBucket)
  159. end;
  160. function TQuickAmazon.PutObject(amBucket, cFilename, amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  161. var
  162. AmazonS3 : TAmazonStorage;
  163. Content : TArray<Byte>;
  164. CloudResponseInfo : TCloudResponseInfo;
  165. begin
  166. Result := False;
  167. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  168. if amBucket = '' then amBucket := '$root';
  169. CloudResponseInfo := TCloudResponseInfo.Create;
  170. try
  171. Content := FileToArray(cFilename);
  172. if amObjectName = '' then amObjectName := cFilename;
  173. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  174. Result := AmazonS3.UploadObject(amBucket,amObjectName,Content,False,nil,nil,amACLType,CloudResponseInfo);
  175. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  176. finally
  177. AmazonS3.Free;
  178. CloudResponseInfo.Free;
  179. end;
  180. end;
  181. function TQuickAmazon.PutObject(amBucket : string; cStream : TStream; amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  182. var
  183. AmazonS3 : TAmazonStorage;
  184. Content : TArray<Byte>;
  185. CloudResponseInfo : TCloudResponseInfo;
  186. begin
  187. amResponseInfo.StatusCode := 500;
  188. if amBucket = '' then amBucket := '$root';
  189. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  190. try
  191. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  192. try
  193. //AmazonS3.Timeout := fTimeout;
  194. CloudResponseInfo := TCloudResponseInfo.Create;
  195. Content := StreamToArray(cStream);
  196. Result := AmazonS3.UploadObject(amBucket,amObjectName,Content,False,nil,nil,amACLType,CloudResponseInfo);
  197. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  198. finally
  199. AmazonS3.Free;
  200. CloudResponseInfo.Free;
  201. end;
  202. except
  203. Result := False;
  204. end;
  205. end;
  206. function TQuickAmazon.GetObject(amBucket, amObjectName, cFilenameTo : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  207. var
  208. AmazonS3 : TAmazonStorage;
  209. fs : TFileStream;
  210. CloudResponseInfo : TCloudResponseInfo;
  211. amParams : TAmazonGetObjectOptionals;
  212. begin
  213. Result := False;
  214. if amBucket = '' then amBucket := '$root';
  215. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  216. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  217. try
  218. //AmazonS3.Timeout := fTimeout;
  219. CloudResponseInfo := TCloudResponseInfo.Create;
  220. if FileExists(cFilenameTo) then fs := TFileStream.Create(cFilenameTo,fmOpenWrite)
  221. else fs := TFileStream.Create(cFilenameTo,fmCreate);
  222. try
  223. try
  224. AmazonS3.GetObject(amBucket,amObjectName,fs,CloudResponseInfo);
  225. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  226. if amResponseInfo.StatusCode = 200 then Result := True;
  227. except
  228. Result := False;
  229. end;
  230. finally
  231. fs.Free;
  232. CloudResponseInfo.Free;
  233. end;
  234. finally
  235. AmazonS3.Free;
  236. end;
  237. end;
  238. function TQuickAmazon.GetObject(amBucket, amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : TMemoryStream;
  239. var
  240. AmazonS3 : TAmazonStorage;
  241. fs : TFileStream;
  242. CloudResponseInfo : TCloudResponseInfo;
  243. begin
  244. Result := TMemoryStream.Create;
  245. if amBucket = '' then amBucket := '$root';
  246. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  247. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  248. try
  249. //AmazonS3.Timeout := fTimeout;
  250. CloudResponseInfo := TCloudResponseInfo.Create;
  251. try
  252. AmazonS3.GetObject(amBucket,amObjectName,Result,CloudResponseInfo);
  253. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  254. except
  255. Result := nil;
  256. end;
  257. finally
  258. AmazonS3.Free;
  259. CloudResponseInfo.Free;
  260. end;
  261. end;
  262. function TQuickAmazon.ExistsObject(amBucket, amObjectName : string; amRegion : TAmazonRegion) : Boolean;
  263. var
  264. amObject : string;
  265. amObjects : TStrings;
  266. ResponseInfo : TAmazonResponseInfo;
  267. begin
  268. Result := False;
  269. amObjects := ListObjectsNames(amBucket,amObjectName,amRegion,ResponseInfo);
  270. try
  271. if (ResponseInfo.StatusCode = 200) and (Assigned(amObjects)) then
  272. begin
  273. for amObject in amObjects do
  274. begin
  275. if amObject = amObjectName then
  276. begin
  277. Result := True;
  278. Break;
  279. end;
  280. end;
  281. end;
  282. finally
  283. amObjects.Free;
  284. end;
  285. end;
  286. function TQuickAmazon.DeleteObject(amBucket,amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  287. var
  288. AmazonS3 : TAmazonStorage;
  289. CloudResponseInfo : TCloudResponseInfo;
  290. begin
  291. Result := False;
  292. if amBucket = '' then amBucket := '$root';
  293. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  294. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  295. try
  296. //AmazonS3.Timeout := fTimeout;
  297. CloudResponseInfo := TCloudResponseInfo.Create;
  298. Result := AmazonS3.DeleteObject(amBucket,amObjectName,CloudResponseInfo);
  299. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  300. finally
  301. AmazonS3.Free;
  302. CloudResponseInfo.Free;
  303. end;
  304. end;
  305. function TQuickAmazon.ListObjects(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TAmazonObjects;
  306. var
  307. AmazonS3 : TAmazonStorage;
  308. amObject : TAmazonObject;
  309. i : Integer;
  310. amBucketResult : TAmazonBucketResult;
  311. CloudResponseInfo : TCloudResponseInfo;
  312. cNextMarker : string;
  313. amParams : TStrings;
  314. a : TAmazonBucketResult;
  315. begin
  316. Result := TAmazonObjects.Create(True);
  317. cNextMarker := '';
  318. if amBucket = '' then amBucket := '$root';
  319. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  320. CloudResponseInfo := TCloudResponseInfo.Create;
  321. try
  322. //AmazonS3.Timeout := fTimeout;
  323. repeat
  324. amParams := TStringList.Create;
  325. try
  326. amParams.Values['prefix'] := amObjectsStartWith;
  327. if cNextMarker <> '' then amParams.Values['marker'] := cNextMarker;
  328. amBucketResult := AmazonS3.GetBucket(amBucket,amParams,CloudResponseInfo,amRegion);
  329. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  330. if Assigned(amBucketResult) then
  331. begin
  332. try
  333. for i := 0 to amBucketResult.Objects.Count-1 do
  334. begin
  335. amObject := TAmazonObject.Create;
  336. amObject.Name := amBucketResult.Objects[i].Name;
  337. amObject.Modified := StrToDateTime(amBucketResult.Objects[i].LastModified);
  338. amObject.Size := amBucketResult.Objects[i].Size;
  339. amObject.IsDeleted := amBucketResult.Objects[i].IsDeleted;
  340. Result.Add(amObject);
  341. end;
  342. finally
  343. amBucketResult.Free;
  344. end;
  345. cNextMarker := amBucketResult.Marker;
  346. end;
  347. finally
  348. amParams.Free;
  349. end;
  350. until (cNextMarker = '') or (amResponseInfo.StatusCode <> 200);
  351. finally
  352. AmazonS3.Free;
  353. CloudResponseInfo.Free;
  354. end;
  355. end;
  356. function TQuickAmazon.ListObjectsNames(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TStrings;
  357. var
  358. AmazonS3 : TAmazonStorage;
  359. i : Integer;
  360. amBucketResult : TAmazonBucketResult;
  361. CloudResponseInfo : TCloudResponseInfo;
  362. cNextMarker : string;
  363. amParams : TStrings;
  364. a : TAmazonBucketResult;
  365. begin
  366. Result := TStringList.Create;
  367. cNextMarker := '';
  368. if amBucket = '' then amBucket := '$root';
  369. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  370. CloudResponseInfo := TCloudResponseInfo.Create;
  371. try
  372. //AmazonS3.Timeout := fTimeout;
  373. repeat
  374. amParams := TStringList.Create;
  375. try
  376. if amObjectsStartWith <> '' then amParams.Values['prefix'] := amObjectsStartWith;
  377. if cNextMarker <> '' then amParams.Values['marker'] := cNextMarker;
  378. amBucketResult := AmazonS3.GetBucket(amBucket,amParams,CloudResponseInfo,amRegion);
  379. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  380. if Assigned(amBucketResult) then
  381. begin
  382. try
  383. for i := 0 to amBucketResult.Objects.Count-1 do Result.Add(amBucketResult.Objects[i].Name);
  384. finally
  385. amBucketResult.Free;
  386. end;
  387. cNextMarker := amBucketResult.Marker;
  388. end;
  389. finally
  390. amParams.Free;
  391. end;
  392. until (cNextMarker = '') or (amResponseInfo.StatusCode <> 200);
  393. finally
  394. AmazonS3.Free;
  395. CloudResponseInfo.Free;
  396. end;
  397. end;
  398. function TQuickAmazon.ExistsBucket(amBucketName : string) : Boolean;
  399. var
  400. amBucket : string;
  401. amBuckets : TStrings;
  402. ResponseInfo : TAmazonResponseInfo;
  403. begin
  404. Result := False;
  405. amBuckets := ListBuckets(ResponseInfo);
  406. try
  407. if (ResponseInfo.StatusCode = 200) and (Assigned(amBuckets)) then
  408. begin
  409. for amBucket in amBuckets do
  410. begin
  411. if amBucket = amBucketName then
  412. begin
  413. Result := True;
  414. Break;
  415. end;
  416. end;
  417. end;
  418. finally
  419. amBuckets.Free;
  420. end;
  421. end;
  422. function TQuickAmazon.ListBuckets(var amResponseInfo : TAmazonResponseInfo) : TStrings;
  423. var
  424. AmazonS3 : TAmazonStorageService;
  425. CloudResponseInfo : TCloudResponseInfo;
  426. Buckets : TStrings;
  427. i : Integer;
  428. begin
  429. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  430. Result := TStringList.Create;
  431. try
  432. //AmazonS3.Timeout := fTimeout;
  433. CloudResponseInfo := TCloudResponseInfo.Create;
  434. Buckets := AmazonS3.ListBuckets(CloudResponseInfo);
  435. try
  436. for i := 0 to Buckets.Count -1 do
  437. begin
  438. Result.Add(Buckets.Names[i]);
  439. end;
  440. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  441. finally
  442. Buckets.Free;
  443. end;
  444. finally
  445. AmazonS3.Free;
  446. CloudResponseInfo.Free;
  447. end;
  448. end;
  449. function TQuickAmazon.CreateBucket(amBucket : string; amBucketRegion : TAmazonRegion; amACLType : TAmazonACLAccess; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  450. var
  451. AmazonS3 : TAmazonStorageService;
  452. CloudResponseInfo : TCloudResponseInfo;
  453. begin
  454. Result := False;
  455. if amBucket = '' then Exit;
  456. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  457. try
  458. CloudResponseInfo := TCloudResponseInfo.Create;
  459. Result := AmazonS3.CreateBucket(amBucket,amACLType,amBucketRegion,CloudResponseInfo);
  460. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  461. finally
  462. AmazonS3.Free;
  463. CloudResponseInfo.Free;
  464. end;
  465. end;
  466. function TQuickAmazon.DeleteBucket(amBucket : string; amBucketRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  467. var
  468. AmazonS3 : TAmazonStorageService;
  469. CloudResponseInfo : TCloudResponseInfo;
  470. begin
  471. Result := False;
  472. if amBucket = '' then Exit;
  473. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  474. try
  475. CloudResponseInfo := TCloudResponseInfo.Create;
  476. Result := AmazonS3.DeleteBucket(amBucket,CloudResponseInfo,amBucketRegion);
  477. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  478. finally
  479. AmazonS3.Free;
  480. CloudResponseInfo.Free;
  481. end;
  482. end;
  483. end.