1 (изменено: Malcev, 2023-03-13 12:46:15)

Тема: AHK: Заливка файлов на filemail.com

Тема для обсуждения "Заливка файлов на filemail.com".
http://forum.script-coding.com/viewtopic.php?id=17680

+ DD

2

Re: AHK: Заливка файлов на filemail.com

Не нашел инфы о том, как долго потом могут храниться эти залитые файлы?

3

Re: AHK: Заливка файлов на filemail.com

7 дней.

4 (изменено: teadrinker, 2019-08-14 02:30:22)

Re: AHK: Заливка файлов на filemail.com

У меня так работает, без учёта количества потоков. Да и разве может процесс 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
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: Malcev, 2019-08-14 05:06:33)

Re: AHK: Заливка файлов на filemail.com

С потоками работает на 5-20% быстрее с 1.5-2 гигабайтным файлами.
Зависит, похоже, от максимальной скорости интернета - чем она больше, тем больше разница.
Проверял 4 раза.
Но в принципе в моем коде не учтены такие вещи, как выпадание интернета - в таких случаях, думаю, возможны битые файлы.
Надо тестировать.

6

Re: AHK: Заливка файлов на filemail.com

Malcev пишет:

С потоками работает на 5-20% быстрее с 1.5-2 гигабайтным файлами.

Возможно, не проверял. Но это не от того, что там есть мешающие друг другу потоки загрузки, а видимо из-за ограничения в AHK количества параллельных псевдо-веток, которые создаются в WatchState(), лишние начинают буфферизироваться и замедлять общую скорость.

В моём варианте тоже не всё учтено, он для демонстрации возможности обойтись без глобальных переменных. Так-то надо везде HTTP.status проверять.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Malcev, 2019-08-14 05:41:59)

Re: AHK: Заливка файлов на filemail.com

Я сравнивал в своем коде с одним потоком и с 4.
С 4 работает на 5  -20% быстрее, что с твоим кодом, что с моим.
Если сравнить твой код с 1 потоком и мой с 1 потоком - результат идентичный.

8

Re: AHK: Заливка файлов на filemail.com

Можно ещё с #MaxThreads попробовать поиграть. По умолчанию их 10.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Заливка файлов на filemail.com

А почему ты считаешь, что дело в ahk, а не в сервере, который оптимизирует скорость загрузки при 4 потоках?

10

Re: AHK: Заливка файлов на filemail.com

Так потому что здесь нет реальных параллельных потоков загрузки. Пока каждый HTTP.Send не отработает, новый не начинается. Хотя, конечно надо проверить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Заливка файлов на filemail.com

В моем коде есть.

12

Re: AHK: Заливка файлов на filemail.com

В этом смысле оба кода не отличаются. Только твой ждёт ответа после 4-го куска файла.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Заливка файлов на filemail.com

Почему?
Он ждет ответа после каждого куска файла, но одновременно не может быть послано более 4.
Надо попробовать замерить скорость загрузки через IE и сравнить.

14

Re: AHK: Заливка файлов на filemail.com

Malcev пишет:

Он ждет ответа после каждого куска файла

Кто — он? Твой ждёт только после 4, мой вообще не ждёт.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Заливка файлов на filemail.com

Мой скрипт.
А теперь зайди в таскменеджер и посмотри сколь съедает памяти твой скрипт при загрузке файла в пару гигабайт.

16 (изменено: teadrinker, 2019-08-14 19:06:40)

Re: AHK: Заливка файлов на filemail.com

Да, недоглядел, но нетрудно исправить:

#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
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Заливка файлов на filemail.com

А что изменилось? У тебя памяти съедает гигабайты.

18

Re: AHK: Заливка файлов на filemail.com

А ты на какой системе запускаешь?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Заливка файлов на filemail.com

На win10 ahk64.

20

Re: AHK: Заливка файлов на filemail.com

А, опечатка там, поправил.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21

Re: AHK: Заливка файлов на filemail.com

