5
// Michael Hutchinson <mhutchinson@novell.com>
7
// Copyright (c) 2009 Novell, Inc. (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
using MonoDevelop.Core;
33
using MonoDevelop.Core.Gui;
34
using System.Collections.Generic;
36
namespace MonoDevelop.Platform
39
public static class AppUpdater
41
const int formatVersion = 1;
42
const string updateAutoPropertyKey = "AppUpdater.CheckAutomatically";
44
static UpdateInfo[] updateInfos;
46
//FIXME: populate from an extension point
47
public static UpdateInfo[] DefaultUpdateInfos {
49
if (updateInfos == null) {
50
var files = new string[] {
51
"/Developer/MonoTouch/updateinfo",
52
"/Developer/MonoTouch/Source/updateinfo",
53
"/Library/Frameworks/Mono.framework/Versions/Current/updateinfo",
54
"/Library/Frameworks/Mono.framework/Versions/Current/updateinfo.csdk",
55
Path.GetDirectoryName (typeof (MacPlatform).Assembly.Location) + "/../../../updateinfo",
56
}.Where (File.Exists);
58
var list = new List<UpdateInfo> ();
59
foreach (string file in files) {
61
list.Add (UpdateInfo.FromFile (file));
62
} catch (Exception ex) {
63
LoggingService.LogError ("Error reading update info file '" + file + "'", ex);
66
updateInfos = list.ToArray ();
73
public static bool CheckAutomatically {
75
return PropertyService.Get<bool> (updateAutoPropertyKey, true);
78
PropertyService.Set (updateAutoPropertyKey, value);
82
public static void RunCheck (bool automatic)
84
RunCheck (DefaultUpdateInfos, automatic);
87
public static void RunCheck (UpdateInfo[] updateInfos, bool automatic)
89
if (updateInfos == null || updateInfos.Length == 0 || (automatic && !CheckAutomatically))
92
var query = new StringBuilder ("http://go-mono.com/macupdate/update?v=");
93
query.Append (formatVersion);
94
foreach (var info in updateInfos)
95
query.AppendFormat ("&{0}={1}", info.AppId, info.VersionId);
97
if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MONODEVELOP_UPDATER_TEST")))
98
query.Append ("&test=1");
100
var request = (HttpWebRequest) WebRequest.Create (query.ToString ());
102
//FIXME: use IfModifiedSince
103
//request.IfModifiedSince = somevalue;
105
request.BeginGetResponse (delegate (IAsyncResult ar) {
106
ReceivedResponse (request, ar, automatic);
110
static void ReceivedResponse (HttpWebRequest request, IAsyncResult ar, bool automatic)
113
using (var response = (HttpWebResponse) request.EndGetResponse (ar)) {
114
var encoding = Encoding.GetEncoding (response.CharacterSet);
115
using (var reader = new StreamReader (response.GetResponseStream(), encoding)) {
116
var doc = System.Xml.Linq.XDocument.Load (reader);
117
var updates = (from x in doc.Root.Elements ("Application")
118
let first = x.Elements ("Update").First ()
119
select new Update () {
120
Name = x.Attribute ("name").Value,
121
Url = first.Attribute ("url").Value,
122
Version = first.Attribute ("version").Value,
123
Date = DateTime.Parse (first.Attribute ("date").Value),
124
Releases = x.Elements ("Update").Select (y => new Release () {
125
Version = y.Attribute ("version").Value,
126
Date = DateTime.Parse (y.Attribute ("date").Value),
131
if (!automatic || (updates != null && updates.Count > 0)) {
132
Gtk.Application.Invoke (delegate {
133
MessageService.ShowCustomDialog (new UpdateDialog (updates));
138
} catch (WebException ex) {
139
LoggingService.LogError ("Error retrieving update information", ex);
141
MessageService.ShowException (ex, GettextCatalog.GetString ("Error retrieving update information"));
142
} catch (Exception ex) {
143
LoggingService.LogError ("Error retrieving update information", ex);
145
MessageService.ShowException (ex, GettextCatalog.GetString ("Error retrieving update information"));
153
public string Version;
154
public DateTime Date;
155
public List<Release> Releases;
160
public string Version;
161
public DateTime Date;
165
public class UpdateInfo
171
public UpdateInfo (Guid appId, long versionId)
174
this.VersionId = versionId;
177
public readonly Guid AppId;
178
public readonly long VersionId;
180
public static UpdateInfo FromFile (string fileName)
182
using (var f = File.OpenText (fileName)) {
183
var s = f.ReadLine ();
184
var parts = s.Split (' ');
185
return new UpdateInfo (new Guid (parts[0]), long.Parse (parts[1]));