I've never dealt with html scraping, and I really don't want to go down that path if I don't have to, but is it possible to create something that can upload to CloudApp, hopefully without using a browser?
I found this, but I don't know how to use that language.
Is it possible to create a wrapper for uploading to CloudApp? Topic is solved
Re: Is it possible to create a wrapper for uploading to CloudApp?
Just wrote one
CloudApp.ahk
Example:
Download: https://github.com/tmplinshi/CloudApp.ahk
CloudApp.ahk
Code: Select all
/*
Requires:
CreateFormData.ahk - https://gist.github.com/tmplinshi/8428a280bba58d25ef0b
BinArr.ahk - https://gist.github.com/tmplinshi/a97d9a99b9aa5a65fd20
Jxon.ahk (by Coco) - https://www.autohotkey.com/boards/viewtopic.php?t=627
Supported methods:
CreateBookmark(name, url)
ListItems(paramters := "page=1&per_page=5")
DeleteItem(url)
ViewItem(url)
uploadFile(FilePath)
Example:
api := New CloudApp("your email", "your password")
objResult := api.uploadFile("D:\Desktop\1.jpg")
MsgBox % Jxon_Dump(objResult)
*/
; CloudApp API Document: https://github.com/cloudapp/api/blob/master/README.md
class CloudApp
{
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
__New(email, password) {
this.http("GET", "https://my.cl.ly/account")
auth := DigestAuth.Build(email, password, "GET", "/account", this.whr.getResponseHeader("WWW-Authenticate"))
oHeaders := {"Authorization": auth}
this.http("GET", "https://my.cl.ly/account",, oHeaders)
this.getCookie()
if (this.whr.Status != 200)
throw "Login failed"
}
CreateBookmark(name, url) {
body := {item: {name: name, redirect_url: url}}
return this.http("POST", "https://my.cl.ly/items", body)
}
/*
Optional paramters:
page=1 : Page number starting at 1.
per_page=5 : Number of items per page.
type=image : Filter items by type (image, bookmark, text, archive, audio, video, or unknown).
deleted=true : Show trashed items.
source=MyApp : Filter items by all or part of the User-Agent.
*/
ListItems(paramters := "page=1&per_page=5") {
return this.http("GET", "https://my.cl.ly/items?" paramters)
}
DeleteItem(url) {
return this.http("DELETE", url)
}
ViewItem(url) {
return this.http("GET", url)
}
uploadFile(FilePath) {
ret := this.http("GET", "https://my.cl.ly/items/new")
objParam := ret.params
objParam.file := [FilePath]
CreateFormData(body, vContentType, objParam)
oHeaders := {"Content-Type": vContentType}
return this.http("POST", ret.url, body, oHeaders, 600)
}
http(method, url, body := "", oHeaders := "", timeoutSeconds := 30) {
whr := this.whr
whr.Open(method, url, true)
whr.SetRequestHeader("Accept", "application/json")
if !oHeaders.HasKey("Content-Type") {
whr.SetRequestHeader("Content-Type", "application/json")
}
if this.cookie {
whr.SetRequestHeader("Cookie", this.cookie)
}
for k, v in oHeaders
whr.SetRequestHeader(k, v)
try {
if IsObject(body)
body := Jxon_Dump(body)
}
If (timeoutSeconds > 30)
whr.SetTimeouts(0, 60000, 30000, timeoutSeconds * 1000)
whr.Send(body)
whr.WaitForResponse()
if InStr(whr.getResponseHeader("Content-Type"), "application/json")
return Jxon_Load(whr.responseText)
}
getCookie() {
hdrs := this.whr.getAllResponseHeaders()
pos := 1
while pos := RegExMatch(hdrs, "`am)^Set-Cookie: \K[^;]+", m, pos+StrLen(m))
this.cookie .= (A_Index>1 ? "; " : "") . m
}
}
; https://en.wikipedia.org/wiki/Digest_access_authentication
class DigestAuth
{
Build(username, password, method, uri, ByRef WWWAuthenticate) {
Loop, Parse, % "realm|qop|algorithm|nonce|opaque", |
RegExMatch(WWWAuthenticate, A_LoopField "=""?\K[^,""]+", %A_LoopField%)
cnonce := this.create_cnonce()
nonceCount := "00000001"
ha1 := this.StrMD5(username ":" realm ":" password)
ha2 := this.StrMD5(method ":" uri)
response := this.StrMD5(ha1 ":" nonce ":" nonceCount ":" cnonce ":" qop ":" ha2)
return "
(Join, LTrim
Digest username=""" username """
realm=""" realm """
nonce=""" nonce """
uri=""" uri """
algorithm=""" algorithm """
cnonce=""" cnonce """
nc=" nonceCount "
qop=""" qop """
response=""" response """
opaque=""" opaque """
)"
}
StrMD5( V ) { ; www.autohotkey.com/forum/viewtopic.php?p=376840#376840
VarSetCapacity( MD5_CTX,104,0 ), DllCall( "advapi32\MD5Init", UInt,&MD5_CTX )
DllCall( "advapi32\MD5Update", UInt,&MD5_CTX, A_IsUnicode ? "AStr" : "Str",V
, UInt,StrLen(V) ), DllCall( "advapi32\MD5Final", UInt,&MD5_CTX )
Loop % StrLen( Hex:="123456789abcdef0" )
N := NumGet( MD5_CTX,87+A_Index,"Char"), MD5 .= SubStr(Hex,N>>4,1) . SubStr(Hex,N&15,1)
Return MD5
}
CreateGUID() { ; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4732
VarSetCapacity(pguid, 16, 0)
if !(DllCall("ole32.dll\CoCreateGuid", "ptr", &pguid)) {
size := VarSetCapacity(sguid, (38 << !!A_IsUnicode) + 1, 0)
if (DllCall("ole32.dll\StringFromGUID2", "ptr", &pguid, "ptr", &sguid, "int", size))
return StrGet(&sguid)
}
return ""
}
create_cnonce() {
guid := this.CreateGUID()
StringLower, guid, guid
return RegExReplace(guid, "[{}-]")
}
}
Code: Select all
; Register your account at https://www.getcloudapp.com/
#Include CloudApp.ahk
; Login
api := New CloudApp("your email", "your password")
; Upload File
objResult := api.uploadFile("D:\Desktop\1.jpg")
MsgBox % Jxon_Dump(objResult)
Re: Is it possible to create a wrapper for uploading to CloudApp? Topic is solved
tmplinshi wrote: ↑12 Jan 2019, 13:19Just wrote one
CloudApp.ahkExample:Code: Select all
/* Requires: CreateFormData.ahk - https://gist.github.com/tmplinshi/8428a280bba58d25ef0b BinArr.ahk - https://gist.github.com/tmplinshi/a97d9a99b9aa5a65fd20 Jxon.ahk (by Coco) - https://www.autohotkey.com/boards/viewtopic.php?t=627 Supported methods: CreateBookmark(name, url) ListItems(paramters := "page=1&per_page=5") DeleteItem(url) ViewItem(url) uploadFile(FilePath) Example: api := New CloudApp("your email", "your password") objResult := api.uploadFile("D:\Desktop\1.jpg") MsgBox % Jxon_Dump(objResult) */ ; CloudApp API Document: https://github.com/cloudapp/api/blob/master/README.md class CloudApp { whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") __New(email, password) { this.http("GET", "https://my.cl.ly/account") auth := DigestAuth.Build(email, password, "GET", "/account", this.whr.getResponseHeader("WWW-Authenticate")) oHeaders := {"Authorization": auth} this.http("GET", "https://my.cl.ly/account",, oHeaders) this.getCookie() if (this.whr.Status != 200) throw "Login failed" } CreateBookmark(name, url) { body := {item: {name: name, redirect_url: url}} return this.http("POST", "https://my.cl.ly/items", body) } /* Optional paramters: page=1 : Page number starting at 1. per_page=5 : Number of items per page. type=image : Filter items by type (image, bookmark, text, archive, audio, video, or unknown). deleted=true : Show trashed items. source=MyApp : Filter items by all or part of the User-Agent. */ ListItems(paramters := "page=1&per_page=5") { return this.http("GET", "https://my.cl.ly/items?" paramters) } DeleteItem(url) { return this.http("DELETE", url) } ViewItem(url) { return this.http("GET", url) } uploadFile(FilePath) { ret := this.http("GET", "https://my.cl.ly/items/new") objParam := ret.params objParam.file := [FilePath] CreateFormData(body, vContentType, objParam) oHeaders := {"Content-Type": vContentType} return this.http("POST", ret.url, body, oHeaders, 600) } http(method, url, body := "", oHeaders := "", timeoutSeconds := 30) { whr := this.whr whr.Open(method, url, true) whr.SetRequestHeader("Accept", "application/json") if !oHeaders.HasKey("Content-Type") { whr.SetRequestHeader("Content-Type", "application/json") } if this.cookie { whr.SetRequestHeader("Cookie", this.cookie) } for k, v in oHeaders whr.SetRequestHeader(k, v) try { if IsObject(body) body := Jxon_Dump(body) } If (timeoutSeconds > 30) whr.SetTimeouts(0, 60000, 30000, timeoutSeconds * 1000) whr.Send(body) whr.WaitForResponse() if InStr(whr.getResponseHeader("Content-Type"), "application/json") return Jxon_Load(whr.responseText) } getCookie() { hdrs := this.whr.getAllResponseHeaders() pos := 1 while pos := RegExMatch(hdrs, "`am)^Set-Cookie: \K[^;]+", m, pos+StrLen(m)) this.cookie .= (A_Index>1 ? "; " : "") . m } } ; https://en.wikipedia.org/wiki/Digest_access_authentication class DigestAuth { Build(username, password, method, uri, ByRef WWWAuthenticate) { Loop, Parse, % "realm|qop|algorithm|nonce|opaque", | RegExMatch(WWWAuthenticate, A_LoopField "=""?\K[^,""]+", %A_LoopField%) cnonce := this.create_cnonce() nonceCount := "00000001" ha1 := this.StrMD5(username ":" realm ":" password) ha2 := this.StrMD5(method ":" uri) response := this.StrMD5(ha1 ":" nonce ":" nonceCount ":" cnonce ":" qop ":" ha2) return " (Join, LTrim Digest username=""" username """ realm=""" realm """ nonce=""" nonce """ uri=""" uri """ algorithm=""" algorithm """ cnonce=""" cnonce """ nc=" nonceCount " qop=""" qop """ response=""" response """ opaque=""" opaque """ )" } StrMD5( V ) { ; www.autohotkey.com/forum/viewtopic.php?p=376840#376840 VarSetCapacity( MD5_CTX,104,0 ), DllCall( "advapi32\MD5Init", UInt,&MD5_CTX ) DllCall( "advapi32\MD5Update", UInt,&MD5_CTX, A_IsUnicode ? "AStr" : "Str",V , UInt,StrLen(V) ), DllCall( "advapi32\MD5Final", UInt,&MD5_CTX ) Loop % StrLen( Hex:="123456789abcdef0" ) N := NumGet( MD5_CTX,87+A_Index,"Char"), MD5 .= SubStr(Hex,N>>4,1) . SubStr(Hex,N&15,1) Return MD5 } CreateGUID() { ; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4732 VarSetCapacity(pguid, 16, 0) if !(DllCall("ole32.dll\CoCreateGuid", "ptr", &pguid)) { size := VarSetCapacity(sguid, (38 << !!A_IsUnicode) + 1, 0) if (DllCall("ole32.dll\StringFromGUID2", "ptr", &pguid, "ptr", &sguid, "int", size)) return StrGet(&sguid) } return "" } create_cnonce() { guid := this.CreateGUID() StringLower, guid, guid return RegExReplace(guid, "[{}-]") } }
Download: https://github.com/tmplinshi/CloudApp.ahkCode: Select all
; Register your account at https://www.getcloudapp.com/ #Include CloudApp.ahk ; Login api := New CloudApp("your email", "your password") ; Upload File objResult := api.uploadFile("D:\Desktop\1.jpg") MsgBox % Jxon_Dump(objResult)
Getting an error on Line 36 of CloudApp.ahk when launched from Test.CloudApp.ahk. I'm guessing that throw requires a catch?? I've never used it before. Changing throw to MsgBox clears the error and displays "Login Failed".
I've not seen some of the code you provided... very interesting and I will have to spend some time going through it line by line to understand it.
Question:
Do I need to provide the credentials enclosed in quotes when setting the API?
Re: Is it possible to create a wrapper for uploading to CloudApp?
I finally had a chance to implement this code into my script. The first several times everything went as planned, but the last two garnered an error, "Show Something". I couldn't track down what caused it, and I didn't grab a screen shot.
Any idea what may have thrown that flag?
Any idea what may have thrown that flag?
Re: Is it possible to create a wrapper for uploading to CloudApp?
It might be timeout, or big files. I tried uploading a 916MB file, and got an error from "ADODB.Stream":
Code: Select all
Error in #include file "D:\code\AutoHotkey\Lib\BinArr.ahk":
0x8007000E - Not enough memory resources are available to complete this operation.
Source: Provider
Description: Not enough memory resources are available to complete this operation.
HelpFile: (null)
HelpContext: 1240640
Specifically: Read
Line#
015: Return,oADO.Read, oADO.Close
016: }
018: {
019: oADO := ComObjCreate("ADODB.Stream")
021: oADO.Type := 1
022: oADO.Open
023: oADO.LoadFromFile(FileName)
---> 024: Return,oADO.Read, oADO.Close
Re: Is it possible to create a wrapper for uploading to CloudApp?
tmplinshi, why do You use ADO object and not get data directly from memory?
https://www.autohotkey.com/boards/viewtopic.php?p=85687#p85687
https://www.autohotkey.com/boards/viewtopic.php?p=85687#p85687
Re: Is it possible to create a wrapper for uploading to CloudApp?
@malcev Because I haven't encountered any error for my scripts using the ADO object, and I'm too lazy to take the time learning the memory approach.. It's on my to-do list though.
Re: Is it possible to create a wrapper for uploading to CloudApp?
I had received that once before on the session prior to my latest post. I didn't understand it, so I restarted my app and got the "Show Something" error the second and third times. My files are less than 20MB.
How can I go about making this more stable? I'm unfamiliar with ADO coding. Truth be told, a LOT of the code you provided is way over my head. I wouldn't even know where to start to learn.
Re: Is it possible to create a wrapper for uploading to CloudApp?
Here it is:
Code: Select all
---------------------------
RDIEmailer.exe
---------------------------
Error: SOMEthing failed
Line#
010: {
011: this.http("GET", "https://my.cl.ly/account")
012: auth := DigestAuth.Build(email, password, "GET", "/account", this.whr.getResponseHeader("WWW-Authenticate"))
013: oHeaders := {"Authorization": auth}
014: this.http("GET", "https://my.cl.ly/account",, oHeaders)
015: this.getCookie()
016: if (this.whr.Status != 200)
---> 017: Throw,"SOMEthing failed"
018: }
019: {
020: body := {item: {name: name, redirect_url: url}}
021: Return,this.http("POST", "https://my.cl.ly/items", body)
022: }
023: {
024: Return,this.http("GET", "https://my.cl.ly/items?" paramters)
The current thread will exit.
---------------------------
OK
---------------------------
Re: Is it possible to create a wrapper for uploading to CloudApp?
That's a "login failed" error. Maybe you typed an incorrect username/password?
Re: Is it possible to create a wrapper for uploading to CloudApp?
Not relating to the CloudApp Wrapper, but still in the same script... can anyone help me to identify the error here?
FileSeries is a local variable being defined on line 542/544. The value of CellSeries_Title is Stewardship Conf, and the value of CellSeries_Num is Message 1. What went wrong here?---------------------------
RDIEmailer.exe
---------------------------
Error: The following variable name contains an illegal character:
"Stewardship Conf"
Line#
536: if !(IsOpen)
536: {
537: oWorkBook.Close()
538: }
540: months := ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Aug","Sep","Oct","Nov","Dec"]
541: if (CellSeries_Num <> "")
541: {
---> 542: FileSeries := %CellSeries_Title% . " " . %CellSeries_Num% . " - "
543: }
543: Else
543: {
544: FileSeries := ""
545: }
546: SplitPath,Attachment,,Folder
547: FileDate := StrSplit(CellDate, "/")
The current thread will exit.
---------------------------
OK
---------------------------
Re: Is it possible to create a wrapper for uploading to CloudApp?
The := means you are in expression mode. That means, variables should (usually) be used without %s.
Using the %'s here causes a double deref, that means, SteStewardship Conf is seen as a variable name (but the space is obv not allowed) instead of variable content, which is not your intention, I assume:
Using the %'s here causes a double deref, that means, SteStewardship Conf is seen as a variable name (but the space is obv not allowed) instead of variable content, which is not your intention, I assume:
TryError: The following variable name contains an illegal character:
"Stewardship Conf"
Code: Select all
FileSeries := CellSeries_Title . " " . CellSeries_Num . " - "
Re: Is it possible to create a wrapper for uploading to CloudApp?
AHHHHhhhhhh.... so the illegal character was the space!! Now it makes sense. I kept looking at it over and over and just could not place what the error was all about.gregster wrote: ↑26 Jan 2019, 12:51The := means you are in expression mode. That means, variables should (usually) be used without %s.
Using the %'s here causes a double deref, that means, SteStewardship Conf is seen as a variable name (but the space is obv not allowed) instead of variable content, which is not your intention, I assume:TryError: The following variable name contains an illegal character:
"Stewardship Conf"Code: Select all
FileSeries := CellSeries_Title . " " . CellSeries_Num . " - "
Thank you.
Re: Is it possible to create a wrapper for uploading to CloudApp?
Here are the two ADO errors I got today. Is there something that I'm doing wrong that is causing this?
---------------------------
RDIEmailer.exe
---------------------------
Error: 0x800A0BBA -
Source: ADODB.Stream
Description: File could not be opened.
HelpFile: C:\Windows\HELP\ADO270.CHM
HelpContext: 1240642
Specifically: LoadFromFile
Line#
126: oADO.Position := 3
127: Return,oADO.Read, oADO.Close
128: }
129: {
130: oADO := ComObjCreate("ADODB.Stream")
131: oADO.Type := 1
132: oADO.Open
---> 133: oADO.LoadFromFile(FileName)
134: Return,oADO.Read, oADO.Close
135: }
136: {
137: oADO := ComObjCreate("ADODB.Stream")
138: oADO.Type := 1
139: oADO.Mode := 3
140: oADO.Open
Continue running the script?
---------------------------
Yes No
---------------------------
---------------------------
RDIEmailer.exe
---------------------------
Error: 0x800A0BB9 -
Source: ADODB.Stream
Description: Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
HelpFile: C:\Windows\HELP\ADO270.CHM
HelpContext: 1240641
Specifically: Write
Line#
135: }
136: {
137: oADO := ComObjCreate("ADODB.Stream")
138: oADO.Type := 1
139: oADO.Mode := 3
140: oADO.Open
141: For i,arr in Arrays
---> 142: oADO.Write(arr)
143: oADO.Position := 0
144: Return,oADO.Read, oADO.Close
145: }
146: {
147: oADO := ComObjCreate("ADODB.Stream")
148: oADO.Type := 1
149: oADO.Mode := 3
Continue running the script?
---------------------------
Yes No
---------------------------
Re: Is it possible to create a wrapper for uploading to CloudApp?
Maybe the file path is wrong, or the file is being opened and locked by another program. I have tesed a .xlsx file that is opened by excel, and got the same error.
Re: Is it possible to create a wrapper for uploading to CloudApp?
Since that help file does not exist on any of my machines, that might be it. However, what's trying to call for it, and why? How do I get that file or work around this issue?
Who is online
Users browsing this forum: No registered users and 74 guests