1. --!movie
  2. --!encoding=utf-8
  3.  
  4. global $
  5.  
  6. global gFile
  7.  
  8. ----------------------------------------
  9. -- Upload file with ftp (synchronous/blocking mode)
  10. -- If remote file exists and is smaller than local file, upload is resumed
  11. ----------------------------------------
  12. on startMovie
  13.     _player.debugPlaybackEnabled = 1
  14.  
  15.     -- libs
  16.     $.import("curl")
  17.     $.import("file")
  18.  
  19.     -- config
  20.     tLocalFile = $.PATH & "test.mp3"
  21.     tRemoteFile = "ftp://domain.com/test/uploaded.mp3"
  22.     tUsername = "john.doe"
  23.     tPassword = "********"
  24.  
  25.     -- open local file
  26.     gFile = $.file.fopen(tLocalFile, "rb")
  27.     tLocalSize = $.file.fsize(gFile)
  28.  
  29.     -- get a CURL handle (xtra instance)
  30.     ch = $.curl.init()
  31.  
  32.     -- specify options
  33.     ch.setOption($.curl.CURLOPT.URL, tRemoteFile)
  34.     ch.setOption($.curl.CURLOPT.USERNAME, tUsername)
  35.     ch.setOption($.curl.CURLOPT.PASSWORD, tPassword)
  36.  
  37.     -- get "header" (=metadata) only for remote file
  38.     ch.setOption($.curl.CURLOPT.NOBODY, 1)
  39.     ch.setOption($.curl.CURLOPT.HEADER, 1)
  40.     res = ch.exec(1)
  41.     if integerP(res) then
  42.         put "ERROR:" && curl_error(res)
  43.         $.file.fclose(gFile)
  44.         exit
  45.     end if
  46.  
  47.     -- parse header, extract size
  48.     headers = $.curl.parseHeaders(res.readRawString(res.length))
  49.     --put headers
  50.     tRemoteSize = integer(headers["Content-Length"])
  51.     fileExists = not voidP(tRemoteSize)
  52.     if voidP(tRemoteSize) then tRemoteSize = 0
  53.     --put "SIZE:" &&    tRemoteSize
  54.  
  55.     if tRemoteSize>=tLocalSize then
  56.         put "File already uploaded. Aborting."
  57.         $.file.fclose(gFile)
  58.         exit
  59.     end if
  60.  
  61.     -- start/resume upload
  62.     ch.setOption($.curl.CURLOPT.HEADER, 0)
  63.     ch.setOption($.curl.CURLOPT.UPLOAD, 1)
  64.  
  65.     if fileExists then
  66.         put "File exists, resuming previous upload"
  67.         ch.setOption($.curl.CURLOPT.APPEND, 1)
  68.         if tRemoteSize>0 then
  69.             -- skip already uploaded bytes in local file
  70.             $.file.fseek(gFile, tRemoteSize)
  71.         end if
  72.     else
  73.         put "File doesn't exist, start new upload"
  74.     end if
  75.  
  76.     -- notice: sourceData callback ONLY supported in sync/blocking mode!
  77.     ch.setSourceDataCallback(#slotGetData)
  78.  
  79.     -- returnMode: 0=return error code (=default), 1=return data
  80.     res = ch.exec(0)
  81.  
  82.     $.file.fclose(gFile)
  83.     gFile = VOID
  84.  
  85.     put "UPLOAD FINISHED!"
  86.     put "ERROR:" && curl_error(res)
  87.  
  88.     --put "SPEED_UPLOAD:" && ch.getInfo($.curl.CURLINFO.SPEED_UPLOAD)
  89.     --put "TOTAL_TIME:" && ch.getInfo($.curl.CURLINFO.TOTAL_TIME)
  90. end
  91.  
  92. ----------------------------------------
  93. -- Be careful, direct data callback, keep it tight!
  94. -- Lingo errors in this handler would fail silently.
  95. -- @callback
  96. -- @param {integer} numBytes - number of bytes the callback should return, if possible
  97. -- @return {bytearray} next chunk of data
  98. ----------------------------------------
  99. on slotGetData (numBytes)
  100.     -- put "slotGetData", numBytes
  101.     return $.file.freadbytes(gFile, numBytes)
  102. end
  103.  
[raw code]