Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez Gual <lluis@novell.com>2011-02-04 05:37:46 +0300
committerLluis Sanchez Gual <lluis@novell.com>2011-02-04 05:37:46 +0300
commit1cae03732c53614872e29ec42e39fa7315d3538b (patch)
tree30667e711a726f9c85ee57b4003a39d85bdd57e9 /Mono.Addins.Setup
parent5341950e897ffa0d13d15b245f240cae1018bcb4 (diff)
Added support for downloable support files, to be used for package
icons, screenshots, etc.
Diffstat (limited to 'Mono.Addins.Setup')
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs18
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs107
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs14
-rw-r--r--Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs79
4 files changed, 211 insertions, 7 deletions
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs
index da784cc..4efa747 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/AddinRepositoryEntry.cs
@@ -27,6 +27,10 @@
//
using System;
+using System.Net;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
namespace Mono.Addins.Setup
{
@@ -61,6 +65,16 @@ namespace Mono.Addins.Setup
else
return Mono.Addins.Addin.CompareVersions (rep.Addin.Version, Addin.Version);
}
+
+ public IAsyncResult BeginDownloadSupportFile (string name, AsyncCallback cb, object state)
+ {
+ return Repository.BeginDownloadSupportFile (name, cb, state);
+ }
+
+ public Stream EndDownloadSupportFile (IAsyncResult ares)
+ {
+ return Repository.EndDownloadSupportFile (ares);
+ }
}
/// <summary>
@@ -95,5 +109,9 @@ namespace Mono.Addins.Setup
string RepositoryName {
get;
}
+
+ IAsyncResult BeginDownloadSupportFile (string name, AsyncCallback cb, object state);
+
+ Stream EndDownloadSupportFile (IAsyncResult ares);
}
}
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs b/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs
index c4de1ae..b168dbe 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/Repository.cs
@@ -30,6 +30,9 @@ using System;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
+using System.IO;
+using System.Net;
+using System.Threading;
namespace Mono.Addins.Setup
{
@@ -49,6 +52,8 @@ namespace Mono.Addins.Setup
get { return url; }
set { url = value; }
}
+
+ internal string CachedFilesDir { get; set; }
[XmlElement ("Repository", Type = typeof(ReferenceRepositoryEntry))]
public RepositoryEntryCollection Repositories {
@@ -98,5 +103,107 @@ namespace Mono.Addins.Setup
else
Repositories.Remove (entry);
}
+
+ public IAsyncResult BeginDownloadSupportFile (string name, AsyncCallback cb, object state)
+ {
+ FileAsyncResult res = new FileAsyncResult ();
+ res.AsyncState = state;
+ res.Callback = cb;
+
+ string cachedFile = Path.Combine (CachedFilesDir, Path.GetFileName (name));
+ if (File.Exists (cachedFile)) {
+ res.FilePath = cachedFile;
+ res.CompletedSynchronously = true;
+ res.SetDone ();
+ return res;
+ }
+
+ Uri u = new Uri (new Uri (Url), name);
+ if (u.Scheme == "file") {
+ res.FilePath = u.AbsolutePath;
+ res.CompletedSynchronously = true;
+ res.SetDone ();
+ return res;
+ }
+ else {
+ HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create (u);
+ res.FilePath = cachedFile;
+ res.Request = req;
+ req.BeginGetResponse (OnGotResponse, res);
+ }
+ return res;
+ }
+
+ void OnGotResponse (IAsyncResult ares)
+ {
+ FileAsyncResult res = (FileAsyncResult) ares.AsyncState;
+ try {
+ WebResponse resp = res.Request.EndGetResponse (ares);
+ string dir = Path.GetDirectoryName (res.FilePath);
+ lock (this) {
+ if (!Directory.Exists (dir))
+ Directory.CreateDirectory (dir);
+ }
+ byte[] buffer = new byte [8092];
+ using (var s = resp.GetResponseStream ()) {
+ using (var f = File.OpenWrite (res.FilePath)) {
+ int nr = 0;
+ while ((nr = s.Read (buffer, 0, buffer.Length)) > 0)
+ f.Write (buffer, 0, nr);
+ }
+ }
+ } catch (Exception ex) {
+ res.Error = ex;
+ }
+ res.SetDone ();
+ }
+
+ public Stream EndDownloadSupportFile (IAsyncResult ares)
+ {
+ FileAsyncResult res = ares as FileAsyncResult;
+ if (res == null)
+ throw new InvalidOperationException ("Invalid IAsyncResult instance");
+ if (res.Error != null)
+ throw res.Error;
+ return File.OpenRead (res.FilePath);
+ }
+ }
+
+ class FileAsyncResult: IAsyncResult
+ {
+ ManualResetEvent done;
+
+ public string FilePath;
+ public HttpWebRequest Request;
+ public AsyncCallback Callback;
+ public Exception Error;
+
+ public void SetDone ()
+ {
+ lock (this) {
+ IsCompleted = true;
+ if (done != null)
+ done.Set ();
+ }
+ if (Callback != null)
+ Callback (this);
+ }
+
+ public object AsyncState { get; set; }
+
+ public WaitHandle AsyncWaitHandle {
+ get {
+ lock (this) {
+ if (done == null)
+ done = new ManualResetEvent (IsCompleted);
+ }
+ return done;
+ }
+ }
+
+ public bool CompletedSynchronously { get; set; }
+
+ public bool IsCompleted { get; set; }
}
+
}
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs
index 35c12af..70ba2a9 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRecord.cs
@@ -60,6 +60,12 @@ namespace Mono.Addins.Setup
set { file = value; }
}
+ public string CachedFilesDir {
+ get {
+ return Path.Combine (Path.GetDirectoryName (File), Path.GetFileNameWithoutExtension (File) + "_files");
+ }
+ }
+
public string Url {
get { return url; }
set { url = value; }
@@ -81,13 +87,18 @@ namespace Mono.Addins.Setup
public Repository GetCachedRepository ()
{
- return (Repository) AddinStore.ReadObject (File, typeof(Repository));
+ Repository repo = (Repository) AddinStore.ReadObject (File, typeof(Repository));
+ if (repo != null)
+ repo.CachedFilesDir = CachedFilesDir;
+ return repo;
}
public void ClearCachedRepository ()
{
if (System.IO.File.Exists (File))
System.IO.File.Delete (File);
+ if (Directory.Exists (CachedFilesDir))
+ Directory.Delete (CachedFilesDir, true);
}
internal void UpdateCachedRepository (Repository newRep)
@@ -98,6 +109,7 @@ namespace Mono.Addins.Setup
AddinStore.WriteObject (File, newRep);
if (name == null)
name = newRep.Name;
+ newRep.CachedFilesDir = CachedFilesDir;
}
}
diff --git a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
index 5bfa8cc..2be981a 100644
--- a/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
+++ b/Mono.Addins.Setup/Mono.Addins.Setup/SetupService.cs
@@ -56,6 +56,7 @@ namespace Mono.Addins.Setup
string installDirectory;
AddinStore store;
AddinSystemConfiguration config;
+ const string addinFilesDir = "_addin_files";
AddinRegistry registry;
@@ -387,6 +388,15 @@ namespace Mono.Addins.Setup
list.Add (f);
}
+ foreach (var prop in conf.Properties) {
+ try {
+ if (File.Exists (Path.Combine (basePath, prop.Value)))
+ list.Add (prop.Value);
+ } catch {
+ // Ignore errors
+ }
+ }
+
monitor.Log ("Creating package " + Path.GetFileName (outFilePath));
foreach (string file in list) {
@@ -461,32 +471,45 @@ namespace Mono.Addins.Setup
string mainFile = Path.Combine (rootPath, relFilePath);
string mainPath = Path.GetDirectoryName (mainFile);
+ string supportFileDir = Path.Combine (mainPath, addinFilesDir);
Repository mainrep = (Repository) AddinStore.ReadObject (mainFile, typeof(Repository));
if (mainrep == null) {
mainrep = new Repository ();
}
+ ReferenceRepositoryEntry repEntry = (ReferenceRepositoryEntry) rootrep.FindEntry (relFilePath);
+ DateTime rootLastModified = repEntry != null ? repEntry.LastModified : DateTime.MinValue;
+
bool modified = false;
monitor.Log.WriteLine ("Checking directory: " + mainPath);
foreach (string file in Directory.GetFiles (mainPath, "*.mpack")) {
+
+ DateTime date = File.GetLastWriteTime (file);
+ if (date > lastModified)
+ lastModified = date;
+
string fname = Path.GetFileName (file);
PackageRepositoryEntry entry = (PackageRepositoryEntry) mainrep.FindEntry (fname);
+ if (date > rootLastModified) {
+ if (entry != null) {
+ mainrep.RemoveEntry (entry);
+ DeleteSupportFiles (supportFileDir, entry.Addin);
+ entry = null;
+ }
+ }
if (entry == null) {
entry = new PackageRepositoryEntry ();
AddinPackage p = (AddinPackage) Package.FromFile (file);
entry.Addin = (AddinInfo) p.Addin;
entry.Url = fname;
+ ExtractSupportFiles (supportFileDir, file, entry.Addin);
mainrep.AddEntry (entry);
modified = true;
monitor.Log.WriteLine ("Added addin: " + fname);
}
allAddins.Add (entry);
-
- DateTime date = File.GetLastWriteTime (file);
- if (date > lastModified)
- lastModified = date;
}
ArrayList toRemove = new ArrayList ();
@@ -494,15 +517,16 @@ namespace Mono.Addins.Setup
if (!File.Exists (Path.Combine (mainPath, entry.Url)))
toRemove.Add (entry);
- foreach (PackageRepositoryEntry entry in toRemove)
+ foreach (PackageRepositoryEntry entry in toRemove) {
+ DeleteSupportFiles (supportFileDir, entry.Addin);
mainrep.RemoveEntry (entry);
+ }
if (modified || toRemove.Count > 0) {
AddinStore.WriteObject (mainFile, mainrep);
monitor.Log.WriteLine ("Updated " + relFilePath);
}
- ReferenceRepositoryEntry repEntry = (ReferenceRepositoryEntry) rootrep.FindEntry (relFilePath);
if (repEntry != null) {
if (repEntry.LastModified < lastModified)
repEntry.LastModified = lastModified;
@@ -514,11 +538,54 @@ namespace Mono.Addins.Setup
}
foreach (string dir in Directory.GetDirectories (mainPath)) {
+ if (Path.GetFileName (dir) == addinFilesDir)
+ continue;
string based = dir.Substring (rootPath.Length + 1);
BuildRepository (monitor, rootrep, rootPath, Path.Combine (based, "main.mrep"), allAddins);
}
}
+ void DeleteSupportFiles (string targetDir, AddinInfo ainfo)
+ {
+ foreach (var prop in ainfo.Properties) {
+ if (prop.Value.StartsWith (addinFilesDir + Path.DirectorySeparatorChar)) {
+ string file = Path.Combine (targetDir, Path.GetFileName (prop.Value));
+ if (File.Exists (file))
+ File.Delete (file);
+ }
+ }
+ if (Directory.Exists (targetDir) && Directory.GetFileSystemEntries (targetDir).Length == 0)
+ Directory.Delete (targetDir, true);
+ }
+
+ void ExtractSupportFiles (string targetDir, string file, AddinInfo ainfo)
+ {
+ Random r = new Random ();
+ ZipFile zfile = new ZipFile (file);
+ foreach (var prop in ainfo.Properties) {
+ ZipEntry ze = zfile.GetEntry (prop.Value);
+ if (ze != null) {
+ string fname;
+ do {
+ fname = Path.Combine (targetDir, r.Next().ToString ("x") + Path.GetExtension (prop.Value));
+ } while (File.Exists (fname));
+
+ if (!Directory.Exists (targetDir))
+ Directory.CreateDirectory (targetDir);
+
+ using (var f = File.OpenWrite (fname)) {
+ using (Stream s = zfile.GetInputStream (ze)) {
+ byte[] buffer = new byte [8092];
+ int nr = 0;
+ while ((nr = s.Read (buffer, 0, buffer.Length)) > 0)
+ f.Write (buffer, 0, nr);
+ }
+ }
+ prop.Value = Path.Combine (addinFilesDir, Path.GetFileName (fname));
+ }
+ }
+ }
+
void GenerateIndexPage (Repository rep, ArrayList addins, string basePath)
{
StreamWriter sw = new StreamWriter (Path.Combine (basePath, "index.html"));