Асинхронная и синхронная функции скачивания файла в MonetLoader

downloadToFile (асинхронная)

---Скачивает асинхронно файл из URL в указанный путь
---@param url string @URL
---@param path string @Путь к файлу, в который будет сохранен скачанный файл
---@param callback? fun(type: "downloading"|"finished"|"error", pos: number, total_size?: number) @Функция, которая будет вызвана при изменении прогресса скачивания или завершении
---@param progressInterval? number @Интервал в секундах между вызовами callback, по умолчанию 0.1
function downloadToFile(url, path, callback, progressInterval)
    callback = callback or function() end
    progressInterval = progressInterval or 0.1
    local effil = require("effil")
    local progressChannel = effil.channel(0)

    local runner = effil.thread(function(url, path)
      local http = require("socket.http")
      local ltn = require("ltn12")

      local _, res, code, headers = pcall(http.request, {
        method = "HEAD",
        url = url,
      })

      local total_size = headers["content-length"] or 0

      local f = io.open(path, "w+b")
      if not f then
        return false, "failed to open file"
      end
      local success, res, status_code = pcall(http.request, {
        method = "GET",
        url = url,
        sink = function(chunk, err)
          local clock = os.clock()
          if chunk and not lastProgress or (clock - lastProgress) >= progressInterval then
            progressChannel:push("downloading", f:seek("end"), total_size)
            lastProgress = os.clock()
          elseif err then
            progressChannel:push("error", err)
          end

          return ltn.sink.file(f)(chunk, err)
        end,
      })

      if not success then
        return false, res
      end

      if not res then
        return false, status_code
      end

      return true, total_size
    end)
    local thread = runner(url, path)

    local function checkStatus()
      local tstatus = thread:status()
      if tstatus == "failed" or tstatus == "completed" then
        local result, value = thread:get()

        if result then
          callback("finished", value)
        else
          callback("error", value)
        end

        return true
      end
    end

    lua_thread.create(function()
      if checkStatus() then
        return
      end

      while thread:status() == "running" do
        if progressChannel:size() > 0 then
          local type, pos, total_size = progressChannel:pop()
          callback(type, pos, total_size)
        end
        wait(0)
      end

      checkStatus()
    end)
  end

Функция downloadToFile асинхронно скачивает файл из указанного URL в указанный путь.

Параметры:

  • url: URL для скачивания.
  • path: Путь к файлу, в который будет сохранен скачанный файл.
  • callback: Функция, вызываемая при изменении прогресса или завершении скачивания. Принимает три параметра:
    • type: Тип события ("downloading" - скачивание в процессе, "finished" - скачивание завершено, "error" - произошла ошибка скачивания).
    • pos: Текущая позиция скачивания (в байтах).
    • total_size: Общий размер файла (доступно только при type == "downloading").
  • progressInterval: Интервал в секундах между вызовами callback (по умолчанию 0.1).

Дополнительная информация при типе "error":

Если тип события равен "error", параметр pos содержит информацию об ошибке, например, код ошибки или текст сообщения об ошибке.

Пример использования:

1
2
3
4
5
6
7
8
9
downloadToFile("https://example.com/file.zip", "file.zip", function(type, pos, total_size)
    if type == "downloading" then
        print(("Скачивание %d/%d"):format(pos, total_size))
    elseif type == "finished" then
        print("Скачивание завершено")
    elseif type == "error" then
        print("Ошибка скачивания: " .. pos)
    end
 end)

downloadToFileSync (синхронная)

1
2
3
4
5
function downloadToFileSync(url, path)
    local http = require("socket.http")
    local ltn12 = require("ltn12")
    http.request({ method = "GET", url = url, sink = ltn12.sink.file(io.open(path, "wb")) })
end

Функция downloadToFileSync синхронно скачивает файл из указанного URL в указанный путь.

Параметры:

  • url: URL для скачивания.
  • path: Путь к файлу, в который будет сохранен скачанный файл.

Дополнительная информация при возникновении ошибки:

Если в процессе скачивания возникает ошибка, функция может выбросить исключение или вернуть код ошибки.

Пример использования:

downloadToFileSync("https://example.com/file.zip", "file.zip")
Edit

Pub: 13 May 2024 08:00 UTC

Edit: 29 Sep 2024 18:56 UTC

Views: 211