1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Globalization ;
4+ using System . IO ;
5+ using System . IO . Compression ;
6+ using System . Linq ;
7+ using System . Threading . Tasks ;
8+ using Deployer . Execution ;
9+
10+ namespace Deployer . Raspberry . Tasks
11+ {
12+ public class UefiDownload : IDeploymentTask
13+ {
14+ private readonly IGitHubDownloader downloader ;
15+ private readonly IFileSystemOperations operations ;
16+
17+ public UefiDownload ( IGitHubDownloader downloader , IFileSystemOperations operations )
18+ {
19+ this . downloader = downloader ;
20+ this . operations = operations ;
21+ }
22+
23+ public async Task Execute ( )
24+ {
25+ using ( var stream = await downloader . OpenZipStream ( "https://github.com/andreiw/RaspberryPiPkg" ) )
26+ {
27+ var zipArchive = new ZipArchive ( stream , ZipArchiveMode . Read ) ;
28+
29+ var mostRecentFolderEntry = GetMostRecentDirEntry ( zipArchive ) ;
30+
31+ var contents = zipArchive . Entries . Where ( x => x . FullName . StartsWith ( mostRecentFolderEntry . FullName ) && ! x . FullName . EndsWith ( "/" ) ) ;
32+ await ExtractContents ( @"Downloaded\UEFI" , mostRecentFolderEntry , contents ) ;
33+ }
34+ }
35+
36+ private async Task ExtractContents ( string destination , ZipArchiveEntry baseEntry ,
37+ IEnumerable < ZipArchiveEntry > entries )
38+ {
39+ foreach ( var entry in entries )
40+ {
41+ var filePath = entry . FullName . Substring ( baseEntry . FullName . Length ) ;
42+
43+ var destFile = Path . Combine ( destination , filePath . Replace ( "/" , "\\ " ) ) ;
44+ var dir = Path . GetDirectoryName ( destFile ) ;
45+ if ( ! operations . DirectoryExists ( dir ) )
46+ {
47+ operations . CreateDirectory ( dir ) ;
48+ }
49+
50+ using ( var destStream = File . Open ( destFile , FileMode . OpenOrCreate ) )
51+ using ( var stream = entry . Open ( ) )
52+ {
53+ await stream . CopyToAsync ( destStream ) ;
54+ }
55+ }
56+ }
57+
58+ private ZipArchiveEntry GetMostRecentDirEntry ( ZipArchive p )
59+ {
60+ var dirs = from e in p . Entries
61+ where e . FullName . EndsWith ( "/" )
62+ select e ;
63+
64+ var splitted = from e in dirs
65+ select new
66+ {
67+ e ,
68+ Parts = e . FullName . Split ( '/' ) ,
69+ } ;
70+
71+ var parsed = from r in splitted
72+ select new
73+ {
74+ r . e ,
75+ Date = FirstParseableOrNull ( r . Parts ) ,
76+ } ;
77+
78+ return parsed . OrderByDescending ( x => x . Date ) . First ( ) . e ;
79+ }
80+
81+ private DateTime ? FirstParseableOrNull ( string [ ] parts )
82+ {
83+ foreach ( var part in parts )
84+ {
85+ var candidate = part . Split ( '-' ) ;
86+ if ( candidate . Length > 1 )
87+ {
88+ var datePart = candidate [ 0 ] ;
89+ if ( DateTime . TryParseExact ( datePart , "yyyyMMMdd" , CultureInfo . InvariantCulture , DateTimeStyles . None , out var date ) )
90+ {
91+ return date ;
92+ }
93+ }
94+ }
95+
96+ return null ;
97+ }
98+ }
99+ }
0 commit comments