--!movie
--!encoding=utf-8
global $
global gFile
----------------------------------------
-- Upload file with ftp (synchronous/blocking mode)
-- If remote file exists and is smaller than local file, upload is resumed
----------------------------------------
on startMovie
_player.debugPlaybackEnabled = 1
-- libs
$.import("curl")
$.import("file")
-- config
tLocalFile = $.PATH & "test.mp3"
tRemoteFile = "ftp://domain.com/test/uploaded.mp3"
tUsername = "john.doe"
tPassword = "********"
-- open local file
gFile = $.file.fopen(tLocalFile, "rb")
tLocalSize = $.file.fsize(gFile)
-- get a CURL handle (xtra instance)
ch = $.curl.init()
-- specify options
ch.setOption($.curl.CURLOPT.URL, tRemoteFile)
ch.setOption($.curl.CURLOPT.USERNAME, tUsername)
ch.setOption($.curl.CURLOPT.PASSWORD, tPassword)
-- get "header" (=metadata) only for remote file
ch.setOption($.curl.CURLOPT.NOBODY, 1)
ch.setOption($.curl.CURLOPT.HEADER, 1)
res = ch.exec(1)
if integerP(res) then
put "ERROR:" && curl_error(res)
$.file.fclose(gFile)
exit
end if
-- parse header, extract size
headers = $.curl.parseHeaders(res.readRawString(res.length))
--put headers
tRemoteSize = integer(headers["Content-Length"])
fileExists = not voidP(tRemoteSize)
if voidP(tRemoteSize) then tRemoteSize = 0
--put "SIZE:" && tRemoteSize
if tRemoteSize>=tLocalSize then
put "File already uploaded. Aborting."
$.file.fclose(gFile)
exit
end if
-- start/resume upload
ch.setOption($.curl.CURLOPT.HEADER, 0)
ch.setOption($.curl.CURLOPT.UPLOAD, 1)
if fileExists then
put "File exists, resuming previous upload"
ch.setOption($.curl.CURLOPT.APPEND, 1)
if tRemoteSize>0 then
-- skip already uploaded bytes in local file
$.file.fseek(gFile, tRemoteSize)
end if
else
put "File doesn't exist, start new upload"
end if
-- notice: sourceData callback ONLY supported in sync/blocking mode!
ch.setSourceDataCallback(#slotGetData)
-- returnMode: 0=return error code (=default), 1=return data
res = ch.exec(0)
$.file.fclose(gFile)
gFile = VOID
put "UPLOAD FINISHED!"
put "ERROR:" && curl_error(res)
--put "SPEED_UPLOAD:" && ch.getInfo($.curl.CURLINFO.SPEED_UPLOAD)
--put "TOTAL_TIME:" && ch.getInfo($.curl.CURLINFO.TOTAL_TIME)
end
----------------------------------------
-- Be careful, direct data callback, keep it tight!
-- Lingo errors in this handler would fail silently.
-- @callback
-- @param {integer} numBytes - number of bytes the callback should return, if possible
-- @return {bytearray} next chunk of data
----------------------------------------
on slotGetData (numBytes)
-- put "slotGetData", numBytes
return $.file.freadbytes(gFile, numBytes)
end