]> gitweb.fluxo.info Git - awesompd.git/commitdiff
Refactored Jamendo part, moved it to different file
authorAlexander Yakushev <yakushev.alex@gmail.com>
Sun, 24 Jul 2011 18:05:55 +0000 (21:05 +0300)
committerAlexander Yakushev <yakushev.alex@gmail.com>
Sun, 24 Jul 2011 18:05:55 +0000 (21:05 +0300)
awesompd.lua
jamendo.lua [new file with mode: 0644]

index 8c6d3825fd5662ce7b33620020c91abd520bc575..8243542c7d1511b4bd64f834a0aab7f2830a34f5 100644 (file)
@@ -5,6 +5,8 @@
 ---------------------------------------------------------------------------
 
 require('utf8')
+require('jamendo')
+
 local naughty = naughty
 local awful = awful
 
@@ -78,7 +80,6 @@ function awesompd:create()
    instance.status_text = "Stopped"
    instance.to_notify = false
    instance.connected = true
-   instance.jamendo_list = {}
 
    instance.recreate_menu = true
    instance.recreate_playback = true
@@ -95,7 +96,6 @@ function awesompd:create()
    instance.output_size = 30
    instance.update_interval = 10
    instance.path_to_icons = ""
-   instance.filename = awful.util.getdir ("cache").."/jamendo_cache"
    instance.ldecorator = " "
    instance.rdecorator = " "
 
@@ -112,7 +112,6 @@ end
 -- Registers timers for the widget
 function awesompd:run()
    enable_dbg = self.debug_mode
-   self:retrieve_cache()
    self:update_track()
    self:check_playlists()
    self.load_icons(self.path_to_icons)
@@ -301,43 +300,31 @@ function awesompd:command_show_menu()
           end 
 end
    
-function awesompd:add_tracks_from_jamendo(parse_table,format)
-   if (table.getn(parse_table) > 0) then
-      local trygetlink = 
-         assert(io.popen("echo $(curl -w %{redirect_url} " .. 
-                         "'http://api.jamendo.com/get2/stream/track/redirect/" .. 
-                         "?streamencoding="..format.."&id=729304')"),'r'):read("*lines")
-      local _, _, prefix = string.find(trygetlink,"stream(%d+)\.jamendo\.com")
-      for i = 1,table.getn(parse_table) do
-         track_link = "http://stream" .. prefix .. ".jamendo.com/stream/" 
-            .. parse_table[i].id .."/".. format .."/"
-         self:command("add " .. track_link)
-         self.jamendo_list[parse_table[i].id] = 
-            parse_table[i].artist .. " - " .. parse_table[i].track
-      end
-   end
-end
+-- function awesompd:add_tracks_from_jamendo(parse_table,format)
+--    if (table.getn(parse_table) > 0) then
+--       local trygetlink = 
+--          assert(io.popen("echo $(curl -w %{redirect_url} " .. 
+--                          "'http://api.jamendo.com/get2/stream/track/redirect/" .. 
+--                          "?streamencoding="..format.."&id=729304')"),'r'):read("*lines")
+--       local _, _, prefix = string.find(trygetlink,"stream(%d+)\.jamendo\.com")
+--       for i = 1,table.getn(parse_table) do
+--          track_link = "http://stream" .. prefix .. ".jamendo.com/stream/" 
+--             .. parse_table[i].id .."/".. format .."/"
+--          self:command("add " .. track_link)
+--          self.jamendo_list[parse_table[i].id] = 
+--             parse_table[i].artist .. " - " .. parse_table[i].track
+--       end
+--    end
+-- end
 
 function awesompd:add_jamendo_top(format)
    return function ()
