MediaLibrary: Refactoring web search API (Lombiq Technologies: ORCH-206), fixes #7118 (#8229)

Fixes #7118
This commit is contained in:
Milán Keszthelyi
2019-07-04 21:04:35 +02:00
committed by Sébastien Ros
parent 902ad928ad
commit 89c562c502
40 changed files with 889 additions and 122 deletions

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Controllers.Api {
[Header("User-Agent", "RestEase")]
public interface IBingApi {
[Get("bing/v7.0/images/search")]
Task<string> GetImagesAsync([Header("Ocp-Apim-Subscription-Key")] string apiKey, string q);
}
}

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Controllers.Api {
[Header("User-Agent", "RestEase")]
public interface IGoogleApi {
[Get("customsearch/v1")]
Task<string> GetImagesAsync(string key, string cx, string q, string searchType = "image");
}
}

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Controllers.Api {
[Header("User-Agent", "RestEase")]
public interface IPixabayApi {
[Get("api/")]
Task<string> GetImagesAsync(string key, string q);
}
}

View File

@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using Orchard.MediaLibrary.WebSearch.Providers;
using Orchard.Security;
namespace Orchard.MediaLibrary.WebSearch.Controllers.Api {
public class WebSearchApiController : ApiController {
private readonly IAuthorizer _authorizer;
private readonly IEnumerable<IWebSearchProvider> _wsp;
public WebSearchApiController(IAuthorizer authorizer, IEnumerable<IWebSearchProvider> wsp) {
_authorizer = authorizer;
_wsp = wsp;
}
[HttpGet]
public IHttpActionResult GetImages(string query, string providerType) {
if (!_authorizer.Authorize(Permissions.AccessMediaWebSearch)) {
return StatusCode(HttpStatusCode.Unauthorized);
}
var selectedProvider = _wsp.FirstOrDefault(provider => provider.Name == providerType);
if (selectedProvider == null || !selectedProvider.IsValid()) {
return NotFound();
}
return Json(selectedProvider.GetImages(query));
}
}
}

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Net;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.Media;
using Orchard.Localization;
using Orchard.MediaLibrary.Models;
@@ -13,6 +14,7 @@ using Orchard.UI.Admin;
namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)]
[OrchardFeature("Orchard.MediaLibrary.WebSearch")]
public class WebSearchController : Controller {
private readonly IMediaLibraryService _mediaLibraryService;
private readonly IContentManager _contentManager;

View File

@@ -0,0 +1,10 @@
using System;
using Orchard.MediaLibrary.WebSearch.Providers;
namespace Orchard.MediaLibrary.WebSearch {
public static class WebSearchProviderExtensions {
public static string GetApiKey(this IWebSearchProvider provider) => provider.Settings.ApiKey;
public static bool IsValid(this IWebSearchProvider provider) => !String.IsNullOrEmpty(provider.GetApiKey());
}
}

View File

@@ -0,0 +1,13 @@
using Orchard.ContentManagement.Handlers;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Models;
namespace Orchard.MediaLibrary.WebSearch.Handlers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Bing")]
public class BingWebSearchSettingsPartHandler : ContentHandler {
public BingWebSearchSettingsPartHandler() {
Filters.Add(new ActivatingFilter<BingWebSearchSettingsPart>("Site"));
Filters.Add(new TemplateFilterForPart<BingWebSearchSettingsPart>("BingWebSearchSettings", "Parts/WebSearch.BingWebSearchSettings", "media"));
}
}
}

View File

@@ -0,0 +1,13 @@
using Orchard.ContentManagement.Handlers;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Models;
namespace Orchard.MediaLibrary.WebSearch.Handlers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Google")]
public class GoogleWebSearchSettingsPartHandler : ContentHandler {
public GoogleWebSearchSettingsPartHandler() {
Filters.Add(new ActivatingFilter<GoogleWebSearchSettingsPart>("Site"));
Filters.Add(new TemplateFilterForPart<GoogleWebSearchSettingsPart>("GoogleWebSearchSettings", "Parts/WebSearch.GoogleWebSearchSettings", "media"));
}
}
}

View File

@@ -0,0 +1,13 @@
using Orchard.ContentManagement.Handlers;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Models;
namespace Orchard.MediaLibrary.WebSearch.Handlers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Pixabay")]
public class PixabayWebSearchSettingsPartHandler : ContentHandler {
public PixabayWebSearchSettingsPartHandler() {
Filters.Add(new ActivatingFilter<PixabayWebSearchSettingsPart>("Site"));
Filters.Add(new TemplateFilterForPart<PixabayWebSearchSettingsPart>("PixabayWebSearchSettings", "Parts/WebSearch.PixabayWebSearchSettings", "media"));
}
}
}

