Тема: AHK: Заливка файлов на filemail.com
Тема для обсуждения "Заливка файлов на filemail.com".
http://forum.script-coding.com/viewtopic.php?id=17680
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Тема для обсуждения "Заливка файлов на filemail.com".
http://forum.script-coding.com/viewtopic.php?id=17680
Не нашел инфы о том, как долго потом могут храниться эти залитые файлы?
7 дней.
У меня так работает, без учёта количества потоков. Да и разве может процесс AHK в несколько потоков загружать файл?
MsgBox, % Clipboard := UploadFileToFilemail("from@gmail.com", "to@gmail.com", "file", "hello!")
UploadFileToFilemail(from, to, subject, message) {
FileSelectFile, filePath,,, Choose file to upload, All Files (*.*)
if !filePath
ExitApp
json := Init(from, to, subject, message)
if error := JsonRead(json, transferID, transferKEY, transferURL)
Return error
SplitPath, filePath, fileName
fileName := URIEncode(fileName)
oFile := FileOpen(filePath, "r")
fileSize := oFile.length
chunkSize := 5242880
chunksNumber := Ceil(fileSize/chunkSize)
lastChunkSize := mod(fileSize, chunkSize)
info := {parts: chunksNumber}
CoordMode, ToolTip
ToolTip, % "parts: " chunksNumber, 3, 3, 1
Loop % chunksNumber {
currentChunkSize := A_Index = chunksNumber ? lastChunkSize : chunkSize
link := transferURL . "?transferid=" . transferID . "&transferkey=" . transferKEY
. "&chunksize=" . chunkSize . "&thefilename=" . fileName . "&totalsize=" . fileSize
. "&chunks=" . chunksNumber . "&chunk=" . A_Index - 1 . "&runtime=html5&retry=0"
SendChunk(oFile, currentChunkSize, link, info)
}
oFile.Close()
while info.parts
Sleep, 100
ToolTip,,,, 1
Return GetUrl(transferID, transferKEY)
}
Init(from, to, subject, message) {
from := URIEncode(from), to := URIEncode(to), subject := URIEncode(subject), message := URIEncode(message)
body := "sourcedetails=plupload(html5)+`%40+https`%3A`%2F`%2Fwww.filemail.com`%2F&to`%5B`%5D="
. to "&from=" from "&subject=" subject "&message=" message "&days=7&confirmation=true"
Return SetRequest(body, "initialize")
}
JsonRead(json, ByRef transferID, ByRef transferKEY, ByRef transferURL) {
RegexMatch(json, "s)""transferid"": ""(.+?)"".+?""transferkey"": ""(.+?)"".+?""transferurl"": ""(.+?)""", match)
transferID := match1, transferKEY := match2, transferURL := match3
if !(transferID && transferKEY && transferURL)
Return json
}
GetUrl(transferID, transferKEY) {
body := "transferid=" . transferid . "&transferkey=" . transferkey . "&failed=false"
responseText := SetRequest(body, "complete")
RegexMatch(responseText, """downloadurl"": ""\K[^""]+", url)
Return url ? url : responseText
}
SetRequest(body, mode) {
HTTP := ComObjCreate("Msxml2.XMLHTTP")
HTTP.Open("POST", "https://www.filemail.com/api/transfer/" . mode, false)
HTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Source", "Web")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.Send(body)
Return HTTP.responseText
}
SendChunk(ByRef oFile, size, link, info) {
safeArr := ComObjArray(0x11, size) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
pData := NumGet( ComObjValue(safeArr) + 8 + A_PtrSize )
oFile.RawRead(pData + 0, size)
HTTP := ComObjCreate("Msxml2.XMLHTTP")
HTTP.Open("POST", link, true)
HTTP.OnReadyStateChange := Func("WatchState").Bind(HTTP, info)
HTTP.SetRequestHeader("Content-Type", "application/octet-stream")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.Send(safeArr)
}
WatchState(HTTP, info) {
if (HTTP.ReadyState != 4)
return
CoordMode, ToolTip
ToolTip, % "rest: " . (--info.parts), 3, 3, 1
}
URIEncode(str, encoding := "UTF-8") {
VarSetCapacity(var, StrPut(str, encoding))
StrPut(str, &var, encoding)
While code := NumGet(Var, A_Index - 1, "UChar") {
bool := (code > 0x7F || code < 0x30 || code = 0x3D)
UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
}
Return UrlStr
}
С потоками работает на 5-20% быстрее с 1.5-2 гигабайтным файлами.
Зависит, похоже, от максимальной скорости интернета - чем она больше, тем больше разница.
Проверял 4 раза.
Но в принципе в моем коде не учтены такие вещи, как выпадание интернета - в таких случаях, думаю, возможны битые файлы.
Надо тестировать.
С потоками работает на 5-20% быстрее с 1.5-2 гигабайтным файлами.
Возможно, не проверял. Но это не от того, что там есть мешающие друг другу потоки загрузки, а видимо из-за ограничения в AHK количества параллельных псевдо-веток, которые создаются в WatchState(), лишние начинают буфферизироваться и замедлять общую скорость.
В моём варианте тоже не всё учтено, он для демонстрации возможности обойтись без глобальных переменных. Так-то надо везде HTTP.status проверять.
Я сравнивал в своем коде с одним потоком и с 4.
С 4 работает на 5 -20% быстрее, что с твоим кодом, что с моим.
Если сравнить твой код с 1 потоком и мой с 1 потоком - результат идентичный.
Можно ещё с #MaxThreads попробовать поиграть. По умолчанию их 10.
А почему ты считаешь, что дело в ahk, а не в сервере, который оптимизирует скорость загрузки при 4 потоках?
Так потому что здесь нет реальных параллельных потоков загрузки. Пока каждый HTTP.Send не отработает, новый не начинается. Хотя, конечно надо проверить.
В моем коде есть.
В этом смысле оба кода не отличаются. Только твой ждёт ответа после 4-го куска файла.
Почему?
Он ждет ответа после каждого куска файла, но одновременно не может быть послано более 4.
Надо попробовать замерить скорость загрузки через IE и сравнить.
Он ждет ответа после каждого куска файла
Кто — он? Твой ждёт только после 4, мой вообще не ждёт.
Мой скрипт.
А теперь зайди в таскменеджер и посмотри сколь съедает памяти твой скрипт при загрузке файла в пару гигабайт.
Да, недоглядел, но нетрудно исправить:
#MaxThreads 255
SetBatchLines, -1
start := A_TickCount
Clipboard := UploadFileToFilemail("from@gmail.com", "to@gmail.com", "file", "hello!")
MsgBox, % (A_TickCount - start)//1000
UploadFileToFilemail(from, to, subject, message) {
FileSelectFile, filePath,,, Choose file to upload, All Files (*.*)
if !filePath
ExitApp
json := Init(from, to, subject, message)
if error := JsonRead(json, transferID, transferKEY, transferURL)
Return error
SplitPath, filePath, fileName
fileName := URIEncode(fileName)
oFile := FileOpen(filePath, "r")
fileSize := oFile.length
chunkSize := 5242880
chunksNumber := Ceil(fileSize/chunkSize)
lastChunkSize := mod(fileSize, chunkSize)
PID := DllCall("GetCurrentProcessId")
hLib := DllCall("LoadLibrary", Str, Psapi.dll, Ptr)
flags := (PROCESS_QUERY_INFORMATION := 0x400) | (PROCESS_SET_QUOTA := 0x100)
info := {parts: chunksNumber, hProc: DllCall("OpenProcess", UInt, flags, UInt, false, UInt, PID, Ptr)}
CoordMode, ToolTip
ToolTip, % "parts: " chunksNumber, 3, 3, 1
Loop % chunksNumber {
currentChunkSize := A_Index = chunksNumber ? lastChunkSize : chunkSize
link := transferURL . "?transferid=" . transferID . "&transferkey=" . transferKEY
. "&chunksize=" . chunkSize . "&thefilename=" . fileName . "&totalsize=" . fileSize
. "&chunks=" . chunksNumber . "&chunk=" . A_Index - 1 . "&runtime=html5&retry=0"
SendChunk(oFile, currentChunkSize, link, info)
}
oFile.Close()
while info.parts
Sleep, 100
DllCall("CloseHandle", Ptr, info.hProc)
DllCall("FreeLibrary", Ptr, hLib)
ToolTip,,,, 1
Return GetUrl(transferID, transferKEY)
}
Init(from, to, subject, message) {
from := URIEncode(from), to := URIEncode(to), subject := URIEncode(subject), message := URIEncode(message)
body := "sourcedetails=plupload(html5)+`%40+https`%3A`%2F`%2Fwww.filemail.com`%2F&to`%5B`%5D="
. to "&from=" from "&subject=" subject "&message=" message "&days=7&confirmation=true"
Return SetRequest(body, "initialize")
}
JsonRead(json, ByRef transferID, ByRef transferKEY, ByRef transferURL) {
RegexMatch(json, "s)""transferid"": ""(.+?)"".+?""transferkey"": ""(.+?)"".+?""transferurl"": ""(.+?)""", match)
transferID := match1, transferKEY := match2, transferURL := match3
if !(transferID && transferKEY && transferURL)
Return json
}
GetUrl(transferID, transferKEY) {
body := "transferid=" . transferid . "&transferkey=" . transferkey . "&failed=false"
responseText := SetRequest(body, "complete")
RegexMatch(responseText, """downloadurl"": ""\K[^""]+", url)
Return url ? url : responseText
}
SetRequest(body, mode) {
HTTP := ComObjCreate("Msxml2.XMLHTTP.6.0")
HTTP.Open("POST", "https://www.filemail.com/api/transfer/" . mode, false)
HTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Source", "Web")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.Send(body)
Return HTTP.responseText
}
SendChunk(ByRef oFile, size, link, info) {
safeArr := ComObjArray(0x11, size) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
pData := NumGet( ComObjValue(safeArr) + 8 + A_PtrSize )
oFile.RawRead(pData + 0, size)
HTTP := ComObjCreate("Msxml2.XMLHTTP.6.0")
HTTP.Open("POST", link, true)
HTTP.OnReadyStateChange := Func("WatchState").Bind(HTTP, info)
HTTP.SetRequestHeader("Content-Type", "application/octet-stream")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.Send(safeArr)
}
WatchState(HTTP, info) {
if (HTTP.ReadyState != 4)
return
DllCall("Psapi\EmptyWorkingSet", Ptr, info.hProc)
CoordMode, ToolTip
ToolTip, % "rest: " . (--info.parts), 3, 3, 1
}
URIEncode(str, encoding := "UTF-8") {
VarSetCapacity(var, StrPut(str, encoding))
StrPut(str, &var, encoding)
While code := NumGet(Var, A_Index - 1, "UChar") {
bool := (code > 0x7F || code < 0x30 || code = 0x3D)
UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
}
Return UrlStr
}
А что изменилось? У тебя памяти съедает гигабайты.
А ты на какой системе запускаешь?
На win10 ahk64.
А, опечатка там, поправил.
Ну не знаю.
У меня только что при заливке 20 гигов, до 4 гигов доходило потребление.
В смысле, на исправленном варианте?
У меня на win 10 не превышает 10 MB, на Win 7 чуть больше.
Да, на исправленном варианте.
И CPU до 10%.
ИМХО все эти игры с памятью, так себе затея.
Кстати, мой вариант - потребление 45мб и cpu 0.2% максимум.
Я, пожалуй, переделаю на winhttprequest с одним потоком и отловом ошибок.
У меня нет файла в 20 гигов, чтоб проверить, сейчас пробовал примерно 1Гб — на Win 7 от 5 MB до 15, и не растёт, на Win 10 ещё меньше, но десятка у меня через Wi-Fi, так что некорректно проверять. А поменьше файл пробовал взять?
Я, пожалуй, переделаю на winhttprequest с одним потоком и отловом ошибок
Так пробовал, без игр с памятью, тоже работает, хотя чуть медленнее.
С 1 Гб у меня так же как у тебя.
В один поток:
#MaxThreads 255
SetBatchLines, -1
start := A_TickCount
Clipboard := UploadFileToFilemail("from@gmail.com", "to@gmail.com", "file", "hello!")
MsgBox, % (A_TickCount - start)//1000
UploadFileToFilemail(from, to, subject, message) {
FileSelectFile, filePath,,, Choose file to upload, All Files (*.*)
if !filePath
ExitApp
json := Init(from, to, subject, message)
if error := JsonRead(json, transferID, transferKEY, transferURL)
Return error
SplitPath, filePath, fileName
fileName := URIEncode(fileName)
oFile := FileOpen(filePath, "r")
fileSize := oFile.length
chunkSize := 5242880
chunksNumber := Ceil(fileSize/chunkSize)
lastChunkSize := mod(fileSize, chunkSize)
info := {parts: chunksNumber}
CoordMode, ToolTip
ToolTip, % "parts: " chunksNumber, 3, 3, 1
Loop % chunksNumber {
currentChunkSize := A_Index = chunksNumber ? lastChunkSize : chunkSize
link := transferURL . "?transferid=" . transferID . "&transferkey=" . transferKEY
. "&chunksize=" . chunkSize . "&thefilename=" . fileName . "&totalsize=" . fileSize
. "&chunks=" . chunksNumber . "&chunk=" . A_Index - 1 . "&runtime=html5&retry=0"
SendChunk(oFile, currentChunkSize, link, info)
}
oFile.Close()
ToolTip,,,, 1
Return GetUrl(transferID, transferKEY)
}
Init(from, to, subject, message) {
from := URIEncode(from), to := URIEncode(to), subject := URIEncode(subject), message := URIEncode(message)
body := "sourcedetails=plupload(html5)+`%40+https`%3A`%2F`%2Fwww.filemail.com`%2F&to`%5B`%5D="
. to "&from=" from "&subject=" subject "&message=" message "&days=7&confirmation=true"
Return SetRequest(body, "initialize")
}
JsonRead(json, ByRef transferID, ByRef transferKEY, ByRef transferURL) {
RegexMatch(json, "s)""transferid"": ""(.+?)"".+?""transferkey"": ""(.+?)"".+?""transferurl"": ""(.+?)""", match)
transferID := match1, transferKEY := match2, transferURL := match3
if !(transferID && transferKEY && transferURL)
Return json
}
GetUrl(transferID, transferKEY) {
body := "transferid=" . transferid . "&transferkey=" . transferkey . "&failed=false"
responseText := SetRequest(body, "complete")
RegexMatch(responseText, """downloadurl"": ""\K[^""]+", url)
Return url ? url : responseText
}
SetRequest(body, mode) {
HTTP := ComObjCreate("Msxml2.XMLHTTP.6.0")
HTTP.Open("POST", "https://www.filemail.com/api/transfer/" . mode, false)
HTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Source", "Web")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.Send(body)
Return HTTP.responseText
}
SendChunk(ByRef oFile, size, link, info) {
safeArr := ComObjArray(0x11, size) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
pData := NumGet( ComObjValue(safeArr) + 8 + A_PtrSize )
oFile.RawRead(pData + 0, size)
HTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1")
HTTP.Open("POST", link, true)
HTTP.SetRequestHeader("Content-Type", "application/octet-stream")
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.Send(safeArr)
HTTP.WaitForResponse()
if ( (s := HTTP.Status) != 200)
throw Exception("Upload Error. Status: " . s)
ToolTip, % "rest: " . (--info.parts), 3, 3, 1
}
URIEncode(str, encoding := "UTF-8") {
VarSetCapacity(var, StrPut(str, encoding))
StrPut(str, &var, encoding)
While code := NumGet(Var, A_Index - 1, "UChar") {
bool := (code > 0x7F || code < 0x30 || code = 0x3D)
UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
}
Return UrlStr
}
Пробовал ещё только один раз WinHttpRequest и SafeArray создавать, ощутимой разницы не заметил.
Вставил свой вариант с проверкой статуса в первое сообщение темы.
if (HTTP.Status = 200) break
А если всё время по какой-то причине не равно? Должно быть, наверно, ограничение количества итераций.
А зачем нужно ограничение?
Ну, будет без конца крутиться.
Через браузер вроде так и сделано.
Надо будет на ночь без инета поставить, а утром включить инет и проверить будет загружаться или нет.
Зачем такие радикальные меры? Да и причина не только в отсутствии интернета может быть, может на сайте что-то не так. Браузер обычно через какое-то время ожидания сообщение об отсутствии соединения выводит.
Кроме того, может быть просто превышен лимит загрузок за сессию.
В данном случае браузер сразу сообщение выводит и просит оставаться на сайте, так как при появлении интернета загрузка продолжится.
Лимит загрузок у меня проверяется.
Только поздно слишком. У меня при превышении лимита ответ 500, следовательно бесконечный цикл с ноликом.
Можно, конечно еще размер проверять и добавить загрузку нескольких файлов, но у меня пока такой надобности не было.
При нескольких файлов, цикл загрузки повторяется для каждого файла отдельно.
Только поздно слишком. У меня при превышении лимита ответ 500, следовательно бесконечный цикл с ноликом.
Точно. Исправил.
Кстати, я обхожу лимит айпи через телефон в режиме модема.
При переключении на c 4g на 2g и обратно - айпи меняется.
Я просто роутер выключаю и включаю.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться