source: trunk/SpotPrice.pas

Last change on this file was 10, checked in by chronos, 2 weeks ago
  • Added: Show spot total price above zero for EANs.
File size: 5.6 KB
Line 
1unit SpotPrice;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, Generics.Defaults, XML,
7 fphttpclient, opensslsockets, DOM, Common, DateUtils, CsvDocument;
8
9type
10 { TSpotPrice }
11
12 TSpotPrice = record
13 Time: TDateTime;
14 Value: Currency;
15 class function Create(Time: TDateTime; Value: Currency): TSpotPrice; static;
16 procedure LoadFromXmlNode(Node: TDOMNode);
17 procedure SaveToXmlNode(Node: TDOMNode);
18 end;
19
20 { TSpotPrices }
21
22 TSpotPrices = class(TList<TSpotPrice>)
23 private
24 function FileNameFilter(FileName: string): Boolean;
25 function Comparer(constref Left, Right: TSpotPrice): Integer;
26 procedure LoadSpotReport(FileName: string);
27 public
28 procedure ClearInterval(IntervalFrom, IntervalTo: TDateTime);
29 function GetBlock(var Text: string; StartText, EndText: string): string;
30 procedure LoadFromWebDate(Date: TDate);
31 procedure LoadFromWeb;
32 procedure Import(Directory: string);
33 procedure LoadFromXmlNode(Node: TDOMNode);
34 procedure SaveToXmlNode(Node: TDOMNode);
35 function SearchByTime(Time: TDateTime): Integer;
36 end;
37
38const
39 SpotPriceName = 'SpotPrice';
40 SpotPricesName = 'SpotPrices';
41 DPH = 1.21;
42
43
44implementation
45
46{ TSpotPrice }
47
48class function TSpotPrice.Create(Time: TDateTime; Value: Currency): TSpotPrice;
49begin
50 Result.Time := Time;
51 Result.Value := Value;
52end;
53
54procedure TSpotPrice.LoadFromXmlNode(Node: TDOMNode);
55begin
56 Time := ReadDateTime(Node, 'Time', Time);
57 Value := ReadDouble(Node, 'Value', Value);
58end;
59
60procedure TSpotPrice.SaveToXmlNode(Node: TDOMNode);
61begin
62 WriteDateTime(Node, 'Time', Time);
63 WriteDouble(Node, 'Value', Value);
64end;
65
66procedure TSpotPrices.LoadFromWebDate(Date: TDate);
67var
68 URL: string;
69 S: string;
70 RowText: string;
71 TableText: string;
72 TimeText: string;
73 ValueText: string;
74 Time: TDateTime;
75 Value: Double;
76begin
77 ClearInterval(Date, Date + 1);
78
79 URL := 'https://spotovaelektrina.cz/denni-ceny/' + DateToStr(Date, XmlFormatSettings);
80 with TFPHttpClient.Create(nil) do
81 try
82 S := Get(URL);
83 TableText := GetBlock(S, '<table class="table" id="prices">', '</table>');
84 repeat
85 RowText := GetBlock(TableText, '<tr>', '</tr>');
86 if RowText <> '' then begin
87
88 TimeText := GetBlock(RowText, '<td>', '</td>');
89 if TimeText <> '' then Time := Date + StrToTime(TimeText);
90
91 ValueText := GetBlock(RowText, '<td>', '</td>').Trim;
92 if ValueText <> '' then begin
93 ValueText := StringReplace(ValueText, 'Kč', '', [rfReplaceAll]).Trim;
94 ValueText := StringReplace(ValueText, Chr($c2) + Chr($a0), '', [rfReplaceAll]);
95 Value := StrToInt(ValueText) / 1000 * DPH;
96 end;
97
98 if ValueText <> '' then
99 Add(TSpotPrice.Create(Time, Value));
100 end else Break;
101 until False;
102 finally
103 Free;
104 end;
105end;
106
107procedure TSpotPrices.LoadFromWeb;
108var
109 I: Integer;
110begin
111 for I := 1 to 15 do
112 LoadFromWebDate(StrToDate(IntToStr(I) + '.4.2026'));
113
114 Sort(TComparer<TSpotPrice>.Construct(Comparer));
115end;
116
117function TSpotPrices.FileNameFilter(FileName: string): Boolean;
118begin
119 Result := ExtractFileExt(FileName) = '.csv';
120end;
121
122function TSpotPrices.Comparer(constref Left, Right: TSpotPrice): Integer;
123begin
124 Result := CompareDateTime(Left.Time, Right.Time);
125end;
126
127procedure TSpotPrices.LoadSpotReport(FileName: string);
128var
129 CSVDoc: TCSVDocument;
130 R: Integer;
131 Date, Time: TDateTime;
132 Value: Currency;
133begin
134 CSVDoc := TCSVDocument.Create;
135 try
136 CSVDoc.LoadFromFile(FileName);
137
138 for R := 1 to CSVDoc.RowCount - 1 do begin
139 Date := StrToDate(CSVDoc.Cells[0, R]);
140 Time := Date + StrToTime(Copy(CSVDoc.Cells[1, R], 1, Pos(' ', CSVDoc.Cells[1, R]) - 1));
141 Value := StrToCurr(CSVDoc.Cells[3, R]) / 1000;
142 Add(TSpotPrice.Create(Time, Value));
143 end;
144 finally
145 CSVDoc.Free;
146 end;
147end;
148
149procedure TSpotPrices.ClearInterval(IntervalFrom, IntervalTo: TDateTime);
150var
151 I: Integer;
152begin
153 for I := Count - 1 downto 0 do
154 if (Items[I].Time >= IntervalFrom) and (Items[I].Time < IntervalTo) then
155 Delete(I);
156end;
157
158procedure TSpotPrices.Import(Directory: string);
159var
160 Reports: TStringList;
161 I: Integer;
162begin
163 Clear;
164
165 Reports := TStringList.Create;
166 try
167 SearchFiles(Reports, Directory, FileNameFilter);
168 for I := 0 to Reports.Count - 1 do
169 LoadSpotReport(Reports[I]);
170 finally
171 Reports.Free;
172 end;
173
174 Sort(TComparer<TSpotPrice>.Construct(Comparer));
175end;
176
177procedure TSpotPrices.LoadFromXmlNode(Node: TDOMNode);
178var
179 Node2: TDOMNode;
180 SpotPrice: TSpotPrice;
181begin
182 Node2 := Node.FirstChild;
183 while Assigned(Node2) and (Node2.NodeName = SpotPriceName) do begin
184 SpotPrice.LoadFromXmlNode(Node2);
185 Add(SpotPrice);
186 Node2 := Node2.NextSibling;
187 end;
188end;
189
190procedure TSpotPrices.SaveToXmlNode(Node: TDOMNode);
191var
192 Node2: TDOMNode;
193 I: Integer;
194begin
195 for I := 0 to Count - 1 do begin
196 Node2 := Node.OwnerDocument.CreateElement(SpotPriceName);
197 Items[I].SaveToXmlNode(Node2);
198 Node.AppendChild(Node2);
199 end;
200end;
201
202function TSpotPrices.SearchByTime(Time: TDateTime): Integer;
203var
204 I: Integer;
205begin
206 I := 0;
207 while (I < Count) and (Items[I].Time <> Time) do Inc(I);
208 if I < Count then Result := I
209 else Result := -1;
210end;
211
212function TSpotPrices.GetBlock(var Text: string; StartText, EndText: string
213 ): string;
214var
215 Index: Integer;
216begin
217 Result := '';
218 Index := Pos(StartText, Text);
219 if Index > 0 then begin
220 Text := Copy(Text, Index + Length(StartText), MaxInt);
221 Index := Pos(EndText, Text);
222 if Index > 0 then begin
223 Result := Copy(Text, 1, Index - 1);
224 Text := Copy(Text, Index + Length(EndText), MaxInt);
225 end;
226 end;
227end;
228
229end.
230
Note: See TracBrowser for help on using the repository browser.