From 12e0b3ac62081a8934d3689605c7daa76b9e6c3f Mon Sep 17 00:00:00 2001 From: Rikki Tooley Date: Sat, 8 Nov 2014 15:34:46 +0000 Subject: [PATCH] Fixing progress report --- IF.Lastfm.sln.DotSettings | 3 +- PROGRESS.md | 6 +- src/IF.Lastfm.Syro/App.xaml | 4 +- src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj | 4 +- src/IF.Lastfm.Syro/MainWindow.xaml | 2 +- src/IF.Lastfm.Syro/Pages/MainPage.xaml | 31 +- src/IF.Lastfm.Syro/Properties/Annotations.cs | 614 ++++++++++++++++++ .../Resources/BoolFlipConverter.cs | 19 + .../Resources/SyroTabControl.xaml | 16 +- src/IF.Lastfm.Syro/Tools/Program.cs | 38 +- .../ViewModels/MainViewModel.cs | 87 ++- .../ViewModels/ViewModelBase.cs | 18 + 12 files changed, 797 insertions(+), 45 deletions(-) create mode 100644 src/IF.Lastfm.Syro/Properties/Annotations.cs create mode 100644 src/IF.Lastfm.Syro/Resources/BoolFlipConverter.cs create mode 100644 src/IF.Lastfm.Syro/ViewModels/ViewModelBase.cs diff --git a/IF.Lastfm.sln.DotSettings b/IF.Lastfm.sln.DotSettings index b43311d..deab0aa 100644 --- a/IF.Lastfm.sln.DotSettings +++ b/IF.Lastfm.sln.DotSettings @@ -1,2 +1,3 @@  - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/PROGRESS.md b/PROGRESS.md index ed3cedb..e071758 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,4 +1,4 @@ -# Api Progress ![Progress](http://progressed.io/bar/20) +# Api Progress ![Progress](http://progressed.io/bar/21) These are all the Last.fm API methods currently available. @@ -6,7 +6,7 @@ These are all the Last.fm API methods currently available. - Methods ~~marked with strikethrough~~ aren't currently implemented. Pull requests are welcome! - Methods _marked with an asterisk *_ aren't listed on [the Last.fm documentation](http://www.last.fm/api), so they might not work! -This list is generated by the [ProgressReport](https://github.com/inflatablefriends/lastfm/tree/master/src/IF.Lastfm.ProgressReport) tool in the solution. Last updated on 26 October 2014 14:45 +This list is generated by the [ProgressReport](https://github.com/inflatablefriends/lastfm/tree/master/src/IF.Lastfm.ProgressReport) tool in the solution. Last updated on 08 November 2014 15:33 ## Album - [album.getInfo](http://www.last.fm/api/show/album.getInfo) @@ -158,6 +158,7 @@ This list is generated by the [ProgressReport](https://github.com/inflatablefrie - [user.getInfo](http://www.last.fm/api/show/user.getInfo) - [user.getRecentStations](http://www.last.fm/api/show/user.getRecentStations) - [user.getRecentTracks](http://www.last.fm/api/show/user.getRecentTracks) +- [user.getRecommendedArtists](http://www.last.fm/api/show/user.getRecommendedArtists) - [user.getShouts](http://www.last.fm/api/show/user.getShouts) - [user.getTopAlbums](http://www.last.fm/api/show/user.getTopAlbums) - [user.shout](http://www.last.fm/api/show/user.shout) @@ -171,7 +172,6 @@ This list is generated by the [ProgressReport](https://github.com/inflatablefrie - ~~[user.getPastEvents](http://www.last.fm/api/show/user.getPastEvents)~~ - ~~[user.getPersonalTags](http://www.last.fm/api/show/user.getPersonalTags)~~ - ~~[user.getPlaylists](http://www.last.fm/api/show/user.getPlaylists)~~ -- ~~[user.getRecommendedArtists](http://www.last.fm/api/show/user.getRecommendedArtists)~~ - ~~[user.getRecommendedEvents](http://www.last.fm/api/show/user.getRecommendedEvents)~~ - ~~[user.getTopArtists](http://www.last.fm/api/show/user.getTopArtists)~~ - ~~[user.getTopTags](http://www.last.fm/api/show/user.getTopTags)~~ diff --git a/src/IF.Lastfm.Syro/App.xaml b/src/IF.Lastfm.Syro/App.xaml index 5400c1d..fd74ece 100644 --- a/src/IF.Lastfm.Syro/App.xaml +++ b/src/IF.Lastfm.Syro/App.xaml @@ -1,7 +1,8 @@ + xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:resources="clr-namespace:IF.Lastfm.Syro.Resources"> @@ -37,6 +38,7 @@ + diff --git a/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj b/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj index 7ad0c25..fdafdb4 100644 --- a/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj +++ b/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj @@ -88,8 +88,11 @@ + + + MSBuild:Compile @@ -174,7 +177,6 @@ - #C0D73B - - + + - - + + @@ -27,7 +27,7 @@ + Value="#cccccc" /> @@ -147,11 +147,15 @@ Value="true"> + + @@ -167,7 +171,7 @@ - > GetApiMethods() return null; } - var html = response.Result.Content.ReadAsStringAsync(); - html.Wait(); + var htmlTask = response.Result.Content.ReadAsStringAsync(); + htmlTask.Wait(); var doc = new HtmlDocument(); - doc.LoadHtml(html.Result); + doc.LoadHtml(htmlTask.Result); - var wspanel = doc.DocumentNode.Descendants("//ul[@class='wspanel']").LastOrDefault(); + var wspanel = doc.DocumentNode.Descendants().FirstOrDefault(d => d.GetAttributeValue("class", "").Contains("wspanel") + && d.PreviousSibling.PreviousSibling.OuterHtml == "

