Skip to content

Instantly share code, notes, and snippets.

@anonymous1184
Last active December 24, 2023 17:05
Show Gist options
  • Save anonymous1184/d0b54fc132420c30088748363d5c7f70 to your computer and use it in GitHub Desktop.
Save anonymous1184/d0b54fc132420c30088748363d5c7f70 to your computer and use it in GitHub Desktop.
ImgUr API

; Version: 2022.11.11.1
; About: https://redd.it/on9gab
#Include %A_LineFile%\..\Socket.ahk
#Include %A_LineFile%\..\WinHttpRequest.ahk
class ImgUr_Api {
__New(Ini, Section:="IMGUR") {
IniRead buffer, % Ini, % Section
if (!buffer)
throw Exception("Invalid configuration file.", -1)
for _,line in StrSplit(buffer, "`n") {
parts := StrSplit(line, "=",, 2)
this["_" parts[1]] := parts[2]
}
if (!this._client_id || !this._client_secret)
throw Exception("No Client ID/Secret.", -1, Ini)
if (!this._port)
throw Exception("Port not defined.", -1, Ini)
if (this._port < 1024 && !A_IsAdmin)
throw Exception("Invalid port for server.", -1, Ini)
this._ini := Ini
this._section := Section
this.http := new WinHttpRequest()
if (!this._access_token)
this.Auth()
while (!this._access_token)
Sleep 50
}
Auth() {
server := new SocketTCP()
server.OnAccept := ObjBindMethod(this, "_Socket")
server.Bind(["0.0.0.0", this._port])
server.Listen()
this._access_token := ""
Run % "https://api.imgur.com/oauth2/authorize"
. "?client_id=" this._client_id
. "&response_type=token"
}
Refresh() {
epoch := this._Epoch()
if (epoch < this._expires_at)
return
ep := "https://api.imgur.com/oauth2/token"
body := { "client_secret": this._client_secret
, "grant_type": "refresh_token"
, "refresh_token": this._refresh_token
, "client_id": this._client_id }
try {
response := this.http.Post(ep, body)
if (!response.Json.HasKey("access_token"))
throw
} catch e {
this.Auth()
return
}
this._Persist("access_token", response.access_token)
this._Persist("expires_at", epoch + response.expires_in)
this._Persist("refresh_token", response.refresh_token)
}
Rest(Method, Endpoint, Body:="", Headers:="") {
this.Refresh()
if (!IsObject(Headers))
Headers := {}
Headers.Authorization := "Bearer " this._access_token
http := ObjBindMethod(this.http, Method)
try
response := http.Call(Endpoint, Body, Headers)
catch
return {"error": "Couldn't complete request."}
try
return response.Json
catch
return {"error": "JSON parse error."}
}
_Epoch() {
epoch := A_NowUTC
epoch -= 19700101, Seconds
return epoch
}
_Persist(Key, Value) {
this["_" Key] := Value
IniWrite % " " Value, % this._ini, % this._section, % Key
}
_Socket(Instance) {
conn := Instance.Accept()
request := conn.RecvText()
request := StrSplit(request, A_Space,, 3)[2]
if (request = "/") {
txt := "HTTP/1.1 200 OK" "`r`n"
txt .= "Connection: Close" "`r`n"
txt .= "Content-Type: text/html" "`r`n"
txt .= "`r`n"
; Content in quirks mode
txt .= "<title>ImgUr Authotization</title>"
txt .= "<script>"
txt .= "http = new XMLHttpRequest();"
txt .= "http.open('GET', '?' + window.location.hash.substring(1), true);"
txt .= "http.send()"
txt .= "</script>"
txt .= "<h1>You can close this tab now.</h1>"
} else {
txt := "HTTP/1.1 204 No Content" "`r`n"
txt .= "Connection: Close" "`r`n"
txt .= "`r`n"
}
conn.SendText(txt)
conn.Disconnect()
if (InStr(request, "error")) {
Instance.Disconnect()
throw Exception("Permission not granted, can't continue.", -1)
}
if (InStr(request, "/?")) {
Instance.Disconnect()
RegExMatch(request, "access_token=\K[^&]+", access)
RegExMatch(request, "expires_in=\K[^&]+", expires)
RegExMatch(request, "refresh_token=\K[^&]+", refresh)
this._Persist("access_token", access)
this._Persist("expires_at", this._Epoch() + expires)
this._Persist("refresh_token", refresh)
}
}
__Delete() {
ObjRelease(this.http)
this.http := ""
}
}

; Version: 2022.11.11.1
; About: https://redd.it/on9gab
#Include %A_LineFile%\..\ImgUr_Api.ahk
class ImgUr_Image extends ImgUr_Api {
; id
Delete(ImgId) {
ep := "https://api.imgur.com/3/image/" ImgId
response := this.Rest("DELETE", ep)
return response.HasKey("data") ? response.data : response
}
Info(ImgId) {
ep := "https://api.imgur.com/3/image/" ImgId
; Use `.http` rather than `Rest()`
header := {"Authorization": "Client-ID " this._client_id}
try
response := this.http.GET(ep,, header)
catch
return {"error": "Couldn't complete request."}
try
return response.Json
catch
return {"error": "JSON parse error."}
}
; id, {title, description}
Update(ImgId, Body) {
ep := "https://api.imgur.com/3/image/" ImgId
response := this.Rest("POST", ep, Body)
return response.HasKey("data") ? response.data : response
}
; {image|url|video, album, name, title, description, disable_audio}
Upload(Body) {
; old: https://api.imgur.com/3/image
ep := "https://api.imgur.com/3/upload"
Body.type := "file"
if (Body.HasKey("image")) {
Body.image := [Body.image]
} else if (Body.HasKey("video")) {
Body.video := [Body.video]
} else if (Body.HasKey("url")) {
Body.type := "url"
Body.image := Body.url
}
if (!Body.HasKey("disable_audio"))
Body.disable_audio := 0
response := this.Rest("POST", ep, Body)
if (response.HasKey("data"))
return response.data
if (Body.type != "url")
return response
path := A_Temp "\" A_Now
UrlDownloadToFile % Body.url, % path
Body.Delete("url")
Body.image := path
response := this.Upload(Body)
FileDelete % path
return response
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment