Skip to content

Commit

Permalink
Add cache folder (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
josesimoes authored Dec 3, 2020
1 parent 72f7edf commit ac13292
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 76 deletions.
275 changes: 200 additions & 75 deletions nanoFirmwareFlasher/FirmwarePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;

namespace nanoFramework.Tools.FirmwareFlasher
{
Expand Down Expand Up @@ -64,132 +66,243 @@ protected FirmwarePackage(string targetName, string fwVersion, bool stable)
/// <returns>a dictionary which keys are the start addresses and the values are the complete filenames (the bin files)</returns>
protected async System.Threading.Tasks.Task<ExitCodes> DownloadAndExtractAsync()
{
string fwFileName = null;

// reference targets
var repoName = _stable ? _refTargetsStableRepo : _refTargetsDevRepo;
string requestUri = $"{_bintrayApiPackages}/{repoName}/{_targetName}";

if (Verbosity >= VerbosityLevel.Normal)
// flag to signal if the work-flow step was successful
bool stepSuccesful = false;

// flag to skip download if the fw package exists and it's recent
bool skipDownload = false;

// setup download folder
// set download path
LocationPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".nanoFramework");

try
{
Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
// create home directory
Directory.CreateDirectory(LocationPath);

// add readme file
File.WriteAllText(
Path.Combine(
LocationPath,
"README.txt"),
_readmeContent);

// set location path to target folder
LocationPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".nanoFramework",
_targetName);
}
catch
{
Console.WriteLine("");

HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);
return ExitCodes.E9006;
}

if (response.StatusCode == HttpStatusCode.NotFound)
var fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();

if (fwFiles.Any())
{
if (Verbosity >= VerbosityLevel.Normal)
// get file creation date (from the 1st one)
if ((DateTime.UtcNow - File.GetLastWriteTimeUtc(fwFiles.First())).TotalHours < 4)
{
Console.WriteLine("");
Console.Write($"Trying to find {_targetName} in community targets repository...");
// fw package has less than 4 hours
// skip download
skipDownload = true;
}
}

if (!skipDownload)
{
// try to perform request
try
{
if (Verbosity >= VerbosityLevel.Normal)
{
Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
}

// try with community targets
requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
repoName = _communityTargetsepo;
HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);

response = await _bintrayClient.GetAsync(requestUri);
if (response.StatusCode == HttpStatusCode.NotFound)
{
if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine("");
Console.Write($"Trying to find {_targetName} in community targets repository...");
}

// try with community targets
requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
repoName = _communityTargetsepo;

response = await _bintrayClient.GetAsync(requestUri);

if (response.StatusCode == HttpStatusCode.NotFound)
{
if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine("");
}

// can't find this target
return ExitCodes.E9005;
}
}

if (response.StatusCode == HttpStatusCode.NotFound)
{
if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine("");
Console.WriteLine($"OK");
}

// can't find this target
return ExitCodes.E9005;
}
}
// read and parse response
string responseBody = await response.Content.ReadAsStringAsync();
BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject<BintrayPackageInfo>(responseBody);

if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine($"OK");
// if no specific version was requested, use latest available
if (string.IsNullOrEmpty(_fwVersion))
{
_fwVersion = packageInfo.LatestVersion;
}

Console.Write($"Downloading firmware package...");
// set exposed property
Version = _fwVersion;

stepSuccesful = true;
}
catch
{
// exception with download, assuming it's something with network connection or Bintray API
}
}

// read and parse response
string responseBody = await response.Content.ReadAsStringAsync();
BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject<BintrayPackageInfo>(responseBody);
// cleanup any fw file in the folder
var filesToDelete = Directory.EnumerateFiles(LocationPath, "*.bin").ToList();
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.hex").ToList());
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.s19").ToList());
filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.dfu").ToList());

// if no specific version was requested, use latest available
if (string.IsNullOrEmpty(_fwVersion))
foreach (var file in filesToDelete)
{
_fwVersion = packageInfo.LatestVersion;
File.Delete(file);
}

// set exposed property
Version = _fwVersion;

// setup download folder
try
// check for file existence or download one
if (stepSuccesful &&
!skipDownload)
{
// set download path
LocationPath = Path.Combine(
Path.GetTempPath(),
Guid.NewGuid().ToString());
// reset flag
stepSuccesful = false;

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

if (Verbosity >= VerbosityLevel.Normal)
// check if we already have the file
if (!File.Exists(
Path.Combine(
LocationPath,
fwFileName)))
{
Console.WriteLine("OK");
if (Verbosity >= VerbosityLevel.Normal)
{
Console.Write($"Downloading firmware package...");
}

try
{
// setup and perform download request
requestUri = $"https://dl.bintray.com/nfbot/{repoName}/{fwFileName}";

using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
{
if (fwFileResponse.IsSuccessStatusCode)
{
using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
{
using (var fileStream = new FileStream(
Path.Combine(LocationPath, fwFileName),
FileMode.Create, FileAccess.Write))
{
await readStream.CopyToAsync(fileStream);
}
}
}
else
{
return ExitCodes.E9007;
}
}

if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine("OK");
}

stepSuccesful = true;
}
catch
{
// exception with download, assuming it's something with network connection or Bintray API
}
}
else
{
Console.WriteLine("");
// file already exists
stepSuccesful = true;
}

if (Verbosity >= VerbosityLevel.Detailed)
{
Console.WriteLine($"Download location is {LocationPath}");
}

// add readme file
File.WriteAllText(
Path.Combine(
LocationPath,
"README.txt"),
_readmeContent);
}
catch

if (!stepSuccesful)
{
Console.WriteLine("");
// couldn't download the fw file
// check if there is one available
fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();

return ExitCodes.E9006;
}
if (fwFiles.Any())
{
// take the 1st one
fwFileName = fwFiles.First();

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

using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
{
if (fwFileResponse.IsSuccessStatusCode)
{
using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
// set property
Version = match[0].Value;

if (Verbosity >= VerbosityLevel.Normal)
{
using (var fileStream = new FileStream(
Path.Combine(LocationPath, fwFileName),
FileMode.Create, FileAccess.Write))
{
await readStream.CopyToAsync(fileStream);
}
Console.WriteLine("Using cached firmware package");
}
}
else
{
// no fw file available

if (Verbosity >= VerbosityLevel.Normal)
{
Console.WriteLine("Failure to download package and couldn't find one in the cache.");
}

return ExitCodes.E9007;
}
}

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

// unzip the firmware
if (Verbosity >= VerbosityLevel.Detailed)
{
Console.Write($"Extracting {fwFileName}...");
Console.Write($"Extracting {Path.GetFileName(fwFileName)}...");
}

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

if (Verbosity >= VerbosityLevel.Detailed)
{
Console.WriteLine("");
Console.WriteLine("OK");
}

// be nice to the user and delete any fw packages other than the last one
var allFwFiles = Directory.EnumerateFiles(LocationPath, "*.zip").OrderByDescending(f => f).ToList();
if (allFwFiles.Count > 1)
{
foreach (var file in allFwFiles.Skip(1))
{
File.Delete(file);
}
}

Console.WriteLine($"Updating to {Version}");

return ExitCodes.OK;
}

Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "1.16.0-preview.{height}",
"version": "1.16.1-preview.{height}",
"assemblyVersion": {
"precision": "revision"
},
Expand Down

0 comments on commit ac13292

Please sign in to comment.