API Methods

"); if (wspanel == null) { - Console.WriteLine("Couldn't parse HTML"); - Console.ReadLine(); - return null; + throw new FormatException(string.Format("Couldn't find wspanel in HTML {0}", htmlTask.Result)); } // each package is a section of the API @@ -72,7 +71,7 @@ internal static Dictionary> GetApiMethods() var ul = package.Element("ul"); - var methodLinks = ul.Descendants("child::li"); + var methodLinks = ul.Elements("li"); var methods = methodLinks.Select(a => a.InnerText); allMethods.Add(h3.InnerText, methods); @@ -133,21 +132,20 @@ private static string GetApiMethodFromCommandType(Type type) #region Report - internal static void WriteReport(Dictionary> apiGroup, List allImplemented) + internal static void WriteReport(Dictionary> apiGroup, List allImplemented, string path) { var markdownBuilder = new StringBuilder(); - var percent = (((double)allImplemented.Count)/apiGroup.SelectMany(api => api.Value).Count()) * 100; + var percent = GetPercentage(apiGroup, allImplemented); markdownBuilder.AppendFormat(_progressReportIntro, (int)Math.Floor(percent), DateTime.UtcNow.ToString("f")); foreach (var group in apiGroup.OrderBy(kv => kv.Key)) { - var apiGroupName = @group.Key; - var implemented = - allImplemented.Where(m => m.StartsWith(apiGroupName.ToLowerInvariant(), StringComparison.Ordinal)).ToList(); + var apiGroupName = group.Key; + var implemented = allImplemented.Where(m => m.StartsWith(apiGroupName.ToLowerInvariant(), StringComparison.Ordinal)).ToList(); - var matches = @group.Value.Intersect(implemented).ToList(); - var notImplemented = @group.Value.Except(implemented).ToList(); - var secret = implemented.Except(@group.Value).ToList(); + var matches = group.Value.Intersect(implemented).ToList(); + var notImplemented = group.Value.Except(implemented).ToList(); + var secret = implemented.Except(group.Value).ToList(); markdownBuilder.AppendFormat("## {0}\n\n", apiGroupName); foreach (var match in matches) @@ -168,7 +166,7 @@ internal static void WriteReport(Dictionary> apiGrou var markdown = markdownBuilder.ToString(); // write to output directory - using (var fs = new FileStream("PROGRESS.md", FileMode.Create)) + using (var fs = new FileStream(path, FileMode.Create)) { using (var sw = new StreamWriter(fs)) { @@ -177,6 +175,12 @@ internal static void WriteReport(Dictionary> apiGrou } } + public static double GetPercentage(Dictionary> apiGroup, List allImplemented) + { + var percent = (((double) allImplemented.Count)/apiGroup.SelectMany(api => api.Value).Count())*100; + return percent; + } + #endregion } } diff --git a/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs b/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs index e76f511..c157450 100644 --- a/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs +++ b/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs @@ -1,4 +1,8 @@ -using IF.Common.Metro.Mvvm; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using IF.Common.Metro.Mvvm; using IF.Lastfm.Syro.Tools; using System.Linq; using System.Threading.Tasks; @@ -6,17 +10,76 @@ namespace IF.Lastfm.Syro.ViewModels { - internal class MainViewModel + internal class MainViewModel : ViewModelBase { + private string _solutionDir; + private bool _generatingProgressReport; + private List _remainingCommands; + private int _apiProgress; + + public bool GeneratingProgressReport + { + get { return _generatingProgressReport; } + set + { + if (value.Equals(_generatingProgressReport)) return; + _generatingProgressReport = value; + OnPropertyChanged(); + } + } + + public string SolutionDir + { + get { return _solutionDir; } + set + { + if (value == _solutionDir) return; + _solutionDir = value; + OnPropertyChanged(); + } + } + + public int ApiProgress + { + get { return _apiProgress; } + set + { + if (value.Equals(_apiProgress)) return; + _apiProgress = value; + OnPropertyChanged(); + } + } + + public List RemainingCommands + { + get { return _remainingCommands; } + set + { + if (Equals(value, _remainingCommands)) return; + _remainingCommands = value; + OnPropertyChanged(); + } + } + public ICommand GenerateProgressReportCommand { get; private set; } public MainViewModel() { GenerateProgressReportCommand = new AsyncDelegateCommand(GenerateProgressReport); + + var currentDir = System.AppDomain.CurrentDomain.BaseDirectory; + SolutionDir = Path.GetFullPath(currentDir + "../../../../"); // assuming this is running in debug dir } private async Task GenerateProgressReport() { + if (GeneratingProgressReport) + { + return; + } + + GeneratingProgressReport = true; + await Task.Run(() => { // scrape Last.fm API documentation @@ -30,11 +93,25 @@ await Task.Run(() => var allImplemented = ProgressReport.GetImplementedCommands().ToList(); // generate the markdown - ProgressReport.WriteReport(apiGroup, allImplemented); + var path = Path.GetFullPath(SolutionDir + "PROGRESS.md"); + ProgressReport.WriteReport(apiGroup, allImplemented, path); - // file is copied to the solution root by a post-build script. - // TODO configure build dir in syro + // ui, duplicating code but w/e + ApiProgress = (int)ProgressReport.GetPercentage(apiGroup, allImplemented); + + var notimp = new List(); + foreach (var group in apiGroup) + { + var implemented = allImplemented.Where(m => m.StartsWith(group.Key.ToLowerInvariant(), StringComparison.Ordinal)).ToList(); + var notImplemented = group.Value.Except(implemented).ToList(); + + notimp.AddRange(notImplemented); + } + + RemainingCommands = notimp; }); + + GeneratingProgressReport = false; } } } diff --git a/src/IF.Lastfm.Syro/ViewModels/ViewModelBase.cs b/src/IF.Lastfm.Syro/ViewModels/ViewModelBase.cs new file mode 100644 index 0000000..7e26d02 --- /dev/null +++ b/src/IF.Lastfm.Syro/ViewModels/ViewModelBase.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; +using IF.Lastfm.Syro.Annotations; + +namespace IF.Lastfm.Syro.ViewModels +{ + internal class ViewModelBase : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); + } + } +} \ No newline at end of file