-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathGitHub.ahk
More file actions
144 lines (130 loc) · 4.67 KB
/
GitHub.ahk
File metadata and controls
144 lines (130 loc) · 4.67 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
135
136
137
138
139
140
141
142
143
144
class GitHub
{
class Context
{
__new(owner, repo, token)
{
this.owner := owner
this.repo := repo
this.token := token
}
Request(method, url, payload:="", headers:="")
{
url := StrReplace(url, ":owner", this.owner)
url := StrReplace(url, ":repo", this.repo)
if SubStr(url,1,1) = "/"
url := "https://api.github.com" url
req := ComObjCreate("Msxml2.XMLHTTP")
req.open(method, url, true)
req.setRequestHeader("Authorization", "token " this.token)
for k,v in headers {
req.setRequestHeader(k,v)
}
req.send(payload)
while req.readyState != 4
sleep 100
return req
}
}
class Release
{
; new Release(context
; , {tag_name, name=tag_name, body, draft=false, prerelease=false})
__new(context, opt)
{
tag_name := opt.tag_name
name := opt.name!="" ? opt.name : tag_name
body := opt.body
body := RegExReplace(body, "[""\\]", "\$0")
body := RegExReplace(body, "\R", "\n")
body := RegExReplace(body, "\t", "\t")
draft := opt.draft ? "true" : "false"
prerelease := opt.prerelease ? "true" : "false"
payload =
(LTrim
{
"tag_name": "%tag_name%",
"name": "%name%",
"body": "%body%",
"draft": %draft%,
"prerelease": %prerelease%
}
)
req := context.Request("POST", "/repos/:owner/:repo/releases", payload)
if (req.statusText != "Created")
{
if InStr(req.responseText, "JSON")
throw Exception("Bad release payload", -1, release)
else
throw Exception("Error creating release; status " req.statusText, -1, req.responseText)
}
JSON_parse_into(req.responseText, this)
this.context := context
}
; Query for an existing (non-draft) release with the given tag
FromTag(context, tag)
{
try {
req := context.Request("GET", "/repos/:owner/:repo/releases/tags/" tag)
if (req.statusText != "OK")
throw 1
}
catch
return
this := {base: this}
JSON_parse_into(req.responseText, this)
this.context := context
return this
}
AddAsset(name, filename)
{
/* ; This could be used to replace an existing asset
Loop % this.assets.length
if this.assets[A_Index-1].name = name
{
this.context.Request("DELETE", "/repos/:owner/:repo/releases/assets/"
. this.assets[A_Index-1].id)
break
}
*/
upload_url := RegExReplace(this.upload_url, "\{\?[^\}]*\bname\b[^\}]*\}"
, "?name=" name, count)
if !count
throw Exception("Bad upload_url", -1, this.upload_url)
bytes := FileReadBytes(filename)
D("! Uploading " name " (" bytes.MaxIndex()+1 " bytes)")
req := this.context.Request("POST", upload_url, bytes
, {"Content-Type": ContentType(filename)})
if (req.statusText != "Created")
throw Exception("Failed to upload asset", -1, req.status " " req.statusText "`n" req.responseText)
return JSON_parse_into(req.responseText, {})
}
}
}
ContentType(filename) {
SplitPath % filename,,, ext
return (ext = "zip") ? "application/zip" : "application/octet-stream"
}
FileReadBytes(filename) {
stream := ComObjCreate("ADODB.Stream")
stream.Type := 1 ; adTypeBinary
stream.Open()
stream.LoadFromFile(filename)
return stream.Read() ; Returns an array of bytes.
}
; Lazy JSON parser : requires AutoHotkey 32-bit or Lib\ActiveScript.ahk
JSON_parse_into(json, obj) {
static js
if !js {
if ActiveScript
js := new ActiveScript("JScript")
else
js := ComObjCreate("ScriptControl"), js.Language := "JScript"
js.Eval("function parseinto(s,o) { e=eval('0,'+s); for (k in e) o[k]=e[k]; return o}")
}
if ComObjType(js)
return js.Run("parseinto", json, obj)
else
return js.parseinto(json, obj)
}
#Include *i <ActiveScript>