fs = require 'fs' http = require 'http' crypto = require 'crypto' xml = require 'node-xml' # soooo annoying that setTimeout takes the ms arg last timeout = (ms, func) -> setTimeout func, ms auth = {} md5 = (str) -> sum = crypto.createHash 'md5' sum.update str return sum.digest 'hex' new_auth_token = (user, pass) -> token = md5(user + md5(pass)) auth.user = user auth.token = token return token auth_file = "#{process.env.HOME}/.libre.fm-cmus.auth" save_auth = (user, pass, callback) -> token = new_auth_token(user, pass) text = JSON.stringify user: user, token: new_auth_token(user, pass) fs.writeFile auth_file, text, 'utf8', callback return token # load login credentials from settings file load_auth = (callback) -> if auth.user and auth.token callback auth return fs.readFile auth_file, 'utf8', (err, data) -> if err callback err else callback null, JSON.parse data # login and get a session key login = (callback) -> load_auth (err, auth) -> return callback(err) if err? http.get { host: 'alpha.libre.fm', port: 80, path: "/2.0/?method=auth.getmobilesession&username=#{auth.user}&authToken=#{auth.token}"}, (res) -> if res.statusCode != 200 console.log "login response code: #{res.statusCode}" callback "login response code: #{res.statusCode}" return res.setEncoding 'utf8' body = '' res.on 'data', (chunk) -> body += chunk res.on 'end', -> element = '' content = '' done = false huh = -> # FIXME switch to an xml parser that will tell me when it's done unless done done = true callback "xml parser failed to do anything with login server response" console.log "xml parser didn't exit: #{body}" parser = new xml.SaxParser (cb) -> cb.onStartElementNS (name, attrs, prefix, uri, namespaces) -> element = name content = '' cb.onCharacters (str) -> content += str cb.onEndElementNS (name, attrs, prefix, uri, namespaces) -> if element is 'key' done = true auth.sk = content console.log("got key \"#{content}\"") callback null, content else if element is 'error' done = true callback "login failed: \"#{content}\"" # ignore other tags stuff in there cb.onEndDocument huh parser.parseString body timeout 1, huh exports.login = login # fixme remove this from the API and call it automatically exports.new_auth_token = new_auth_token exports.save_auth = save_auth