View File

@@ -0,0 +1,17 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Environment.Extensions;
using Orchard.Localization;
namespace Orchard.MediaLibrary.WebSearch.Handlers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch")]
public class WebSearchSettingsPartHandler : ContentHandler {
public Localizer T { get; set; }
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
if (context.ContentItem.ContentType != "Site") return;
base.GetItemMetadata(context);
context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Media")));
}
}
}

View File

@@ -0,0 +1,6 @@
using Orchard.Environment.Extensions;
namespace Orchard.MediaLibrary.WebSearch.Models {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Bing")]
public class BingWebSearchSettingsPart : WebSearchSettingsBase { }
}

View File

@@ -0,0 +1,12 @@
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
namespace Orchard.MediaLibrary.WebSearch.Models {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Google")]
public class GoogleWebSearchSettingsPart : WebSearchSettingsBase {
public string SearchEngineId {
get => this.Retrieve(x => x.SearchEngineId);
set => this.Store(x => x.SearchEngineId, value);
}
}
}

View File

@@ -0,0 +1,5 @@
namespace Orchard.MediaLibrary.WebSearch.Models {
public interface IWebSearchSettings {
string ApiKey { get; set; }
}
}

View File

@@ -0,0 +1,6 @@
using Orchard.Environment.Extensions;
namespace Orchard.MediaLibrary.WebSearch.Models {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Pixabay")]
public class PixabayWebSearchSettingsPart : WebSearchSettingsBase { }
}

View File

@@ -0,0 +1,10 @@
using Orchard.ContentManagement;
namespace Orchard.MediaLibrary.WebSearch.Models {
public abstract class WebSearchSettingsBase : ContentPart, IWebSearchSettings {
public string ApiKey {
get => this.Retrieve(x => x.ApiKey);
set => this.Store(x => x.ApiKey, value);
}
}
}

View File

@@ -0,0 +1,27 @@
Name: Orchard.MediaLibrary.WebSearch
AntiForgery: enabled
Author: The Orchard Team, Lombiq Technologies Ltd.
Website: https://orchardproject.net
Version: 1.0
OrchardVersion: 1.10.3
Features:
Orchard.MediaLibrary.WebSearch:
Description: Base functionality for Orchard to be able import images from web search results to the Media Library.
Category: Media
Name: Media Library Web Search
Dependencies: Orchard.MediaLibrary
Orchard.MediaLibrary.WebSearch.Bing:
Description: Bing web search provider for importing images to the Media Library.
Category: Media
Name: Media Library Web Search - Bing
Dependencies: Orchard.MediaLibrary.WebSearch
Orchard.MediaLibrary.WebSearch.Pixabay:
Description: Pixabay web search provider for importing images to the Media Library.
Category: Media
Name: Media Library Web Search - Pixabay
Dependencies: Orchard.MediaLibrary.WebSearch
Orchard.MediaLibrary.WebSearch.Google:
Description: Google web search provider for importing images to the Media Library.
Category: Media
Name: Media Library Web Search - Google
Dependencies: Orchard.MediaLibrary.WebSearch

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{8EE141BE-7217-4F5B-8214-3146BEFA07E3}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.MediaLibrary.WebSearch</RootNamespace>
<AssemblyName>Orchard.MediaLibrary.WebSearch</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>4.0</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<Use64BitIISExpress />
<UseGlobalApplicationHostFile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
<CodeAnalysisRuleSet>..\..\..\OrchardBasicCorrectness.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="RestEase, Version=1.4.9.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\RestEase.1.4.9\lib\net45\RestEase.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\Api\IGoogleApi.cs" />
<Compile Include="Controllers\Api\WebSearchApiController.cs" />
<Compile Include="Controllers\WebSearchController.cs" />
<Compile Include="Extensions\WebSearchProviderExtensions.cs" />
<Compile Include="Handlers\GoogleWebSearchSettingsPartHandler.cs" />
<Compile Include="Handlers\BingWebSearchSettingsPartHandler.cs" />
<Compile Include="Handlers\PixabayWebSearchSettingsPartHandler.cs" />
<Compile Include="Handlers\WebSearchSettingsPartHandler.cs" />
<Compile Include="Controllers\Api\IBingApi.cs" />
<Compile Include="Controllers\Api\IPixabayApi.cs" />
<Compile Include="Models\GoogleWebSearchSettingsPart.cs" />
<Compile Include="Models\PixabayWebSearchSettingsPart.cs" />
<Compile Include="Models\BingWebSearchSettingsPart.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\GoogleWebSearchProvider.cs" />
<Compile Include="Providers\IWebSearchProvider.cs" />
<Compile Include="Providers\PixabayWebSearchProvider.cs" />
<Compile Include="Providers\WebSearchMenu.cs" />
<Compile Include="Providers\BingWebSearchProvider.cs" />
<Compile Include="Models\IWebSearchSettings.cs" />
<Compile Include="Models\WebSearchSettingsBase.cs" />
<Compile Include="ViewModels\WebSearchResult.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Styles\Images\ajax-loader.gif" />
<Content Include="Styles\menu.websearch-mediaproviders.css" />
<Content Include="Styles\orchard-websearch-admin.css" />
<Content Include="packages.config" />
<Content Include="Web.config" />
<Content Include="Styles\Web.config" />
<Content Include="Module.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard.Framework</Name>
<Private>$(MvcBuildViews)</Private>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name>
<Private>$(MvcBuildViews)</Private>
</ProjectReference>
<ProjectReference Include="..\Orchard.MediaLibrary\Orchard.MediaLibrary.csproj">
<Project>{73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b}</Project>
<Name>Orchard.MediaLibrary</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\WebSearch\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\WebSearch.PixabayWebSearchSettings.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\WebSearch.BingWebSearchSettings.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\WebSearch.GoogleWebSearchSettings.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>45979</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>https://github.com/OrchardCMS/Orchard</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
namespace Orchard.MediaLibrary.WebSearch {
public class Permissions : IPermissionProvider {
public static readonly Permission AccessMediaWebSearch =
new Permission { Description = "Access Media Web Search", Name = nameof(AccessMediaWebSearch), ImpliedBy = new[] { MediaLibrary.Permissions.ManageMediaContent } };
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() =>
new[] {
AccessMediaWebSearch
};
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() =>
new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] { AccessMediaWebSearch }
},
new PermissionStereotype {
Name = "Editor",
Permissions = new[] { AccessMediaWebSearch }
},
};
}
}

View File

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// 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("Orchard.MediaLibrary.WebSearch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("Orchard")]
[assembly: AssemblyCopyright("")]
[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("e4d2186b-4697-44bf-8454-9183b9df6700")]
// 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 Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.10.3")]
[assembly: AssemblyFileVersion("1.10.3")]

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Controllers.Api;
using Orchard.MediaLibrary.WebSearch.Models;
using Orchard.MediaLibrary.WebSearch.ViewModels;
using Orchard.Services;
using Orchard.Settings;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Providers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Bing")]
public class BingWebSearchProvider : IWebSearchProvider {
private const string BingBaseUrl = "https://api.cognitive.microsoft.com";
private readonly ISiteService _siteService;
private readonly IJsonConverter _jsonConverter;
public BingWebSearchProvider(ISiteService siteService, IJsonConverter jsonConverter) {
_siteService = siteService;
_jsonConverter = jsonConverter;
}
private BingWebSearchSettingsPart _settings =>
_siteService.GetSiteSettings().As<BingWebSearchSettingsPart>();
public IWebSearchSettings Settings => _settings;
public string Name => "Bing";
public IEnumerable<WebSearchResult> GetImages(string query) {
var client = RestClient.For<IBingApi>(BingBaseUrl);
var apiResponse = client.GetImagesAsync(this.GetApiKey(), query);
var apiResult = _jsonConverter.Deserialize<dynamic>(apiResponse.Result);
var webSearchResult = new List<WebSearchResult>();
foreach (var hit in apiResult.value) {
string imageSize = hit.contentSize;
webSearchResult.Add(new WebSearchResult() {
ThumbnailUrl = hit.thumbnailUrl,
Width = hit.width,
Height = hit.height,
ImageUrl = hit.contentUrl,
Size = int.Parse(imageSize.Substring(0, imageSize.Length - 2)),
PageUrl = hit.hostPageUrl
});
}
return webSearchResult.Any() ? webSearchResult : Enumerable.Empty<WebSearchResult>();
}
}
}

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Controllers.Api;
using Orchard.MediaLibrary.WebSearch.Models;
using Orchard.MediaLibrary.WebSearch.ViewModels;
using Orchard.Services;
using Orchard.Settings;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Providers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Google")]
public class GoogleWebSearchProvider : IWebSearchProvider {
private const string GoogleBaseUrl = "https://www.googleapis.com";
private readonly ISiteService _siteService;
private readonly IJsonConverter _jsonConverter;
public GoogleWebSearchProvider(ISiteService siteService, IJsonConverter jsonConverter) {
_siteService = siteService;
_jsonConverter = jsonConverter;
}
private GoogleWebSearchSettingsPart _settings =>
_siteService.GetSiteSettings().As<GoogleWebSearchSettingsPart>();
public IWebSearchSettings Settings => _settings;
public string Name => "Google";
public IEnumerable<WebSearchResult> GetImages(string query) {
var client = RestClient.For<IGoogleApi>(GoogleBaseUrl);
var apiResponse = client.GetImagesAsync(this.GetApiKey(), _settings.SearchEngineId, query);
var apiResult = _jsonConverter.Deserialize<dynamic>(apiResponse.Result);
var webSearchResult = new List<WebSearchResult>();
foreach (var hit in apiResult.items) {
string imageSize = hit.contentSize;
webSearchResult.Add(new WebSearchResult() {
ThumbnailUrl = hit.image.thumbnailLink,
Width = hit.image.width,
Height = hit.image.height,
ImageUrl = hit.link,
Size = hit.image.byteSize,
PageUrl = hit.image.contextLink
});
}
return webSearchResult.Any() ? webSearchResult : Enumerable.Empty<WebSearchResult>();
}
}
}

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using Orchard.MediaLibrary.WebSearch.Models;
using Orchard.MediaLibrary.WebSearch.ViewModels;
namespace Orchard.MediaLibrary.WebSearch.Providers {
public interface IWebSearchProvider : IDependency {
string Name { get; }
IWebSearchSettings Settings { get; }
IEnumerable<WebSearchResult> GetImages(string query);
}
}

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
using Orchard.MediaLibrary.WebSearch.Controllers.Api;
using Orchard.MediaLibrary.WebSearch.Models;
using Orchard.MediaLibrary.WebSearch.ViewModels;
using Orchard.Services;
using Orchard.Settings;
using RestEase;
namespace Orchard.MediaLibrary.WebSearch.Providers {
[OrchardFeature("Orchard.MediaLibrary.WebSearch.Pixabay")]
public class PixabayWebSearchProvider : IWebSearchProvider {
private const string PixabayBaseUrl = "https://pixabay.com";
private readonly ISiteService _siteService;
private readonly IJsonConverter _jsonConverter;
public PixabayWebSearchProvider(ISiteService siteService, IJsonConverter jsonConverter) {
_siteService = siteService;
_jsonConverter = jsonConverter;
}
public string Name => "Pixabay";
private PixabayWebSearchSettingsPart _settings =>
_siteService.GetSiteSettings().As<PixabayWebSearchSettingsPart>();
public IWebSearchSettings Settings => _settings;
public IEnumerable<WebSearchResult> GetImages(string query) {
var client = RestClient.For<IPixabayApi>(PixabayBaseUrl);
var apiResponse = client.GetImagesAsync(this.GetApiKey(), query);
var apiResult = _jsonConverter.Deserialize<dynamic>(apiResponse.Result);
var webSearchResult = new List<WebSearchResult>();
foreach (var hit in apiResult.hits) {
webSearchResult.Add(new WebSearchResult() {
ThumbnailUrl = hit.previewURL,
Width = hit.imageWidth,
Height = hit.imageHeight,
ImageUrl = hit.largeImageURL,
Size = hit.imageSize,
PageUrl = hit.pageURL
});
}
return webSearchResult.Any() ? webSearchResult : Enumerable.Empty<WebSearchResult>();
}
}
}

