mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-21 18:49:41 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -14,6 +14,10 @@ namespace Orchard.Tests.Stubs {
|
||||
return Directory.GetDirectories(path);
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListFiles(string path, bool recursive) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool FileExists(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ namespace Orchard.Core.Shapes {
|
||||
|
||||
var zone = context.New.Zone();
|
||||
zone.Id = "zone-" + name;
|
||||
zone.Classes.Add(zone.Id);
|
||||
zone.Classes.Add("zone");
|
||||
return zone;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
@//Model.Zones.AddRenderPartial("head:before", "HeadPreload", Model);
|
||||
@//Html.Zone("head", ":metas :styles :scripts"); %>
|
||||
@Display(Model.Head)
|
||||
<script>(function(d){d.className="dyn "+d.className.substring(7,d.length);})(document.documentElement);</script>
|
||||
<script>(function(d){d.className="dyn"+d.className.substring(6,d.className.length);})(document.documentElement);</script>
|
||||
</head>
|
||||
<body>
|
||||
@Display(Model.Body)
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace Orchard.CodeGeneration.Commands {
|
||||
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
||||
|
||||
private static readonly string[] _ignoredExtensions = new [] {
|
||||
"dll", "obj", "pdb", "exclude"
|
||||
"obj", "pdb", "exclude"
|
||||
};
|
||||
private static readonly string[] _ignoredPaths = new [] {
|
||||
"/bin/", "/obj/"
|
||||
"/obj/"
|
||||
};
|
||||
private static readonly string[] _themeDirectories = new [] {
|
||||
"", "Content", "Styles", "Scripts", "Views", "Zones"
|
||||
|
||||
@@ -11,9 +11,11 @@ namespace Orchard.Packaging {
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Gallery"), "5", menu => menu
|
||||
.Add(T("Browse Gallery"), "1.0", item => item
|
||||
.Action("Index", "Gallery", new { area = "Orchard.Packaging" }))
|
||||
.Add(T("Gallery Feeds"), "2.0", item => item
|
||||
.Add(T("Browse Modules"), "1.0", item => item
|
||||
.Action("ModulesIndex", "Gallery", new { area = "Orchard.Packaging" }))
|
||||
.Add(T("Browse Themes"), "2.0", item => item
|
||||
.Action("ThemesIndex", "Gallery", new { area = "Orchard.Packaging" }))
|
||||
.Add(T("Gallery Feeds"), "3.0", item => item
|
||||
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" })));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,10 @@ namespace Orchard.Packaging.Commands {
|
||||
Context.Output.WriteLine(T("Success"));
|
||||
}
|
||||
catch (WebException webException) {
|
||||
var text = new StreamReader(webException.Response.GetResponseStream()).ReadToEnd();
|
||||
string text = "";
|
||||
if (webException.Response != null) {
|
||||
text = new StreamReader(webException.Response.GetResponseStream()).ReadToEnd();
|
||||
}
|
||||
throw new ApplicationException(text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Orchard.Packaging.Commands {
|
||||
}
|
||||
|
||||
[CommandHelp("package install <filename>\r\n\t" + "Install a module from a package <filename>.")]
|
||||
[CommandName("package install ")]
|
||||
[CommandName("package install")]
|
||||
public void InstallPackage(string filename) {
|
||||
if (!File.Exists(filename)) {
|
||||
Context.Output.WriteLine(T("File \"{0}\" does not exist.", filename));
|
||||
|
||||
@@ -34,10 +34,14 @@ namespace Orchard.Packaging.Controllers {
|
||||
|
||||
Localizer T { get; set; }
|
||||
|
||||
public ActionResult Index() {
|
||||
public ActionResult ModulesIndex() {
|
||||
return Modules(Guid.Empty);
|
||||
}
|
||||
|
||||
public ActionResult ThemesIndex() {
|
||||
return Themes(Guid.Empty);
|
||||
}
|
||||
|
||||
public ActionResult Sources() {
|
||||
return View("Sources", new PackagingSourcesViewModel {
|
||||
Sources = _packagingSourceManager.GetSources(),
|
||||
@@ -47,7 +51,7 @@ namespace Orchard.Packaging.Controllers {
|
||||
public ActionResult Remove(Guid id) {
|
||||
_packagingSourceManager.RemoveSource(id);
|
||||
_notifier.Information(T("The feed has been removed successfully."));
|
||||
Update();
|
||||
Update(null);
|
||||
return RedirectToAction("Sources");
|
||||
}
|
||||
|
||||
@@ -90,7 +94,7 @@ namespace Orchard.Packaging.Controllers {
|
||||
|
||||
_packagingSourceManager.AddSource(new PackagingSource { Id = Guid.NewGuid(), FeedUrl = url, FeedTitle = title });
|
||||
_notifier.Information(T("The feed has been added successfully."));
|
||||
Update();
|
||||
Update(null);
|
||||
return RedirectToAction("Sources");
|
||||
}
|
||||
catch ( Exception exception ) {
|
||||
@@ -102,18 +106,28 @@ namespace Orchard.Packaging.Controllers {
|
||||
|
||||
public ActionResult Modules(Guid? sourceId) {
|
||||
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
|
||||
|
||||
|
||||
return View("Modules", new PackagingModulesViewModel {
|
||||
Modules = _packagingSourceManager.GetModuleList(selectedSource),
|
||||
Modules = _packagingSourceManager.GetModuleList(selectedSource).Where(p => p.SyndicationItem.Categories.All(c => c.Name == "Orchard Module" || c.Name != "Orchard Theme")),
|
||||
Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
|
||||
SelectedSource = selectedSource
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult Update() {
|
||||
public ActionResult Themes(Guid? sourceId) {
|
||||
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
|
||||
|
||||
return View("Themes", new PackagingModulesViewModel {
|
||||
Modules = _packagingSourceManager.GetModuleList(selectedSource).Where(p => p.SyndicationItem.Categories.Any(c => c.Name == "Orchard Theme")),
|
||||
Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
|
||||
SelectedSource = selectedSource
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult Update(string cameFrom) {
|
||||
_packagingSourceManager.UpdateLists();
|
||||
_notifier.Information(T("List of available modules and themes is updated."));
|
||||
return RedirectToAction("Index");
|
||||
return RedirectToAction(cameFrom == "Themes" ? "ThemesIndex" : "ModulesIndex");
|
||||
}
|
||||
|
||||
public ActionResult Harvest(string extensionName, string feedUrl) {
|
||||
@@ -147,16 +161,16 @@ namespace Orchard.Packaging.Controllers {
|
||||
_packageManager.Push(packageData, model.FeedUrl, model.User, model.Password);
|
||||
_notifier.Information(T("Harvested {0} and published onto {1}", model.ExtensionName, model.FeedUrl));
|
||||
|
||||
Update();
|
||||
Update(null);
|
||||
|
||||
return RedirectToAction("Harvest", new { model.ExtensionName, model.FeedUrl });
|
||||
}
|
||||
|
||||
public ActionResult Install(string syndicationId) {
|
||||
public ActionResult Install(string syndicationId, string cameFrom) {
|
||||
var packageData = _packageManager.Download(syndicationId);
|
||||
_packageManager.Install(packageData.PackageStream);
|
||||
_notifier.Information(T("Installed module"));
|
||||
return RedirectToAction("Modules");
|
||||
return RedirectToAction(cameFrom == "Themes" ? "ThemesIndex" : "ModulesIndex");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Gallery\Themes.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
@@ -16,6 +18,19 @@ namespace Orchard.Packaging.Services {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
|
||||
private static readonly string[] _ignoredThemeExtensions = new[] {
|
||||
"obj", "pdb", "exclude"
|
||||
};
|
||||
private static readonly string[] _ignoredThemePaths = new[] {
|
||||
"/obj/"
|
||||
};
|
||||
|
||||
private static bool IgnoreFile(string filePath) {
|
||||
return String.IsNullOrEmpty(filePath) ||
|
||||
_ignoredThemePaths.Any(filePath.Contains) ||
|
||||
_ignoredThemeExtensions.Contains(Path.GetExtension(filePath) ?? "");
|
||||
}
|
||||
|
||||
public PackageBuilder(IExtensionManager extensionManager, IWebSiteFolder webSiteFolder) {
|
||||
_extensionManager = extensionManager;
|
||||
_webSiteFolder = webSiteFolder;
|
||||
@@ -27,7 +42,7 @@ namespace Orchard.Packaging.Services {
|
||||
var context = new CreateContext();
|
||||
BeginPackage(context);
|
||||
try {
|
||||
EstablishPaths(context, _webSiteFolder, extensionDescriptor.Location, extensionDescriptor.Name);
|
||||
EstablishPaths(context, _webSiteFolder, extensionDescriptor.Location, extensionDescriptor.Name, extensionDescriptor.ExtensionType);
|
||||
SetCoreProperties(context, extensionDescriptor);
|
||||
|
||||
string projectFile = extensionDescriptor.Name + ".csproj";
|
||||
@@ -36,6 +51,10 @@ namespace Orchard.Packaging.Services {
|
||||
EmbedProjectFiles(context, "Compile", "Content", "None", "EmbeddedResource");
|
||||
EmbedReferenceFiles(context);
|
||||
}
|
||||
else if (extensionDescriptor.ExtensionType == "Theme") {
|
||||
// this is a simple theme with no csproj
|
||||
EmbedThemeFiles(context);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EndPackage(context);
|
||||
@@ -110,6 +129,21 @@ namespace Orchard.Packaging.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private void EmbedThemeFiles(CreateContext context) {
|
||||
var basePath = context.SourcePath;
|
||||
foreach (var virtualPath in context.SourceFolder.ListFiles(context.SourcePath, true)) {
|
||||
// ignore dlls, etc
|
||||
if (IgnoreFile(virtualPath)) {
|
||||
continue;
|
||||
}
|
||||
// full virtual path given but we need the relative path so it can be put into
|
||||
// the package that way (the package itself is the logical base path).
|
||||
// Get it by stripping the basePath off including the slash.
|
||||
var relativePath = virtualPath.Replace(basePath, "");
|
||||
EmbedVirtualFile(context, relativePath, MediaTypeNames.Application.Octet);
|
||||
}
|
||||
}
|
||||
|
||||
private XName Ns(string localName) {
|
||||
return XName.Get(localName, "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
}
|
||||
@@ -120,9 +154,14 @@ namespace Orchard.Packaging.Services {
|
||||
context.Package = Package.Open(context.Stream, FileMode.Create, FileAccess.ReadWrite);
|
||||
}
|
||||
|
||||
private static void EstablishPaths(CreateContext context, IWebSiteFolder webSiteFolder, string locationPath, string moduleName) {
|
||||
private static void EstablishPaths(CreateContext context, IWebSiteFolder webSiteFolder, string locationPath, string moduleName, string moduleType) {
|
||||
context.SourceFolder = webSiteFolder;
|
||||
context.SourcePath = "~/Modules/" + moduleName + "/";
|
||||
if (moduleType == "Theme") {
|
||||
context.SourcePath = "~/Themes/" + moduleName + "/";
|
||||
}
|
||||
else {
|
||||
context.SourcePath = "~/Modules/" + moduleName + "/";
|
||||
}
|
||||
context.TargetPath = "\\" + moduleName + "\\";
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace Orchard.Packaging.Services {
|
||||
ExtractProjectFiles(context, "Compile", "Content", "None", "EmbeddedResource");
|
||||
ExtractReferenceFiles(context);
|
||||
}
|
||||
else if (context.ExtensionType == "Theme") {
|
||||
// this is a simple theme with no csproj
|
||||
ExtractThemeFiles(context);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EndPackage(context);
|
||||
@@ -108,6 +112,14 @@ namespace Orchard.Packaging.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractThemeFiles(ExpandContext context) {
|
||||
foreach (var relativePath in from p in context.Package.GetParts()
|
||||
where p.Uri.ToString().StartsWith("/" + context.ExtensionName + "/", StringComparison.OrdinalIgnoreCase)
|
||||
select p.Uri.ToString().Substring(("/" + context.ExtensionName + "/").Length)) {
|
||||
ExtractFile(context, relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
private bool PartExists(ExpandContext context, string relativePath) {
|
||||
Uri projectUri = PackUriHelper.CreatePartUri(new Uri(context.SourcePath + relativePath, UriKind.Relative));
|
||||
return context.Package.PartExists(projectUri);
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Orchard.Packaging.Services {
|
||||
}
|
||||
|
||||
public IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null) {
|
||||
IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new[] { packagingSource } )
|
||||
return (packagingSource == null ? GetSources() : new[] {packagingSource})
|
||||
.SelectMany(
|
||||
source =>
|
||||
Bind(ParseFeed(GetModuleListForSource(source)),
|
||||
@@ -64,11 +64,8 @@ namespace Orchard.Packaging.Services {
|
||||
Source = source,
|
||||
SyndicationFeed = feed,
|
||||
SyndicationItem = item,
|
||||
PackageStreamUri = item.Links.Single().GetAbsoluteUri().AbsoluteUri,
|
||||
}))));
|
||||
|
||||
|
||||
return packageInfos.ToArray();
|
||||
PackageStreamUri = item.Links.Where(l => String.IsNullOrEmpty(l.RelationshipType)).FirstOrDefault().GetAbsoluteUri().AbsoluteUri,
|
||||
})))).ToArray();
|
||||
}
|
||||
|
||||
private string GetModuleListForSource(PackagingSource source) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@model Orchard.Packaging.ViewModels.PackagingModulesViewModel
|
||||
@{ Style.Require("PackagingAdmin"); }
|
||||
|
||||
<h1>@Html.TitleForPage(T("Browse Gallery").ToString())</h1>
|
||||
<h1>@Html.TitleForPage(T("Browse Gallery - Modules").ToString())</h1>
|
||||
|
||||
<div class="manage">@Html.ActionLink(T("Refresh").ToString(), "Update", new object{}, new { @class = "button primaryAction" })</div>
|
||||
<div class="manage">@Html.ActionLink(T("Refresh").ToString(), "Update", new { cameFrom = "Modules" }, new { @class = "button primaryAction" })</div>
|
||||
@using ( Html.BeginFormAntiForgeryPost(Url.Action("Modules", "Gallery")) ) {
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="filterResults" class="bulk-filter">@T("Feed:")</label>
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
|
||||
<div class="related">
|
||||
@Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})@T(" | ")
|
||||
@Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id},{"cameFrom", "Modules"}})@T(" | ")
|
||||
<a href="@item.PackageStreamUri">@T("Download")</a>
|
||||
</div>
|
||||
|
||||
@@ -40,5 +40,4 @@
|
||||
</div>
|
||||
</li>}
|
||||
</ul>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
@model Orchard.Packaging.ViewModels.PackagingModulesViewModel
|
||||
@{
|
||||
Style.Require("PackagingAdmin");
|
||||
Style.Require("ThemesAdmin");
|
||||
}
|
||||
|
||||
<h1>@Html.TitleForPage(T("Browse Gallery - Themes").ToString())</h1>
|
||||
|
||||
<div class="manage">@Html.ActionLink(T("Refresh").ToString(), "Update", new { cameFrom = "Themes" }, new { @class = "button primaryAction" })</div>
|
||||
@using ( Html.BeginFormAntiForgeryPost(Url.Action("Themes", "Gallery")) ) {
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="filterResults" class="bulk-filter">@T("Feed:")</label>
|
||||
<select id="sourceId" name="sourceId">
|
||||
@Html.SelectOption("", Model.SelectedSource == null, T("Any (show all feeds)").ToString())
|
||||
@foreach (var source in Model.Sources) {
|
||||
Html.SelectOption(source.Id, Model.SelectedSource != null && Model.SelectedSource.Id == source.Id, source.FeedTitle);
|
||||
}
|
||||
</select>
|
||||
<button type="submit">@T("Apply")</button>
|
||||
</fieldset>
|
||||
}
|
||||
|
||||
@if (Model.Modules.Count() > 0) {
|
||||
<ul class="templates">
|
||||
@foreach (var item in Model.Modules) {
|
||||
<li>
|
||||
@{
|
||||
var author = item.SyndicationItem.Authors.Any() ? String.Join(", ", item.SyndicationItem.Authors.Select(a => a.Name)) : T("Unknown").Text;
|
||||
var title = item.SyndicationItem.Title == null ? T("(No title)").Text : item.SyndicationItem.Title.Text;
|
||||
var thumbnail = item.SyndicationItem.Links.Where(l=>l.RelationshipType=="thumbnail").Select(l=>l.Uri.ToString()).FirstOrDefault();
|
||||
}
|
||||
<div>
|
||||
<h3>@title</h3>
|
||||
@if(!String.IsNullOrEmpty(thumbnail)) {
|
||||
@Html.Image(thumbnail, Html.Encode(title), null)
|
||||
}
|
||||
<br/>
|
||||
@Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id},{"cameFrom", "Themes" }}, new Dictionary<string, object> { { "class", "button" } })
|
||||
<a class="button" href="@item.PackageStreamUri">@T("Download")</a>
|
||||
<h5>@T("By") @author</h5>
|
||||
<p>
|
||||
@T("Version: {0}", "1.0")<br />
|
||||
@(item.SyndicationItem.Summary == null ? T("(No description").Text : item.SyndicationItem.Summary.Text)<br />
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Widgets.Models;
|
||||
|
||||
namespace Orchard.Widgets.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class LayerPartDriver : ContentPartDriver<LayerPart> {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Widgets.Models;
|
||||
|
||||
namespace Orchard.Widgets.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class WidgetPartDriver : ContentPartDriver<WidgetPart> {
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,9 @@ namespace Orchard.Widgets {
|
||||
public void CreateDefaultLayers() {
|
||||
IContent defaultLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Default"; t.Record.LayerRule = "true"; });
|
||||
_contentManager.Publish(defaultLayer.ContentItem);
|
||||
IContent authenticatedLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Authenticated"; t.Record.LayerRule = "Authenticated"; });
|
||||
IContent authenticatedLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Authenticated"; t.Record.LayerRule = "authenticated"; });
|
||||
_contentManager.Publish(authenticatedLayer.ContentItem);
|
||||
IContent anonymousLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Anonymous"; t.Record.LayerRule = "not Authenticated"; });
|
||||
IContent anonymousLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Anonymous"; t.Record.LayerRule = "not authenticated"; });
|
||||
_contentManager.Publish(anonymousLayer.ContentItem);
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ namespace Orchard.Widgets {
|
||||
cfg => cfg
|
||||
.WithPart("WidgetPart")
|
||||
.WithPart("BodyPart")
|
||||
.WithSetting("stereotype", "widget")
|
||||
);
|
||||
|
||||
CreateDefaultLayers();
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Drivers\LayerPartDriver.cs" />
|
||||
<Compile Include="Drivers\WidgetPartDriver.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Handlers\LayerPartHandler.cs" />
|
||||
<Compile Include="Handlers\WidgetPartHandler.cs" />
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Orchard.Widgets.RuleEngine {
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "Authenticated", StringComparison.OrdinalIgnoreCase)) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "authenticated", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Orchard.Widgets.RuleEngine {
|
||||
}
|
||||
|
||||
public void Process(RuleContext ruleContext) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "Url", StringComparison.OrdinalIgnoreCase)) {
|
||||
if (!String.Equals(ruleContext.FunctionName, "url", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,10 @@
|
||||
<Content Include="Themes\TheAdmin\Styles\images\menuOpen.gif" />
|
||||
<Content Include="Themes\TheAdmin\Styles\images\menuOpenHover.gif" />
|
||||
<Content Include="Themes\TheThemeMachine\draft.html" />
|
||||
<Content Include="Themes\TheThemeMachine\Styles\site.css" />
|
||||
<Content Include="Themes\TheThemeMachine\Theme.png" />
|
||||
<Content Include="Themes\TheThemeMachine\Theme.txt" />
|
||||
<None Include="Themes\TheThemeMachine\Views\Document.cshtml" />
|
||||
<Content Include="Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
@@ -285,17 +287,16 @@
|
||||
<Content Include="Themes\TheAdmin\Views\User.cshtml" />
|
||||
<Content Include="Themes\TheAdmin\Views\Header.cshtml" />
|
||||
<Content Include="Themes\Web.config" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Layout.cshtml" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Zone.cshtml" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Zone-Sidebar.cshtml" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Zone-Navigation.cshtml" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Menu.cshtml" />
|
||||
<Content Include="Themes\TheThemeMachine\Views\Items\Content.Blog.cshtml" />
|
||||
<None Include="Themes\TheThemeMachine\Views\Layout.cshtml" />
|
||||
<None Include="Themes\TheThemeMachine\Views\Menu.cshtml">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
<Folder Include="Themes\ClassicDark\DesignerNotes\" />
|
||||
<Folder Include="Themes\SafeMode\Content\Images\" />
|
||||
<Folder Include="Themes\TheThemeMachine\Styles\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
||||
155
src/Orchard.Web/Themes/TheThemeMachine/Styles/site.css
Normal file
155
src/Orchard.Web/Themes/TheThemeMachine/Styles/site.css
Normal file
@@ -0,0 +1,155 @@
|
||||
/* Reset
|
||||
***************************************************************/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* remember to define focus styles! */
|
||||
:focus {
|
||||
outline: 0;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
/* tables still need 'cellspacing="0"' in the markup */
|
||||
table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
}
|
||||
caption, th, td {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: "";
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: "" "";
|
||||
}
|
||||
|
||||
/* Tell the browser to render HTML 5 elements as block */
|
||||
header, footer, aside, nav, article {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Clearing Float
|
||||
***************************************************************/
|
||||
group:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.group {display: inline-block;} /* for IE/Mac */
|
||||
|
||||
/* Typography (Optional)
|
||||
***************************************************************/
|
||||
|
||||
|
||||
|
||||
/* General
|
||||
***************************************************************/
|
||||
/* Default font settings.
|
||||
The font-size 62.5% sets the base font to 10px */
|
||||
body {
|
||||
font-size: 62.5%;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
font-family: Segoe UI,Trebuchet,Arial,Sans-Serif;
|
||||
}
|
||||
|
||||
a {}
|
||||
a:link {}
|
||||
a:hover{}
|
||||
a:visited{}
|
||||
|
||||
/* Headings */
|
||||
|
||||
h1,h2,h3,h4,h5,h6 { font-weight: normal; }
|
||||
|
||||
h1 { font-size: 3em;}
|
||||
h2 { font-size: 1.3em; }
|
||||
h3 { font-size: 1.2em; }
|
||||
h4 { font-size: 1.1em; }
|
||||
h5 { font-size: 1em; }
|
||||
h6 { font-size: 1em; }
|
||||
|
||||
h1 img, h2 img, h3 img,
|
||||
h4 img, h5 img, h6 img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size:1.2em;
|
||||
line-height:2em;
|
||||
}
|
||||
|
||||
/* Structure
|
||||
***************************************************************/
|
||||
#layout-wrapper {
|
||||
width:960px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
#header {}
|
||||
#logo {}
|
||||
|
||||
|
||||
/* Navigation */
|
||||
|
||||
nav ul li {
|
||||
margin:2em 0 0 0;
|
||||
float:left;
|
||||
}
|
||||
|
||||
nav ul li a {
|
||||
font-size:1.4em;
|
||||
margin:0 1.8em;
|
||||
display:block;
|
||||
text-decoration:none;
|
||||
text-transform:uppercase;
|
||||
float:left;
|
||||
}
|
||||
|
||||
#footer {}
|
||||
|
||||
/* Main
|
||||
***************************************************************/
|
||||
|
||||
/* Secondary
|
||||
***************************************************************/
|
||||
|
||||
/* Forms
|
||||
***************************************************************/
|
||||
|
||||
/* Misc
|
||||
***************************************************************/
|
||||
|
||||
/* For testing purposes */
|
||||
|
||||
div, nav, section {
|
||||
border:1px solid #CCC;
|
||||
}
|
||||
19
src/Orchard.Web/Themes/TheThemeMachine/Views/Document.cshtml
Normal file
19
src/Orchard.Web/Themes/TheThemeMachine/Views/Document.cshtml
Normal file
@@ -0,0 +1,19 @@
|
||||
@using Orchard.Mvc.Html
|
||||
@using Orchard.UI.Resources
|
||||
@{
|
||||
RegisterLink(new LinkEntry {Type = "image/x-icon", Rel = "shortcut icon", Href = Url.Content("~/modules/orchard.themes/Content/orchard.ico")});
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="static @Html.ClassForPage()">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>@Model.Title</title>
|
||||
@Display(Model.Head)
|
||||
<script>(function(d){d.className="dyn"+d.className.substring(6,d.className.length);})(document.documentElement);</script>
|
||||
</head>
|
||||
<body>
|
||||
@// Layout (template) is in the Body zone @ the default position (nothing, zero, zilch)
|
||||
@Display(Model.Body)
|
||||
@Display(Model.Tail)
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
@using Orchard.Blogs.Extensions
|
||||
@using Orchard.UI.Resources
|
||||
@{
|
||||
RegisterLink(new LinkEntry { Rel = "wlwmanifest", Type = "application/wlwmanifest+xml", Href = Url.BlogLiveWriterManifest((string)Model.Slug) });
|
||||
RegisterLink(new LinkEntry { Rel = "EditURI", Type = "application/rsd+xml", Title = "RSD", Href = Url.BlogRsd((string)Model.Slug) });
|
||||
}
|
||||
<h1>@Html.TitleForPage((string)Model.Title)</h1>
|
||||
@Display(Model.manage)
|
||||
@Display(Model.metadata)
|
||||
@Display(Model.primary)
|
||||
@@ -1,34 +1,55 @@
|
||||
@using Orchard.UI.Resources
|
||||
@{
|
||||
Style.Include("~/themes/Classic/styles/site.css");
|
||||
Style.Include("~/themes/Classic/styles/blog.css");
|
||||
}
|
||||
<div id="wrapper">
|
||||
@// HTML.Include will render a div with a class="user-display"
|
||||
@// Can use this -> {Html.Include("User");}
|
||||
@// or the following. At least they appear to do the same thing currently. The first is a standard Html.Include, the second "displays the (New) User shape"
|
||||
@Display.User()
|
||||
@// Top Navigation and branding
|
||||
<div id="headercontainer">
|
||||
<div id="header">
|
||||
<h1>@WorkContext.CurrentSite.SiteName</h1>
|
||||
<div class="menucontainer">
|
||||
@Display(Model.Navigation)
|
||||
</div>
|
||||
<div class="clearBoth"></div>
|
||||
</div>
|
||||
</div>
|
||||
@{
|
||||
Style.Include("site.css");
|
||||
|
||||
<div id="main">
|
||||
<div id="content">
|
||||
@// Main Content
|
||||
@Display(Model.Content)
|
||||
// cool stuff goes up here
|
||||
var homeUrl = Href("~/");
|
||||
|
||||
// Zone is an alias for Display
|
||||
Func<dynamic, dynamic> Zone = x => Display(x);
|
||||
|
||||
if (Model.Sidebar != null) {
|
||||
Html.AddPageClassNames(new[]{"icanhassidebar"});
|
||||
}
|
||||
}
|
||||
<div id="layout-wrapper">
|
||||
<header id="layout-header">
|
||||
@// needs to be the page title, not page (head) title...
|
||||
<h1><a href="@homeUrl">@WorkContext.CurrentSite.SiteName</a></h1>
|
||||
@if(Model.Header != null) {
|
||||
<div id="header">
|
||||
@Zone(Model.Header)
|
||||
</div>
|
||||
<div id="sidebar">
|
||||
@Display(Model.search)
|
||||
@Display(Model.sidebar)
|
||||
}
|
||||
@if(Model.Navigation != null) {
|
||||
<div id="navigation">
|
||||
@Zone(Model.Navigation)
|
||||
</div>
|
||||
@// End Content
|
||||
@Display.Footer(Navigation:Model.Navigation)
|
||||
}
|
||||
</header>
|
||||
@if(Model.Messages != null) {
|
||||
<div id="messages">
|
||||
@Zone(Model.Messages)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if(Model.Featured != null) {
|
||||
<div id="featured">
|
||||
@Zone(Model.Featured)
|
||||
</div>
|
||||
}
|
||||
@// the model content for the page is in the Content zone @ the default position (nothing, zero, zilch)
|
||||
@if(Model.Content != null) {
|
||||
<div id="content">
|
||||
@Zone(Model.Content)
|
||||
</div>
|
||||
}
|
||||
@if(Model.Sidebar != null) {
|
||||
<aside>
|
||||
@Zone(Model.Sidebar)
|
||||
</aside>
|
||||
}
|
||||
@if(Model.Footer != null) {
|
||||
<footer>
|
||||
@Zone(Model.Footer)
|
||||
</footer>
|
||||
}
|
||||
</div>
|
||||
@@ -1,13 +1,13 @@
|
||||
<!-- Model is Model.Menu from the layout (Page.Menu) -->
|
||||
<nav>
|
||||
<ul>
|
||||
<li class="first current"><a href="#">Home</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
<li><a href="#">About</a></li>
|
||||
<li><a href="#">Full Page</a></li>
|
||||
<li><a href="#">Image Page</a></li>
|
||||
<li><a href="#">Gallery Page</a></li>
|
||||
<li><a href="#">Nested Page</a></li>
|
||||
<li class="last"><a href="#">Contact</a></li>
|
||||
</ul>
|
||||
@{
|
||||
// these should move somewhere else
|
||||
Model.Id = "menu-" + Model.MenuName.ToLower();
|
||||
Model.Classes.Add(Model.Id);
|
||||
Model.Classes.Add("menu");
|
||||
var tag = Html.Resolve<Orchard.DisplayManagement.Shapes.ITagBuilderFactory>().Create(Model, "ul");
|
||||
}
|
||||
@tag.StartElement
|
||||
@DisplayChildren(Model)
|
||||
@tag.EndElement <!-- /@Model.Id -->
|
||||
</nav>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="zone zone-@Model.ZoneName">
|
||||
@Display...
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="zone zone-@Model.ZoneName">
|
||||
@Display...
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
<div class="zone zone-@Model.ZoneName">
|
||||
@Display...
|
||||
</div>
|
||||
@@ -8,6 +8,7 @@ namespace Orchard.FileSystems.WebSite {
|
||||
/// </summary>
|
||||
public interface IWebSiteFolder : IVolatileProvider {
|
||||
IEnumerable<string> ListDirectories(string virtualPath);
|
||||
IEnumerable<string> ListFiles(string virtualPath, bool recursive);
|
||||
|
||||
bool FileExists(string virtualPath);
|
||||
string ReadFile(string virtualPath);
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
|
||||
namespace Orchard.FileSystems.WebSite {
|
||||
@@ -18,18 +17,26 @@ namespace Orchard.FileSystems.WebSite {
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListDirectories(string virtualPath) {
|
||||
if (!HostingEnvironment.VirtualPathProvider.DirectoryExists(virtualPath))
|
||||
if (!_virtualPathProvider.DirectoryExists(virtualPath)) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
return HostingEnvironment.VirtualPathProvider
|
||||
.GetDirectory(virtualPath)
|
||||
.Directories.OfType<VirtualDirectory>()
|
||||
.Select(d => d.VirtualPath)
|
||||
.ToArray();
|
||||
return _virtualPathProvider.ListDirectories(virtualPath);
|
||||
}
|
||||
|
||||
private IEnumerable<string> ListFiles(IEnumerable<string> directories) {
|
||||
return directories.SelectMany(d => ListFiles(d, true));
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListFiles(string virtualPath, bool recursive) {
|
||||
if (!recursive) {
|
||||
return _virtualPathProvider.ListFiles(virtualPath);
|
||||
}
|
||||
return _virtualPathProvider.ListFiles(virtualPath).Concat(ListFiles(ListDirectories(virtualPath)));
|
||||
}
|
||||
|
||||
public bool FileExists(string virtualPath) {
|
||||
return HostingEnvironment.VirtualPathProvider.FileExists(virtualPath);
|
||||
return _virtualPathProvider.FileExists(virtualPath);
|
||||
}
|
||||
|
||||
public string ReadFile(string virtualPath) {
|
||||
@@ -37,8 +44,9 @@ namespace Orchard.FileSystems.WebSite {
|
||||
}
|
||||
|
||||
public string ReadFile(string virtualPath, bool actualContent) {
|
||||
if (!HostingEnvironment.VirtualPathProvider.FileExists(virtualPath))
|
||||
if (!_virtualPathProvider.FileExists(virtualPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (actualContent) {
|
||||
var physicalPath = _virtualPathProvider.MapPath(virtualPath);
|
||||
@@ -49,7 +57,7 @@ namespace Orchard.FileSystems.WebSite {
|
||||
}
|
||||
}
|
||||
else {
|
||||
using (var stream = VirtualPathProvider.OpenFile(Normalize(virtualPath))) {
|
||||
using (var stream = _virtualPathProvider.OpenFile(Normalize(virtualPath))) {
|
||||
using (var reader = new StreamReader(stream)) {
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
@@ -74,7 +82,7 @@ namespace Orchard.FileSystems.WebSite {
|
||||
}
|
||||
}
|
||||
else {
|
||||
using (var stream = VirtualPathProvider.OpenFile(Normalize(virtualPath))) {
|
||||
using (var stream = _virtualPathProvider.OpenFile(Normalize(virtualPath))) {
|
||||
stream.CopyTo(destination);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +93,8 @@ namespace Orchard.FileSystems.WebSite {
|
||||
}
|
||||
|
||||
static string Normalize(string virtualPath) {
|
||||
// todo: use IVirtualPathProvider instance instead of static.
|
||||
// Currently IVirtualPathProvider has no way of doing normalization like this
|
||||
return HostingEnvironment.VirtualPathProvider.GetFile(virtualPath).VirtualPath;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -1,19 +1,30 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace PackageIndexReferenceImplementation.Controllers {
|
||||
public class StreamResult : ActionResult {
|
||||
public string ContentType { get; set; }
|
||||
public Stream Stream { get; set; }
|
||||
public DateTime? LastModifiedDate { get; set; }
|
||||
|
||||
public StreamResult(string contentType, Stream stream) {
|
||||
public StreamResult(string contentType, Stream stream) : this(contentType, stream, null) {
|
||||
}
|
||||
|
||||
public StreamResult(string contentType, Stream stream, DateTime? lastModified) {
|
||||
ContentType = contentType;
|
||||
Stream = stream;
|
||||
LastModifiedDate = lastModified;
|
||||
}
|
||||
|
||||
public override void ExecuteResult(ControllerContext context) {
|
||||
context.HttpContext.Response.ContentType = ContentType;
|
||||
Stream.CopyTo(context.HttpContext.Response.OutputStream);
|
||||
var response = context.HttpContext.Response;
|
||||
response.ContentType = ContentType;
|
||||
if (LastModifiedDate.HasValue) {
|
||||
response.Cache.SetLastModified(LastModifiedDate.Value);
|
||||
response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
|
||||
}
|
||||
Stream.CopyTo(response.OutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace PackageIndexReferenceImplementation.Controllers {
|
||||
var password = Encoding.UTF8.GetString(Convert.FromBase64String(HttpContext.Request.Headers["Password"]));
|
||||
|
||||
if ( !FormsAuthentication.Authenticate(user, password) ) {
|
||||
throw new AuthenticationException("This credentials are not valid fo this action.");
|
||||
throw new AuthenticationException("This credentials are not valid for this action.");
|
||||
}
|
||||
|
||||
var utcNowDateString = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd");
|
||||
@@ -74,7 +74,8 @@ namespace PackageIndexReferenceImplementation.Controllers {
|
||||
}
|
||||
|
||||
private string UpdateSyndicationItem(PackageProperties packageProperties, SyndicationItem item) {
|
||||
if (!string.IsNullOrEmpty(packageProperties.Category)) {
|
||||
|
||||
if (!string.IsNullOrEmpty(packageProperties.Creator)) {
|
||||
item.Authors.Clear();
|
||||
//parse package.PackageProperties.Creator into email-style authors
|
||||
item.Authors.Add(new SyndicationPerson { Name = packageProperties.Creator });
|
||||
@@ -85,6 +86,11 @@ namespace PackageIndexReferenceImplementation.Controllers {
|
||||
item.Categories.Add(new SyndicationCategory(packageProperties.Category));
|
||||
}
|
||||
|
||||
var contentType = packageProperties.ContentType;
|
||||
if (!item.Categories.Any(c => c.Name == contentType)) {
|
||||
item.Categories.Add(new SyndicationCategory(contentType));
|
||||
}
|
||||
|
||||
if (packageProperties.Modified.HasValue) {
|
||||
item.LastUpdatedTime = new DateTimeOffset(packageProperties.Modified.Value);
|
||||
}
|
||||
@@ -97,15 +103,16 @@ namespace PackageIndexReferenceImplementation.Controllers {
|
||||
item.Summary = new TextSyndicationContent(packageProperties.Description);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(packageProperties.Title)) {
|
||||
item.Title = new TextSyndicationContent(packageProperties.Title);
|
||||
}
|
||||
|
||||
var mediaIdentifier = packageProperties.Identifier + "-" + packageProperties.Version + ".zip";
|
||||
|
||||
var mediaUrl = Url.Action("Resource", "Media", new RouteValueDictionary { { "Id", mediaIdentifier }, { "ContentType", "application/x-package" } });
|
||||
item.Links.Clear();
|
||||
item.Links.Add(new SyndicationLink(new Uri(HostBaseUri(), new Uri(mediaUrl, UriKind.Relative))));
|
||||
|
||||
if (contentType == "Orchard Theme") {
|
||||
var previewUrl = Url.Action("PreviewTheme", "Media", new RouteValueDictionary { { "Id", mediaIdentifier }, { "ContentType", "application/x-package" } });
|
||||
item.Links.Add(new SyndicationLink(new Uri(HostBaseUri(), new Uri(previewUrl, UriKind.Relative)), "thumbnail", null, null, 0));
|
||||
}
|
||||
return mediaIdentifier;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using PackageIndexReferenceImplementation.Services;
|
||||
|
||||
namespace PackageIndexReferenceImplementation.Controllers
|
||||
{
|
||||
public class MediaController : Controller
|
||||
{
|
||||
namespace PackageIndexReferenceImplementation.Controllers {
|
||||
public class MediaController : Controller {
|
||||
private readonly MediaStorage _mediaStorage;
|
||||
|
||||
public MediaController() {
|
||||
_mediaStorage = new MediaStorage();
|
||||
}
|
||||
|
||||
public ActionResult Resource(string id, string contentType)
|
||||
{
|
||||
public ActionResult Resource(string id, string contentType) {
|
||||
return new StreamResult(contentType, _mediaStorage.GetMedia(id + ":" + contentType));
|
||||
}
|
||||
|
||||
public ActionResult PreviewTheme(string id, string contentType) {
|
||||
var stream = _mediaStorage.GetMedia(id + ":" + contentType);
|
||||
var package = Package.Open(stream, FileMode.Open, FileAccess.Read);
|
||||
if (package.PackageProperties.ContentType != "Orchard Theme") {
|
||||
return new HttpNotFoundResult();
|
||||
}
|
||||
|
||||
var themeName = package.PackageProperties.Identifier;
|
||||
var previewUri = new Uri("/" + themeName + "/Theme.png", UriKind.Relative);
|
||||
Stream previewStream;
|
||||
DateTime lastModified;
|
||||
if (package.PartExists(previewUri)) {
|
||||
lastModified = _mediaStorage.GetLastModifiedDate(id + ":" + contentType);
|
||||
previewStream = package.GetPart(new Uri("/" + themeName + "/Theme.png", UriKind.Relative)).GetStream();
|
||||
}
|
||||
else {
|
||||
var defaultPreviewPath = HostingEnvironment.MapPath("~/Content/DefaultThemePreview.png");
|
||||
if (defaultPreviewPath == null || !System.IO.File.Exists(defaultPreviewPath)) {
|
||||
return new HttpNotFoundResult();
|
||||
}
|
||||
lastModified = System.IO.File.GetLastWriteTimeUtc(defaultPreviewPath);
|
||||
previewStream = System.IO.File.Open(defaultPreviewPath, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
return new StreamResult("image/png", previewStream, lastModified);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}</ProjectGuid>
|
||||
<ProjectTypeGuids>{e53f8fea-eae0-44a6-8774-ffd645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PackageIndexReferenceImplementation</RootNamespace>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageIndexReferenceImplementation", "PackageIndexReferenceImplementation.csproj", "{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Hosting;
|
||||
|
||||
@@ -25,6 +26,15 @@ namespace PackageIndexReferenceImplementation.Services {
|
||||
return new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
}
|
||||
|
||||
public DateTime GetLastModifiedDate(string identifier) {
|
||||
if (!Directory.Exists(HostingEnvironment.MapPath("~/App_Data/Media")))
|
||||
Directory.CreateDirectory(HostingEnvironment.MapPath("~/App_Data/Media"));
|
||||
|
||||
var safeIdentifier = GetSafeIdentifier(identifier);
|
||||
var filePath = HostingEnvironment.MapPath("~/App_Data/Media/" + safeIdentifier);
|
||||
return File.GetLastWriteTimeUtc(filePath);
|
||||
}
|
||||
|
||||
static string GetSafeIdentifier(string identifier) {
|
||||
var invalidFileNameChars = Path.GetInvalidFileNameChars().Concat(Path.GetInvalidPathChars()).Distinct();
|
||||
var safeIdentifier = identifier.Replace("^", string.Format("^{0:X2}", (int)'^'));
|
||||
|
||||
Reference in New Issue
Block a user