Ну не знаю.
У меня только что при заливке 20 гигов, до 4 гигов доходило потребление.

22

Re: AHK: Заливка файлов на filemail.com

В смысле, на исправленном варианте?
У меня на win 10 не превышает 10 MB, на Win 7 чуть больше.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: Заливка файлов на filemail.com

Да, на исправленном варианте.

24 (изменено: Malcev, 2019-08-14 19:29:59)

Re: AHK: Заливка файлов на filemail.com

И CPU до 10%.
ИМХО все эти игры с памятью, так себе затея.
Кстати, мой вариант - потребление 45мб и cpu 0.2% максимум.
Я, пожалуй, переделаю на winhttprequest с одним потоком и отловом ошибок.

25

Re: AHK: Заливка файлов на filemail.com

У меня нет файла в 20 гигов, чтоб проверить, сейчас пробовал примерно 1Гб — на Win 7 от 5 MB до 15, и не растёт, на Win 10 ещё меньше, но десятка у меня через Wi-Fi, так что некорректно проверять. А поменьше файл пробовал взять?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

26

Re: AHK: Заливка файлов на filemail.com

Malcev пишет:

Я, пожалуй, переделаю на winhttprequest с одним потоком и отловом ошибок

Так пробовал, без игр с памятью, тоже работает, хотя чуть медленнее.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Заливка файлов на filemail.com

С 1 Гб у меня так же как у тебя.

28 (изменено: teadrinker, 2019-08-14 20:03:37)

Re: AHK: Заливка файлов на filemail.com

В один поток:

#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
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

29

Re: AHK: Заливка файлов на filemail.com

Пробовал ещё только один раз WinHttpRequest и SafeArray создавать, ощутимой разницы не заметил.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

30

Re: AHK: Заливка файлов на filemail.com

Вставил свой вариант с проверкой статуса в первое сообщение темы.

31

Re: AHK: Заливка файлов на filemail.com

      if (HTTP.Status = 200)
         break

А если всё время по какой-то причине не равно? Должно быть, наверно, ограничение количества итераций.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

32

Re: AHK: Заливка файлов на filemail.com

А зачем нужно ограничение?

33

Re: AHK: Заливка файлов на filemail.com

Ну, будет без конца крутиться.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

34

Re: AHK: Заливка файлов на filemail.com

Через браузер вроде так и сделано.
Надо будет на ночь без инета поставить, а утром включить инет и проверить будет загружаться или нет.

35

Re: AHK: Заливка файлов на filemail.com

Зачем такие радикальные меры? Да и причина не только в отсутствии интернета может быть, может на сайте что-то не так. Браузер обычно через какое-то время ожидания сообщение об отсутствии соединения выводит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

36

Re: AHK: Заливка файлов на filemail.com

Кроме того, может быть просто превышен лимит загрузок за сессию.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

37

Re: AHK: Заливка файлов на filemail.com

В данном случае браузер сразу сообщение выводит и просит оставаться на сайте, так как при появлении интернета загрузка продолжится.

38

Re: AHK: Заливка файлов на filemail.com

Лимит загрузок у меня проверяется.

39

Re: AHK: Заливка файлов на filemail.com

Только поздно слишком. У меня при превышении лимита ответ 500, следовательно бесконечный цикл с ноликом.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40

Re: AHK: Заливка файлов на filemail.com

Можно, конечно еще размер проверять и добавить загрузку нескольких файлов, но у меня пока такой надобности не было.
При нескольких файлов, цикл загрузки повторяется для каждого файла отдельно.

41

Re: AHK: Заливка файлов на filemail.com

teadrinker пишет:

Только поздно слишком. У меня при превышении лимита ответ 500, следовательно бесконечный цикл с ноликом.

Точно. Исправил.
Кстати, я обхожу лимит айпи через телефон в режиме модема.
При переключении на c 4g на 2g и обратно - айпи меняется.

42

Re: AHK: Заливка файлов на filemail.com

Я просто роутер выключаю и включаю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder