-
Notifications
You must be signed in to change notification settings - Fork 6
/
updatecheck.go
114 lines (98 loc) · 2.8 KB
/
updatecheck.go
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
// updatecheck.go - Reads and find latest update from updates.xml.
// Copyright (c) 2018 - 2020 Richard Huang <[email protected]>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
package host
import (
"encoding/xml"
"runtime"
)
// An App is represent one application returned by updates.xml.
//
// <app appid='tld.domain.sub.app.name'></app>
type App struct {
AppId *string `xml:"appid,attr"`
Updates []*Update `xml:"updatecheck"`
}
// An Update is represent application download URL and latest version.
//
// It can have target OS optionally. This is an extended attribute that is not
// part of original Google Chrome update manifest.
//
// <updatecheck codebase='https://sub.domain.tld/app.download.all' os='darwin' version='1.0.0' />
type Update struct {
Goos *string `xml:"os,attr"`
Url *string `xml:"codebase,attr"`
Version *string `xml:"version,attr"`
}
// An UpdateCheckResponse implements Google Chrome update manifest XML format
// borrowed from Google's Omaha.
// See https://developer.chrome.com/apps/autoupdate#update_manifest
//
// <gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'></gupdate>
type UpdateCheckResponse struct {
Apps []*App `xml:"app"`
XMLName xml.Name `xml:"gupdate"`
}
// getAppId returns application identifier.
func (a *App) getAppId() string {
if a.AppId != nil {
return *a.AppId
}
return ""
}
// getUrlAndVersion returns application download URL and latest version that
// match runtime.GOOS, otherwise it will return the first available one.
func (a *App) getUrlAndVersion() (string, string) {
url := ""
version := ""
for _, update := range a.Updates {
if update.getGoos() == runtime.GOOS {
url = update.getUrl()
version = update.getVersion()
break
}
}
if (url == "" || version == "") && len(a.Updates) > 0 {
update := a.Updates[0]
url = update.getUrl()
version = update.getVersion()
}
return url, version
}
// getGoos returns application target OS.
func (u *Update) getGoos() string {
if u.Goos != nil {
return *u.Goos
}
return ""
}
// getUrl returns application download URL.
func (u *Update) getUrl() string {
if u.Url != nil {
return *u.Url
}
return ""
}
// getVersion returns application latest version.
func (u *Update) getVersion() string {
if u.Version != nil {
return *u.Version
}
return ""
}
// GetUrlAndVersion returns download URL and latest version of given
// application name.
func (u *UpdateCheckResponse) GetUrlAndVersion(appName string) (string, string) {
url := ""
version := ""
for _, app := range u.Apps {
if app.getAppId() == appName {
url, version = app.getUrlAndVersion()
break
}
}
return url, version
}