ToXxiCxMoDz

Untitled

Jan 20th, 2021 (edited)
524
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local arg = { ... }
  2.  
  3. local expect = require "cc.expect"
  4. local expect, field = expect.expect, expect.field
  5.  
  6. local unserialise_json
  7. do
  8.     local sub, find, match, concat, tonumber = string.sub, string.find, string.match, table.concat, tonumber
  9.  
  10.     --- Skip any whitespace
  11.     local function skip(str, pos)
  12.         local _, last = find(str, "^[ \n\r\t]+", pos)
  13.         if last then return last + 1 else return pos end
  14.     end
  15.  
  16.     local escapes = {
  17.         ["b"] = '\b', ["f"] = '\f', ["n"] = '\n', ["r"] = '\r', ["t"] = '\t',
  18.         ["\""] = "\"", ["/"] = "/", ["\\"] = "\\",
  19.     }
  20.  
  21.     local mt = {}
  22.  
  23.     local function error_at(pos, msg, ...)
  24.         if select('#', ...) > 0 then msg = msg:format(...) end
  25.         error(setmetatable({ pos = pos, msg = msg }, mt))
  26.     end
  27.  
  28.     local function expected(pos, actual, exp)
  29.         if actual == "" then actual = "end of input" else actual = ("%q"):format(actual) end
  30.         error_at(pos, "Unexpected %s, expected %s.", actual, exp)
  31.     end
  32.  
  33.     local function parse_string(str, pos, terminate)
  34.         local buf, n = {}, 1
  35.  
  36.         while true do
  37.             local c = sub(str, pos, pos)
  38.             if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end
  39.             if c == terminate then break end
  40.  
  41.             if c == '\\' then
  42.                 -- Handle the various escapes
  43.                 c = sub(str, pos + 1, pos + 1)
  44.                 if c == "" then error_at(pos, "Unexpected end of input, expected escape sequence.") end
  45.  
  46.                 if c == "u" then
  47.                     local num_str = match(str, "^%x%x%x%x", pos + 2)
  48.                     if not num_str then error_at(pos, "Malformed unicode escape %q.", sub(str, pos + 2, pos + 5)) end
  49.                     buf[n], n, pos = utf8.char(tonumber(num_str, 16)), n + 1, pos + 6
  50.                 else
  51.                     local unesc = escapes[c]
  52.                     if not unesc then error_at(pos + 1, "Unknown escape character %q.", c) end
  53.                     buf[n], n, pos = unesc, n + 1, pos + 2
  54.                 end
  55.             elseif c >= '\x20' then
  56.                 buf[n], n, pos = c, n + 1, pos + 1
  57.             else
  58.                 error_at(pos + 1, "Unescaped whitespace %q.", c)
  59.             end
  60.         end
  61.  
  62.         return concat(buf, "", 1, n - 1), pos + 1
  63.     end
  64.  
  65.     local num_types = { b = true, B = true, s = true, S = true, l = true, L = true, f = true, F = true, d = true, D = true }
  66.     local function parse_number(str, pos, opts)
  67.         local _, last, num_str = find(str, '^(-?%d+%.?%d*[eE]?[+-]?%d*)', pos)
  68.         local val = tonumber(num_str)
  69.         if not val then error_at(pos, "Malformed number %q.", num_str) end
  70.  
  71.         if opts.nbt_style and num_types[sub(str, last + 1, last + 1)] then return val, last + 2 end
  72.  
  73.         return val, last + 1
  74.     end
  75.  
  76.     local function parse_ident(str, pos)
  77.         local _, last, val = find(str, '^([%a][%w_]*)', pos)
  78.         return val, last + 1
  79.     end
  80.  
  81.     local arr_types = { I = true, L = true, B = true }
  82.     local function decode_impl(str, pos, opts)
  83.         local c = sub(str, pos, pos)
  84.         if c == '"' then return parse_string(str, pos + 1, '"')
  85.         elseif c == "'" and opts.nbt_style then return parse_string(str, pos + 1, "\'")
  86.         elseif c == "-" or c >= "0" and c <= "9" then return parse_number(str, pos, opts)
  87.         elseif c == "t" then
  88.             if sub(str, pos + 1, pos + 3) == "rue" then return true, pos + 4 end
  89.         elseif c == 'f' then
  90.             if sub(str, pos + 1, pos + 4) == "alse" then return false, pos + 5 end
  91.         elseif c == 'n' then
  92.             if sub(str, pos + 1, pos + 3) == "ull" then
  93.                 if opts.parse_null then
  94.                     return json_null, pos + 4
  95.                 else
  96.                     return nil, pos + 4
  97.                 end
  98.             end
  99.         elseif c == "{" then
  100.             local obj = {}
  101.  
  102.             pos = skip(str, pos + 1)
  103.             c = sub(str, pos, pos)
  104.  
  105.             if c == "" then return error_at(pos, "Unexpected end of input, expected '}'.") end
  106.             if c == "}" then return obj, pos + 1 end
  107.  
  108.             while true do
  109.                 local key, value
  110.                 if c == "\"" then key, pos = parse_string(str, pos + 1, "\"")
  111.                 elseif opts.nbt_style then key, pos = parse_ident(str, pos)
  112.                 else return expected(pos, c, "object key")
  113.                 end
  114.  
  115.                 pos = skip(str, pos)
  116.  
  117.                 c = sub(str, pos, pos)
  118.                 if c ~= ":" then return expected(pos, c, "':'") end
  119.  
  120.                 value, pos = decode_impl(str, skip(str, pos + 1), opts)
  121.                 obj[key] = value
  122.  
  123.                 -- Consume the next delimiter
  124.                 pos = skip(str, pos)
  125.                 c = sub(str, pos, pos)
  126.                 if c == "}" then break
  127.                 elseif c == "," then pos = skip(str, pos + 1)
  128.                 else return expected(pos, c, "',' or '}'")
  129.                 end
  130.  
  131.                 c = sub(str, pos, pos)
  132.             end
  133.  
  134.             return obj, pos + 1
  135.  
  136.         elseif c == "[" then
  137.             local arr, n = {}, 1
  138.  
  139.             pos = skip(str, pos + 1)
  140.             c = sub(str, pos, pos)
  141.  
  142.             if arr_types[c] and sub(str, pos + 1, pos + 1) == ";" and opts.nbt_style then
  143.                 pos = skip(str, pos + 2)
  144.                 c = sub(str, pos, pos)
  145.             end
  146.  
  147.             if c == "" then return expected(pos, c, "']'") end
  148.             if c == "]" then return empty_json_array, pos + 1 end
  149.  
  150.             while true do
  151.                 n, arr[n], pos = n + 1, decode_impl(str, pos, opts)
  152.  
  153.                 -- Consume the next delimiter
  154.                 pos = skip(str, pos)
  155.                 c = sub(str, pos, pos)
  156.                 if c == "]" then break
  157.                 elseif c == "," then pos = skip(str, pos + 1)
  158.                 else return expected(pos, c, "',' or ']'")
  159.                 end
  160.             end
  161.  
  162.             return arr, pos + 1
  163.         elseif c == "" then error_at(pos, 'Unexpected end of input.')
  164.         end
  165.  
  166.         error_at(pos, "Unexpected character %q.", c)
  167.     end
  168.  
  169.     --- Converts a serialised JSON string back into a reassembled Lua object.
  170.     --
  171.     -- This may be used with @{textutils.serializeJSON}, or when communicating
  172.     -- with command blocks or web APIs.
  173.     --
  174.     -- @tparam string s The serialised string to deserialise.
  175.     -- @tparam[opt] { nbt_style? = boolean, parse_null? = boolean } options
  176.     -- Options which control how this JSON object is parsed.
  177.     --
  178.     --  - `nbt_style`: When true, this will accept [stringified NBT][nbt] strings,
  179.     --    as produced by many commands.
  180.     --  - `parse_null`: When true, `null` will be parsed as @{json_null}, rather
  181.     --    than `nil`.
  182.     --
  183.     --  [nbt]: https://minecraft.gamepedia.com/NBT_format
  184.     -- @return[1] The deserialised object
  185.     -- @treturn[2] nil If the object could not be deserialised.
  186.     -- @treturn string A message describing why the JSON string is invalid.
  187.     unserialise_json = function(s, options)
  188.         expect(1, s, "string")
  189.         expect(2, options, "table", "nil")
  190.  
  191.         if options then
  192.             field(options, "nbt_style", "boolean", "nil")
  193.             field(options, "nbt_style", "boolean", "nil")
  194.         else
  195.             options = {}
  196.         end
  197.  
  198.         local ok, res, pos = pcall(decode_impl, s, skip(s, 1), options)
  199.         if not ok then
  200.             if type(res) == "table" and getmetatable(res) == mt then
  201.                 return nil, ("Malformed JSON at position %d: %s"):format(res.pos, res.msg)
  202.             end
  203.  
  204.             error(res, 0)
  205.         end
  206.  
  207.         pos = skip(s, pos)
  208.         if pos <= #s then
  209.             return nil, ("Malformed JSON at position %d: Unexpected trailing character %q."):format(pos, sub(s, pos, pos))
  210.         end
  211.         return res
  212.  
  213.     end
  214. end
  215.  
  216. function updateStatus()
  217.     local monitor = peripheral.wrap( "top" )
  218.     local headers = {
  219.         [ "Accept" ] = "application/json",
  220.         [ "Content-Type" ] = "application/json",
  221.         [ "Authorization" ] = "Bearer " .. arg[1]
  222.     }
  223.     local result = http.get("https://api.spotify.com/v1/me/player?market=US", headers)
  224.     local json = unserialise_json(result.readAll())
  225.     local songName = json.item.name
  226.     local artistName = json.item.artists[1].nam
  227.     monitor.write(songName .. "\n")
  228.     monitor.write(artistName)
  229. end
  230.  
  231. while(true)
  232. do
  233.     updateStatus()
  234.     os.sleep(15)
  235. end
RAW Paste Data