-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
CloudAPI.Types.pas
221 lines (194 loc) · 6.81 KB
/
CloudAPI.Types.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
unit CloudAPI.Types;
interface
uses
System.Classes;
type
{$SCOPEDENUMS ON}
TcaFileToSendType = (Error = 254, Unknown = 0, ID = 100, URL = 101, &File = 102, Stream = 103);
TcaParameterType = (Cookie, GetOrPost, UrlSegment, HttpHeader, RequestBody, QueryString, QueryStringWithoutEncode);
TcaMethod = (GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH, MERGE, COPY);
{$SCOPEDENUMS OFF}
/// <summary>
/// Содержит информацию о файле
/// </summary>
TcaFileToSend = record
private
FUrlOrIdOrFilePath: string;
FContent: TStream;
FType: TcaFileToSendType;
FName: string;
private
function GetFileName: string;
class function TestString(const AValue: string): TcaFileToSendType; static;
class function Create(const AData: string; AContent: TStream;
const ATag: TcaFileToSendType = TcaFileToSendType.Unknown): TcaFileToSend; static;
{$REGION 'operator overload'}
public
class operator Equal(a, b: TcaFileToSend): Boolean;
class operator Implicit(const AValue: string): TcaFileToSend;
class operator Implicit(AValue: TStream): TcaFileToSend;
{$ENDREGION}
public
/// <summary>
/// Возвращает Ссылку либо ID либо Имя файла
/// </summary>
function GetUrlOrIdOrFilePath: string;
/// <summary>
/// Хранит тип файла
/// </summary>
property &Type: TcaFileToSendType read FType write FType;
/// <summary>
/// Имя файла
/// </summary>
property Name: string read FName write FName;
/// <summary>
/// Идентификатор файла
/// </summary>
property ID: string read FUrlOrIdOrFilePath write FUrlOrIdOrFilePath;
/// <summary>
/// Ссылка на файл
/// </summary>
property URL: string read FUrlOrIdOrFilePath write FUrlOrIdOrFilePath;
/// <summary>
/// Контент (TStream)
/// </summary>
property Content: TStream read FContent write FContent;
/// <summary>
/// Полный путь к файлу на диске
/// </summary>
property FilePath: string read FUrlOrIdOrFilePath write FUrlOrIdOrFilePath;
class function FromFile(const AFileName: string): TcaFileToSend; static;
class function FromID(const AID: string): TcaFileToSend; static;
class function FromURL(const AUrl: string): TcaFileToSend; static;
class function FromStream(const AContent: TStream; const AFileName: string): TcaFileToSend; static;
class function Empty: TcaFileToSend; static;
function IsEmpty: Boolean;
end;
TcaRequestLimit = record
private
FIsGlobal: Boolean;
FStartedAt: TDateTime;
FEndingAt: TDateTime;
FLimit: Int64;
FName: string;
public
class function Create(const ALimit: Int64; const AName: string; const AIsGlobal: Boolean): TcaRequestLimit; static;
property StartedAt: TDateTime read FStartedAt write FStartedAt;
property EndingAt: TDateTime read FEndingAt write FEndingAt;
property Limit: Int64 read FLimit write FLimit;
property Name: string read FName write FName;
function IsExpired: Boolean;
function ActualLimit: Int64;
property IsGlobal: Boolean read FIsGlobal write FIsGlobal;
class function DatesDuration(const AAfter, ABefore: TDateTime): UInt64; static;
end;
implementation
uses
System.DateUtils,
System.SysUtils;
{ TtgFileToSend }
class function TcaFileToSend.Create(const AData: string; AContent: TStream;
const ATag: TcaFileToSendType = TcaFileToSendType.Unknown): TcaFileToSend;
begin
Result.&Type := ATag;
Result.FUrlOrIdOrFilePath := AData;
Result.Content := AContent;
end;
class function TcaFileToSend.Empty: TcaFileToSend;
begin
Result := TcaFileToSend.Create('', nil, TcaFileToSendType.Error);
end;
class operator TcaFileToSend.Equal(a, b: TcaFileToSend): Boolean;
begin
Result := (a.FUrlOrIdOrFilePath = b.FUrlOrIdOrFilePath) and (a.&Type = b.&Type) and (a.Content = b.Content);
end;
function TcaFileToSend.GetFileName: string;
var
LBeginPos: integer;
begin
LBeginPos := FUrlOrIdOrFilePath.LastIndexOfAny(['\', '/']) + 1;
Result := FUrlOrIdOrFilePath.Substring(LBeginPos);
end;
function TcaFileToSend.GetUrlOrIdOrFilePath: string;
begin
Result := FUrlOrIdOrFilePath;
end;
class function TcaFileToSend.FromFile(const AFileName: string): TcaFileToSend;
begin
if not FileExists(AFileName) then
raise EFileNotFoundException.CreateFmt('File %S not found!', [AFileName]);
Result := TcaFileToSend.Create(AFileName, nil, TcaFileToSendType.&File);
Result.Name := Result.GetFileName;
end;
class function TcaFileToSend.FromID(const AID: string): TcaFileToSend;
begin
Result := TcaFileToSend.Create(AID, nil, TcaFileToSendType.ID);
end;
class function TcaFileToSend.FromStream(const AContent: TStream; const AFileName: string): TcaFileToSend;
begin
if AFileName.IsEmpty then
raise Exception.Create('TtgFileToSend: AFileName is empty!');
if not Assigned(AContent) then
raise EStreamError.Create('Stream not assigned!');
Result := TcaFileToSend.Create(AFileName, AContent, TcaFileToSendType.Stream);
Result.Name := Result.GetFileName;
end;
class function TcaFileToSend.FromURL(const AUrl: string): TcaFileToSend;
begin
Result := TcaFileToSend.Create(AUrl, nil, TcaFileToSendType.URL);
end;
class operator TcaFileToSend.Implicit(const AValue: string): TcaFileToSend;
begin
case TestString(AValue) of
TcaFileToSendType.ID:
Result := TcaFileToSend.FromID(AValue);
TcaFileToSendType.URL:
Result := TcaFileToSend.FromURL(AValue);
TcaFileToSendType.&File:
Result := TcaFileToSend.FromFile(AValue);
end;
end;
class operator TcaFileToSend.Implicit(AValue: TStream): TcaFileToSend;
begin
Result := TcaFileToSend.FromStream(AValue, 'file');
end;
function TcaFileToSend.IsEmpty: Boolean;
begin
Result := FUrlOrIdOrFilePath.IsEmpty and not Assigned(Content);
end;
class function TcaFileToSend.TestString(const AValue: string): TcaFileToSendType;
begin
if FileExists(AValue) then
Result := TcaFileToSendType.&File
else if AValue.contains('://') then
Result := TcaFileToSendType.URL
else
Result := TcaFileToSendType.ID;
end;
{ TcaRequestLimit }
function TcaRequestLimit.ActualLimit: Int64;
begin
Result := DatesDuration(EndingAt, Now);
end;
class function TcaRequestLimit.Create(const ALimit: Int64; const AName: string; const AIsGlobal: Boolean)
: TcaRequestLimit;
begin
Result.Limit := ALimit;
Result.Name := AName;
Result.IsGlobal := AIsGlobal;
Result.StartedAt := Now;
Result.EndingAt := IncMilliSecond(Result.StartedAt, Result.Limit);
end;
class function TcaRequestLimit.DatesDuration(const AAfter, ABefore: TDateTime): UInt64;
var
LAftMSec, LBefMSec: Int64;
begin
LAftMSec := DateTimeToMilliseconds(AAfter);
LBefMSec := DateTimeToMilliseconds(ABefore);
Result := LAftMSec - LBefMSec;
end;
function TcaRequestLimit.IsExpired: Boolean;
begin
Result := Now > EndingAt;
end;
end.