Skip to content

Commit ac13292

Browse files
authored
Add cache folder (#43)
1 parent 72f7edf commit ac13292

File tree

2 files changed

+201
-76
lines changed

2 files changed

+201
-76
lines changed

nanoFirmwareFlasher/FirmwarePackage.cs

Lines changed: 200 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
using System;
88
using System.IO;
99
using System.IO.Compression;
10+
using System.Linq;
1011
using System.Net;
1112
using System.Net.Http;
13+
using System.Text.RegularExpressions;
1214

1315
namespace nanoFramework.Tools.FirmwareFlasher
1416
{
@@ -64,132 +66,243 @@ protected FirmwarePackage(string targetName, string fwVersion, bool stable)
6466
/// <returns>a dictionary which keys are the start addresses and the values are the complete filenames (the bin files)</returns>
6567
protected async System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
6668
{
69+
string fwFileName = null;
70+
6771
// reference targets
6872
var repoName = _stable ? _refTargetsStableRepo : _refTargetsDevRepo;
6973
string requestUri = $"{_bintrayApiPackages}/{repoName}/{_targetName}";
7074

71-
if (Verbosity >= VerbosityLevel.Normal)
75+
// flag to signal if the work-flow step was successful
76+
bool stepSuccesful = false;
77+
78+
// flag to skip download if the fw package exists and it's recent
79+
bool skipDownload = false;
80+
81+
// setup download folder
82+
// set download path
83+
LocationPath = Path.Combine(
84+
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
85+
".nanoFramework");
86+
87+
try
7288
{
73-
Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
89+
// create home directory
90+
Directory.CreateDirectory(LocationPath);
91+
92+
// add readme file
93+
File.WriteAllText(
94+
Path.Combine(
95+
LocationPath,
96+
"README.txt"),
97+
_readmeContent);
98+
99+
// set location path to target folder
100+
LocationPath = Path.Combine(
101+
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
102+
".nanoFramework",
103+
_targetName);
74104
}
105+
catch
106+
{
107+
Console.WriteLine("");
75108

76-
HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);
109+
return ExitCodes.E9006;
110+
}
77111

78-
if (response.StatusCode == HttpStatusCode.NotFound)
112+
var fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();
113+
114+
if (fwFiles.Any())
79115
{
80-
if (Verbosity >= VerbosityLevel.Normal)
116+
// get file creation date (from the 1st one)
117+
if ((DateTime.UtcNow - File.GetLastWriteTimeUtc(fwFiles.First())).TotalHours < 4)
81118
{
82-
Console.WriteLine("");
83-
Console.Write($"Trying to find {_targetName} in community targets repository...");
119+
// fw package has less than 4 hours
120+
// skip download
121+
skipDownload = true;
84122
}
123+
}
124+
125+
if (!skipDownload)
126+
{
127+
// try to perform request
128+
try
129+
{
130+
if (Verbosity >= VerbosityLevel.Normal)
131+
{
132+
Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
133+
}
85134

86-
// try with community targets
87-
requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
88-
repoName = _communityTargetsepo;
135+
HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);
89136

90-
response = await _bintrayClient.GetAsync(requestUri);
137+
if (response.StatusCode == HttpStatusCode.NotFound)
138+
{
139+
if (Verbosity >= VerbosityLevel.Normal)
140+
{
141+
Console.WriteLine("");
142+
Console.Write($"Trying to find {_targetName} in community targets repository...");
143+
}
144+
145+
// try with community targets
146+
requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
147+
repoName = _communityTargetsepo;
148+
149+
response = await _bintrayClient.GetAsync(requestUri);
150+
151+
if (response.StatusCode == HttpStatusCode.NotFound)
152+
{
153+
if (Verbosity >= VerbosityLevel.Normal)
154+
{
155+
Console.WriteLine("");
156+
}
157+
158+
// can't find this target
159+
return ExitCodes.E9005;
160+
}
161+
}
91162

92-
if (response.StatusCode == HttpStatusCode.NotFound)
93-
{
94163
if (Verbosity >= VerbosityLevel.Normal)
95164
{
96-
Console.WriteLine("");
165+
Console.WriteLine($"OK");
97166
}
98167

99-
// can't find this target
100-
return ExitCodes.E9005;
101-
}
102-
}
168+
// read and parse response
169+
string responseBody = await response.Content.ReadAsStringAsync();
170+
BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject<BintrayPackageInfo>(responseBody);
103171

104-
if (Verbosity >= VerbosityLevel.Normal)
105-
{
106-
Console.WriteLine($"OK");
172+
// if no specific version was requested, use latest available
173+
if (string.IsNullOrEmpty(_fwVersion))
174+
{
175+
_fwVersion = packageInfo.LatestVersion;
176+
}
107177

108-
Console.Write($"Downloading firmware package...");
178+
// set exposed property
179+
Version = _fwVersion;
180+
181+
stepSuccesful = true;
182+
}
183+
catch
184+
{
185+
// exception with download, assuming it's something with network connection or Bintray API
186+
}
109187
}
110188

111-
// read and parse response
112-
string responseBody = await response.Content.ReadAsStringAsync();
113-
BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject<BintrayPackageInfo>(responseBody);
189+
// cleanup any fw file in the folder
190+
var filesToDelete = Directory.EnumerateFiles(LocationPath, "*.bin").ToList();
191+
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.hex").ToList());
192+
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.s19").ToList());
193+
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.dfu").ToList());
114194

115-
// if no specific version was requested, use latest available
116-
if (string.IsNullOrEmpty(_fwVersion))
195+
foreach (var file in filesToDelete)
117196
{
118-
_fwVersion = packageInfo.LatestVersion;
197+
File.Delete(file);
119198
}
120199

121-
// set exposed property
122-
Version = _fwVersion;
123-
124-
// setup download folder
125-
try
200+
// check for file existence or download one
201+
if (stepSuccesful &&
202+
!skipDownload)
126203
{
127-
// set download path
128-
LocationPath = Path.Combine(
129-
Path.GetTempPath(),
130-
Guid.NewGuid().ToString());
204+
// reset flag
205+
stepSuccesful = false;
131206

132-
// create directory
133-
Directory.CreateDirectory(LocationPath);
207+
fwFileName = $"{_targetName}-{_fwVersion}.zip";
134208

135-
if (Verbosity >= VerbosityLevel.Normal)
209+
// check if we already have the file
210+
if (!File.Exists(
211+
Path.Combine(
212+
LocationPath,
213+
fwFileName)))
136214
{
137-
Console.WriteLine("OK");
215+
if (Verbosity >= VerbosityLevel.Normal)
216+
{
217+
Console.Write($"Downloading firmware package...");
218+
}
219+
220+
try
221+
{
222+
// setup and perform download request
223+
requestUri = $"https://dl.bintray.com/nfbot/{repoName}/{fwFileName}";
224+
225+
using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
226+
{
227+
if (fwFileResponse.IsSuccessStatusCode)
228+
{
229+
using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
230+
{
231+
using (var fileStream = new FileStream(
232+
Path.Combine(LocationPath, fwFileName),
233+
FileMode.Create, FileAccess.Write))
234+
{
235+
await readStream.CopyToAsync(fileStream);
236+
}
237+
}
238+
}
239+
else
240+
{
241+
return ExitCodes.E9007;
242+
}
243+
}
244+
245+
if (Verbosity >= VerbosityLevel.Normal)
246+
{
247+
Console.WriteLine("OK");
248+
}
249+
250+
stepSuccesful = true;
251+
}
252+
catch
253+
{
254+
// exception with download, assuming it's something with network connection or Bintray API
255+
}
138256
}
139257
else
140258
{
141-
Console.WriteLine("");
259+
// file already exists
260+
stepSuccesful = true;
142261
}
143-
144-
if (Verbosity >= VerbosityLevel.Detailed)
145-
{
146-
Console.WriteLine($"Download location is {LocationPath}");
147-
}
148-
149-
// add readme file
150-
File.WriteAllText(
151-
Path.Combine(
152-
LocationPath,
153-
"README.txt"),
154-
_readmeContent);
155262
}
156-
catch
263+
264+
if (!stepSuccesful)
157265
{
158-
Console.WriteLine("");
266+
// couldn't download the fw file
267+
// check if there is one available
268+
fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();
159269

160-
return ExitCodes.E9006;
161-
}
270+
if (fwFiles.Any())
271+
{
272+
// take the 1st one
273+
fwFileName = fwFiles.First();
162274

163-
// setup and perform download request
164-
string fwFileName = $"{_targetName}-{_fwVersion}.zip";
165-
requestUri = $"https://dl.bintray.com/nfbot/{repoName}/{fwFileName}";
275+
// get the version form the file name
276+
var pattern = @"(\d+\.\d+\.\d+)(\.\d+|-.+)(?=\.zip)";
277+
var match = Regex.Matches(fwFileName, pattern, RegexOptions.IgnoreCase);
166278

167-
using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
168-
{
169-
if (fwFileResponse.IsSuccessStatusCode)
170-
{
171-
using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
279+
// set property
280+
Version = match[0].Value;
281+
282+
if (Verbosity >= VerbosityLevel.Normal)
172283
{
173-
using (var fileStream = new FileStream(
174-
Path.Combine(LocationPath, fwFileName),
175-
FileMode.Create, FileAccess.Write))
176-
{
177-
await readStream.CopyToAsync(fileStream);
178-
}
284+
Console.WriteLine("Using cached firmware package");
179285
}
180286
}
181287
else
182288
{
289+
// no fw file available
290+
291+
if (Verbosity >= VerbosityLevel.Normal)
292+
{
293+
Console.WriteLine("Failure to download package and couldn't find one in the cache.");
294+
}
295+
183296
return ExitCodes.E9007;
184297
}
185298
}
186299

187-
Console.WriteLine($"Updating to {_fwVersion}");
300+
// got here, must have a file!
188301

189302
// unzip the firmware
190303
if (Verbosity >= VerbosityLevel.Detailed)
191304
{
192-
Console.Write($"Extracting {fwFileName}...");
305+
Console.Write($"Extracting {Path.GetFileName(fwFileName)}...");
193306
}
194307

195308
ZipFile.ExtractToDirectory(
@@ -198,9 +311,21 @@ protected async System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
198311

199312
if (Verbosity >= VerbosityLevel.Detailed)
200313
{
201-
Console.WriteLine("");
314+
Console.WriteLine("OK");
202315
}
203316

317+
// be nice to the user and delete any fw packages other than the last one
318+
var allFwFiles = Directory.EnumerateFiles(LocationPath, "*.zip").OrderByDescending(f => f).ToList();
319+
if (allFwFiles.Count > 1)
320+
{
321+
foreach (var file in allFwFiles.Skip(1))
322+
{
323+
File.Delete(file);
324+
}
325+
}
326+
327+
Console.WriteLine($"Updating to {Version}");
328+
204329
return ExitCodes.OK;
205330
}
206331

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3-
"version": "1.16.0-preview.{height}",
3+
"version": "1.16.1-preview.{height}",
44
"assemblyVersion": {
55
"precision": "revision"
66
},

0 commit comments

Comments
 (0)