255
CheckAddinUpdates (updates, level);
237
257
} catch (Exception ex) {
258
LoggingService.LogError ("Could not retrieve update information", ex);
238
259
error = GettextCatalog.GetString ("Error retrieving update information");
239
260
errorDetail = ex;
241
263
callback (new UpdateResult (updates, level, error, errorDetail));
266
public static void QueryAddinUpdates (UpdateLevel level, Action<UpdateResult> callback)
268
System.Threading.ThreadPool.QueueUserWorkItem (delegate {
269
List<Update> updates = new List<Update> ();
271
Exception errorDetail = null;
274
CheckAddinUpdates (updates, level);
276
} catch (Exception ex) {
277
LoggingService.LogError ("Could not retrieve update information", ex);
278
error = GettextCatalog.GetString ("Error retrieving update information");
282
callback (new UpdateResult (updates, level, error, errorDetail));
286
static void CheckAddinUpdates (List<Update> updates, UpdateLevel level)
288
for (UpdateLevel n=UpdateLevel.Stable; n<=level; n++)
289
Runtime.AddinSetupService.RegisterMainRepository ((UpdateLevel)n, true);
291
AddinUpdateHandler.QueryAddinUpdates ();
293
updates.AddRange (GetAddinUpdates (UpdateLevel.Stable));
294
if (level >= UpdateLevel.Beta)
295
updates.AddRange (GetAddinUpdates (UpdateLevel.Beta));
296
if (level >= UpdateLevel.Alpha)
297
updates.AddRange (GetAddinUpdates (UpdateLevel.Alpha));
298
if (level == UpdateLevel.Test)
299
updates.AddRange (GetAddinUpdates (UpdateLevel.Test));
302
static IEnumerable<Update> GetAddinUpdates (UpdateLevel level)
304
List<Update> res = new List<Update> ();
305
string url = Runtime.AddinSetupService.GetMainRepositoryUrl (level);
306
List<AddinRepositoryEntry> list = new List<AddinRepositoryEntry> ();
307
list.AddRange (Runtime.AddinSetupService.Repositories.GetAvailableUpdates (url));
308
FilterOldVersions (list);
309
foreach (var ventry in list) {
311
UpdateRank rank = GetUpdateRank (entry.Addin.Properties.GetPropertyValue ("UpdateRank"));
312
if (rank != UpdateRank.Important)
314
string sdate = entry.Addin.Properties.GetPropertyValue ("ReleaseDate");
316
if (!string.IsNullOrEmpty (sdate))
317
date = DateTime.Parse (sdate, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
320
res.Add (new Update () {
321
Name = entry.Addin.Name,
322
InstallAction = (m) => InstallAddin (m, entry),
323
Version = entry.Addin.Version,
326
Releases = ParseReleases (entry.Addin.Id, entry).ToList ()
332
static void FilterOldVersions (List<AddinRepositoryEntry> addins)
334
Dictionary<string,string> versions = new Dictionary<string, string> ();
335
foreach (AddinRepositoryEntry a in addins) {
338
Addin.GetIdParts (a.Addin.Id, out id, out version);
339
if (!versions.TryGetValue (id, out last) || Addin.CompareVersions (last, version) > 0)
340
versions [id] = version;
342
for (int n=0; n<addins.Count; n++) {
343
AddinRepositoryEntry a = addins [n];
345
Addin.GetIdParts (a.Addin.Id, out id, out version);
346
if (versions [id] != version)
347
addins.RemoveAt (n--);
351
static IEnumerable<Release> ParseReleases (string addinId, AddinRepositoryEntry entry)
353
// Format of release notes is:
354
// {{version1,date1}} release note text {{version2,date2}} release note text ...
357
// {{1.1,2011-01-10}} Release notes for 1.1 {{1.2,2011-03-22}} Release notes for 2.3
359
string releaseNotes = entry.Addin.Properties.GetPropertyValue ("ReleaseNotes");
360
if (releaseNotes.Length == 0) {
361
string file = entry.Addin.Properties.GetPropertyValue ("ReleaseNotesFile");
362
if (file.Length > 0) {
363
IAsyncResult res = entry.BeginDownloadSupportFile (file, null, null);
364
res.AsyncWaitHandle.WaitOne ();
366
using (Stream s = entry.EndDownloadSupportFile (res)) {
367
StreamReader sr = new StreamReader (s);
368
releaseNotes = sr.ReadToEnd ();
370
} catch (Exception ex) {
371
LoggingService.LogError ("Could not download release notes", ex);
376
if (releaseNotes.Length == 0)
379
var addin = AddinManager.Registry.GetAddin (Addin.GetIdName (addinId));
380
string currentVersion = addin != null ? addin.Version : null;
382
int i = releaseNotes.IndexOf ("{{");
384
int j = releaseNotes.IndexOf ("}}", i + 2);
387
string[] h = releaseNotes.Substring (i + 2, j - i - 2).Trim ().Split (',');
391
if (!DateTime.TryParse (h[1].Trim (), CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out date))
393
int k = releaseNotes.IndexOf ("{{", j + 2);
394
string version = h[0].Trim ();
395
if (currentVersion == null || Addin.CompareVersions (currentVersion, version) > 0) {
396
string txt = k != -1 ? releaseNotes.Substring (j + 2, k - j - 2) : releaseNotes.Substring (j + 2);
397
yield return new Release () {
400
Notes = txt.Trim (' ','\t','\r','\n')
407
static IAsyncOperation InstallAddin (IProgressMonitor monitor, AddinRepositoryEntry addin)
409
// Add-in engine changes must be done in the gui thread since mono.addins is not thread safe
410
DispatchService.GuiDispatch (delegate {
412
Runtime.AddinSetupService.Install (new ProgressStatusMonitor (monitor), addin);
415
return monitor.AsyncOperation;
419
/// Parses an update rank string
424
/// <param name='updateRankString'>
425
/// Update rank string.
428
/// This method parses an update rank string. If the rank is conditioned to an update tag, it will
429
/// check the presence of the tag
431
internal static UpdateRank GetUpdateRank (string updateRankString)
433
string slevel = null;
434
foreach (string cond in updateRankString.Split (new char[] {' '}, StringSplitOptions.RemoveEmptyEntries)) {
435
int i = cond.IndexOf (':');
440
if (tags.Contains (cond.Substring (0, i))) {
441
slevel = cond.Substring (i+1);
446
if (slevel != null && Enum.TryParse<UpdateRank> (slevel, out level))
449
return UpdateRank.Normal;