example code to submit a track to last.fm

Code:
 
--------------------------------------------------------------------------------
-- LASTFM                                                    mhwlng --
--------------------------------------------------------------------------------
 
print('Loading marcel\\lastfm.lua')
 
http=require("socket.http")
 
Marcel = Marcel or {}
 
Marcel.LASTFM = Marcel.LASTFM or {}
 
Marcel.LASTFM.handshakedata = Marcel.LASTFM.handshakedata or nil
 
-- queue mechanism taken from Rob H's NetRemote.lua
 
--!!!!!!!!!!!!!!!!!!!!!!!change!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Marcel.LASTFM.username = "????"
 
Marcel.LASTFM.password = "????"
 
Marcel.LASTFM.queue = {mutex = thread.newmutex(),  tracks = {}}
 
function Marcel.LASTFM.TablequeueCount()
  return table.getn(Marcel.LASTFM.queue.tracks)
end
 
function Marcel.LASTFM.TablequeueEmpty()
  return Marcel.LASTFM.TablequeueCount() == 0
end
 
function Marcel.LASTFM.handshake(username,password)
  local timestamp = os.time();
  local url = "http://post.audioscrobbler.com/?"..
        "hs=true&"..
        "p=1.2&"..
        "c=tst&"..
        "v=1.0&"..
        "u="..username.."&"..
        "t="..timestamp.."&"..
        "a="..gip.MD5(gip.MD5(password)..timestamp)
  local HSHTML,HTTPERROR = http.request(url);
  if ((HTTPERROR == 200) and (HSHTML ~= nil)) then
    local handshakedata={}
    HSDATA = string.Split (HSHTML,"\n");
    handshakedata.status = HSDATA[1];
    handshakedata.session = HSDATA[2];
    handshakedata.nowplayingurl = HSDATA[3];
    handshakedata.submiturl = HSDATA[4];
    return handshakedata
  end
end
 
function Marcel.LASTFM.lastfmsubmit (artist,album,trackname,tracklength,handshakedata)
  local now = os.time()
  local UTC = os.time(os.date("!*t", now))
  -- ??? timestamp should be utc, but last.fm plugin in jrmc also uses the local time ????
  local bodydata = "s="..handshakedata.session.."&"..
                   "a[0]="..artist.."&"..
                   "t[0]="..trackname.."&"..
                   "i[0]="..now.."&"..
                   "o[0]=P&"..
                   "r[0]=&"..
                   "l[0]="..tostring(tracklength).."&"..
                   "b[0]="..album.."&"..
                   "n[0]=&"..
                   "m[0]="
  local t = {}
  local r,HTTPERROR = http.request{url=handshakedata.submiturl,
    method="POST",
    source = ltn12.source.string(bodydata),
    sink = ltn12.sink.table(t),
    headers={
      ["content-length"] = string.len(bodydata),
      ["Connection"]="Keep-Alive",
      ["Cache-Control"]="no-cache",
      ["Cookie"]=cookie,
      ["Content-type"]="application/x-www-form-urlencoded"}
    };
  local status=table.concat(t);
  if ((r==1) and (HTTPERROR==200) and (status ~= nil)) then
    return string.sub(status,1,-2)
  end
  return "FAILED\n"
end
 
function Marcel.LASTFM.submit(username,password,artist,album,trackname,tracklength)
  for i = 1, 3 do
    if Marcel.LASTFM.handshakedata == nil or Marcel.LASTFM.handshakedata.status~="OK" or Marcel.LASTFM.handshakedata.session == nil  then
      Marcel.LASTFM.handshakedata = Marcel.LASTFM.handshake(username,password);
    end
    if Marcel.LASTFM.handshakedata ~= nil then
      if Marcel.LASTFM.handshakedata.status=="OK" and Marcel.LASTFM.handshakedata.session ~= nil  then
        for j = 1, 3 do
          local status = Marcel.LASTFM.lastfmsubmit (artist,album,trackname,tracklength,Marcel.LASTFM.handshakedata)
          if (status == "OK") then
            return status
          end
          print ("last.fm RETRY submit : "..status)
          win.Sleep (60000)
        end
        Marcel.LASTFM.handshakedata = nil;
      else
        if (i==3) then
          return Marcel.LASTFM.handshakedata.status
        end
        print ("last.fm RETRY handshake : "..Marcel.LASTFM.handshakedata.status)
        win.Sleep (60000)
      end
    else
      print ("last.fm RETRY handshake")
      win.Sleep (60000)
    end
  end
  return "FAILED"
end
 
function Marcel.LASTFM.ProcessClientqueue(username,password)
  while not gir.IsLuaExiting() do
    Marcel.LASTFM.queue.mutex:lock()
    if not Marcel.LASTFM.TablequeueEmpty() then
      local temp = table.remove(Marcel.LASTFM.queue.tracks, 1)
      local status = Marcel.LASTFM.submit( username,
                                           password,
                                           temp.artist,
                                           temp.album,
                                           temp.trackname,
                                           temp.tracklength)
      if (status == "OK") then
        print ("last.fm submitted "..temp.artist.." - "..temp.album.." - "..temp.trackname)
      else
        print ("last.fm "..status.. " "..temp.artist.." - "..temp.album.." - "..temp.trackname)
      end
    end
    Marcel.LASTFM.queue.mutex:unlock()
    win.Sleep(5000);
  end
end
 
-- must be utf-8 encoded !!!
function Marcel.LASTFM.QueueTrack(ar,al,trn,trl)
  Marcel.LASTFM.queue.mutex:lock()
  table.insert(Marcel.LASTFM.queue.tracks, {artist=ar,album=al,trackname=trn,tracklength=trl})
  Marcel.LASTFM.queue.mutex:unlock()
end
 
Marcel.LASTFM.lastfmthreadObj = thread.newthread(Marcel.LASTFM.ProcessClientqueue, {Marcel.LASTFM.username,Marcel.LASTFM.password})
 
print('Loaded marcel\\lastfm.lua')

Code:
require ("marcel\\lastfm")
Marcel.LASTFM.QueueTrack(artist,album,trackname,duration)
Marcel