-             local top_list = "curl -A 'Mozilla/4.0' -fsm 5 \"http://api.jamendo.com/get2/" ..
-                "id+name+url+stream+album_name+album_url+album_id+artist_id+artist_name" .. 
-                "/track/jsonpretty/track_album+album_artist/?n=100&order=ratingweek_desc\""
-             local bus = assert(io.popen(top_list, 'r'))
-             local r = bus:read("*all")
-             bus:close()
-             local parse_table = {}
-             string.gsub(r, "\"id\":(%d+),%s+\"name\":\"([^\"]+)[^%}]*\"artist_name\":\"([^\"]+)\"",
-                         function(_id,_track,_artist)
-                            table.insert(parse_table, 
-                                         { id = _id, 
-                                           track = (_track or ""),
-                                           artist = (_artist or "")})
-                         end)
-             self:add_tracks_from_jamendo(parse_table,format)
+             local track_table = jamendo.return_track_table()
+             for i = 1,table.getn(track_table) do
+                self:command("add " .. track_table[i].stream)
+             end
              self.recreate_menu = true
              self.recreate_list = true
-             self:save_cache()
           end
 end
 
@@ -384,7 +371,7 @@ function awesompd:get_list_menu()
         local end_num = (self.current_number + 15 < total_count ) and self.current_number + 15 or total_count
         for i = start_num, end_num do
             if (string.find(self.list_array[i],"jamendo.com")) then