View File

@@ -1,7 +1,7 @@
using Orchard.Localization;
using Orchard.UI.Navigation;
namespace Orchard.MediaLibrary.Providers {
namespace Orchard.MediaLibrary.WebSearch.Providers {
public class WebSearchMenu : INavigationProvider {
public Localizer T { get; set; }
@@ -14,9 +14,8 @@ namespace Orchard.MediaLibrary.Providers {
public void GetNavigation(NavigationBuilder builder) {
builder.AddImageSet("websearch")
.Add(T("Web Search"), "7",
menu => menu.Action("Index", "WebSearch", new { area = "Orchard.MediaLibrary" })
.Permission(Permissions.ManageOwnMedia)
.Permission(Permissions.ImportMediaContent));
menu => menu.Action("Index", "WebSearch", new { area = "Orchard.MediaLibrary.WebSearch" })
.Permission(Permissions.AccessMediaWebSearch));
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>
<handlers accessPolicy="Script,Read">
<!-- For any request to a file exists on disk, return it via native http module. AccessPolicy="Script" above is to allow for a managed 404 page. -->
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
</handlers>
</system.webServer>
</configuration>

View File

@@ -66,6 +66,14 @@
padding-left: 5px;
}
#websearch-results .overlay .filename {
overflow: hidden;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
/* PROPERTIES */
#websearch-properties {
@@ -153,16 +161,17 @@
/* SEARCH */
.query-container {
display: flex;
margin: 5px;
width: 90%;
margin-bottom: 10px;
}
#query {
margin-right: 40px;
.media-websearch-input-field {
width: 100%;
}
#query input {
.media-websearch-input-field input {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
@@ -170,12 +179,11 @@
height: 28px;
}
#icon {
float: right;
.media-websearch-search-icon {
width: 40px;
}
#icon button {
.media-websearch-search-icon button {
height: 28px;
width: 40px;
border: none;
@@ -188,6 +196,15 @@
font-size: 18px;
}
.media-websearch-api-selector-container {
margin-left: 10px;
}
.media-websearch-api-selector-container .media-websearch-api-selector {
padding-top: 5px;
padding-bottom: 5px;
}
.actions {
margin-top: 5px;
}

View File

@@ -0,0 +1,10 @@
namespace Orchard.MediaLibrary.WebSearch.ViewModels {
public class WebSearchResult {
public string ThumbnailUrl { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string ImageUrl { get; set; }
public int Size { get; set; }
public string PageUrl { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
@model Orchard.MediaLibrary.WebSearch.Models.BingWebSearchSettingsPart
<fieldset>
<legend>@T("Bing Web Search")</legend>
<div>
@Html.TextBoxFor(m => m.ApiKey, new { type = "password", @class = "text medium"})
<span class="hint">@T("Your private key.")</span>
</div>
@T("Get a free API Key on {0}.", Html.Raw("<a href=\"https://azure.microsoft.com/en-us/services/cognitive-services/bing-web-search-api\">Azure</a>"))
</fieldset>

View File

@@ -0,0 +1,14 @@
@model Orchard.MediaLibrary.WebSearch.Models.GoogleWebSearchSettingsPart
<fieldset>
<legend>@T("Google Web Search")</legend>
<div>
@Html.TextBoxFor(m => m.ApiKey, new { type = "password", @class = "text medium"})
<span class="hint">@T("Your private key.")</span>
@Html.TextBoxFor(m => m.SearchEngineId, new { type = "password", @class = "text medium"})
<span class="hint">@T("Your search engine ID aka cx.")</span>
</div>
@T("Get a free API Key on {0}. Also, you need to create custom search engine at {1} based on your search criteria.", Html.Raw("<a href=\"https://console.developers.google.com/\">Google API Console</a>"), Html.Raw("<a href=\"https://cse.google.com/cse/create/new\">Google Custom Search<a>"))
</fieldset>

View File

@@ -0,0 +1,11 @@
@model Orchard.MediaLibrary.WebSearch.Models.PixabayWebSearchSettingsPart
<fieldset>
<legend>@T("Pixabay Web Search")</legend>
<div>
@Html.TextBoxFor(m => m.ApiKey, new { type = "password", @class = "text medium" })
<span class="hint">@T("Your private key.")</span>
</div>
@T("Get a free API Key on {0}.", Html.Raw("<a href=\"https://pixabay.com/api/docs\">Pixabay</a>"))
</fieldset>

View File

@@ -1,8 +1,8 @@
@model Orchard.MediaLibrary.ViewModels.ImportMediaViewModel
@using System.Text
@using Orchard.ContentManagement
@using Orchard.MediaLibrary.Models
@using Orchard.MediaLibrary.WebSearch
@using Orchard.MediaLibrary.WebSearch.Providers
@using System.Linq
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
@@ -14,57 +14,77 @@
Style.Include("orchard-mediaproviders-admin.css");
Style.Include("orchard-websearch-admin.css");
Style.Require("FontAwesome");
var webSearchProviders = WorkContext.Resolve<IEnumerable<IWebSearchProvider>>();
var hasValidProvider = webSearchProviders.Any();
var hasValidApiKey = webSearchProviders.Any(provider => provider.IsValid());
var apiNames = webSearchProviders.Select(provider => provider.Name);
}
@Display.Metas()
@Display.HeadScripts()
@Display.HeadLinks()
@Display.StyleSheetLinks()
@{
var apiKey = WorkContext.CurrentSite.As<WebSearchSettingsPart>().ApiKey;
}
</head>
<body>
<div id="websearch-main">
<!-- Register for an API account on https://datamarket.azure.com/dataset/5BA839F1-12CE-4CCE-BF57-A49D98D29A44 -->
@if (String.IsNullOrWhiteSpace(apiKey)) {
@if (!hasValidProvider)
{
<div id="message-api">
@T("You need to enable a Web Search provider feature like \"Media Library Web Search - Bing\".")
</div>
return;
}
@if (!hasValidApiKey)
{
<div id="message-api">
@T("You need to define an API Key in the Media settings before being able to use this feature.")
</div>
return;
}
<form data-bind="submit: doSearch">
<div class="query-container">
<div id="icon">
<div id="query" class="media-websearch-input-field">
<input type="text" autofocus placeholder="@T("Search")" />
</div>
<div id="icon" class="media-websearch-search-icon">
<button type="submit" class="fa fa-search"></button>
</div>
<div id="query">
<input type="text" autofocus placeholder="@T("search")"/>
<div id="media-websearch-api-selector-container" class="media-websearch-api-selector-container">
<select id="media-websearch-api-selector" name="ApiNames" class="media-websearch-api-selector">
@foreach (var provider in webSearchProviders)
{
<option value="@provider.Name" @(provider.IsValid() ? "" : "disabled")>@provider.Name</option>
}
</select>
</div>
</div>
</form>
<ul id="websearch-results" data-bind="foreach: results">
<li data-bind="style: { backgroundImage: 'url(' + data.Thumbnail.MediaUrl + ')' }, css: { 'has-focus': hasFocus(), 'selected': selected() }">
<li data-bind="style: { backgroundImage: 'url(' + data.ThumbnailUrl + ')' }, css: { 'has-focus': hasFocus(), 'selected': selected() }">
<div class="overlay">
<p class="filename" data-bind="text: getFilename()"></p>
<p class="dimensions" data-bind="text: data.Width + ' x ' + data.Height + ' - ' + Math.round(data.FileSize/1024) + ' KB'"></p>
<p class="dimensions" data-bind="text: data.Width + ' x ' + data.Height + ' - ' + kilobytes() + ' KB'"></p>
</div>
</li>
</ul>
</div>
<div id="websearch-properties">
<article data-bind="with: focus">
<h1>@T("PROPERTIES")</h1>
<div class="thumbnail" data-bind="style: { backgroundImage: 'url(' + data.Thumbnail.MediaUrl + ')' }"></div>
<div class="thumbnail" data-bind="style: { backgroundImage: 'url(' + data.ThumbnailUrl + ')' }"></div>
<div class="dimensions"><em>@T("Dimensions:")</em> <span data-bind="text: data.Width + ' x ' + data.Height"></span></div>
<div class="filename"><em>@T("Filename:")</em> <span data-bind="text: getFilename()"></span></div>
<div class="filesize"><em>@T("Size:")</em> <span data-bind="text: Math.round(data.FileSize/1024) + ' KB'"></span></div>
<div class="filesize"><em>@T("Size:")</em> <span data-bind="text: kilobytes() + ' KB'"></span></div>
<div class="actions">
<a class="source button" data-bind="attr: {href: data.SourceUrl}" target="_blank">@T("Page")</a>
<a class="media button" data-bind="attr: {href: data.MediaUrl}" target="_blank">@T("Open")</a>
<a class="source button" data-bind="attr: {href: data.PageUrl}" target="_blank">@T("Page")</a>
<a class="media button" data-bind="attr: {href: data.ImageUrl}" target="_blank">@T("Open")</a>
</div>
</article>
@@ -73,7 +93,7 @@
<button id="button-import"> @if (Model.Replace == null) { <text>@T("Import")</text> } else { <text>@T("Replace")</text> } </button>
<ul data-bind="foreach: selection">
<li>
<div class="selection" data-bind="click: $parent.focus, style: { backgroundImage: 'url(' + data.Thumbnail.MediaUrl + ')' }">
<div class="selection" data-bind="click: $parent.focus, style: { backgroundImage: 'url(' + data.ThumbnailUrl + ')' }">
<div class="selection-overlay">
<div class="selection-progress" data-bind="css: status(), attr: { 'title': tooltip() == '' ? null : tooltip() }"></div>
</div>
@@ -83,7 +103,8 @@
</div>
</div>
@using(Script.Foot()) {
@using (Script.Foot())
{
<script type="text/javascript">
//<![CDATA[
$(function () {
@@ -103,12 +124,12 @@
};
self.getFilename = function () {
var value = self.data.MediaUrl;
return value.substr(value.lastIndexOf('/') + 1);
var value = self.data.ImageUrl;
return value.substr(value.lastIndexOf("/") + 1);
};
self.kilobytes = function () {
return Math.round(self.data.FileSize / 1024);
return Math.round(data.Size/1024);
};
}
@@ -120,20 +141,22 @@
self.focus = ko.observable();
self.results = ko.observableArray();
self.filename = function () {
return value.substr(value.lastIndexOf('/') + 1);
};
self.doSearch = function () {
var query = $('#query > input').val();
var url = 'https://api.datamarket.azure.com/Bing/Search/Image?$format=json&Query=%27' + encodeURIComponent(query) + '%27';
var query = $(".media-websearch-input-field > input").val();
var selectedApi = $("#media-websearch-api-selector-container > #media-websearch-api-selector").val();
var url = "@Url.HttpRouteUrl("", new { Area = "Orchard.MediaLibrary.WebSearch", Controller = "WebSearchApi" })";
$.ajax({
type: "POST",
type: "GET",
url: url,
headers: { "Authorization": "Basic @Convert.ToBase64String(Encoding.ASCII.GetBytes(":" + @apiKey))" }
data: {
query: query,
providerType: selectedApi
},
}).done(function (msg) {
var results = msg.d.results;
var results = msg;
self.clearSelection();
self.results([]);
for (var i = 0; i < results.length; i++) {
@@ -186,7 +209,6 @@
self.focus(searchResult);
};
};
var viewModel = new WebSearchViewModel();
@@ -215,9 +237,9 @@
$("#button-import").on("click", function (e) {
viewModel.selection().forEach(function (item) {
var url = item.data.MediaUrl;
item.status('uploading');
item.tooltip('');
var url = item.data.ImageUrl;
item.status("uploading");
item.tooltip("");
@if (Model.Replace == null) {
<text>
$.post('@Url.Action("Import")', {
@@ -239,10 +261,10 @@
}
.done(function (data) {
if (data.error) {
item.status('failure');
item.status("failure");
item.tooltip(data.error);
} else {
item.status('success');
item.status("success");
item.tooltip("Media imported successfully.");
@if(Model.Replace != null) {
<text>
@@ -252,8 +274,8 @@
}
})
.fail(function (jqXhr, data) {
console.log('failed: ' + JSON.stringify(textStatus));
item.status('failure');
console.log("failed: " + JSON.stringify(textStatus));
item.status("failure");
})
.always(function () {
});

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
<add namespace="System.Linq" />
<add namespace="System.Collections.Generic" />
<add namespace="Orchard.Mvc.Html" />
</namespaces>
</pages>
</system.web.webPages.razor>
<!-- Registering Roslyn as a compiler for Razor IntelliSense. -->
<appSettings>
<add key="aspnet:RoslynCompilerLocation" value="..\..\bin\roslyn" />
</appSettings>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:latest" />
</compilers>
</system.codedom>
<system.web>
<compilation targetFramework="4.5.2">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="Orchard.Framework,Culture=neutral, PublicKeyToken=null" />
<add assembly="Orchard.Core,Culture=neutral, PublicKeyToken=null" />
</assemblies>
</compilation>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30AD4FE6B2A6AEED" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="AA95F207798DFDB4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863AF14B0044DA" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net452" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net452" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net452" />
<package id="RestEase" version="1.4.9" targetFramework="net452" />
</packages>

View File

@@ -1,23 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Localization;
using Orchard.MediaLibrary.Models;
namespace Orchard.MediaLibrary.Handlers {
public class WebSearchSettingsPartHandler : ContentHandler {
public WebSearchSettingsPartHandler() {
T = NullLocalizer.Instance;
Filters.Add(new ActivatingFilter<WebSearchSettingsPart>("Site"));
Filters.Add(new TemplateFilterForPart<WebSearchSettingsPart>("WebSearchSettings", "Parts/WebSearch.WebSearchSettings", "media"));
}
public Localizer T { get; set; }
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
if (context.ContentItem.ContentType != "Site")
return;
base.GetItemMetadata(context);
context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Media")));
}
}
}

View File

@@ -1,12 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.FieldStorage.InfosetStorage;
namespace Orchard.MediaLibrary.Models {
public class WebSearchSettingsPart : ContentPart {
public string ApiKey {
get { return this.As<InfosetPart>().Get<WebSearchSettingsPart>("ApiKey"); }
set { this.As<InfosetPart>().Set<WebSearchSettingsPart>("ApiKey", value); }
}
}
}

View File

@@ -113,7 +113,6 @@
<Content Include="Styles\menu.media-library-admin.css" />
<Content Include="Styles\menu.oembed-mediaproviders.css" />
<Content Include="Styles\orchard-oembed-admin.css" />
<Content Include="Styles\menu.websearch-mediaproviders.css" />
<Content Include="Styles\menu.clientstorage-mediaproviders.css" />
<Content Include="Styles\dialog-mode.css" />
<Content Include="Styles\media-library-picker-admin.css" />
@@ -122,7 +121,6 @@
<Content Include="Styles\Images\processing.gif" />
<Content Include="Styles\orchard-clientstorage-admin.css" />
<Content Include="Styles\Images\ajax-loader.gif" />
<Content Include="Styles\orchard-websearch-admin.css" />
<Content Include="Styles\orchard-mediaproviders-admin.css" />
<Content Include="Styles\orchard-medialibrary-admin.css" />
<Content Include="Web.config">
@@ -182,7 +180,6 @@
<Compile Include="Controllers\ClientStorageController.cs" />
<Compile Include="Controllers\OEmbedController.cs" />
<Compile Include="Controllers\FolderController.cs" />
<Compile Include="Controllers\WebSearchController.cs" />
<Compile Include="Drivers\AudioPartDriver.cs" />
<Compile Include="Drivers\OEmbedPartDriver.cs" />
<Compile Include="Drivers\MediaLibraryPickerFieldDriver.cs" />
@@ -200,14 +197,12 @@
<Compile Include="Handlers\MediaLibraryPickerFieldHandler.cs" />
<Compile Include="Handlers\MediaPartHandler.cs" />
<Compile Include="Drivers\MediaPartDriver.cs" />
<Compile Include="Handlers\WebSearchSettingsPartHandler.cs" />
<Compile Include="Migrations.cs" />
<Compile Include="Models\AudioPart.cs" />
<Compile Include="Models\FolderHierarchy.cs" />
<Compile Include="Models\MediaFile.cs" />
<Compile Include="Models\MediaFolder.cs" />
<Compile Include="Models\MediaLibraryExplorerPart.cs" />
<Compile Include="Models\WebSearchSettingsPart.cs" />
<Compile Include="Models\ImagePart.cs" />
<Compile Include="Models\DocumentPart.cs" />
<Compile Include="Models\VideoPart.cs" />
@@ -217,7 +212,6 @@
<Compile Include="Permissions.cs" />
<Compile Include="Providers\ClientStorageMenu.cs" />
<Compile Include="Providers\OEmbedMenu.cs" />
<Compile Include="Providers\WebSearchMenu.cs" />
<Compile Include="ResourceManifest.cs" />
<Compile Include="Security\MediaAuthorizationEventHandler.cs" />
<Compile Include="Services\IMediaLibraryService.cs" />
@@ -255,9 +249,6 @@
<ItemGroup>
<Content Include="Views\Admin\Import.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\WebSearch\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Folder\Create.cshtml" />
</ItemGroup>
@@ -377,9 +368,6 @@
<ItemGroup>
<Content Include="Views\Media-OEmbed.Thumbnail.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\WebSearch.WebSearchSettings.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Media.Raw.cshtml" />
</ItemGroup>

View File

@@ -1,11 +0,0 @@
@model Orchard.MediaLibrary.Models.WebSearchSettingsPart
<fieldset>
<legend>@T("Web Search")</legend>
<div>
@Html.TextBoxFor(m => m.ApiKey, new { @class = "text medium"})
<span class="hint">@T("Your private key.")</span>
</div>
@T("Get a free API Key on {0}", Html.Raw("<a href=\"http://datamarket.azure.com/dataset/bing/search\">http://datamarket.azure.com/dataset/bing/search</a>"))
</fieldset>

View File

@@ -94,6 +94,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Web", "Orchard.Web\
{6BD8B2FA-F2E3-4AC8-A4C3-2925A653889A} = {6BD8B2FA-F2E3-4AC8-A4C3-2925A653889A}
{14C049FD-B35B-415A-A824-87F26B26E7FD} = {14C049FD-B35B-415A-A824-87F26B26E7FD}
{085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC} = {085948FF-0E9B-4A9A-B564-F8B8B4BDDDBC}
{8EE141BE-7217-4F5B-8214-3146BEFA07E3} = {8EE141BE-7217-4F5B-8214-3146BEFA07E3}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Framework", "Orchard\Orchard.Framework.csproj", "{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}"
@@ -285,6 +286,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.OpenId", "Orchard.W
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Glimpse", "Orchard.Web\Modules\Orchard.Glimpse\Orchard.Glimpse.csproj", "{71E17466-D937-49D7-8C7D-77CCBAB8CCF4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.MediaLibrary.WebSearch", "Orchard.Web\Modules\Orchard.MediaLibrary.WebSearch\Orchard.MediaLibrary.WebSearch.csproj", "{8EE141BE-7217-4F5B-8214-3146BEFA07E3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CodeCoverage|Any CPU = CodeCoverage|Any CPU
@@ -1138,6 +1141,16 @@ Global
{71E17466-D937-49D7-8C7D-77CCBAB8CCF4}.FxCop|Any CPU.Build.0 = Release|Any CPU
{71E17466-D937-49D7-8C7D-77CCBAB8CCF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71E17466-D937-49D7-8C7D-77CCBAB8CCF4}.Release|Any CPU.Build.0 = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Coverage|Any CPU.Build.0 = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.FxCop|Any CPU.Build.0 = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EE141BE-7217-4F5B-8214-3146BEFA07E3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1228,6 +1241,7 @@ Global
{1CC62F45-E6FF-43D5-84BF-509A1085D994} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
{42E217C1-E163-4B6B-9E8F-42BEE21B6896} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{71E17466-D937-49D7-8C7D-77CCBAB8CCF4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{8EE141BE-7217-4F5B-8214-3146BEFA07E3} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = packages\TransientFaultHandling.Core.5.1.1209.1\lib\NET4