From 3a8fdd263de92f89d1c9fd7c15ba3c49eed39c20 Mon Sep 17 00:00:00 2001 From: Alexander Yakushev Date: Sat, 10 Sep 2011 18:03:24 +0300 Subject: Added feature to browse current artist or album on Jamendo --- awesompd.lua | 66 ++++++++++++++++++++++++++++++++++++----------- jamendo.lua | 83 ++++++++++++++++++++++++++++++++++++++++-------------------- rcsample.lua | 4 +++ 3 files changed, 110 insertions(+), 43 deletions(-) diff --git a/awesompd.lua b/awesompd.lua index 10b5442..7562873 100644 --- a/awesompd.lua +++ b/awesompd.lua @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- -- @author Alexander Yakushev -- @copyright 2010-2011 Alexander Yakushev --- @release v1.0.5 +-- @release v1.0.6 --------------------------------------------------------------------------- require('utf8') @@ -137,6 +137,7 @@ function awesompd:create() instance.recreate_options = true instance.recreate_jamendo_formats = true instance.recreate_jamendo_order = true + instance.recreate_jamendo_browse = true instance.current_number = 0 instance.menu_shown = false @@ -151,6 +152,7 @@ function awesompd:create() instance.rdecorator = " " instance.show_album_cover = true instance.album_cover_size = 50 + instance.browser = "firefox" -- Widget configuration instance.widget:add_signal("mouse::enter", function(c) @@ -287,6 +289,14 @@ function awesompd:command_clear_playlist() self.recreate_list = true end end + +function awesompd:command_open_in_browser(link) + return function() + if self.browser then + awful.util.spawn(self.browser .. " '" .. link .. "'") + end + end +end -- /// End of mpc command functions /// @@ -306,18 +316,23 @@ function awesompd:command_show_menu() self.connected then self:check_list() self:check_playlists() + local jamendo_menu = { { "Search by", + { { "Nothing (Top 100)", self:menu_jamendo_top() }, + { "Artist", self:menu_jamendo_search_by(jamendo.SEARCH_ARTIST) }, + { "Album", self:menu_jamendo_search_by(jamendo.SEARCH_ALBUM) }, + { "Tag", self:menu_jamendo_search_by(jamendo.SEARCH_TAG) }}} } + local browse_menu = self:menu_jamendo_browse() + if browse_menu then + table.insert(jamendo_menu, browse_menu) + end + table.insert(jamendo_menu, self:menu_jamendo_format()) + table.insert(jamendo_menu, self:menu_jamendo_order()) + new_menu = { { "Playback", self:menu_playback() }, { "Options", self:menu_options() }, { "List", self:menu_list() }, { "Playlists", self:menu_playlists() }, - { "Jamendo", - { { "Search by", - { { "Nothing (Top 100)", self:menu_jamendo_top() }, - { "Artist", self:menu_jamendo_search_by(jamendo.SEARCH_ARTIST) }, - { "Album", self:menu_jamendo_search_by(jamendo.SEARCH_ALBUM) }, - { "Tag", self:menu_jamendo_search_by(jamendo.SEARCH_TAG) }}}, - self:menu_jamendo_format(), - self:menu_jamendo_order() }} } + { "Jamendo", jamendo_menu } } end table.insert(new_menu, { "Servers", self:menu_servers() }) self.main_menu = awful.menu({ items = new_menu, width = 300 }) @@ -384,16 +399,16 @@ function awesompd:menu_list() if self.recreate_list then local new_menu = {} if self.list_array then - local total_count = table.getn(self.list_array) - local start_num = (self.current_number - 15 > 0) and self.current_number - 15 or 1 - local end_num = (self.current_number + 15 < total_count ) and self.current_number + 15 or total_count - for i = start_num, end_num do + local total_count = table.getn(self.list_array) + local start_num = (self.current_number - 15 > 0) and self.current_number - 15 or 1 + local end_num = (self.current_number + 15 < total_count ) and self.current_number + 15 or total_count + for i = start_num, end_num do table.insert(new_menu, { jamendo.replace_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) or nil} ) - end + end end self.recreate_list = false self.list_menu = new_menu @@ -524,6 +539,27 @@ function awesompd:menu_jamendo_format() return self.jamendo_formats_menu end +function awesompd:menu_jamendo_browse() + if self.recreate_jamendo_browse and self.browser then + local track = jamendo.get_track_by_link(self.unique_text) + local new_menu + if track then + local artist_link = + "http://www.jamendo.com/artist/" .. track.artist_link_name + local album_link = + "http://www.jamendo.com/album/" .. track.album_id + new_menu = { { "Artist's page" , + self:command_open_in_browser(artist_link) }, + { "Album's page" , + self:command_open_in_browser(album_link) } } + self.jamendo_browse_menu = { "Browse on Jamendo", new_menu } + else + self.jamendo_browse_menu = nil + end + end + return self.jamendo_browse_menu +end + function awesompd:menu_jamendo_order() if self.recreate_jamendo_order then local setorder = @@ -946,5 +982,5 @@ end -- configuration /// function awesompd:command_toggle() - self:command_playpause() + return self:command_playpause() end diff --git a/jamendo.lua b/jamendo.lua index 78dc962..9104ac3 100644 --- a/jamendo.lua +++ b/jamendo.lua @@ -58,7 +58,7 @@ ALL_ORDERS = { ORDER_RELEVANCE, ORDER_RANDOM, ORDER_RATINGDAILY, ORDER_RATINGWEEKLY, ORDER_RATINGTOTAL } current_request_table = { unit = "track", - fields = {"id", "artist_name", "name", + fields = {"id", "artist_url", "artist_name", "name", "stream", "album_image" }, joins = { "track_album", "album_artist" }, params = { streamencoding = FORMAT_MP3, @@ -68,6 +68,7 @@ current_request_table = { unit = "track", -- Local variables local jamendo_list = {} local cache_file = awful.util.getdir ("cache").."/jamendo_cache" +local cache_header = "[version=1.0.6]" local album_covers_folder = awful.util.getdir("cache") .. "/jamendo_covers/" local default_mp3_stream = nil local search_template = { fields = { "id", "name" }, @@ -90,9 +91,21 @@ function get_default_mp3_stream() return default_mp3_stream.id end --- Returns the track ID from the given link to Jamendo stream. -function get_id_from_link(link) +-- Returns the track ID from the given link to Jamendo stream. MPD +-- transforms Ogg stream links into normal track names. Good for it +-- but bad for us! We don't know if the song is streamed from Jamendo +-- anymore. The best we can do is to look through the whole +-- jamendo_list and compare it with the given track name. If +-- scan_for_song_name is not nil, then we will perform this check. +function get_id_from_link(link, scan_for_song_name) local _, _, id = string.find(link,"stream/(%d+)") + if not id and scan_for_song_name then + for _, track in pairs(jamendo_list) do + if track.display_name == link then + return track.id + end + end + end return id end @@ -113,6 +126,22 @@ function get_name_by_link(link) end end +-- Returns the album id for given music stream. +function get_album_id_by_link(link) + local id = get_id_from_link(link, true) + if id and jamendo_list[id] then + return jamendo_list[id].album_id + end +end + +-- Returns the track table for the given music stream. +function get_track_by_link(link) + local id = get_id_from_link(link, true) + if id and jamendo_list[id] then + return jamendo_list[id] + end +end + -- If a track is actually a Jamendo stream, replace it with normal -- track name. function replace_link(track) @@ -136,6 +165,8 @@ function return_track_table(request_table) -- 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].artist_link_name = + string.find(parse_table[i].artist_url, "jamendo.com\\/artist\\/(.+)") parse_table[i].display_name = parse_table[i].artist_name .. " - " .. parse_table[i].name -- Do Jamendo a favor, extract album_id for the track yourself @@ -303,14 +334,22 @@ function retrieve_cache() local bus = io.open(cache_file) local track = {} if bus then - for l in bus:lines() do - local _, _, id, album_id, track_name = - string.find(l,"(%d+)-(%d+)-(.+)") - track = {} - track.id = id - track.album_id = album_id - track.display_name = track_name - jamendo_list[id] = track + local header = bus:read("*line") + if header == cache_header then + for l in bus:lines() do + local _, _, id, artist_link_name, album_id, track_name = + string.find(l,"(%d+)-([^-]+)-(%d+)-(.+)") + track = {} + track.id = id + track.artist_link_name = artist_link_name + track.album_id = album_id + track.display_name = track_name + jamendo_list[id] = track + end + else + -- We encountered an outdated version of the cache + -- file. Let's just remove it. + awful.util.spawn("rm -f " .. cache_file) end end end @@ -319,8 +358,9 @@ end -- file. function save_cache() local bus = io.open(cache_file, "w") + bus:write(cache_header .. "\n") for id,track in pairs(jamendo_list) do - bus:write(string.format("%s-%s-%s\n", id, + bus:write(string.format("%s-%s-%s-%s\n", id, track.artist_link_name, track.album_id, track.display_name)) end bus:flush() @@ -374,22 +414,9 @@ end -- Checks if track_name is actually a link to Jamendo stream. If true -- returns the file with album cover for the track. function try_get_cover(track_name) - if string.find(track_name, "jamendo.com/stream") then - return get_album_cover(get_id_from_link(track_name)) - else - -- MPD transforms Ogg stream links into normal track names. Good - -- for it but bad for us! We don't know if the song is streamed - -- from Jamendo anymore. The best we can do for now is to look - -- through the whole jamendo_list and compare it with the given - -- track name. - for _, track in pairs(jamendo_list) do - if track.display_name == track_name then - return get_album_cover(track.id) - end - end - -- Seems like it is not a Jamendo stream. And even if it is, we - -- still can't do anything. - return nil + local id = get_id_from_link(track_name, true) + if id then + return get_album_cover(id) end end diff --git a/rcsample.lua b/rcsample.lua index 336f2ef..6a54f4a 100644 --- a/rcsample.lua +++ b/rcsample.lua @@ -96,6 +96,10 @@ mysystray = widget({ type = "systray" }) -- this option on the fly in awesompd itself. -- possible formats: awesompd.FORMAT_MP3, awesompd.FORMAT_OGG musicwidget.jamendo_format = awesompd.FORMAT_MP3 + + -- Specify the browser you use so awesompd can open links from + -- Jamendo in it. + musicwidget.browser = "firefox" -- If true, song notifications for Jamendo tracks and local tracks -- will also contain album cover image. -- cgit v1.2.3