-               table.insert(new_menu, { self.jamendo_list[awesompd.get_id_from_link(self.list_array[i])],
+               table.insert(new_menu, { jamendo.get_name_by_link(self.list_array[i]),
                                         self:command_play_specific(i),
                                         self.current_number == i and 
                                            (self.status == "Playing" and self.ICONS.PLAY or self.ICONS.PAUSE)
@@ -550,34 +537,6 @@ 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
-      for l in bus:lines() do
-         local _, _, id, track = string.find(l,"(%d+)-(.+)")
-         self.jamendo_list[id] = track
-      end
-   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
-      bus:write(id.."-"..name.."\n")
-   end
-   bus:flush()
-   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
-end
-
 function awesompd.split (s,t)
    local l = {n=0}
    local f = function (s)
@@ -687,7 +646,7 @@ function awesompd:update_track(file)
         local new_track = track_line
         if new_track ~= self.unique_text then
             if (string.find(new_track,"jamendo.com")) then
-               self.text = self.jamendo_list[awesompd.get_id_from_link(new_track)]
+               self.text = jamendo.get_name_by_link(new_track)
             else
                self.text = new_track
             end
@@ -762,93 +721,3 @@ 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
diff --git a/jamendo.lua b/jamendo.lua
new file mode 100644 (file)
index 0000000..1f4a915
--- /dev/null
@@ -0,0 +1,237 @@
+module('jamendo', package.seeall)
+
+-- Grab environment
+local os = os
+
+-- Global variables
+FORMAT_MP3 = { display = "MP3 (128k)", 
+               short_display = "MP3", 
+               value = "mp31" }
+FORMAT_OGG = { display = "Ogg Vorbis (q4)", 
+               short_display = "Ogg", 
+               value = "ogg2" }
+ORDER_RATINGDAILY = { display = "Daily rating", 
+                      short_display = "daily rating", 
+                      value = "ratingday_desc" }
+ORDER_RATINGWEEKLY = { display = "Weekly rating", 
+                      short_display = "weekly rating", 
+                      value = "ratingweek_desc" }
+ORDER_RATINGTOTAL = { display = "All time rating", 
+                      short_display = "all time rating", 
+                      value = "ratingtotal_desc" }
+ORDER_RANDOM = { display = "Random", 
+                 short_display = "random", 
+                 value = "random_desc" }
+SEARCH_ARTIST = { display = "Artist",
+                  value = "artist" }
+SEARCH_ALBUM = { display = "Album",
+                 value = "album" }
+SEARCH_TAG = { display = "Tag",
+               value = "tag_idstr" }
+
+current_request_table = { format = FORMAT_MP3,
+                          order = ORDER_RATINGWEEKLY }
+
+-- Local variables
+local jamendo_list = {}
+local cache_file = awful.util.getdir ("cache").."/jamendo_cache"
+local default_mp3_stream = nil
+
+-- Returns default stream number for MP3 format. Requests API for it
+-- not more often than every hour.
+function get_default_mp3_stream()
+   if not default_mp3_stream or 
+      (os.time() - default_mp3_stream.last_checked) > 3600 then
+      local trygetlink = 
+         assert(io.popen("echo $(curl -w %{redirect_url} " .. 
+                         "'http://api.jamendo.com/get2/stream/track/redirect/" .. 
+                         "?streamencoding="..format.."&id=729304')",'r')):read("*line")
+      local _, _, prefix = string.find(trygetlink,"stream(%d+)\.jamendo\.com")
+      default_mp3_stream = { id = prefix, last_checked = os.time() }
+   end
+   return default_mp3_stream.id
+end
+
+-- Returns the track ID from the given link to Jamendo stream.
+function get_id_from_link(link)
+   local _, _, id = string.find(link,"stream/(%d+)")
+   return id
+end
+
+-- Returns link to music stream for the given track ID. Uses MP3
+-- format and the default stream for it.
+function get_link_by_id(id)
+   return string.format("http://stream%s.jamendo.com/stream/%s/mp31/", 
+                        get_default_mp3_stream(), id)
+end
+
+-- Returns track name for given music stream.
+function get_name_by_link(link)
+   return jamendo_list[get_id_from_link(link)]
+end
+
+-- Returns table of track IDs, names and other things based on the
+-- request table.
+function return_track_table(request_table)
+   local req_string = form_request(request_table)
+   local bus = assert(io.popen(req_string, 'r'))
+   local response = bus:read("*all")
+   bus:close()
+   parse_table = parse_json(response)
+   for i = 1, table.getn(parse_table) do
+      if parse_table[i].stream == "" then
+         -- Some songs don't have Ogg stream, use MP3 instead
+         parse_table[i].stream = get_link_by_id(parse_table[i].id)
+      end
+      parse_table[i].display_name = 
+         parse_table[i].artist_name .. " - " .. parse_table[i].name
+      -- Save fetched tracks for further caching
+      jamendo_list[parse_table[i].id] = parse_table[i].display_name
+   end
+   save_cache()
+   return parse_table
+end
+
+-- Generates the request to Jamendo API based on provided request
+-- table. If request_table is nil, uses current_request_table instead.
+function form_request(request_table)
+   local curl_str = 'echo $(curl -w %%{redirect_url} ' ..
+      '"http://api.jamendo.com/get2/id+artist_name+name+stream/' ..
+      'track/json/track_album+album_artist/?n=100&order=%s&streamencoding=%s")'
+   if request_table then
+      local format = request_table.format or current_request_table.format
+      local order = request_table.order or current_request_table.order
+      return string.format(curl_str, order.value, format.value)
+   else
+      print("Request : " .. string.format(curl_str, 
+                           current_request_table.order.value,
+                                        current_request_table.format.value))
+      return string.format(curl_str, 
+                           current_request_table.order.value,
+                           current_request_table.format.value)
+   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 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 = 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 utf8_codes_to_symbols (s)
+   local hexnums = "[%dabcdefABCDEF]"
+   local pattern = string.format("\\u(%s%s%s%s?)", 
+                                 hexnums, hexnums, hexnums, hexnums)
+   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
+
+-- Retrieves mapping of track IDs to track names to avoid redundant
+-- queries when Awesome gets restarted.
+function retrieve_cache()
+   local bus = io.open(cache_file)
+   if bus then
+      for l in bus:lines() do
+         local _, _, id, track = string.find(l,"(%d+)-(.+)")
+         jamendo_list[id] = track
+      end
+   end
+end
+
+-- Saves track IDs to track names mapping into the cache file.
+function save_cache()
+   local bus = io.open(cache_file, "w")
+   for id,name in pairs(jamendo_list) do
+      bus:write(id.."-"..name.."\n")
+   end
+   bus:flush()
+   bus:close()
+end
+
+-- Retrieve cache on initialization
+retrieve_cache()