Initial commit — AllMusicGuide scraper and music metadata tagger
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A86C05AB-9720-4D6E-AC5E-9CDE6364945A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MusicMetaTagger.Client.AllMusicGuide</RootNamespace>
|
||||
<AssemblyName>MusicMetaTagger.Client.AllMusicGuide</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HtmlAgilityPack">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.4.6\lib\Net40\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Services\MusicGuideCache.cs" />
|
||||
<Compile Include="Services\Searchers\AlbumArtistSearcher.cs" />
|
||||
<Compile Include="Services\Searchers\AlbumSearcher.cs" />
|
||||
<Compile Include="Services\Searchers\SongArtistSearcher.cs" />
|
||||
<Compile Include="Services\TrackOriginalRelease.cs" />
|
||||
<Compile Include="Services\TrackRater.cs" />
|
||||
<Compile Include="Services\TrackSearcher.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\AlbumClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\AlbumResultPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\ArtistClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\ArtistDiscographyAlbumPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\ArtistDiscographyCompilationPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\ArtistDiscographyEpSinglesPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\ArtistResultPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\IXmlClientBase.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\SongClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\SongResultPageClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\WebXmlClient.cs" />
|
||||
<Compile Include="RemoteDataAccess\Client\XmlClientBase.cs" />
|
||||
<Compile Include="RemoteDataAccess\MusicGuideScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\AlbumParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\AlbumResultPageParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\AlbumResultParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ArtistDiscographyPageParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ArtistDiscographyParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ArtistParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ArtistResultPageParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ArtistResultParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\IParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\ParserBase.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\SongParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\SongResultPageParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\SongResultParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Parser\TrackParser.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\AlbumResultPageScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\AlbumScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\ArtistDiscographyScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\ArtistResultPageScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\ArtistScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\IScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\ScraperBase.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\SongResultPageScraper.cs" />
|
||||
<Compile Include="RemoteDataAccess\Scraper\SongScraper.cs" />
|
||||
<Compile Include="Properties\AlbumResultPageScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>AlbumResultPageScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AlbumResultScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>AlbumResultScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AlbumScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>AlbumScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AllMusicGuideSettings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>AllMusicGuideSettings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\ArtistDiscographyPageScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>ArtistDiscographyPageScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\ArtistDiscographyScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>ArtistDiscographyScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\ArtistResultPageScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>ArtistResultPageScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\ArtistResultScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>ArtistResultScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\ArtistScaper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>ArtistScaper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\SongAppearsOnAlbumScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>SongAppearsOnAlbumScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\SongResultPageScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>SongResultPageScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\SongResultScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>SongResultScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\SongScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>SongScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\TrackScraper.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>TrackScraper.settings</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\AlbumResultPageScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>AlbumResultPageScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\AlbumResultScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>AlbumResultScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\AlbumScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>AlbumScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\AllMusicGuideSettings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>AllMusicGuideSettings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\ArtistDiscographyPageScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ArtistDiscographyPageScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\ArtistDiscographyScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ArtistDiscographyScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\ArtistResultPageScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ArtistResultPageScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\ArtistResultScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ArtistResultScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\ArtistScaper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>ArtistScaper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\SongAppearsOnAlbumScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>SongAppearsOnAlbumScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\SongResultPageScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>SongResultPageScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\SongResultScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>SongResultScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\SongScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>SongScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Properties\TrackScraper.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>TrackScraper.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{EDA98A07-0BF5-4FEE-B341-D8A6A7E581F5}</Project>
|
||||
<Name>Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,44 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class AlbumResultPageScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static AlbumResultPageScraper defaultInstance = ((AlbumResultPageScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AlbumResultPageScraper())));
|
||||
|
||||
public static AlbumResultPageScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'right-of-image\')]")]
|
||||
public string AlbumXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/search/ajax_results/albums/{0}")]
|
||||
public string AlbumResultUrl {
|
||||
get {
|
||||
return ((string)(this["AlbumResultUrl"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="AlbumResultPageScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="AlbumXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'right-of-image')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumResultUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/search/ajax_results/albums/{0}</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,116 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class AlbumResultScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static AlbumResultScraper defaultInstance = ((AlbumResultScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AlbumResultScraper())));
|
||||
|
||||
public static AlbumResultScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a/@href")]
|
||||
public string AlbumUrlXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string AlbumUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a")]
|
||||
public string TitleXpath {
|
||||
get {
|
||||
return ((string)(this["TitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(19|20)\\d{2}")]
|
||||
public string YearRegex {
|
||||
get {
|
||||
return ((string)(this["YearRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]")]
|
||||
public string ArtistNoUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistNoUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'info\']")]
|
||||
public string InfoXpath {
|
||||
get {
|
||||
return ((string)(this["InfoXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(?<=\\n).*")]
|
||||
public string GenreRegex {
|
||||
get {
|
||||
return ((string)(this["GenreRegex"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="AlbumResultScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="AlbumUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="TitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="YearRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(19|20)\d{2}</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistNoUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="InfoXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='info']</Value>
|
||||
</Setting>
|
||||
<Setting Name="GenreRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(?<=\n).*</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,207 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class AlbumScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static AlbumScraper defaultInstance = ((AlbumScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AlbumScraper())));
|
||||
|
||||
public static AlbumScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'album-title\']/text()")]
|
||||
public string TitleXpath {
|
||||
get {
|
||||
return ((string)(this["TitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/album/{0}")]
|
||||
public string AlbumUrl {
|
||||
get {
|
||||
return ((string)(this["AlbumUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@id=\'tracks\']//tbody/tr[td[@class=\'tracknum\']]")]
|
||||
public string TrackXpath {
|
||||
get {
|
||||
return ((string)(this["TrackXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'image-container\']/img/@src")]
|
||||
public string CoverUrlXpath {
|
||||
get {
|
||||
return ((string)(this["CoverUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'editorial-rating\']//span[@itemprop=\'rating\']")]
|
||||
public string RatingXpath {
|
||||
get {
|
||||
return ((string)(this["RatingXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'release-date\']")]
|
||||
public string ReleaseDateXpath {
|
||||
get {
|
||||
return ((string)(this["ReleaseDateXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'album-artist\']/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'album-artist\']/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'themes\')]//a")]
|
||||
public string ThemesXpath {
|
||||
get {
|
||||
return ((string)(this["ThemesXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'moods\')]//a")]
|
||||
public string MoodsXpath {
|
||||
get {
|
||||
return ((string)(this["MoodsXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'review-body\']/div")]
|
||||
public string ReviewXpath {
|
||||
get {
|
||||
return ((string)(this["ReviewXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@id=\'review\']//*[@class=\'author\']")]
|
||||
public string ReviewerXpath {
|
||||
get {
|
||||
return ((string)(this["ReviewerXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(?<=by\\s*).*")]
|
||||
public string ReviewerRegex {
|
||||
get {
|
||||
return ((string)(this["ReviewerRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'id-details\']//*[contains(.,\'Rovi Music ID\')]/following-sibling::*[1]/" +
|
||||
"span")]
|
||||
public string AlbumIdXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumIdXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'styles\')]//a[contains(.,\'Soundtrack\')]")]
|
||||
public string SoundtrackXpath {
|
||||
get {
|
||||
return ((string)(this["SoundtrackXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("\\d{4}")]
|
||||
public string ReleaseYearRegex {
|
||||
get {
|
||||
return ((string)(this["ReleaseYearRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'styles\')]//a")]
|
||||
public string StylesXpath {
|
||||
get {
|
||||
return ((string)(this["StylesXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute(".*(?=\\?.*)")]
|
||||
public string CoverUrlRegex {
|
||||
get {
|
||||
return ((string)(this["CoverUrlRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'album-pick\')]")]
|
||||
public string PickXpath {
|
||||
get {
|
||||
return ((string)(this["PickXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="AlbumScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="TitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='album-title']/text()</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/album/{0}</Value>
|
||||
</Setting>
|
||||
<Setting Name="TrackXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@id='tracks']//tbody/tr[td[@class='tracknum']]</Value>
|
||||
</Setting>
|
||||
<Setting Name="CoverUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='image-container']/img/@src</Value>
|
||||
</Setting>
|
||||
<Setting Name="RatingXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='editorial-rating']//span[@itemprop='rating']</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReleaseDateXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='release-date']</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='album-artist']/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='album-artist']/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ThemesXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'themes')]//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="MoodsXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'moods')]//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReviewXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='review-body']/div</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReviewerXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@id='review']//*[@class='author']</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReviewerRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(?<=by\s*).*</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='id-details']//*[contains(.,'Rovi Music ID')]/following-sibling::*[1]/span</Value>
|
||||
</Setting>
|
||||
<Setting Name="SoundtrackXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'styles')]//a[contains(.,'Soundtrack')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReleaseYearRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">\d{4}</Value>
|
||||
</Setting>
|
||||
<Setting Name="StylesXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'styles')]//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="CoverUrlRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">.*(?=\?.*)</Value>
|
||||
</Setting>
|
||||
<Setting Name="PickXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'album-pick')]</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,50 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class AllMusicGuideSettings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static AllMusicGuideSettings defaultInstance = ((AllMusicGuideSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AllMusicGuideSettings())));
|
||||
|
||||
public static AllMusicGuideSettings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0.6")]
|
||||
public double AlbumResultsRelevanceThreshold {
|
||||
get {
|
||||
return ((double)(this["AlbumResultsRelevanceThreshold"]));
|
||||
}
|
||||
set {
|
||||
this["AlbumResultsRelevanceThreshold"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0.6")]
|
||||
public double ArtistResultsRelevanceThreshold {
|
||||
get {
|
||||
return ((double)(this["ArtistResultsRelevanceThreshold"]));
|
||||
}
|
||||
set {
|
||||
this["ArtistResultsRelevanceThreshold"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ItunesAMG.AllMusicGuide" GeneratedClassName="AllMusicGuideSettings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="AlbumResultsRelevanceThreshold" Type="System.Double" Scope="User">
|
||||
<Value Profile="(Default)">0.6</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistResultsRelevanceThreshold" Type="System.Double" Scope="User">
|
||||
<Value Profile="(Default)">0.6</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,99 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class ArtistDiscographyPageScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static ArtistDiscographyPageScraper defaultInstance = ((ArtistDiscographyPageScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ArtistDiscographyPageScraper())));
|
||||
|
||||
public static ArtistDiscographyPageScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//table[contains(@class,\'album-table\')]/tbody/tr")]
|
||||
public string DiscographyXpath {
|
||||
get {
|
||||
return ((string)(this["DiscographyXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/artist/{0}/overview/main")]
|
||||
public string DiscographyAlbumUrl {
|
||||
get {
|
||||
return ((string)(this["DiscographyAlbumUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/artist/{0}/overview/singles")]
|
||||
public string DiscographyEpSinglesUrl {
|
||||
get {
|
||||
return ((string)(this["DiscographyEpSinglesUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/artist/{0}/overview/compilations")]
|
||||
public string DiscographyCompilationUrl {
|
||||
get {
|
||||
return ((string)(this["DiscographyCompilationUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@id=\"discography\"]//ul[@class=\'sub-tabs\']/li[contains(@class,\'active\')]/@clas" +
|
||||
"s")]
|
||||
public string ReleaseTypeXpath {
|
||||
get {
|
||||
return ((string)(this["ReleaseTypeXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute(".*(?=\\sactive)")]
|
||||
public string ReleaseTypeRegex {
|
||||
get {
|
||||
return ((string)(this["ReleaseTypeRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'artist-name\']/text()")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'id-details\']//*[contains(.,\'Rovi Music ID\')]/following-sibling::*[1]")]
|
||||
public string ArtistIdXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistIdXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="ArtistDiscographyPageScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="DiscographyXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//table[contains(@class,'album-table')]/tbody/tr</Value>
|
||||
</Setting>
|
||||
<Setting Name="DiscographyAlbumUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/artist/{0}/overview/main</Value>
|
||||
</Setting>
|
||||
<Setting Name="DiscographyEpSinglesUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/artist/{0}/overview/singles</Value>
|
||||
</Setting>
|
||||
<Setting Name="DiscographyCompilationUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/artist/{0}/overview/compilations</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReleaseTypeXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@id="discography"]//ul[@class='sub-tabs']/li[contains(@class,'active')]/@class</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReleaseTypeRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">.*(?=\sactive)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='artist-name']/text()</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='id-details']//*[contains(.,'Rovi Music ID')]/following-sibling::*[1]</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,107 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class ArtistDiscographyScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static ArtistDiscographyScraper defaultInstance = ((ArtistDiscographyScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ArtistDiscographyScraper())));
|
||||
|
||||
public static ArtistDiscographyScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[contains(@class,\'title\')]/a[contains(@class,\'full-title\')]/@href")]
|
||||
public string AlbumUrlXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string AlbumUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[@class=\'ed-rating\']/@data-sort-value")]
|
||||
public string RatingXpath {
|
||||
get {
|
||||
return ((string)(this["RatingXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[contains(@class,\'year\')][contains(@class,\'pick\')]")]
|
||||
public string PickXpath {
|
||||
get {
|
||||
return ((string)(this["PickXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[contains(@class,\'year\')]")]
|
||||
public string YearXpath {
|
||||
get {
|
||||
return ((string)(this["YearXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[contains(@class,\'title\')]/a[contains(@class,\'full-title\')]")]
|
||||
public string TitleXpath {
|
||||
get {
|
||||
return ((string)(this["TitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//td[@class=\'label\']/*[@class=\'full-title\']")]
|
||||
public string LabelXpath {
|
||||
get {
|
||||
return ((string)(this["LabelXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(?<=\\s*\\[).*(?=\\]$)")]
|
||||
public string ReleaseTypeRegex {
|
||||
get {
|
||||
return ((string)(this["ReleaseTypeRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("\\d{1,2}")]
|
||||
public string RatingRegex {
|
||||
get {
|
||||
return ((string)(this["RatingRegex"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="ArtistDiscographyScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="AlbumUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[contains(@class,'title')]/a[contains(@class,'full-title')]/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="RatingXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[@class='ed-rating']/@data-sort-value</Value>
|
||||
</Setting>
|
||||
<Setting Name="PickXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[contains(@class,'year')][contains(@class,'pick')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="YearXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[contains(@class,'year')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="TitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[contains(@class,'title')]/a[contains(@class,'full-title')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="LabelXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//td[@class='label']/*[@class='full-title']</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReleaseTypeRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(?<=\s*\[).*(?=\]$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="RatingRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">\d{1,2}</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,44 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class ArtistResultPageScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static ArtistResultPageScraper defaultInstance = ((ArtistResultPageScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ArtistResultPageScraper())));
|
||||
|
||||
public static ArtistResultPageScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/search/ajax_results/artists/{0}")]
|
||||
public string ArtistResultUrl {
|
||||
get {
|
||||
return ((string)(this["ArtistResultUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'right-of-image\')]")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="ArtistResultPageScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="ArtistResultUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/search/ajax_results/artists/{0}</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'right-of-image')]</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class ArtistResultScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static ArtistResultScraper defaultInstance = ((ArtistResultScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ArtistResultScraper())));
|
||||
|
||||
public static ArtistResultScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'name\')]/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'name\')]/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'info\']")]
|
||||
public string InfoXpath {
|
||||
get {
|
||||
return ((string)(this["InfoXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute(".*(?=\\n)*")]
|
||||
public string GenreRegex {
|
||||
get {
|
||||
return ((string)(this["GenreRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(?<=\\n).*(19|20)\\d{2}.*")]
|
||||
public string YearsActiveRegex {
|
||||
get {
|
||||
return ((string)(this["YearsActiveRegex"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="ArtistResultScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'name')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'name')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="InfoXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='info']</Value>
|
||||
</Setting>
|
||||
<Setting Name="GenreRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">.*(?=\n)*</Value>
|
||||
</Setting>
|
||||
<Setting Name="YearsActiveRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(?<=\n).*(19|20)\d{2}.*</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class ArtistScaper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static ArtistScaper defaultInstance = ((ArtistScaper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ArtistScaper())));
|
||||
|
||||
public static ArtistScaper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/artist/{0}")]
|
||||
public string ArtistUrl {
|
||||
get {
|
||||
return ((string)(this["ArtistUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/artist/{0}/overview/main")]
|
||||
public string DiscographyAlbumUrl {
|
||||
get {
|
||||
return ((string)(this["DiscographyAlbumUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'id-details\']//*[contains(.,\'Rovi Music ID\')]/following-sibling::*[1]")]
|
||||
public string ArtistIdXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistIdXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'genres\']//a")]
|
||||
public string GenreXpath {
|
||||
get {
|
||||
return ((string)(this["GenreXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'styles\']//a")]
|
||||
public string StylesXpath {
|
||||
get {
|
||||
return ((string)(this["StylesXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'artist-name\']/text()")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="ArtistScaper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="ArtistUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/artist/{0}</Value>
|
||||
</Setting>
|
||||
<Setting Name="DiscographyAlbumUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/artist/{0}/overview/main</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='id-details']//*[contains(.,'Rovi Music ID')]/following-sibling::*[1]</Value>
|
||||
</Setting>
|
||||
<Setting Name="GenreXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='genres']//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="StylesXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='styles']//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='artist-name']/text()</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MusicMetaTagger.Client.AllMusicGuide")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MusicMetaTagger.Client.AllMusicGuide")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("26de737f-4e88-484b-95ab-f4edec53c9ee")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,107 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class SongAppearsOnAlbumScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static SongAppearsOnAlbumScraper defaultInstance = ((SongAppearsOnAlbumScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new SongAppearsOnAlbumScraper())));
|
||||
|
||||
public static SongAppearsOnAlbumScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a/@href")]
|
||||
public string AlbumUrlXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string AlbumUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["AlbumUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a")]
|
||||
public string TitleXpath {
|
||||
get {
|
||||
return ((string)(this["TitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(19|20)\\d{2}")]
|
||||
public string YearRegex {
|
||||
get {
|
||||
return ((string)(this["YearRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]")]
|
||||
public string ArtistNoUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistNoUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'year\']")]
|
||||
public string YearXpath {
|
||||
get {
|
||||
return ((string)(this["YearXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="SongAppearsOnAlbumScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="AlbumUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="TitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="YearRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(19|20)\d{2}</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistNoUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="YearXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='year']</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,47 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class SongResultPageScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static SongResultPageScraper defaultInstance = ((SongResultPageScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new SongResultPageScraper())));
|
||||
|
||||
public static SongResultPageScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/search/ajax_results/songs/{0}")]
|
||||
public string SongResultUrl {
|
||||
get {
|
||||
return ((string)(this["SongResultUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'right-of-image\')]")]
|
||||
public string SongXpath {
|
||||
get {
|
||||
return ((string)(this["SongXpath"]));
|
||||
}
|
||||
set {
|
||||
this["SongXpath"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="SongResultPageScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="SongResultUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/search/ajax_results/songs/{0}</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongXpath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">//*[contains(@class,'right-of-image')]</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,89 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class SongResultScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static SongResultScraper defaultInstance = ((SongResultScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new SongResultScraper())));
|
||||
|
||||
public static SongResultScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a")]
|
||||
public string SongTitleXpath {
|
||||
get {
|
||||
return ((string)(this["SongTitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string SongUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["SongUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'performer\')]/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'title\')]/a/@href")]
|
||||
public string SongUrlIdXpath {
|
||||
get {
|
||||
return ((string)(this["SongUrlIdXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'performer\')]/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("(?<=^\").*(?=\"$)")]
|
||||
public string SongTitleRegex {
|
||||
get {
|
||||
return ((string)(this["SongTitleRegex"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="SongResultScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="SongTitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'performer')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongUrlIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'title')]/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'performer')]/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongTitleRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">(?<=^").*(?="$)</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,98 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.18033
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class SongScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static SongScraper defaultInstance = ((SongScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new SongScraper())));
|
||||
|
||||
public static SongScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'song-title\']")]
|
||||
public string SongTitleXpath {
|
||||
get {
|
||||
return ((string)(this["SongTitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string SongUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["SongUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'song-artist\']/a/@href")]
|
||||
public string ArtistUrlXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string ArtistUrIdRegex {
|
||||
get {
|
||||
return ((string)(this["ArtistUrIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//link[@rel=\'canonical\']/@href")]
|
||||
public string SongUrlIdXpath {
|
||||
get {
|
||||
return ((string)(this["SongUrlIdXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'song-artist\']/a")]
|
||||
public string ArtistXpath {
|
||||
get {
|
||||
return ((string)(this["ArtistXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("http://www.allmusic.com/song/{0}")]
|
||||
public string SongUrl {
|
||||
get {
|
||||
return ((string)(this["SongUrl"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@id=\'appearances\']//tbody/tr")]
|
||||
public string AlbumXpath {
|
||||
get {
|
||||
return ((string)(this["AlbumXpath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MusicMetaTagger.Client.AllMusicGuide.Properties" GeneratedClassName="SongScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="SongTitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='song-title']</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='song-artist']/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistUrIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongUrlIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//link[@rel='canonical']/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="ArtistXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='song-artist']/a</Value>
|
||||
</Setting>
|
||||
<Setting Name="SongUrl" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">http://www.allmusic.com/song/{0}</Value>
|
||||
</Setting>
|
||||
<Setting Name="AlbumXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@id='appearances']//tbody/tr</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,122 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class TrackScraper : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static TrackScraper defaultInstance = ((TrackScraper)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new TrackScraper())));
|
||||
|
||||
public static TrackScraper Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'pick\')]")]
|
||||
public string PickXpath {
|
||||
get {
|
||||
return ((string)(this["PickXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'tracknum\']")]
|
||||
public string TrackNumberXpath {
|
||||
get {
|
||||
return ((string)(this["TrackNumberXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'title\']//a/@href")]
|
||||
public string TrackUrlXpath {
|
||||
get {
|
||||
return ((string)(this["TrackUrlXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string TrackUrlIdRegex {
|
||||
get {
|
||||
return ((string)(this["TrackUrlIdRegex"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'title\']//a")]
|
||||
public string TitleXpath {
|
||||
get {
|
||||
return ((string)(this["TitleXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'artist\')]//a")]
|
||||
public string ComposerXpath {
|
||||
get {
|
||||
return ((string)(this["ComposerXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[@class=\'time\']")]
|
||||
public string TimeXpath {
|
||||
get {
|
||||
return ((string)(this["TimeXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'performer\')]/*[@class=\'primary\']/a/@href")]
|
||||
public string PerformerIdXpath {
|
||||
get {
|
||||
return ((string)(this["PerformerIdXpath"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("[a-zA-Z]{2}[0-9]+(?=$)")]
|
||||
public string PerformerIdRegex {
|
||||
get {
|
||||
return ((string)(this["PerformerIdRegex"]));
|
||||
}
|
||||
set {
|
||||
this["PerformerIdRegex"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("//*[contains(@class,\'performer\')]//a/@href")]
|
||||
public string PerformerIdAlternateXpath {
|
||||
get {
|
||||
return ((string)(this["PerformerIdAlternateXpath"]));
|
||||
}
|
||||
set {
|
||||
this["PerformerIdAlternateXpath"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AllMusicGuide.Client.Properties" GeneratedClassName="TrackScraper">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="PickXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'pick')]</Value>
|
||||
</Setting>
|
||||
<Setting Name="TrackNumberXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='tracknum']</Value>
|
||||
</Setting>
|
||||
<Setting Name="TrackUrlXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='title']//a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="TrackUrlIdRegex" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="TitleXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='title']//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="ComposerXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'artist')]//a</Value>
|
||||
</Setting>
|
||||
<Setting Name="TimeXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[@class='time']</Value>
|
||||
</Setting>
|
||||
<Setting Name="PerformerIdXpath" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">//*[contains(@class,'performer')]/*[@class='primary']/a/@href</Value>
|
||||
</Setting>
|
||||
<Setting Name="PerformerIdRegex" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">[a-zA-Z]{2}[0-9]+(?=$)</Value>
|
||||
</Setting>
|
||||
<Setting Name="PerformerIdAlternateXpath" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">//*[contains(@class,'performer')]//a/@href</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class AlbumClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string albumId)
|
||||
{
|
||||
var settings = AlbumScraper.Default;
|
||||
return ReadFromCriteria(settings.AlbumUrl, albumId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class AlbumResultPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string criteria)
|
||||
{
|
||||
var settings = AlbumResultPageScraper.Default;
|
||||
return ReadFromCriteria(settings.AlbumResultUrl, criteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class ArtistClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string artistId)
|
||||
{
|
||||
var settings = ArtistScaper.Default;
|
||||
return ReadFromCriteria(settings.ArtistUrl, artistId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class ArtistDiscographyAlbumPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string artistId)
|
||||
{
|
||||
var settings = ArtistDiscographyPageScraper.Default;
|
||||
return ReadFromCriteria(settings.DiscographyAlbumUrl, artistId);
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class ArtistDiscographyCompilationPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string artistId)
|
||||
{
|
||||
var settings = ArtistDiscographyPageScraper.Default;
|
||||
return ReadFromCriteria(settings.DiscographyCompilationUrl, artistId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class ArtistDiscographyEpSinglesPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string artistId)
|
||||
{
|
||||
var settings = ArtistDiscographyPageScraper.Default;
|
||||
return ReadFromCriteria(settings.DiscographyEpSinglesUrl, artistId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class ArtistResultPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string criteria)
|
||||
{
|
||||
var settings = ArtistResultPageScraper.Default;
|
||||
return ReadFromCriteria(settings.ArtistResultUrl, criteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public interface IXmlClientBase
|
||||
{
|
||||
XmlDocument Read(string criteria);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class SongClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string criteria)
|
||||
{
|
||||
var settings = SongScraper.Default;
|
||||
return ReadFromCriteria(settings.SongUrl, criteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public class SongResultPageClient : XmlClientBase
|
||||
{
|
||||
public override XmlDocument Read(string criteria)
|
||||
{
|
||||
var settings = SongResultPageScraper.Default;
|
||||
return ReadFromCriteria(settings.SongResultUrl, criteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using HtmlAgilityPack;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public static class WebXmlClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the HTML grabbed from the passed in URL.
|
||||
/// </summary>
|
||||
/// <param name="url"> The URL. </param>
|
||||
/// <returns> A string containing html </returns>
|
||||
public static string GetHtml(Uri url)
|
||||
{
|
||||
var tries = 0;
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = new WebClient();
|
||||
using (var data = client.OpenRead(url))
|
||||
using (var reader = new StreamReader(data))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (tries++ > 3)
|
||||
throw new WebException(ex.Message + " : " + url, ex);
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveFile(Uri url, string filename)
|
||||
{
|
||||
var client = new WebClient();
|
||||
client.DownloadFile(url, filename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the HTML parsed into a standard XmlDocument. Uses the HtmlAgilityPack library for "out of the web" (poorly formatted) html file support.
|
||||
/// </summary>
|
||||
/// <param name="html"> The HTML </param>
|
||||
/// <returns> An XmlDocument from the HTML </returns>
|
||||
public static XmlDocument GetHtmlXml(string html)
|
||||
{
|
||||
// Sometimes the biography will have "<..." in it. Annoying.
|
||||
html = html.Replace("<...", "");
|
||||
html = html.Replace("<class=\"subtitle\">", "");
|
||||
html = html.Replace("< ", "");
|
||||
|
||||
var htmlDoc = new HtmlDocument {OptionOutputAsXml = true};
|
||||
htmlDoc.LoadHtml(html);
|
||||
// this element will have unencoded entities in an attribute, messing up the xml
|
||||
var selectSingleNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@class='rovi-share']");
|
||||
if (selectSingleNode != null)
|
||||
selectSingleNode.Remove();
|
||||
selectSingleNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='similar-albums']");
|
||||
if (selectSingleNode != null)
|
||||
selectSingleNode.Remove();
|
||||
// fix for ajax results having more than one root node
|
||||
if (htmlDoc.DocumentNode.ChildNodes.All(n => n.Name != "html"))
|
||||
{
|
||||
var el = htmlDoc.CreateElement("html");
|
||||
var nodes = htmlDoc.DocumentNode.ChildNodes;
|
||||
el.AppendChildren(nodes);
|
||||
htmlDoc.DocumentNode.RemoveAllChildren();
|
||||
htmlDoc.DocumentNode.AppendChild(el);
|
||||
}
|
||||
|
||||
var xmlDocument = new XmlDocument();
|
||||
using (Stream stream = new MemoryStream())
|
||||
using (var xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8))
|
||||
{
|
||||
htmlDoc.Save(xmlTextWriter);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
xmlDocument.Load(streamReader);
|
||||
}
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the HTML grabbed from the passed in URL parsed into a standard XmlDocument. Uses the HtmlAgilityPack library for "out of the web" html file support.
|
||||
/// </summary>
|
||||
/// <param name="url"> The URL. </param>
|
||||
/// <returns> An XmlDocument from the HTML </returns>
|
||||
public static XmlDocument GetHtmlXml(Uri url)
|
||||
{
|
||||
return GetHtmlXml(GetHtml(url));
|
||||
}
|
||||
|
||||
// TODO: Refactor!
|
||||
/// <summary>
|
||||
/// Downloads the cover art to a local file. If the album doesn't have cover art, this will return null.
|
||||
/// </summary>
|
||||
/// <exception cref="HttpException">Thrown on HTTP error.</exception>
|
||||
/// <returns> </returns>
|
||||
public static FileInfo DownloadCoverArt(Album album)
|
||||
{
|
||||
if (String.IsNullOrEmpty(album.CoverUrl))
|
||||
return null;
|
||||
if (album.CoverUrl.Contains("no_cover"))
|
||||
return null;
|
||||
|
||||
var directoryInfo = new DirectoryInfo(".\\ImageCache");
|
||||
if (!Directory.Exists(directoryInfo.FullName))
|
||||
directoryInfo.Create();
|
||||
|
||||
var fileInfo = new FileInfo(directoryInfo.FullName + "\\" + album.AlbumId + ".jpg");
|
||||
|
||||
if (!fileInfo.Exists)
|
||||
SaveFile(new Uri(album.CoverUrl), fileInfo.FullName);
|
||||
|
||||
return fileInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client
|
||||
{
|
||||
public abstract class XmlClientBase : IXmlClientBase
|
||||
{
|
||||
public abstract XmlDocument Read(string criteria);
|
||||
|
||||
protected static XmlDocument ReadFromCriteria(string urlFormat, string criteria)
|
||||
{
|
||||
|
||||
if (String.IsNullOrEmpty(criteria))
|
||||
return new XmlDocument();
|
||||
//throw new ArgumentNullException("criteria");
|
||||
|
||||
criteria = Uri.EscapeUriString(criteria);
|
||||
var url = String.Format(urlFormat, criteria);
|
||||
return WebXmlClient.GetHtmlXml(new Uri(url));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// Inspired by this Perl module: http://backpan.perl.org/authors/id/Y/YO/YOHAMED/WWW-AllMusicGuide.html
|
||||
/// </summary>
|
||||
public class MusicGuideScraper : IMusicGuide
|
||||
{
|
||||
private readonly IScraper<Album> _albumScraper;
|
||||
private readonly IScraper<List<AlbumResult>> _albumResultScraper;
|
||||
private readonly IScraper<Artist> _artistScraper;
|
||||
private readonly IScraper<List<ArtistResult>> _artistResultScraper;
|
||||
private readonly IScraper<List<ArtistDiscography>> _discographyScraper;
|
||||
|
||||
private readonly IScraper<List<SongResult>> _songResultScraper;
|
||||
private readonly IScraper<Song> _songScraper;
|
||||
|
||||
public MusicGuideScraper(IScraper<Album> albumScraper, IScraper<List<AlbumResult>> albumResultScraper, IScraper<Artist> artistScraper, IScraper<List<ArtistResult>> artistResultScraper, IScraper<List<ArtistDiscography>> discographyScraper, IScraper<List<SongResult>> songResultScraper, IScraper<Song> songScraper)
|
||||
{
|
||||
_albumScraper = albumScraper;
|
||||
_albumResultScraper = albumResultScraper;
|
||||
_artistScraper = artistScraper;
|
||||
_artistResultScraper = artistResultScraper;
|
||||
_discographyScraper = discographyScraper;
|
||||
_songResultScraper = songResultScraper;
|
||||
_songScraper = songScraper;
|
||||
}
|
||||
|
||||
public Artist GetArtist(string artistId)
|
||||
{
|
||||
var artist = _artistScraper.Scrape(artistId);
|
||||
artist.Discography = _discographyScraper.Scrape(artistId);
|
||||
return artist;
|
||||
}
|
||||
|
||||
public Album GetAlbum(string albumId)
|
||||
{
|
||||
return _albumScraper.Scrape(albumId);
|
||||
}
|
||||
|
||||
public Song GetSong(string songId)
|
||||
{
|
||||
return _songScraper.Scrape(songId);
|
||||
}
|
||||
|
||||
public List<ArtistResult> SearchArtist(string artistName)
|
||||
{
|
||||
return _artistResultScraper.Scrape(artistName);
|
||||
}
|
||||
|
||||
public List<AlbumResult> SearchAlbum(string albumName)
|
||||
{
|
||||
return _albumResultScraper.Scrape(albumName);
|
||||
}
|
||||
|
||||
public List<SongResult> SearchSong(string songName)
|
||||
{
|
||||
return _songResultScraper.Scrape(songName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class AlbumParser : ParserBase<Album>
|
||||
{
|
||||
public override Album Parse(XmlDocument xml)
|
||||
{
|
||||
var album = new Album();
|
||||
var settings = AlbumScraper.Default;
|
||||
|
||||
if (XpathMatch(xml, settings.ArtistUrlXpath))
|
||||
{
|
||||
var artistUrl = XpathMatchString(xml, settings.ArtistUrlXpath);
|
||||
album.ArtistId = RegexCapture(artistUrl, settings.ArtistUrlIdRegex);
|
||||
album.ArtistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
album.VariousArtists = true;
|
||||
album.ArtistName = "Various Artists";
|
||||
}
|
||||
|
||||
if (XpathMatch(xml, settings.SoundtrackXpath))
|
||||
{
|
||||
album.Soundtrack = true;
|
||||
}
|
||||
|
||||
var albumId = XpathMatchString(xml, settings.AlbumIdXpath);
|
||||
album.AlbumId = StringUtility.CleanId(albumId);
|
||||
|
||||
album.Title = XpathMatchString(xml, settings.TitleXpath);
|
||||
if (XpathMatch(xml, settings.ReleaseDateXpath))
|
||||
album.ReleaseDate = XpathMatchString(xml, settings.ReleaseDateXpath);
|
||||
|
||||
//rating
|
||||
if (XpathMatch(xml, settings.RatingXpath))
|
||||
{
|
||||
float rating;
|
||||
if (float.TryParse(XpathMatchString(xml, settings.RatingXpath), out rating))
|
||||
album.Rating = Convert.ToInt32(rating*2);
|
||||
}
|
||||
|
||||
if (XpathMatch(xml, settings.PickXpath))
|
||||
album.Pick = true;
|
||||
|
||||
if (XpathMatch(xml, settings.CoverUrlXpath))
|
||||
{
|
||||
var coverUrl = XpathMatchString(xml, settings.CoverUrlXpath);
|
||||
album.CoverUrl = RegexCapture(coverUrl, settings.CoverUrlRegex);
|
||||
}
|
||||
if (XpathMatch(xml, settings.ReviewXpath))
|
||||
album.Review = XpathMatchString(xml, settings.ReviewXpath);
|
||||
|
||||
if (XpathMatch(xml, settings.ReviewerXpath))
|
||||
{
|
||||
var reviewer = XpathMatchString(xml, settings.ReviewerXpath);
|
||||
album.Reviewer = RegexCapture(reviewer, settings.ReviewerRegex).Trim();
|
||||
}
|
||||
|
||||
if (XpathMatch(xml, settings.StylesXpath))
|
||||
album.Styles = XpathMatchStringList(xml, settings.StylesXpath);
|
||||
if (XpathMatch(xml, settings.MoodsXpath))
|
||||
album.Moods = XpathMatchStringList(xml, settings.MoodsXpath);
|
||||
if (XpathMatch(xml, settings.ThemesXpath))
|
||||
album.Themes = XpathMatchStringList(xml, settings.ThemesXpath);
|
||||
|
||||
album.Tracks = new List<Track>();
|
||||
|
||||
if (XpathMatch(xml, settings.TrackXpath))
|
||||
{
|
||||
var trackParser = new TrackParser();
|
||||
var tracks =
|
||||
from tXml in XpathMatchXmlList(xml, settings.TrackXpath)
|
||||
let t = trackParser.Parse(tXml)
|
||||
where t.PerformerIds.Any() && t.TrackLength > TimeSpan.MinValue
|
||||
select t;
|
||||
|
||||
foreach (var track in tracks)
|
||||
{
|
||||
track.AlbumId = album.AlbumId;
|
||||
album.Tracks.Add(track);
|
||||
}
|
||||
}
|
||||
return album;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class AlbumResultPageParser : ParserBase<List<AlbumResult>>
|
||||
{
|
||||
public override List<AlbumResult> Parse(XmlDocument xml)
|
||||
{
|
||||
var albumResults = new List<AlbumResult>();
|
||||
var settings = AlbumResultPageScraper.Default;
|
||||
var albumResultScraper = new AlbumResultParser();
|
||||
|
||||
if (XpathMatch(xml, settings.AlbumXpath))
|
||||
{
|
||||
var albumResultInfoXmlList = XpathMatchXmlList(xml, settings.AlbumXpath);
|
||||
albumResults.AddRange(albumResultInfoXmlList.Select(albumResultScraper.Parse));
|
||||
var i = 1;
|
||||
albumResults.ForEach(ar => ar.ResultOrder = i++);
|
||||
}
|
||||
return albumResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class AlbumResultParser : ParserBase<AlbumResult>
|
||||
{
|
||||
public override AlbumResult Parse(XmlDocument xml)
|
||||
{
|
||||
var albumResult = new AlbumResult();
|
||||
var settings = AlbumResultScraper.Default;
|
||||
|
||||
var albumUrl = XpathMatchString(xml, settings.AlbumUrlXpath);
|
||||
albumResult.AlbumId = RegexCapture(albumUrl, settings.AlbumUrlIdRegex);
|
||||
|
||||
if (XpathMatch(xml, settings.InfoXpath))
|
||||
{
|
||||
var infoRaw = XpathMatchString(xml, settings.InfoXpath);
|
||||
if (RegexMatch(infoRaw, settings.YearRegex))
|
||||
{
|
||||
var year = RegexCapture(infoRaw, settings.YearRegex);
|
||||
int yearInt;
|
||||
if (Int32.TryParse(year, out yearInt))
|
||||
albumResult.Year = yearInt;
|
||||
}
|
||||
if (RegexMatch(infoRaw, settings.GenreRegex))
|
||||
{
|
||||
var genre = RegexCapture(infoRaw, settings.GenreRegex);
|
||||
albumResult.Genre = genre.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (XpathMatch(xml, settings.ArtistUrlXpath))
|
||||
{
|
||||
var artistId = XpathMatchString(xml, settings.ArtistUrlXpath);
|
||||
albumResult.ArtistId = RegexCapture(artistId, settings.ArtistUrIdRegex);
|
||||
albumResult.ArtistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
}
|
||||
else if (XpathMatch(xml, settings.ArtistNoUrlXpath))
|
||||
{
|
||||
albumResult.ArtistName = XpathMatchString(xml, settings.ArtistNoUrlXpath);
|
||||
}
|
||||
|
||||
albumResult.AlbumTitle = XpathMatchString(xml, settings.TitleXpath);
|
||||
|
||||
return albumResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class ArtistDiscographyPageParser : ParserBase<List<ArtistDiscography>>
|
||||
{
|
||||
public override List<ArtistDiscography> Parse(XmlDocument xml)
|
||||
{
|
||||
var artistDiscographies = new List<ArtistDiscography>();
|
||||
var settings = ArtistDiscographyPageScraper.Default;
|
||||
|
||||
if (XpathMatch(xml, settings.DiscographyXpath))
|
||||
{
|
||||
var releaseTypeStr = XpathMatchString(xml, settings.ReleaseTypeXpath);
|
||||
releaseTypeStr = RegexCapture(releaseTypeStr, settings.ReleaseTypeRegex);
|
||||
|
||||
ReleaseType releaseType;
|
||||
switch (releaseTypeStr)
|
||||
{
|
||||
case "main":
|
||||
releaseType = ReleaseType.Album;
|
||||
break;
|
||||
case "singles":
|
||||
releaseType = ReleaseType.Single;
|
||||
break;
|
||||
case "compilations":
|
||||
releaseType = ReleaseType.Compilation;
|
||||
break;
|
||||
default:
|
||||
throw new ApplicationException("Unknown release type");
|
||||
}
|
||||
|
||||
var discographyParser = new ArtistDiscographyParser(releaseType);
|
||||
artistDiscographies.AddRange(
|
||||
from albumXml in XpathMatchXmlList(xml, settings.DiscographyXpath)
|
||||
let album = discographyParser.Parse(albumXml)
|
||||
where album.Year > 0
|
||||
select album);
|
||||
|
||||
var artistId = StringUtility.CleanId(XpathMatchString(xml, settings.ArtistIdXpath));
|
||||
var artistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
|
||||
foreach (var artistDiscography in artistDiscographies)
|
||||
{
|
||||
artistDiscography.ArtistId = artistId;
|
||||
artistDiscography.ArtistName = artistName;
|
||||
}
|
||||
}
|
||||
return artistDiscographies;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class ArtistDiscographyParser : ParserBase<ArtistDiscography>
|
||||
{
|
||||
private readonly ReleaseType _releaseType;
|
||||
|
||||
public ArtistDiscographyParser(ReleaseType releaseType)
|
||||
{
|
||||
_releaseType = releaseType;
|
||||
}
|
||||
|
||||
public override ArtistDiscography Parse(XmlDocument xml)
|
||||
{
|
||||
var artistDiscography = new ArtistDiscography();
|
||||
var settings = ArtistDiscographyScraper.Default;
|
||||
|
||||
var albumUrl = XpathMatchString(xml, settings.AlbumUrlXpath);
|
||||
artistDiscography.AlbumId = RegexCapture(albumUrl, settings.AlbumUrlIdRegex);
|
||||
|
||||
var year = XpathMatchString(xml, settings.YearXpath);
|
||||
if (year.Length > 0 && StringUtility.IsNumeric(year))
|
||||
artistDiscography.Year = Convert.ToInt32(XpathMatchString(xml, settings.YearXpath));
|
||||
|
||||
//rating
|
||||
if (XpathMatch(xml, settings.RatingXpath))
|
||||
{
|
||||
var ratingString = XpathMatchString(xml, settings.RatingXpath);
|
||||
if (!string.IsNullOrEmpty(ratingString))
|
||||
{
|
||||
ratingString = RegexCapture(ratingString, settings.RatingRegex);
|
||||
int rating;
|
||||
if (int.TryParse(ratingString, out rating))
|
||||
artistDiscography.Rating = Convert.ToInt32(rating);
|
||||
}
|
||||
}
|
||||
|
||||
artistDiscography.Pick = XpathMatch(xml, settings.PickXpath);
|
||||
|
||||
if (XpathMatch(xml, settings.LabelXpath))
|
||||
artistDiscography.Label = XpathMatchString(xml, settings.LabelXpath);
|
||||
|
||||
artistDiscography.AlbumTitle = XpathMatchString(xml, settings.TitleXpath);
|
||||
|
||||
artistDiscography.ReleaseType = _releaseType;
|
||||
// EPs will have "[EP]" after the title
|
||||
if (RegexMatch(artistDiscography.AlbumTitle, settings.ReleaseTypeRegex))
|
||||
{
|
||||
var releaseType = RegexCapture(artistDiscography.AlbumTitle, settings.ReleaseTypeRegex);
|
||||
if (releaseType == "EP")
|
||||
artistDiscography.ReleaseType = ReleaseType.EP;
|
||||
}
|
||||
else if (artistDiscography.AlbumTitle.Contains("Box Set"))
|
||||
artistDiscography.ReleaseType = ReleaseType.BoxSet;
|
||||
|
||||
// TODO: add "has review"
|
||||
|
||||
return artistDiscography;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class ArtistParser : ParserBase<Artist>
|
||||
{
|
||||
public override Artist Parse(XmlDocument artistXml)
|
||||
{
|
||||
var scraper = ArtistScaper.Default;
|
||||
var artist = new Artist();
|
||||
|
||||
artist.ArtistId = StringUtility.CleanId(XpathMatchString(artistXml, scraper.ArtistIdXpath));
|
||||
artist.ArtistName = XpathMatchString(artistXml, scraper.ArtistXpath);
|
||||
|
||||
if (XpathMatch(artistXml, scraper.GenreXpath))
|
||||
artist.Genre = XpathMatchString(artistXml, scraper.GenreXpath);
|
||||
|
||||
artist.Styles =
|
||||
XpathMatch(artistXml, scraper.StylesXpath)
|
||||
? XpathMatchStringList(artistXml, scraper.StylesXpath)
|
||||
: new List<string>();
|
||||
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class ArtistResultPageParser : ParserBase<List<ArtistResult>>
|
||||
{
|
||||
public override List<ArtistResult> Parse(XmlDocument xml)
|
||||
{
|
||||
var artistResults = new List<ArtistResult>();
|
||||
var settings = ArtistResultPageScraper.Default;
|
||||
var artistResultParser = new ArtistResultParser();
|
||||
|
||||
if (XpathMatch(xml, settings.ArtistXpath))
|
||||
{
|
||||
var artistResultsXmlList = XpathMatchXmlList(xml, settings.ArtistXpath);
|
||||
artistResults = artistResultsXmlList.Select(artistResultParser.Parse).ToList();
|
||||
var i = 1;
|
||||
artistResults.ForEach(ar => ar.ResultOrder = i++);
|
||||
}
|
||||
return artistResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class ArtistResultParser : ParserBase<ArtistResult>
|
||||
{
|
||||
public override ArtistResult Parse(XmlDocument xml)
|
||||
{
|
||||
var artistResult = new ArtistResult();
|
||||
var settings = ArtistResultScraper.Default;
|
||||
|
||||
var artistId = XpathMatchString(xml, settings.ArtistUrlXpath);
|
||||
artistResult.ArtistId = RegexCapture(artistId, settings.ArtistUrIdRegex);
|
||||
|
||||
artistResult.ArtistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
if (XpathMatch(xml, settings.InfoXpath))
|
||||
{
|
||||
var infoRaw = XpathMatchString(xml, settings.InfoXpath);
|
||||
if (RegexMatch(infoRaw, settings.YearsActiveRegex))
|
||||
{
|
||||
var yearsActive = RegexCapture(infoRaw, settings.YearsActiveRegex);
|
||||
artistResult.YearsActive = yearsActive.Trim();
|
||||
}
|
||||
if (RegexMatch(infoRaw, settings.GenreRegex))
|
||||
{
|
||||
var genre = RegexCapture(infoRaw, settings.GenreRegex);
|
||||
artistResult.Genre = genre.Trim();
|
||||
}
|
||||
}
|
||||
return artistResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public interface IParser<out TEntity>
|
||||
{
|
||||
TEntity Parse(XmlDocument xml);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public abstract class ParserBase<TEntity> : IParser<TEntity>
|
||||
{
|
||||
public abstract TEntity Parse(XmlDocument xml);
|
||||
|
||||
protected static string RegexCapture(string str, string regexStr)
|
||||
{
|
||||
var regex = new Regex(regexStr);
|
||||
var match = regex.Match(str);
|
||||
if (match.Captures.Count == 0)
|
||||
throw new ApplicationException("Couldn't make regex match for "
|
||||
+ regexStr + " in " + str);
|
||||
return match.Captures[0].Value;
|
||||
}
|
||||
|
||||
protected static bool RegexMatch(string str, string regexStr)
|
||||
{
|
||||
var regex = new Regex(regexStr);
|
||||
var match = regex.Match(str);
|
||||
return match.Captures.Count > 0;
|
||||
}
|
||||
|
||||
protected static bool XpathMatch(XmlDocument xml, string xPath)
|
||||
{
|
||||
var nodes = xml.SelectNodes(xPath);
|
||||
return nodes != null && nodes.Count > 0;
|
||||
}
|
||||
|
||||
protected static string XpathMatchString(XmlDocument xml, string xPath)
|
||||
{
|
||||
var titleNodes = xml.SelectNodes(xPath);
|
||||
if (titleNodes == null || titleNodes.Count == 0)
|
||||
{
|
||||
//xml.Save(@"problem_" + DateTime.Now.Ticks + ".xml");
|
||||
throw new ApplicationException(string.Format("Couldn't find matching nodes for : \"{0}\" in {1}", xPath,
|
||||
xml.InnerXml));
|
||||
}
|
||||
var decodedValue = WebUtility.HtmlDecode(titleNodes[0].InnerText);
|
||||
return decodedValue.Trim();
|
||||
}
|
||||
|
||||
protected static List<string> XpathMatchStringList(XmlDocument xml, string xPath)
|
||||
{
|
||||
var titleNodes = xml.SelectNodes(xPath);
|
||||
if (titleNodes == null || titleNodes.Count == 0)
|
||||
throw new ApplicationException("Couldn't find matching nodes for : " + xPath);
|
||||
|
||||
return (
|
||||
from XmlNode node in titleNodes
|
||||
select WebUtility.HtmlDecode(node.InnerText)
|
||||
into decodedValue
|
||||
select decodedValue.Trim()
|
||||
).ToList();
|
||||
}
|
||||
|
||||
protected static IEnumerable<XmlDocument> XpathMatchXmlList(XmlDocument xml, string xPath)
|
||||
{
|
||||
var titleNodes = xml.SelectNodes(xPath);
|
||||
if (titleNodes == null || titleNodes.Count == 0)
|
||||
{
|
||||
xml.Save("problem.xml");
|
||||
throw new ApplicationException("Couldn't find matching nodes for : " + xPath);
|
||||
}
|
||||
|
||||
var xmlList = new List<XmlDocument>();
|
||||
foreach (XmlNode node in titleNodes)
|
||||
{
|
||||
var xmlDocument = new XmlDocument();
|
||||
xmlDocument.LoadXml(xml.FirstChild.InnerXml + "<root></root>");
|
||||
|
||||
var importNode = xmlDocument.ImportNode(node, true);
|
||||
if (xmlDocument.DocumentElement == null)
|
||||
throw new ApplicationException("xmlDocument.DocumentElement Null");
|
||||
xmlDocument.DocumentElement.AppendChild(importNode);
|
||||
|
||||
xmlList.Add(xmlDocument);
|
||||
}
|
||||
return xmlList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class SongAppearsOnAlbumParser : ParserBase<SongAppearsOnAlbum>
|
||||
{
|
||||
public override SongAppearsOnAlbum Parse(XmlDocument xml)
|
||||
{
|
||||
var albumResult = new SongAppearsOnAlbum();
|
||||
var settings = SongAppearsOnAlbumScraper.Default;
|
||||
|
||||
var albumUrl = XpathMatchString(xml, settings.AlbumUrlXpath);
|
||||
albumResult.AlbumId = RegexCapture(albumUrl, settings.AlbumUrlIdRegex);
|
||||
|
||||
if (XpathMatch(xml, settings.YearXpath))
|
||||
{
|
||||
var yearRaw = XpathMatchString(xml, settings.YearXpath);
|
||||
if (RegexMatch(yearRaw, settings.YearRegex))
|
||||
{
|
||||
var year = RegexCapture(yearRaw, settings.YearRegex);
|
||||
int yearInt;
|
||||
if (Int32.TryParse(year, out yearInt))
|
||||
albumResult.Year = yearInt;
|
||||
}
|
||||
}
|
||||
|
||||
if (XpathMatch(xml, settings.ArtistUrlXpath))
|
||||
{
|
||||
var artistId = XpathMatchString(xml, settings.ArtistUrlXpath);
|
||||
albumResult.ArtistId = RegexCapture(artistId, settings.ArtistUrIdRegex);
|
||||
albumResult.ArtistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
}
|
||||
else if (XpathMatch(xml, settings.ArtistNoUrlXpath))
|
||||
{
|
||||
albumResult.ArtistName = XpathMatchString(xml, settings.ArtistNoUrlXpath);
|
||||
}
|
||||
|
||||
albumResult.AlbumTitle = XpathMatchString(xml, settings.TitleXpath);
|
||||
|
||||
return albumResult;
|
||||
}
|
||||
}
|
||||
|
||||
public class SongParser : ParserBase<Song>
|
||||
{
|
||||
public override Song Parse(XmlDocument xml)
|
||||
{
|
||||
var song = new Song();
|
||||
var settings = SongScraper.Default;
|
||||
|
||||
song.SongTitle = XpathMatchString(xml, settings.SongTitleXpath);
|
||||
var songUrlId = XpathMatchString(xml, settings.SongUrlIdXpath);
|
||||
song.SongId = RegexCapture(songUrlId, settings.SongUrlIdRegex);
|
||||
|
||||
song.AppearsOnAlbum = new List<SongAppearsOnAlbum>();
|
||||
var songAppearsOnAlbumParser = new SongAppearsOnAlbumParser();
|
||||
|
||||
if (XpathMatch(xml, settings.AlbumXpath))
|
||||
{
|
||||
var albumResultInfoXmlList = XpathMatchXmlList(xml, settings.AlbumXpath);
|
||||
song.AppearsOnAlbum.AddRange(albumResultInfoXmlList.Select(songAppearsOnAlbumParser.Parse));
|
||||
var i = 1;
|
||||
song.AppearsOnAlbum.ForEach(ar => ar.ResultOrder = i++);
|
||||
}
|
||||
|
||||
return song;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class SongResultPageParser : ParserBase<List<SongResult>>
|
||||
{
|
||||
public override List<SongResult> Parse(XmlDocument xml)
|
||||
{
|
||||
var songResults = new List<SongResult>();
|
||||
var settings = SongResultPageScraper.Default;
|
||||
var songResultScraper = new SongResultParser();
|
||||
|
||||
if (XpathMatch(xml, settings.SongXpath))
|
||||
{
|
||||
var songResultInfoXmlList = XpathMatchXmlList(xml, settings.SongXpath);
|
||||
songResults.AddRange(songResultInfoXmlList.Select(songResultScraper.Parse));
|
||||
var i = 1;
|
||||
songResults.ForEach(ar => ar.ResultOrder = i++);
|
||||
}
|
||||
return songResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class SongResultParser : ParserBase<SongResult>
|
||||
{
|
||||
public override SongResult Parse(XmlDocument xml)
|
||||
{
|
||||
var songResult = new SongResult();
|
||||
var settings = SongResultScraper.Default;
|
||||
|
||||
songResult.SongTitle = XpathMatchString(xml, settings.SongTitleXpath);
|
||||
if (RegexMatch(songResult.SongTitle, settings.SongTitleRegex))
|
||||
songResult.SongTitle = RegexCapture(songResult.SongTitle, settings.SongTitleRegex);
|
||||
|
||||
var songUrl = XpathMatchString(xml, settings.SongUrlIdXpath);
|
||||
songResult.SongId = RegexCapture(songUrl, settings.SongUrlIdRegex);
|
||||
|
||||
if (XpathMatch(xml, settings.ArtistUrlXpath))
|
||||
{
|
||||
var artistId = XpathMatchString(xml, settings.ArtistUrlXpath);
|
||||
songResult.ArtistId = RegexCapture(artistId, settings.ArtistUrIdRegex);
|
||||
songResult.ArtistName = XpathMatchString(xml, settings.ArtistXpath);
|
||||
}
|
||||
|
||||
return songResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Properties;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser
|
||||
{
|
||||
public class TrackParser : ParserBase<Track>
|
||||
{
|
||||
public override Track Parse(XmlDocument xml)
|
||||
{
|
||||
var track = new Track();
|
||||
var settings = TrackScraper.Default;
|
||||
|
||||
if (XpathMatch(xml, settings.TrackUrlXpath))
|
||||
{
|
||||
var trackUrl = XpathMatchString(xml, settings.TrackUrlXpath);
|
||||
track.TrackId = RegexCapture(trackUrl, settings.TrackUrlIdRegex);
|
||||
}
|
||||
|
||||
track.TrackNumber = Convert.ToInt32(XpathMatchString(xml, settings.TrackNumberXpath));
|
||||
|
||||
track.Pick = XpathMatch(xml, settings.PickXpath);
|
||||
|
||||
track.TrackTitle =
|
||||
XpathMatch(xml, settings.TitleXpath)
|
||||
? XpathMatchString(xml, settings.TitleXpath)
|
||||
: string.Empty;
|
||||
|
||||
if (XpathMatch(xml, settings.ComposerXpath))
|
||||
track.Composer =
|
||||
String.Join(", ",
|
||||
XpathMatchStringList(xml, settings.ComposerXpath).ToArray());
|
||||
|
||||
track.PerformerIds = new List<string>();
|
||||
var performerIdXpath = settings.PerformerIdXpath;
|
||||
if (!XpathMatch(xml, settings.PerformerIdXpath))
|
||||
performerIdXpath = settings.PerformerIdAlternateXpath;
|
||||
|
||||
if (XpathMatch(xml, performerIdXpath))
|
||||
{
|
||||
var performerIdsRaw = XpathMatchStringList(xml, performerIdXpath);
|
||||
foreach (var performerIdRaw in performerIdsRaw)
|
||||
{
|
||||
if (RegexMatch(performerIdRaw, settings.PerformerIdRegex))
|
||||
track.PerformerIds.Add(RegexCapture(performerIdRaw, settings.PerformerIdRegex));
|
||||
}
|
||||
}
|
||||
|
||||
var timeString = XpathMatchString(xml, settings.TimeXpath);
|
||||
track.TrackLength = StringUtility.ConvertTimeSpan(timeString);
|
||||
|
||||
return track;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class AlbumResultPageScraper : ScraperBase<List<AlbumResult>, AlbumResultPageClient, AlbumResultPageParser>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class AlbumScraper : ScraperBase<Album, AlbumClient, AlbumParser>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class ArtistDiscographyScraper : IScraper<List<ArtistDiscography>>
|
||||
{
|
||||
public List<ArtistDiscography> Scrape(string artistId)
|
||||
{
|
||||
var parser = new ArtistDiscographyPageParser();
|
||||
var xmlClients =
|
||||
new IXmlClientBase[]
|
||||
{
|
||||
new ArtistDiscographyAlbumPageClient(),
|
||||
new ArtistDiscographyCompilationPageClient(),
|
||||
new ArtistDiscographyEpSinglesPageClient()
|
||||
};
|
||||
return xmlClients.Select(c => c.Read(artistId)).SelectMany(parser.Parse).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class ArtistResultPageScraper : ScraperBase<List<ArtistResult>, ArtistResultPageClient, ArtistResultPageParser>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class ArtistScraper : ScraperBase<Artist, ArtistClient, ArtistParser>
|
||||
{
|
||||
public new Artist Scrape(string artistId)
|
||||
{
|
||||
var artist = base.Scrape(artistId);
|
||||
|
||||
var artistDiscographyScraper = new ArtistDiscographyScraper();
|
||||
artist.Discography = artistDiscographyScraper.Scrape(artistId);
|
||||
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public interface IScraper<out TEntity>
|
||||
{
|
||||
TEntity Scrape(string criteria);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public abstract class ScraperBase<TEntity, TClient, TParser> : IScraper<TEntity>
|
||||
where TClient : IXmlClientBase, new()
|
||||
where TParser : IParser<TEntity>, new()
|
||||
{
|
||||
public TEntity Scrape(string criteria)
|
||||
{
|
||||
var xmlDocument = new TClient().Read(criteria);
|
||||
return new TParser().Parse(xmlDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class SongResultPageScraper : ScraperBase<List<SongResult>, SongResultPageClient, SongResultPageParser>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Client;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Scraper
|
||||
{
|
||||
public class SongScraper : ScraperBase<Song, SongClient, SongParser>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services
|
||||
{
|
||||
public class MusicGuideCache : IMusicGuide
|
||||
{
|
||||
private readonly Func<string, Album> _getAlbum;
|
||||
private readonly Func<string, Artist> _getArtist;
|
||||
private readonly Func<string, Song> _getSong;
|
||||
private readonly Func<string, List<ArtistResult>> _searchArtist;
|
||||
private readonly Func<string, List<AlbumResult>> _searchAlbum;
|
||||
private readonly Func<string, List<SongResult>> _searchSong;
|
||||
|
||||
public MusicGuideCache(IMusicGuide @base)
|
||||
{
|
||||
Func<string, Album> getAlbum = @base.GetAlbum;
|
||||
_getAlbum = getAlbum.MemoizeFunction();
|
||||
|
||||
Func<string, Artist> getArtist = @base.GetArtist;
|
||||
_getArtist = getArtist.MemoizeFunction();
|
||||
|
||||
Func<string, Song> getSong = @base.GetSong;
|
||||
_getSong = getSong.MemoizeFunction();
|
||||
|
||||
Func<string, List<ArtistResult>> searchArtist = @base.SearchArtist;
|
||||
_searchArtist = searchArtist.MemoizeFunction();
|
||||
|
||||
Func<string, List<AlbumResult>> searchAlbum = @base.SearchAlbum;
|
||||
_searchAlbum = searchAlbum.MemoizeFunction();
|
||||
|
||||
Func<string, List<SongResult>> searchSong = @base.SearchSong;
|
||||
_searchSong = searchSong.MemoizeFunction();
|
||||
}
|
||||
|
||||
public Artist GetArtist(string artistId)
|
||||
{
|
||||
return _getArtist(artistId);
|
||||
}
|
||||
|
||||
public Album GetAlbum(string albumId)
|
||||
{
|
||||
return _getAlbum(albumId);
|
||||
}
|
||||
|
||||
public Song GetSong(string songId)
|
||||
{
|
||||
return _getSong(songId);
|
||||
}
|
||||
|
||||
public List<ArtistResult> SearchArtist(string artistName)
|
||||
{
|
||||
return _searchArtist(artistName);
|
||||
}
|
||||
|
||||
public List<AlbumResult> SearchAlbum(string albumName)
|
||||
{
|
||||
return _searchAlbum(albumName);
|
||||
}
|
||||
|
||||
public List<SongResult> SearchSong(string songName)
|
||||
{
|
||||
return _searchSong(songName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Queries;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services.Searchers
|
||||
{
|
||||
public class AlbumArtistSearcher : ITrackSearcher
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
|
||||
public AlbumArtistSearcher(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
}
|
||||
|
||||
public event StatusHandler SearchStatusUpdate;
|
||||
|
||||
private void OnStatusUpdate(string status)
|
||||
{
|
||||
if (SearchStatusUpdate != null)
|
||||
SearchStatusUpdate.Invoke(new StatusEventArgs(status));
|
||||
}
|
||||
|
||||
public Track SearchTrack(TrackQuery trackQuery, CancellationToken canellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(trackQuery.AlbumTitle)
|
||||
|| string.IsNullOrEmpty(trackQuery.ArtistName))
|
||||
return null;
|
||||
|
||||
var albumResults = ScoreUtility.ScoreResults(_musicGuide.SearchAlbum, trackQuery.AlbumTitle).ToList();
|
||||
var artistName = GetArtistName(trackQuery);
|
||||
var artistResults = ScoreUtility.ScoreResults(_musicGuide.SearchArtist, artistName);
|
||||
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
|
||||
var matchingAlbums = ScoreUtility.Match(
|
||||
albumResults, artistResults,
|
||||
(album, artist) =>
|
||||
album.ArtistId == artist.ArtistId).ToList();
|
||||
|
||||
if (trackQuery.AlbumPartOfCompilation)
|
||||
matchingAlbums = matchingAlbums.Union(
|
||||
from album in albumResults
|
||||
where
|
||||
album.Obj.ArtistId == null
|
||||
|| album.Obj.AlbumTitle.Contains("Soundtrack")
|
||||
select album
|
||||
).ToList();
|
||||
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
|
||||
OnStatusUpdate("Found " + matchingAlbums.Count() + " potential matching albums");
|
||||
|
||||
return (from album in matchingAlbums
|
||||
let tracks = _musicGuide.GetAlbum(album.Obj.AlbumId).Tracks
|
||||
let match = TrackSimilarity.MatchTrack(trackQuery, tracks)
|
||||
where match != null
|
||||
select match).FirstOrDefault();
|
||||
}
|
||||
|
||||
private static string GetArtistName(TrackQuery trackQuery)
|
||||
{
|
||||
var artistName = trackQuery.ArtistName;
|
||||
if (!string.IsNullOrEmpty(trackQuery.AlbumArtistName) && !trackQuery.AlbumArtistName.Contains("Various"))
|
||||
artistName = trackQuery.AlbumArtistName;
|
||||
return artistName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Queries;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services.Searchers
|
||||
{
|
||||
public class AlbumSearcher : ITrackSearcher
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
|
||||
public AlbumSearcher(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
}
|
||||
|
||||
public event StatusHandler SearchStatusUpdate;
|
||||
|
||||
public Track SearchTrack(TrackQuery trackQuery, CancellationToken canellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(trackQuery.AlbumTitle))
|
||||
return null;
|
||||
|
||||
var albumResults = ScoreUtility.ScoreResults(_musicGuide.SearchAlbum, trackQuery.AlbumTitle);
|
||||
|
||||
foreach (ScoreContainer<AlbumResult> album in albumResults.Take(10))
|
||||
{
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
|
||||
var tracks = _musicGuide.GetAlbum(album.Obj.AlbumId).Tracks;
|
||||
var match = TrackSimilarity.MatchTrack(trackQuery, tracks);
|
||||
if (match != null) return match;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Queries;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
using MusicMetaTagger.Core.Utility;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services.Searchers
|
||||
{
|
||||
public class SongArtistSearcher : ITrackSearcher
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
|
||||
public SongArtistSearcher(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
}
|
||||
|
||||
public event StatusHandler SearchStatusUpdate;
|
||||
|
||||
public Track SearchTrack(TrackQuery trackQuery, CancellationToken canellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(trackQuery.TrackTitle)
|
||||
|| string.IsNullOrEmpty(trackQuery.ArtistName))
|
||||
return null;
|
||||
|
||||
var songResults = ScoreUtility.ScoreResults(_musicGuide.SearchSong, trackQuery.TrackTitle);
|
||||
var artistName = GetArtistName(trackQuery);
|
||||
var artistResults = ScoreUtility.ScoreResults(_musicGuide.SearchArtist, artistName);
|
||||
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
|
||||
var matchingSongs = ScoreUtility.Match(songResults, artistResults, (s, a) => s.ArtistId == a.ArtistId).ToList();
|
||||
|
||||
foreach (var song in matchingSongs)
|
||||
{
|
||||
foreach (var album in _musicGuide.GetSong(song.Obj.SongId).AppearsOnAlbum)
|
||||
{
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
|
||||
var tracks = _musicGuide.GetAlbum(album.AlbumId).Tracks;
|
||||
var match = TrackSimilarity.MatchTrack(trackQuery, tracks);
|
||||
if (match != null) return match;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetArtistName(TrackQuery trackQuery)
|
||||
{
|
||||
var artistName = trackQuery.ArtistName;
|
||||
if (!string.IsNullOrEmpty(trackQuery.AlbumArtistName) && !trackQuery.AlbumArtistName.Contains("Various"))
|
||||
artistName = trackQuery.AlbumArtistName;
|
||||
return artistName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services
|
||||
{
|
||||
public class TrackOriginalRelease : ITrackOriginalRelease
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
|
||||
public TrackOriginalRelease(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
}
|
||||
|
||||
public Track GetTrackOriginalRelease(Track track)
|
||||
{
|
||||
var song = _musicGuide.GetSong(track.TrackId);
|
||||
// TODO: iterate through albums until track is found
|
||||
var firstAlbum = song.AppearsOnAlbum[0];
|
||||
|
||||
var album = _musicGuide.GetAlbum(firstAlbum.AlbumId);
|
||||
return TrackSimilarity.MatchTrack(track, album.Tracks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services
|
||||
{
|
||||
public class TrackRater : ITrackRater
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
|
||||
public TrackRater(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
}
|
||||
|
||||
public int? RateTrack(Track track)
|
||||
{
|
||||
if (track == null)
|
||||
throw new ArgumentNullException("track");
|
||||
|
||||
if (track.PerformerIds == null || track.PerformerIds.Count == 0)
|
||||
return null;
|
||||
|
||||
// get the track pick statistics for this album
|
||||
var albumInfo = _musicGuide.GetAlbum(track.AlbumId);
|
||||
|
||||
if (!albumInfo.Rating.HasValue)
|
||||
return null;
|
||||
|
||||
// get the album rating statistics for this artist
|
||||
double artistAlbumRatingMean = 0;
|
||||
var artistInfo = _musicGuide.GetArtist(albumInfo.ArtistId);
|
||||
|
||||
if (artistInfo != null)
|
||||
{
|
||||
var currentDi =
|
||||
artistInfo.Discography.Find(di => di.AlbumId == albumInfo.AlbumId);
|
||||
|
||||
artistAlbumRatingMean =
|
||||
(from di in artistInfo.Discography
|
||||
where currentDi == null || di.ReleaseType == currentDi.ReleaseType
|
||||
where di.Rating.HasValue
|
||||
select di.Rating.Value).Average();
|
||||
}
|
||||
|
||||
// calculate the track rating
|
||||
var trackRating = albumInfo.Rating.Value;
|
||||
if (albumInfo.Rating.Value >= 9 && albumInfo.Tracks.Any(t => t.Pick)) trackRating -= 1;
|
||||
if (artistAlbumRatingMean >= 8 && albumInfo.Tracks.Any(t => t.Pick)) trackRating -= 1;
|
||||
if (albumInfo.Pick) trackRating += 1;
|
||||
if (track.Pick) trackRating += 2;
|
||||
|
||||
return Math.Min(Math.Max(0, trackRating), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using MusicMetaTagger.Client.AllMusicGuide.Services.Searchers;
|
||||
using MusicMetaTagger.Core.Model;
|
||||
using MusicMetaTagger.Core.Queries;
|
||||
using MusicMetaTagger.Core.Services;
|
||||
|
||||
namespace MusicMetaTagger.Client.AllMusicGuide.Services
|
||||
{
|
||||
public class TrackSearcher : ITrackSearcher
|
||||
{
|
||||
private readonly IMusicGuide _musicGuide;
|
||||
private readonly ITrackSearcher[] _searchers;
|
||||
|
||||
public TrackSearcher(IMusicGuide musicGuide)
|
||||
{
|
||||
_musicGuide = musicGuide;
|
||||
_searchers = new ITrackSearcher[]
|
||||
{
|
||||
new AlbumArtistSearcher(_musicGuide),
|
||||
new SongArtistSearcher(_musicGuide),
|
||||
new AlbumSearcher(_musicGuide),
|
||||
};
|
||||
|
||||
foreach (var searcher in _searchers)
|
||||
searcher.SearchStatusUpdate += NestedSearcher_SearchStatusUpdate;
|
||||
}
|
||||
|
||||
public event StatusHandler SearchStatusUpdate;
|
||||
|
||||
private void OnStatusUpdate(string status)
|
||||
{
|
||||
if (SearchStatusUpdate != null)
|
||||
SearchStatusUpdate.Invoke(new StatusEventArgs(status));
|
||||
}
|
||||
|
||||
void NestedSearcher_SearchStatusUpdate(StatusEventArgs data)
|
||||
{
|
||||
if (SearchStatusUpdate != null)
|
||||
SearchStatusUpdate.Invoke(data);
|
||||
}
|
||||
|
||||
public Track SearchTrack(TrackQuery trackQuery, CancellationToken canellationToken)
|
||||
{
|
||||
var statusSearch =
|
||||
String.Format("Searching for Album - Artist - Track: '{0} - {1} - {2}'",
|
||||
trackQuery.AlbumTitle ?? "unknown", trackQuery.ArtistName ?? "unknown",
|
||||
trackQuery.TrackTitle);
|
||||
OnStatusUpdate(statusSearch);
|
||||
|
||||
Track matchingTrack = null;
|
||||
foreach (var searcher in _searchers)
|
||||
{
|
||||
var track = searcher.SearchTrack(trackQuery, canellationToken);
|
||||
if (track != null)
|
||||
{
|
||||
matchingTrack = track;
|
||||
break;
|
||||
}
|
||||
if (canellationToken.IsCancellationRequested)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matchingTrack != null)
|
||||
{
|
||||
TrackMatchFound(matchingTrack);
|
||||
return matchingTrack;
|
||||
}
|
||||
|
||||
OnStatusUpdate("No Matches Found");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the callback with the matching track
|
||||
/// </summary>
|
||||
private void TrackMatchFound(Track matchTrack)
|
||||
{
|
||||
var artistName = !string.IsNullOrEmpty(matchTrack.PerformerIds[0])
|
||||
? _musicGuide.GetArtist(matchTrack.PerformerIds[0]).ArtistName
|
||||
: "Unknown";
|
||||
var matchAlbumInfo = _musicGuide.GetAlbum(matchTrack.AlbumId);
|
||||
var status = String.Format("Found Match: {0} - {1} - {2} - {3}", artistName, matchAlbumInfo.Title, matchTrack.TrackTitle, matchTrack.TrackLength);
|
||||
OnStatusUpdate(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.SongScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistScaper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistDiscographyPageScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistResultPageScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.AlbumResultPageScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<applicationSettings>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.SongScraper>
|
||||
<setting name="SongTitleXpath" serializeAs="String">
|
||||
<value>//*[@class='song-title']</value>
|
||||
</setting>
|
||||
<setting name="SongUrlIdRegex" serializeAs="String">
|
||||
<value>[a-zA-Z]{2}[0-9]+(?=$)</value>
|
||||
</setting>
|
||||
<setting name="ArtistUrlXpath" serializeAs="String">
|
||||
<value>//*[@class='song-artist']/a/@href</value>
|
||||
</setting>
|
||||
<setting name="ArtistUrIdRegex" serializeAs="String">
|
||||
<value>[a-zA-Z]{2}[0-9]+(?=$)</value>
|
||||
</setting>
|
||||
<setting name="SongUrlIdXpath" serializeAs="String">
|
||||
<value>//link[@rel='canonical']/@href</value>
|
||||
</setting>
|
||||
<setting name="ArtistXpath" serializeAs="String">
|
||||
<value>//*[@class='song-artist']/a</value>
|
||||
</setting>
|
||||
<setting name="SongUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/song/{0}</value>
|
||||
</setting>
|
||||
<setting name="AlbumXpath" serializeAs="String">
|
||||
<value>//*[@id='appearances']//tbody/tr</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.SongScraper>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistScaper>
|
||||
<setting name="ArtistUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/artist/{0}</value>
|
||||
</setting>
|
||||
<setting name="DiscographyAlbumUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/artist/{0}/overview/main</value>
|
||||
</setting>
|
||||
<setting name="ArtistIdXpath" serializeAs="String">
|
||||
<value>//*[@class='id-details']//*[contains(.,'Rovi Music ID')]/following-sibling::*[1]</value>
|
||||
</setting>
|
||||
<setting name="GenreXpath" serializeAs="String">
|
||||
<value>//*[@class='genres']//a</value>
|
||||
</setting>
|
||||
<setting name="StylesXpath" serializeAs="String">
|
||||
<value>//*[@class='styles']//a</value>
|
||||
</setting>
|
||||
<setting name="ArtistXpath" serializeAs="String">
|
||||
<value>//*[@class='artist-name']/text()</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistScaper>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistDiscographyPageScraper>
|
||||
<setting name="DiscographyXpath" serializeAs="String">
|
||||
<value>//table[contains(@class,'album-table')]/tbody/tr</value>
|
||||
</setting>
|
||||
<setting name="DiscographyAlbumUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/artist/{0}/overview/main</value>
|
||||
</setting>
|
||||
<setting name="DiscographyEpSinglesUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/artist/{0}/overview/singles</value>
|
||||
</setting>
|
||||
<setting name="DiscographyCompilationUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/artist/{0}/overview/compilations</value>
|
||||
</setting>
|
||||
<setting name="ReleaseTypeXpath" serializeAs="String">
|
||||
<value>//*[@id="discography"]//ul[@class='sub-tabs']/li[contains(@class,'active')]/@class</value>
|
||||
</setting>
|
||||
<setting name="ReleaseTypeRegex" serializeAs="String">
|
||||
<value>.*(?=\sactive)</value>
|
||||
</setting>
|
||||
<setting name="ArtistXpath" serializeAs="String">
|
||||
<value>//*[@class='artist-name']/text()</value>
|
||||
</setting>
|
||||
<setting name="ArtistIdXpath" serializeAs="String">
|
||||
<value>//*[@class='id-details']//*[contains(.,'Rovi Music ID')]/following-sibling::*[1]</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistDiscographyPageScraper>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper>
|
||||
<setting name="SongResultUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/search/ajax_results/songs/{0}</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistResultPageScraper>
|
||||
<setting name="ArtistResultUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/search/ajax_results/artists/{0}</value>
|
||||
</setting>
|
||||
<setting name="ArtistXpath" serializeAs="String">
|
||||
<value>//*[contains(@class,'right-of-image')]</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.ArtistResultPageScraper>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.AlbumResultPageScraper>
|
||||
<setting name="AlbumXpath" serializeAs="String">
|
||||
<value>//*[contains(@class,'right-of-image')]</value>
|
||||
</setting>
|
||||
<setting name="AlbumResultUrl" serializeAs="String">
|
||||
<value>http://www.allmusic.com/search/ajax_results/albums/{0}</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.AlbumResultPageScraper>
|
||||
</applicationSettings>
|
||||
<userSettings>
|
||||
<MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper>
|
||||
<setting name="SongXpath" serializeAs="String">
|
||||
<value>//*[contains(@class,'right-of-image')]</value>
|
||||
</setting>
|
||||
</MusicMetaTagger.Client.AllMusicGuide.Properties.SongResultPageScraper>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net40" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user