forked from fuse4x/support
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAutoUpdater.m
More file actions
134 lines (105 loc) · 5.19 KB
/
AutoUpdater.m
File metadata and controls
134 lines (105 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
// AutoUpdater.m
// support
//
// Created by Anatol Pomozov on 6/12/11.
// Copyright 2011 fuse4x.org. All rights reserved.
//
#include <stdio.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSURL.h>
#include <Foundation/NSCharacterSet.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSNumberFormatter.h>
#include <Foundation/NSException.h>
#include <CoreFoundation/CFUserNotification.h>
#include <AppKit/NSWorkspace.h>
#include <fuse/fuse_version.h>
const CFStringRef APPLICATION_NAME = CFSTR("org.fuse4x.autoupdater");
NSString* FEED_URL = @"http://fuse4x.org/updates/stable";
NSString* DOWNLOAD_URL = @"https://github.com/downloads/fuse4x/fuse4x/Fuse4X-%@.pkg";
NSString *parseVersion(NSString *content) {
content = [content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return content;
}
// Returns [str1 compare:str2]
NSComparisonResult compareVersions(NSString *str1, NSString *str2) {
NSArray *version1 = [str1 componentsSeparatedByString: @"."];
NSArray *version2 = [str2 componentsSeparatedByString: @"."];
if ([version1 count] > 3)
[NSException raise:@"Invalid version" format:@"version '%@' is invalid", str1];
if ([version2 count] > 3)
[NSException raise:@"Invalid version" format:@"version '%@' is invalid", str2];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
for (int i = 0; i < [version1 count]; i++) {
NSNumber *part1 = [f numberFromString: [version1 objectAtIndex:i]];
NSNumber *part2 = [NSNumber numberWithInt:0];
if ([version2 objectAtIndex:i] != NULL)
part2 = [f numberFromString: [version2 objectAtIndex:i]];
if (part1 == NULL)
[NSException raise:@"Invalid version" format:@"version '%@' is invalid", str1];
if (part2 == NULL)
[NSException raise:@"Invalid version" format:@"version '%@' is invalid", str2];
NSComparisonResult result = [part1 compare:part2];
if (result != NSOrderedSame)
return result;
}
return NSOrderedSame;
}
bool isValidVersion(NSString *version) {
if (version == NULL)
return false;
NSArray *array = [version componentsSeparatedByString: @"."];
if ([array count] > 3)
return false;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
for (id element in array) {
NSNumber *part = [f numberFromString: element];
if (part == NULL)
return false;
}
return true;
}
int main(void)
{
// TODO Check that another instance of autoupdater is not running
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:FEED_URL];
NSString *newVersion = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:NULL];
newVersion = parseVersion(newVersion);
if (newVersion == NULL)
return 0; // response is not properly formatted
NSString *currentVersion = (NSString*)CFPreferencesCopyAppValue(CFSTR("skipVersion"), APPLICATION_NAME);
if (!isValidVersion(currentVersion)) {
currentVersion = @FUSE4X_VERSION;
}
if (compareVersions(currentVersion, @FUSE4X_VERSION) != NSOrderedDescending) {
// If we have already newer version that skipped - remove the pref
CFPreferencesSetAppValue(CFSTR("skipVersion"), NULL, APPLICATION_NAME);
CFPreferencesAppSynchronize(APPLICATION_NAME);
currentVersion = @FUSE4X_VERSION;
}
if(compareVersions(newVersion, currentVersion) == NSOrderedDescending) {
CFOptionFlags response;
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(dictionary, kCFUserNotificationAlertHeaderKey, @"A new version of Fuse4X available");
CFDictionarySetValue(dictionary, kCFUserNotificationAlertMessageKey, @"Generally it is a good idea to update Fuse4X. The new version adds more features, fixes bugs and provides the best possible user experience.");
CFDictionarySetValue(dictionary, kCFUserNotificationAlternateButtonTitleKey, @"Skip this version");
CFDictionarySetValue(dictionary, kCFUserNotificationOtherButtonTitleKey, @"Notify me later");
CFDictionarySetValue(dictionary, kCFUserNotificationDefaultButtonTitleKey, @"Download It");
CFUserNotificationRef notification = CFUserNotificationCreate(NULL, 0, kCFUserNotificationNoteAlertLevel, NULL, dictionary);
CFUserNotificationReceiveResponse(notification, 0, &response);
if (response == kCFUserNotificationDefaultResponse) {
NSString *url = [NSString stringWithFormat:DOWNLOAD_URL, newVersion];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
} else if (response == kCFUserNotificationAlternateResponse) {
// save to prefs that we do not want to download this version
CFPreferencesSetAppValue(CFSTR("skipVersion"), newVersion, APPLICATION_NAME);
CFPreferencesAppSynchronize(APPLICATION_NAME);
}
}
[pool release];
return 0;
}