mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Move Orchard Packaging API to Orchard Frx
We have decided to use OPC for Orchard packages, so it makes sense to move the API from Futures to the Frx. --HG-- branch : dev rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/AtomExtensions.cs => src/Orchard/Packaging/AtomExtensions.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/IPackageBuilder.cs => src/Orchard/Packaging/IPackageBuilder.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/IPackageExpander.cs => src/Orchard/Packaging/IPackageExpander.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/IPackageManager.cs => src/Orchard/Packaging/IPackageManager.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/IPackageSourceManager.cs => src/Orchard/Packaging/IPackageSourceManager.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageBuilder.cs => src/Orchard/Packaging/PackageBuilder.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageData.cs => src/Orchard/Packaging/PackageData.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageEntry.cs => src/Orchard/Packaging/PackageEntry.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageExpander.cs => src/Orchard/Packaging/PackageExpander.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageManager.cs => src/Orchard/Packaging/PackageManager.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageSource.cs => src/Orchard/Packaging/PackageSource.cs rename : src/Orchard.Web/Modules/Futures.Modules.Packaging/Services/PackageSourceManager.cs => src/Orchard/Packaging/PackageSourceManager.cs
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Futures.Modules.Packaging.Services;
|
||||
using Orchard.Commands;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Packaging;
|
||||
|
||||
namespace Futures.Modules.Packaging.Commands {
|
||||
public class PackagingCommands : DefaultOrchardCommandHandler {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Futures.Modules.Packaging.Services;
|
||||
using Futures.Modules.Packaging.ViewModels;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Packaging;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
|
@@ -37,7 +37,6 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Entity" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
@@ -64,25 +63,12 @@
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Web.Services" />
|
||||
<Reference Include="System.EnterpriseServices" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Commands\PackagingCommands.cs" />
|
||||
<Compile Include="Controllers\DownloadStreamResult.cs" />
|
||||
<Compile Include="Controllers\PackagingController.cs" />
|
||||
<Compile Include="Services\AtomExtensions.cs" />
|
||||
<Compile Include="Services\IPackageBuilder.cs" />
|
||||
<Compile Include="Services\IPackageExpander.cs" />
|
||||
<Compile Include="Services\IPackageManager.cs" />
|
||||
<Compile Include="Services\IPackageSourceManager.cs" />
|
||||
<Compile Include="Services\PackageBuilder.cs" />
|
||||
<Compile Include="Services\PackageData.cs" />
|
||||
<Compile Include="Services\PackageEntry.cs" />
|
||||
<Compile Include="Services\PackageExpander.cs" />
|
||||
<Compile Include="Services\PackageManager.cs" />
|
||||
<Compile Include="Services\PackageSource.cs" />
|
||||
<Compile Include="Services\PackageSourceManager.cs" />
|
||||
<Compile Include="ViewModels\PackagingHarvestViewModel.cs" />
|
||||
<Compile Include="ViewModels\PackagingModulesViewModel.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -100,6 +86,7 @@
|
||||
<Folder Include="Content\" />
|
||||
<Folder Include="Models\" />
|
||||
<Folder Include="Scripts\" />
|
||||
<Folder Include="Services\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
|
@@ -1,14 +0,0 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
static class AtomExtensions {
|
||||
public static string Atom(this XElement entry, string localName) {
|
||||
var element = entry.Element(AtomXName(localName));
|
||||
return element != null ? element.Value : null;
|
||||
}
|
||||
|
||||
public static XName AtomXName(string localName) {
|
||||
return XName.Get(localName, "http://www.w3.org/2005/Atom");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
using System.IO;
|
||||
using Orchard;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public interface IPackageBuilder : IDependency {
|
||||
Stream BuildPackage(ExtensionDescriptor extensionDescriptor);
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
using System.IO;
|
||||
using Orchard;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public interface IPackageExpander : IDependency {
|
||||
void ExpandPackage(Stream packageStream);
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
using Orchard;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public interface IPackageManager : IDependency {
|
||||
PackageData Harvest(string extensionName);
|
||||
PackageData Download(string feedItemId);
|
||||
|
||||
void Push(PackageData packageData, string feedUrl);
|
||||
void Install(PackageData packageData);
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public interface IPackageSourceManager : IDependency {
|
||||
IEnumerable<PackageSource> GetSources();
|
||||
void AddSource(PackageSource source);
|
||||
void RemoveSource(Guid id);
|
||||
void UpdateLists();
|
||||
|
||||
IEnumerable<PackageEntry> GetModuleList();
|
||||
}
|
||||
}
|
@@ -1,152 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.WebSite;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageBuilder : IPackageBuilder {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
|
||||
public PackageBuilder(IExtensionManager extensionManager, IWebSiteFolder webSiteFolder) {
|
||||
_extensionManager = extensionManager;
|
||||
_webSiteFolder = webSiteFolder;
|
||||
}
|
||||
|
||||
class CreateContext {
|
||||
public Stream Stream { get; set; }
|
||||
public Package Package { get; set; }
|
||||
|
||||
public IWebSiteFolder SourceFolder { get; set; }
|
||||
public string SourcePath { get; set; }
|
||||
public string TargetPath { get; set; }
|
||||
|
||||
public XDocument Project { get; set; }
|
||||
}
|
||||
|
||||
public Stream BuildPackage(ExtensionDescriptor extensionDescriptor) {
|
||||
var context = new CreateContext();
|
||||
BeginPackage(context);
|
||||
try {
|
||||
EstablishPaths(context, _webSiteFolder, extensionDescriptor.Location, extensionDescriptor.Name);
|
||||
SetCoreProperties(context, extensionDescriptor);
|
||||
|
||||
var projectFile = extensionDescriptor.Name + ".csproj";
|
||||
if (LoadProject(context, projectFile)) {
|
||||
EmbedVirtualFile(context, projectFile, System.Net.Mime.MediaTypeNames.Text.Xml);
|
||||
EmbedProjectFiles(context, "Compile", "Content", "None", "EmbeddedResource");
|
||||
EmbedReferenceFiles(context);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EndPackage(context);
|
||||
}
|
||||
|
||||
return context.Stream;
|
||||
}
|
||||
|
||||
private void SetCoreProperties(CreateContext context, ExtensionDescriptor extensionDescriptor) {
|
||||
var properties = context.Package.PackageProperties;
|
||||
properties.Title = extensionDescriptor.DisplayName ?? extensionDescriptor.Name;
|
||||
//properties.Subject = "";
|
||||
properties.Creator = extensionDescriptor.Author;
|
||||
properties.Keywords = extensionDescriptor.Tags;
|
||||
properties.Description = extensionDescriptor.Description;
|
||||
//properties.LastModifiedBy = "";
|
||||
//properties.Revision = "";
|
||||
//properties.LastPrinted = "";
|
||||
//properties.Created = "";
|
||||
//properties.Modified = "";
|
||||
properties.Category = extensionDescriptor.Features.Where(f => f.Name == extensionDescriptor.Name).Select(f => f.Category).FirstOrDefault();
|
||||
properties.Identifier = extensionDescriptor.Name;
|
||||
properties.ContentType = "Orchard " + extensionDescriptor.ExtensionType;
|
||||
//properties.Language = "";
|
||||
properties.Version = extensionDescriptor.Version;
|
||||
properties.ContentStatus = "";
|
||||
}
|
||||
|
||||
|
||||
private void EmbedProjectFiles(CreateContext context, params string[] itemGroupTypes) {
|
||||
var itemGroups = context.Project
|
||||
.Elements(Ns("Project"))
|
||||
.Elements(Ns("ItemGroup"));
|
||||
|
||||
foreach (var itemGroupType in itemGroupTypes) {
|
||||
var includePaths = itemGroups
|
||||
.Elements(Ns(itemGroupType))
|
||||
.Attributes("Include")
|
||||
.Select(x => x.Value);
|
||||
foreach (var includePath in includePaths) {
|
||||
EmbedVirtualFile(context, includePath, System.Net.Mime.MediaTypeNames.Application.Octet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EmbedReferenceFiles(CreateContext context) {
|
||||
var entries = context.Project
|
||||
.Elements(Ns("Project"))
|
||||
.Elements(Ns("ItemGroup"))
|
||||
.Elements(Ns("Reference"))
|
||||
.Select(reference => new {
|
||||
Include = reference.Attribute("Include"),
|
||||
HintPath = reference.Element(Ns("HintPath"))
|
||||
})
|
||||
.Where(entry => entry.Include != null);
|
||||
|
||||
foreach (var entry in entries) {
|
||||
var assemblyName = new AssemblyName(entry.Include.Value);
|
||||
var hintPath = entry.HintPath != null ? entry.HintPath.Value : null;
|
||||
|
||||
var virtualPath = "bin/" + assemblyName.Name + ".dll";
|
||||
if (context.SourceFolder.FileExists(context.SourcePath + virtualPath)) {
|
||||
EmbedVirtualFile(context, virtualPath, System.Net.Mime.MediaTypeNames.Application.Octet);
|
||||
}
|
||||
else if (hintPath != null) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private XName Ns(string localName) {
|
||||
return XName.Get(localName, "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
}
|
||||
|
||||
|
||||
static void BeginPackage(CreateContext context) {
|
||||
context.Stream = new MemoryStream();
|
||||
context.Package = Package.Open(context.Stream, FileMode.Create, FileAccess.ReadWrite);
|
||||
}
|
||||
|
||||
static void EstablishPaths(CreateContext context, IWebSiteFolder webSiteFolder, string locationPath, string moduleName) {
|
||||
context.SourceFolder = webSiteFolder;
|
||||
context.SourcePath = "~/Modules/" + moduleName + "/";
|
||||
context.TargetPath = "\\" + moduleName + "\\";
|
||||
}
|
||||
|
||||
static bool LoadProject(CreateContext context, string relativePath) {
|
||||
var virtualPath = context.SourcePath + relativePath;
|
||||
if (context.SourceFolder.FileExists(virtualPath)) {
|
||||
context.Project = XDocument.Parse(context.SourceFolder.ReadFile(context.SourcePath + relativePath));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Uri EmbedVirtualFile(CreateContext context, string relativePath, string contentType) {
|
||||
var partUri = PackUriHelper.CreatePartUri(new Uri(context.TargetPath + relativePath, UriKind.Relative));
|
||||
var packagePart = context.Package.CreatePart(partUri, contentType);
|
||||
using (var stream = packagePart.GetStream(FileMode.Create, FileAccess.Write)) {
|
||||
context.SourceFolder.CopyFileTo(context.SourcePath + relativePath, stream);
|
||||
}
|
||||
return partUri;
|
||||
}
|
||||
|
||||
static void EndPackage(CreateContext context) {
|
||||
context.Package.Close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageData {
|
||||
public string ExtensionName { get; set; }
|
||||
public string ExtensionVersion { get; set; }
|
||||
|
||||
public Stream PackageStream { get; set; }
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
using System.ServiceModel.Syndication;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageEntry {
|
||||
public PackageSource Source { get; set; }
|
||||
public SyndicationFeed SyndicationFeed { get; set; }
|
||||
public SyndicationItem SyndicationItem { get; set; }
|
||||
public string PackageStreamUri { get; set; }
|
||||
}
|
||||
}
|
@@ -1,172 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.FileSystems.WebSite;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageExpander : IPackageExpander {
|
||||
private const string ContentTypePrefix = "Orchard ";
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
|
||||
public PackageExpander(
|
||||
IExtensionManager extensionManager,
|
||||
IWebSiteFolder webSiteFolder,
|
||||
IVirtualPathProvider virtualPathProvider) {
|
||||
_extensionManager = extensionManager;
|
||||
_webSiteFolder = webSiteFolder;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
}
|
||||
|
||||
class ExpandContext {
|
||||
public Stream Stream { get; set; }
|
||||
public Package Package { get; set; }
|
||||
|
||||
public string ExtensionName { get; set; }
|
||||
public string ExtensionType { get; set; }
|
||||
|
||||
public string TargetPath { get; set; }
|
||||
|
||||
public string SourcePath { get; set; }
|
||||
|
||||
public XDocument Project { get; set; }
|
||||
}
|
||||
|
||||
public void ExpandPackage(Stream packageStream) {
|
||||
var context = new ExpandContext();
|
||||
BeginPackage(context, packageStream);
|
||||
try {
|
||||
GetCoreProperties(context);
|
||||
EstablishPaths(context, _virtualPathProvider);
|
||||
|
||||
var projectFile = context.ExtensionName + ".csproj";
|
||||
if (LoadProject(context, projectFile)) {
|
||||
ExtractFile(context, projectFile);
|
||||
ExtractProjectFiles(context, "Compile", "Content", "None", "EmbeddedResource");
|
||||
ExtractReferenceFiles(context);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EndPackage(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractFile(ExpandContext context, string relativePath) {
|
||||
var partUri = PackUriHelper.CreatePartUri(new Uri(context.SourcePath + relativePath, UriKind.Relative));
|
||||
var packagePart = context.Package.GetPart(partUri);
|
||||
using (var packageStream = packagePart.GetStream(FileMode.Open, FileAccess.Read)) {
|
||||
var filePath = Path.Combine(context.TargetPath, relativePath);
|
||||
var folderPath = Path.GetDirectoryName(filePath);
|
||||
if (!Directory.Exists(folderPath))
|
||||
Directory.CreateDirectory(folderPath);
|
||||
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) {
|
||||
packageStream.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractProjectFiles(ExpandContext context, params string[] itemGroupTypes) {
|
||||
var itemGroups = context.Project
|
||||
.Elements(Ns("Project"))
|
||||
.Elements(Ns("ItemGroup"));
|
||||
|
||||
foreach (var itemGroupType in itemGroupTypes) {
|
||||
var includePaths = itemGroups
|
||||
.Elements(Ns(itemGroupType))
|
||||
.Attributes("Include")
|
||||
.Select(x => x.Value);
|
||||
foreach (var includePath in includePaths) {
|
||||
ExtractFile(context, includePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractReferenceFiles(ExpandContext context) {
|
||||
var entries = context.Project
|
||||
.Elements(Ns("Project"))
|
||||
.Elements(Ns("ItemGroup"))
|
||||
.Elements(Ns("Reference"))
|
||||
.Select(reference => new {
|
||||
Include = reference.Attribute("Include"),
|
||||
HintPath = reference.Element(Ns("HintPath"))
|
||||
})
|
||||
.Where(entry => entry.Include != null);
|
||||
|
||||
foreach (var entry in entries) {
|
||||
var assemblyName = new AssemblyName(entry.Include.Value);
|
||||
var hintPath = entry.HintPath != null ? entry.HintPath.Value : null;
|
||||
|
||||
var virtualPath = "bin/" + assemblyName.Name + ".dll";
|
||||
if (PartExists(context, virtualPath)) {
|
||||
ExtractFile(context, virtualPath);
|
||||
}
|
||||
else if (hintPath != null) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool PartExists(ExpandContext context, string relativePath) {
|
||||
var projectUri = PackUriHelper.CreatePartUri(new Uri(context.SourcePath + relativePath, UriKind.Relative));
|
||||
return context.Package.PartExists(projectUri);
|
||||
}
|
||||
|
||||
|
||||
private XName Ns(string localName) {
|
||||
return XName.Get(localName, "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
}
|
||||
private static bool LoadProject(ExpandContext context, string relativePath) {
|
||||
var projectUri = PackUriHelper.CreatePartUri(new Uri(context.SourcePath + relativePath, UriKind.Relative));
|
||||
if (!context.Package.PartExists(projectUri))
|
||||
return false;
|
||||
var part = context.Package.GetPart(projectUri);
|
||||
using (var stream = part.GetStream(FileMode.Open, FileAccess.Read)) {
|
||||
context.Project = XDocument.Load(stream);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void BeginPackage(ExpandContext context, Stream packageStream) {
|
||||
if (packageStream.CanSeek) {
|
||||
context.Stream = packageStream;
|
||||
}
|
||||
else {
|
||||
context.Stream = new MemoryStream();
|
||||
packageStream.CopyTo(context.Stream);
|
||||
}
|
||||
context.Package = Package.Open(context.Stream, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
|
||||
private void EndPackage(ExpandContext context) {
|
||||
context.Package.Close();
|
||||
}
|
||||
|
||||
private void GetCoreProperties(ExpandContext context) {
|
||||
context.ExtensionName = context.Package.PackageProperties.Identifier;
|
||||
|
||||
var contentType = context.Package.PackageProperties.ContentType;
|
||||
if (contentType.StartsWith(ContentTypePrefix))
|
||||
context.ExtensionType = contentType.Substring(ContentTypePrefix.Length);
|
||||
}
|
||||
|
||||
private void EstablishPaths(ExpandContext context, IVirtualPathProvider virtualPathProvider) {
|
||||
context.SourcePath = "\\" + context.ExtensionName + "\\";
|
||||
if (context.ExtensionType == "Theme") {
|
||||
context.TargetPath = virtualPathProvider.MapPath("~/Themes-temp/" + context.ExtensionName);
|
||||
}
|
||||
else if (context.ExtensionType == "Module") {
|
||||
context.TargetPath = virtualPathProvider.MapPath("~/Modules-temp/" + context.ExtensionName);
|
||||
}
|
||||
else {
|
||||
throw new ApplicationException("Unknown extension type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Orchard.Environment.Extensions;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageManager : IPackageManager {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IPackageSourceManager _packageSourceManager;
|
||||
private readonly IPackageBuilder _packageBuilder;
|
||||
private readonly IPackageExpander _packageExpander;
|
||||
|
||||
public PackageManager(
|
||||
IExtensionManager extensionManager,
|
||||
IPackageSourceManager packageSourceManager,
|
||||
IPackageBuilder packageBuilder,
|
||||
IPackageExpander packageExpander) {
|
||||
_extensionManager = extensionManager;
|
||||
_packageSourceManager = packageSourceManager;
|
||||
_packageBuilder = packageBuilder;
|
||||
_packageExpander = packageExpander;
|
||||
}
|
||||
|
||||
public PackageData Harvest(string extensionName) {
|
||||
var extensionDescriptor = _extensionManager.AvailableExtensions().FirstOrDefault(x => x.Name == extensionName);
|
||||
if (extensionDescriptor == null)
|
||||
return null;
|
||||
return new PackageData {
|
||||
ExtensionName = extensionDescriptor.Name,
|
||||
ExtensionVersion = extensionDescriptor.Version,
|
||||
PackageStream = _packageBuilder.BuildPackage(extensionDescriptor),
|
||||
};
|
||||
}
|
||||
|
||||
public void Push(PackageData packageData, string feedUrl) {
|
||||
|
||||
var request = WebRequest.Create(feedUrl);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "application/x-package";
|
||||
using (var requestStream = request.GetRequestStream()) {
|
||||
packageData.PackageStream.Seek(0, SeekOrigin.Begin);
|
||||
packageData.PackageStream.CopyTo(requestStream);
|
||||
}
|
||||
|
||||
using (request.GetResponse()) {
|
||||
// forces request and disposes results
|
||||
}
|
||||
}
|
||||
|
||||
public PackageData Download(string feedItemId) {
|
||||
var entry = _packageSourceManager.GetModuleList().Single(x => x.SyndicationItem.Id == feedItemId);
|
||||
var request = WebRequest.Create(entry.PackageStreamUri);
|
||||
using (var response = request.GetResponse()) {
|
||||
using (var responseStream = response.GetResponseStream()) {
|
||||
var stream = new MemoryStream();
|
||||
responseStream.CopyTo(stream);
|
||||
var package = Package.Open(stream);
|
||||
try {
|
||||
return new PackageData {
|
||||
ExtensionName = package.PackageProperties.Identifier,
|
||||
ExtensionVersion = package.PackageProperties.Version,
|
||||
PackageStream = stream
|
||||
};
|
||||
}
|
||||
finally {
|
||||
package.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Install(PackageData packageData) {
|
||||
_packageExpander.ExpandPackage(packageData.PackageStream);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageSource {
|
||||
public Guid Id { get; set; }
|
||||
public string FeedUrl { get; set; }
|
||||
}
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.ServiceModel.Syndication;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Orchard.FileSystems.AppData;
|
||||
|
||||
namespace Futures.Modules.Packaging.Services {
|
||||
public class PackageSourceManager : IPackageSourceManager {
|
||||
private readonly IAppDataFolder _appDataFolder;
|
||||
private static readonly XmlSerializer _sourceSerializer = new XmlSerializer(typeof(List<PackageSource>), new XmlRootAttribute("Sources"));
|
||||
|
||||
public PackageSourceManager(IAppDataFolder appDataFolder) {
|
||||
_appDataFolder = appDataFolder;
|
||||
}
|
||||
|
||||
static string GetSourcesPath() {
|
||||
return ".Packaging/Sources.xml";
|
||||
}
|
||||
static string GetFeedCachePath(PackageSource source) {
|
||||
return ".Packaging/Feed." + source.Id.ToString("n") + ".xml";
|
||||
}
|
||||
|
||||
public IEnumerable<PackageSource> GetSources() {
|
||||
var text = _appDataFolder.ReadFile(GetSourcesPath());
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return Enumerable.Empty<PackageSource>();
|
||||
|
||||
var textReader = new StringReader(_appDataFolder.ReadFile(GetSourcesPath()));
|
||||
return (IEnumerable<PackageSource>)_sourceSerializer.Deserialize(textReader);
|
||||
}
|
||||
|
||||
void SaveSources(IEnumerable<PackageSource> sources) {
|
||||
var textWriter = new StringWriter();
|
||||
_sourceSerializer.Serialize(textWriter, sources.ToList());
|
||||
|
||||
_appDataFolder.CreateFile(GetSourcesPath(), textWriter.ToString());
|
||||
}
|
||||
|
||||
public void AddSource(PackageSource source) {
|
||||
UpdateSource(source);
|
||||
SaveSources(GetSources().Concat(new[] { source }));
|
||||
}
|
||||
|
||||
public void RemoveSource(Guid id) {
|
||||
SaveSources(GetSources().Where(x => x.Id != id));
|
||||
}
|
||||
|
||||
public void UpdateLists() {
|
||||
foreach (var source in GetSources()) {
|
||||
UpdateSource(source);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSource(PackageSource source) {
|
||||
var feed = XDocument.Load(source.FeedUrl, LoadOptions.PreserveWhitespace);
|
||||
_appDataFolder.CreateFile(GetFeedCachePath(source), feed.ToString(SaveOptions.DisableFormatting));
|
||||
}
|
||||
|
||||
|
||||
static XName Atom(string localName) {
|
||||
return AtomExtensions.AtomXName(localName);
|
||||
}
|
||||
|
||||
static IEnumerable<T> Unit<T>(T t) where T : class {
|
||||
return t != null ? new[] { t } : Enumerable.Empty<T>();
|
||||
}
|
||||
static IEnumerable<T2> Bind<T, T2>(T t, Func<T, IEnumerable<T2>> f) where T : class {
|
||||
return Unit(t).SelectMany(f);
|
||||
}
|
||||
|
||||
private SyndicationFeed ParseFeed(string content) {
|
||||
var formatter = new Atom10FeedFormatter<SyndicationFeed>();
|
||||
formatter.ReadFrom(XmlReader.Create(new StringReader(content)));
|
||||
return formatter.Feed;
|
||||
}
|
||||
|
||||
public IEnumerable<PackageEntry> GetModuleList() {
|
||||
var packageInfos = GetSources()
|
||||
.SelectMany(
|
||||
source =>
|
||||
Bind(ParseFeed(_appDataFolder.ReadFile(GetFeedCachePath(source))),
|
||||
feed =>
|
||||
feed.Items.SelectMany(
|
||||
item =>
|
||||
Unit(new PackageEntry {
|
||||
Source = source,
|
||||
SyndicationFeed = feed,
|
||||
SyndicationItem = item,
|
||||
PackageStreamUri = item.Links.Single().GetAbsoluteUri().AbsoluteUri,
|
||||
}))));
|
||||
|
||||
|
||||
return packageInfos.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Futures.Modules.Packaging.Services;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Packaging;
|
||||
|
||||
namespace Futures.Modules.Packaging.ViewModels {
|
||||
public class PackagingHarvestViewModel {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Futures.Modules.Packaging.Services;
|
||||
using Orchard.Packaging;
|
||||
|
||||
namespace Futures.Modules.Packaging.ViewModels {
|
||||
public class PackagingModulesViewModel {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Futures.Modules.Packaging.Services;
|
||||
using Orchard.Packaging;
|
||||
|
||||
namespace Futures.Modules.Packaging.ViewModels {
|
||||
public class PackagingSourcesViewModel {
|
||||
|
Reference in New Issue
Block a user