diff options
author | Alexander Yakushev <yakushev.alex@gmail.com> | 2011-07-24 17:42:58 +0300 |
---|---|---|
committer | Alexander Yakushev <yakushev.alex@gmail.com> | 2011-07-24 17:42:58 +0300 |
commit | ac1df4e248df5cbdf5ece49e63673f95c6fff233 (patch) | |
tree | 07ea7667b9c74cc271f2f3d9ebd3431ec333f3ff | |
parent | 2d57895a6dd93ab79a09df13842b4bfd3829626c (diff) | |
download | awesompd-ac1df4e248df5cbdf5ece49e63673f95c6fff233.tar.gz awesompd-ac1df4e248df5cbdf5ece49e63673f95c6fff233.tar.bz2 |
Added safer JSON parser and fix for unicode symbols from Jamendo
-rw-r--r-- | awesompd.lua | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/awesompd.lua b/awesompd.lua index ab32013..8c6d382 100644 --- a/awesompd.lua +++ b/awesompd.lua @@ -550,6 +550,8 @@ function awesompd:wrap_output(text) awesompd.protect_string(text), self.rdecorator) end +-- Retrieves mapping of track IDs to track names to avoid redundant +-- queries when Awesome gets restarted. function awesompd:retrieve_cache() local bus = io.open(self.filename) if bus then @@ -560,6 +562,7 @@ function awesompd:retrieve_cache() end end +-- Saves track IDs to track names mapping into the cache file. function awesompd:save_cache() local bus = io.open(self.filename, "w") for id,name in pairs(self.jamendo_list) do @@ -569,6 +572,7 @@ function awesompd:save_cache() bus:close() end +-- Returns the track ID from the given link to Jamendo stream. function awesompd.get_id_from_link(link) local _, _, id = string.find(link,"stream/(%d+)") return id @@ -708,7 +712,6 @@ function awesompd:update_track(file) self.status_text = self.status .. " " .. progress end end - end function awesompd:update_state(state_string) @@ -749,6 +752,9 @@ function awesompd:run_prompt(welcome,hook) hook) end +-- Replaces control characters with escaped ones. +-- for_menu - defines if the special escable table for menus should be +-- used. function awesompd.protect_string(str, for_menu) if for_menu then return utf8replace(str, awesompd.ESCAPE_MENU_SYMBOL_MAPPING) @@ -756,3 +762,93 @@ function awesompd.protect_string(str, for_menu) return utf8replace(str, awesompd.ESCAPE_SYMBOL_MAPPING) end end + +-- Primitive function for parsing Jamendo API JSON response. Does not +-- support arrays. Supports only strings and numbers as values. +-- Provides basic safety (correctly handles special symbols like comma +-- and curly brackets inside strings) +-- text - JSON text +function awesompd.parse_json(text) + local parse_table = {} + local block = {} + local i = 0 + local inblock = false + local instring = false + local curr_key = nil + local curr_val = nil + while i and i < string.len(text) do + if not inblock then -- We are not inside the block, find next { + i = string.find(text, "{", i+1) + inblock = true + block = {} + else + if not curr_key then -- We haven't found key yet + if not instring then -- We are not in string, check for more tags + local j = string.find(text, '"', i+1) + local k = string.find(text, '}', i+1) + if j and j < k then -- There are more tags in this block + i = j + instring = true + else -- Block is over, find its ending + i = k + inblock = false + table.insert(parse_table, block) + end + else -- We are in string, find its ending + _, i, curr_key = string.find(text,'(.-[^%\\])"', i+1) + instring = false + end + else -- We have the key, let's find the value + if not curr_val then -- Value is not found yet + if not instring then -- Not in string, check if value is string + local j = string.find(text, '"', i+1) + local k = string.find(text, '[,}]', i+1) + if j and j < k then -- Value is string + i = j + instring = true + else -- Value is int + _, i, curr_val = string.find(text,'(%d+)', i+1) + end + else -- We are in string, find its ending + local j = string.find(text, '"', i+1) + if j == i+1 then -- String is empty + i = j + curr_val = "" + else + _, i, curr_val = string.find(text,'(.-[^%\\])"', i+1) + curr_val = awesompd.utf8_codes_to_symbols(curr_val) + end + instring = false + end + else -- We have both key and value, add it to table + block[curr_key] = curr_val + curr_key = nil + curr_val = nil + end + end + end + end + return parse_table +end + +-- Jamendo returns Unicode symbols as \uXXXX. Lua does not transform +-- them into symbols so we need to do it ourselves. +function awesompd.utf8_codes_to_symbols (s) + local hexnums = "[%dabcdefABCDEF]" + local pattern = string.format("\\u(%s%s%s%s?)", + hexnums, hexnums, hexnums, hexnums) + print("Pattern is : " .. pattern) + local decode = function(code) + code = tonumber(code, 16) + -- Grab high and low byte + local hi = math.floor(code / 256) * 4 + 192 + local lo = math.mod(code, 256) + -- Reduce low byte to 64, add overflow to high + local oflow = math.floor(lo / 64) + hi = hi + oflow + lo = math.mod(code, 64) + 128 + -- Return symbol as \hi\lo + return string.char(hi, lo) + end + return string.gsub(s, pattern, decode) +end |