Browse Source

Awesome-3.5 config added.

awesome-3.5
Kolan Sh 7 years ago
parent
commit
4dc9d763ba
100 changed files with 4541 additions and 0 deletions
  1. BIN
      Icons/16x16/battery.png
  2. BIN
      Icons/16x16/cpu.png
  3. BIN
      Icons/16x16/down.png
  4. BIN
      Icons/16x16/down_up.png
  5. BIN
      Icons/16x16/mem.png
  6. BIN
      Icons/16x16/net-wifi.png
  7. BIN
      Icons/16x16/net-wired.png
  8. BIN
      Icons/16x16/up.png
  9. BIN
      Icons/16x16/vol-hi.png
  10. BIN
      Icons/cpu.png
  11. BIN
      Icons/mem.png
  12. BIN
      Icons/volume.png
  13. BIN
      Icons/weather.png
  14. +33
    -0
      aurup.lua
  15. +9
    -0
      autostart.lua
  16. +19
    -0
      awesompd/README.md
  17. +67
    -0
      awesompd/asyncshell.lua
  18. +1140
    -0
      awesompd/awesompd.lua
  19. BIN
      awesompd/icons/check_icon.png
  20. BIN
      awesompd/icons/default_album_cover.png
  21. BIN
      awesompd/icons/next_icon.png
  22. BIN
      awesompd/icons/pause_icon.png
  23. BIN
      awesompd/icons/play_icon.png
  24. BIN
      awesompd/icons/play_pause_icon.png
  25. BIN
      awesompd/icons/prev_icon.png
  26. BIN
      awesompd/icons/radio_icon.png
  27. BIN
      awesompd/icons/stop_icon.png
  28. +524
    -0
      awesompd/jamendo.lua
  29. +407
    -0
      awesompd/rcsample.lua
  30. +158
    -0
      awesompd/utf8.lua
  31. +50
    -0
      bitcoin.lua
  32. +133
    -0
      diskusage.lua
  33. +126
    -0
      freedesktop/desktop.lua
  34. +97
    -0
      freedesktop/menu.lua
  35. +255
    -0
      freedesktop/utils.lua
  36. +33
    -0
      gfxtemp.lua
  37. +47
    -0
      gmail_parser.py
  38. +95
    -0
      html.lua
  39. +119
    -0
      keybinds.lua
  40. +123
    -0
      keydoc.lua
  41. +36
    -0
      list.lua
  42. +33
    -0
      namecoin.lua
  43. +34
    -0
      pacmanup.lua
  44. +1
    -0
      perceptive/.gitignore
  45. +43
    -0
      perceptive/README.md
  46. +83
    -0
      perceptive/init.lua
  47. BIN
      perceptive/screenshot.png
  48. +87
    -0
      perceptive/weather-fetcher.py
  49. +601
    -0
      rc.lua
  50. +3
    -0
      set_wall.sh
  51. +33
    -0
      sysinf.lua
  52. +3
    -0
      themes/default/README
  53. BIN
      themes/default/icon/Arch.png
  54. BIN
      themes/default/icon/Arch.png.bak
  55. BIN
      themes/default/icon/awesome16.png
  56. BIN
      themes/default/layouts/dwindle.png
  57. BIN
      themes/default/layouts/dwindlew.png
  58. BIN
      themes/default/layouts/fairh.png
  59. BIN
      themes/default/layouts/fairhw.png
  60. BIN
      themes/default/layouts/fairv.png
  61. BIN
      themes/default/layouts/fairvw.png
  62. BIN
      themes/default/layouts/floating.png
  63. BIN
      themes/default/layouts/floatingw.png
  64. BIN
      themes/default/layouts/fullscreen.png
  65. BIN
      themes/default/layouts/fullscreenw.png
  66. BIN
      themes/default/layouts/magnifier.png
  67. BIN
      themes/default/layouts/magnifierw.png
  68. BIN
      themes/default/layouts/max.png
  69. BIN
      themes/default/layouts/maxw.png
  70. BIN
      themes/default/layouts/spiral.png
  71. BIN
      themes/default/layouts/spiralw.png
  72. BIN
      themes/default/layouts/tile.png
  73. BIN
      themes/default/layouts/tilebottom.png
  74. BIN
      themes/default/layouts/tilebottomw.png
  75. BIN
      themes/default/layouts/tileleft.png
  76. BIN
      themes/default/layouts/tileleftw.png
  77. BIN
      themes/default/layouts/tiletop.png
  78. BIN
      themes/default/layouts/tiletopw.png
  79. BIN
      themes/default/layouts/tilew.png
  80. BIN
      themes/default/submenu.png
  81. BIN
      themes/default/taglist/squarefw.png
  82. BIN
      themes/default/taglist/squarefw.png2
  83. BIN
      themes/default/taglist/squarew.png
  84. BIN
      themes/default/taglist/squarew.png2
  85. BIN
      themes/default/tasklist/floating.png
  86. BIN
      themes/default/tasklist/floatingw.png
  87. +149
    -0
      themes/default/theme.lua
  88. BIN
      themes/default/titlebar/close_focus.png
  89. BIN
      themes/default/titlebar/close_normal.png
  90. BIN
      themes/default/titlebar/floating_focus_active.png
  91. BIN
      themes/default/titlebar/floating_focus_inactive.png
  92. BIN
      themes/default/titlebar/floating_normal_active.png
  93. BIN
      themes/default/titlebar/floating_normal_inactive.png
  94. BIN
      themes/default/titlebar/maximized_focus_active.png
  95. BIN
      themes/default/titlebar/maximized_focus_inactive.png
  96. BIN
      themes/default/titlebar/maximized_normal_active.png
  97. BIN
      themes/default/titlebar/maximized_normal_inactive.png
  98. BIN
      themes/default/titlebar/ontop_focus_active.png
  99. BIN
      themes/default/titlebar/ontop_focus_inactive.png
  100. BIN
      themes/default/titlebar/ontop_normal_active.png

BIN
Icons/16x16/battery.png View File

Before After
Width: 16  |  Height: 16  |  Size: 191B

BIN
Icons/16x16/cpu.png View File

Before After
Width: 16  |  Height: 16  |  Size: 204B

BIN
Icons/16x16/down.png View File

Before After
Width: 16  |  Height: 16  |  Size: 298B

BIN
Icons/16x16/down_up.png View File

Before After
Width: 16  |  Height: 16  |  Size: 218B

BIN
Icons/16x16/mem.png View File

Before After
Width: 16  |  Height: 16  |  Size: 171B

BIN
Icons/16x16/net-wifi.png View File

Before After
Width: 16  |  Height: 16  |  Size: 216B

BIN
Icons/16x16/net-wired.png View File

Before After
Width: 16  |  Height: 16  |  Size: 217B

BIN
Icons/16x16/up.png View File

Before After
Width: 16  |  Height: 16  |  Size: 299B

BIN
Icons/16x16/vol-hi.png View File

Before After
Width: 16  |  Height: 16  |  Size: 247B

BIN
Icons/cpu.png View File

Before After
Width: 24  |  Height: 24  |  Size: 1.4KB

BIN
Icons/mem.png View File

Before After
Width: 128  |  Height: 128  |  Size: 5.0KB

BIN
Icons/volume.png View File

Before After
Width: 57  |  Height: 57  |  Size: 1000B

BIN
Icons/weather.png View File

Before After
Width: 60  |  Height: 60  |  Size: 4.3KB

+ 33
- 0
aurup.lua View File

@@ -0,0 +1,33 @@
-- {{{ init environment
local wakka = {}
local capi = {
mouse = mouse,
screen = screen
}

-- {{{ display
-- formats the lines for the notify
local function display()
local lines = "<u>AUR Updates:</u>\n"
local f = io.popen("cower -u", "r")
local s = f:read('*all')
line = lines .. "\n" .. s .. "\n"
f:close()
return line
end
-- }}}
-- }}}

function wakka.addToWidget(mywidget)
mywidget:add_signal('mouse::enter', function ()
usage = naughty.notify({
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
timeout = 0,
hover_timeout = 0.5,
screen = capi.mouse.screen
})
end)
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
end

return wakka

+ 9
- 0
autostart.lua View File

@@ -0,0 +1,9 @@
os.execute ("numlockx on &")
os.execute ("xsetroot -cursor_name left_ptr &")
os.execute ("xscreensaver -no-splash &")
os.execute ("pidgin &")
os.execute ("pgrep stardict || stardict &")
os.execute ("pgrep urxvt || urxvt &")
os.execute ("pgrep firefox || firefox &")
os.execute ("nvidia-settings -a GPUOverclockingState=1 -a GPU2DClockFreqs=135,135 -a GPU3DClockFreqs=629,480")
os.execute (os.getenv("HOME").."/.config/awesome/set_wall.sh "..os.getenv("HOME").."/wallpapers/")

+ 19
- 0
awesompd/README.md View File

@@ -0,0 +1,19 @@
## Description ##

This is an advanced MPD widget\client for AwesomeWM.

For the detailed installation guide please see http://awesome.naquadah.org/wiki/Awesompd_widget .

Also you can find an example of the widget configuration in the file rcsample.lua.

## Version explanation ##

Use this version with Awesome v3.4.x. If you are using the git pre-4.0 version of Awesome, please consider using [this](https://github.com/alexander-yakushev/awesompd/tree/for-awesome-git) version instead.

### Changes in 1.1.0 ###

* Album covers are now also shown for the local tracks (images are taken from the current track's folder)
* When the Jamendo track is playing you can visit artist's or album's page from the Jamendo menu
* Notification now shows the album name for the current track (for both local and Jamendo tracks)
* A few minor modifications and bugfixes


+ 67
- 0
awesompd/asyncshell.lua View File

@@ -0,0 +1,67 @@
-- Asynchronous io.popen for Awesome WM.
-- How to use...
-- ...asynchronously:
-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
-- ...synchronously
-- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error"

asyncshell = {}
asyncshell.request_table = {}
asyncshell.id_counter = 0
asyncshell.folder = "/tmp/asyncshell"
asyncshell.file_template = asyncshell.folder .. '/req'

-- Create a directory for asynchell response files
os.execute("mkdir -p " .. asyncshell.folder)

-- Returns next tag - unique identifier of the request
local function next_id()
asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000
return asyncshell.id_counter
end

-- Sends an asynchronous request for an output of the shell command.
-- @param command Command to be executed and taken output from
-- @param callback Function to be called when the command finishes
-- @return Request ID
function asyncshell.request(command, callback)
local id = next_id()
local tmpfname = asyncshell.file_template .. id
asyncshell.request_table[id] = {callback = callback}
local req =
string.format("bash -c '%s > %s; " ..
'echo "asyncshell.deliver(%s)" | ' ..
"awesome-client' 2> /dev/null",
string.gsub(command, "'", "'\\''"), tmpfname, id, tmpfname)
awful.util.spawn(req)
return id
end

-- Calls the remembered callback function on the output of the shell
-- command.
-- @param id Request ID
-- @param output The output file of the shell command to be delievered
function asyncshell.deliver(id)
if asyncshell.request_table[id] and
asyncshell.request_table[id].callback then
local output = io.open(asyncshell.file_template .. id, 'r')
asyncshell.request_table[id].callback(output)
end
end

-- Sends a synchronous request for an output of the command. Waits for
-- the output, but if the given timeout expires returns nil.
-- @param command Command to be executed and taken output from
-- @param timeout Maximum amount of time to wait for the result
-- @return File handler on success, nil otherwise
function asyncshell.demand(command, timeout)
local id = next_id()
local tmpfname = asyncshell.file_template .. id
local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " ..
"(sleep %s; echo asynchell_timeout)",
command, tmpfname, timeout))
local result = f:read("*line")
if result == "asyncshell_done" then
return io.open(tmpfname)
end
end

+ 1140
- 0
awesompd/awesompd.lua
File diff suppressed because it is too large
View File


BIN
awesompd/icons/check_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 241B

BIN
awesompd/icons/default_album_cover.png View File

Before After
Width: 128  |  Height: 128  |  Size: 18KB

BIN
awesompd/icons/next_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 242B

BIN
awesompd/icons/pause_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 210B

BIN
awesompd/icons/play_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 234B

BIN
awesompd/icons/play_pause_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 248B

BIN
awesompd/icons/prev_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 240B

BIN
awesompd/icons/radio_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 342B

BIN
awesompd/icons/stop_icon.png View File

Before After
Width: 16  |  Height: 16  |  Size: 210B

+ 524
- 0
awesompd/jamendo.lua View File

@@ -0,0 +1,524 @@
---------------------------------------------------------------------------
-- @author Alexander Yakushev <yakushev.alex@gmail.com>
-- @copyright 2011 Alexander Yakushev
-- @release v1.1.5
---------------------------------------------------------------------------

-- Grab environment
local os = os
local awful = awful
local string = string
local table = table
local io = io
local pairs = pairs
local type = type
local assert = assert
local print = print
local tonumber = tonumber
local math = math
local tostring = tostring
local asyncshell = asyncshell

module('jamendo')

-- UTILITY STUFF
-- Checks whether file specified by filename exists.
local function file_exists(filename, mode)
mode = mode or 'r'
f = io.open(filename, mode)
if f then
f:close()
return true
else
return false
end
end

-- 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" }
ORDER_RELEVANCE = { display = "None (consecutive)",
short_display = "none",
value = "searchweight_desc" }
SEARCH_ARTIST = { display = "Artist",
unit = "artist",
value = "artist_id" }
SEARCH_ALBUM = { display = "Album",
unit = "album",
value = "album_id" }
SEARCH_TAG = { display = "Tag",
unit = "tag",
value = "tag_id" }
ALL_FORMATS = { FORMAT_MP3, FORMAT_OGG }
ALL_ORDERS = { ORDER_RELEVANCE, ORDER_RANDOM, ORDER_RATINGDAILY,
ORDER_RATINGWEEKLY, ORDER_RATINGTOTAL }

current_request_table = { unit = "track",
fields = {"id", "artist_url", "artist_name", "name",
"stream", "album_image", "album_name" },
joins = { "track_album", "album_artist" },
params = { streamencoding = FORMAT_MP3,
order = ORDER_RATINGWEEKLY,
n = 100 }}

-- Local variables
local jamendo_list = {}
local cache_file = awful.util.getdir ("cache").."/jamendo_cache"
local cache_header = "[version=1.1.0]"
local album_covers_folder = awful.util.getdir("cache") .. "/jamendo_covers/"
local default_mp3_stream = nil
local search_template = { fields = { "id", "name" },
joins = {},
params = { order = ORDER_RELEVANCE,
n = 1}}

-- DEPRECATED. Will be removed in the next major release.
-- Returns default stream number for MP3 format. Requests API for it
-- not more often than every hour.
local function get_default_mp3_stream()
if not default_mp3_stream or
(os.time() - default_mp3_stream.last_checked) > 3600 then
local trygetlink =
perform_request("echo $(curl -w %{redirect_url} " ..
"'http://api.jamendo.com/get2/stream/track/redirect/" ..
"?streamencoding="..FORMAT_MP3.value.."&id=729304')")
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. If the
-- given text is not the Jamendo stream returns nil.
function get_id_from_link(link)
local _, _, id = string.find(link,"storage%-new.newjamendo.com%?trackid=(%d+)")
return id
end

-- Returns link to music stream for the given track ID. Uses MP3
-- format and the default stream for it.
local function get_link_by_id(id)
-- This function is subject to change in the future.
return string.format("http://storage-new.newjamendo.com?trackid=%s&format=mp31&u=0", id)
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_name)
local track = get_track_by_link(track_name)
if track then
return track.display_name
else
return track_name
end
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 response = perform_request(req_string)
if not response then
return nil -- Bad internet connection
end
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].artist_link_name =
string.find(parse_table[i].artist_url, "\\/artist\\/(.+)")
-- Remove Jamendo escape slashes
parse_table[i].artist_name =
string.gsub(parse_table[i].artist_name, "\\/", "/")
parse_table[i].name = string.gsub(parse_table[i].name, "\\/", "/")

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
-- from album_image link :)
local _, _, album_id =
string.find(parse_table[i].album_image, "\\/(%d+)\\/covers")
parse_table[i].album_id = album_id or 0
-- Save fetched tracks for further caching
jamendo_list[parse_table[i].id] = parse_table[i]
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.
-- For all values that do not exist in request_table use ones from
-- current_request_table.
-- return - HTTP-request
function form_request(request_table)
local curl_str = "curl -A 'Mozilla/4.0' -fsm 5 \"%s\""
local url = "http://api.jamendo.com/en/?m=get2%s%s"
request_table = request_table or current_request_table
local fields = request_table.fields or current_request_table.fields
local joins = request_table.joins or current_request_table.joins
local unit = request_table.unit or current_request_table.unit
-- Form field&joins string (like field1+field2+fieldN%2Fjoin+)
local fnj_string = "&m_params="
for i = 1, table.getn(fields) do
fnj_string = fnj_string .. fields[i] .. "+"
end
fnj_string = string.sub(fnj_string,1,string.len(fnj_string)-1)
fnj_string = fnj_string .. "%2F" .. unit .. "%2Fjson%2F"
for i = 1, table.getn(joins) do
fnj_string = fnj_string .. joins[i] .. "+"
end
fnj_string = fnj_string .. "%2F"
local params = {}
-- If parameters where supplied in request_table, add them to the
-- parameters in current_request_table.
if request_table.params and
request_table.params ~= current_request_table.params then
-- First fill params with current_request_table parameters
for k, v in pairs(current_request_table.params) do
params[k] = v
end
-- Then add and overwrite them with request_table parameters
for k, v in pairs(request_table.params) do
params[k] = v
end
else -- Or just use current_request_table.params
params = current_request_table.params
end
-- Form parameter string (like param1=value1&param2=value2)
local param_string = ""
for k, v in pairs(params) do
if type(v) == "table" then
v = v.value
end
v = string.gsub(v, " ", "+")
param_string = param_string .. "&" .. k .. "=" .. v
end

return string.format(curl_str, string.format(url, fnj_string, param_string))
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, we found 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)
if code < 128 then -- one-byte symbol
return string.char(code)
elseif code < 2048 then -- two-byte symbol
-- Grab high and low bytes
local hi = math.floor(code / 64)
local lo = math.mod(code, 64)
-- Return symbol as \hi\lo
return string.char(hi + 192, lo + 128)
elseif code < 65536 then
-- Grab high, middle and low bytes
local hi = math.floor(code / 4096)
local leftover = code - hi * 4096
local mi = math.floor(leftover / 64)
leftover = leftover - mi * 64
local lo = math.mod(leftover, 64)
-- Return symbol as \hi\mi\lo
return string.char(hi + 224, mi + 160, lo + 128)
elseif code < 1114112 then
-- Grab high, highmiddle, lowmiddle and low bytes
local hi = math.floor(code / 262144)
local leftover = code - hi * 262144
local hm = math.floor(leftover / 4096)
leftover = leftover - hm * 4096
local lm = math.floor(leftover / 64)
local lo = math.mod(leftover, 64)
-- Return symbol as \hi\hm\lm\lo
return string.char(hi + 240, hm + 128, lm + 128, lo + 128)
else -- It is not Unicode symbol at all
return tostring(code)
end
end
return string.gsub(s, pattern, decode)
end

-- Retrieves mapping of track IDs to track names and album IDs to
-- avoid redundant queries when Awesome gets restarted.
local function retrieve_cache()
local bus = io.open(cache_file)
local track = {}
if bus then
local header = bus:read("*line")
if header == cache_header then
for l in bus:lines() do
local _, _, id, artist_link_name, album_name, album_id, track_name =
string.find(l,"(%d+)-([^-]+)-([^-]+)-(%d+)-(.+)")
track = {}
track.id = id
track.artist_link_name = string.gsub(artist_link_name, '\\_', '-')
track.album_name = string.gsub(album_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

-- Saves track IDs to track names and album IDs mapping into the cache
-- 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-%s-%s\n", id,
string.gsub(track.artist_link_name, '-', '\\_'),
string.gsub(track.album_name, '-', '\\_'),
track.album_id, track.display_name))
end
bus:flush()
bus:close()
end

-- Retrieve cache on initialization
retrieve_cache()

-- Returns a filename of the album cover and formed wget request that
-- downloads the album cover for the given track name. If the album
-- cover already exists returns nil as the second argument.
function fetch_album_cover_request(track_id)
local track = jamendo_list[track_id]
local album_id = track.album_id

if album_id == 0 then -- No cover for tracks without album!
return nil
end
local file_path = album_covers_folder .. album_id .. ".jpg"

if not file_exists(file_path) then -- We need to download it
-- First check if cache directory exists
f = io.popen('test -d ' .. album_covers_folder .. ' && echo t')
if f:read("*line") ~= 't' then
awful.util.spawn("mkdir " .. album_covers_folder)
end
f:close()
if not track.album_image then -- Wow! We have album_id, but
local a_id = tostring(album_id) --don't have album_image. Well,
local prefix = --it happens.
string.sub(a_id, 1, string.len(a_id) - 3)
track.album_image =
string.format("http://imgjam.com/albums/s%s/%s/covers/1.100.jpg",
prefix == "" and 0 or prefix, a_id)
end
return file_path, string.format("wget %s -O %s 2> /dev/null",
track.album_image, file_path)
else -- Cover already downloaded, return its filename and nil
return file_path, nil
end
end

-- Returns a file containing an album cover for given track id. First
-- searches in the cache folder. If file is not there, fetches it from
-- the Internet and saves into the cache folder.
function get_album_cover(track_id)
local file_path, fetch_req = fetch_album_cover_request(track_id)
if fetch_req then
local f = io.popen(fetch_req)
f:close()

-- Let's check if file is finally there, just in case
if not file_exists(file_path) then
return nil
end
end
return file_path
end

-- Same as get_album_cover, but downloads (if necessary) the cover
-- asynchronously.
function get_album_cover_async(track_id)
local file_path, fetch_req = fetch_album_cover_request(track_id)
if fetch_req then
asyncshell.request(fetch_req)
end
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)
local id = get_id_from_link(track_name)
if id then
return get_album_cover(id)
end
end

-- Same as try_get_cover, but calls get_album_cover_async inside.
function try_get_cover_async(track_name)
local id = get_id_from_link(track_name)
if id then
return get_album_cover_async(id)
end
end

-- Returns the track table for given query and search method.
-- what - search method - SEARCH_ARTIST, ALBUM or TAG
-- s - string to search
function search_by(what, s)
-- Get a default request and set unit and query
local req = search_template
req.unit = what.unit
req.params.searchquery = s
local resp = perform_request(form_request(req))
if resp then
local search_res = parse_json(resp)[1]
if search_res then
-- Now when we got the search result, find tracks filtered by
-- this result.
local params = {}
params[what.value] = search_res.id
req = { params = params }
local track_table = return_track_table(req)
return { search_res = search_res, tracks = track_table }
end
end
end

-- Executes request_string with io.popen and returns the response.
function perform_request(reqest_string)
local bus = assert(io.popen(reqest_string,'r'))
local response = bus:read("*all")
bus:close()
-- Curl with popen can sometimes fail to fetch data when the
-- connection is slow. Let's try again if it fails.
if string.len(response) == 0 then
bus = assert(io.popen(reqest_string,'r'))
response = bus:read("*all")
bus:close()
-- If it still can't read anything, return nil
if string.len(response) ~= 0 then
return nil
end
end
return response
end

-- Sets default streamencoding in current_request_table.
function set_current_format(format)
current_request_table.params.streamencoding = format
end

-- Sets default order in current_request_table.
function set_current_order(order)
current_request_table.params.order = order
end

+ 407
- 0
awesompd/rcsample.lua View File

@@ -0,0 +1,407 @@
-- Standard awesome library
require("awful")
require("awful.autofocus")
require("awful.rules")
-- Theme handling library
require("beautiful")
-- Notification library
require("naughty")

-- Load Debian menu entries
require("debian.menu")

-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
beautiful.init("/usr/share/awesome/themes/default/theme.lua")

-- This is used later as the default terminal and editor to run.
terminal = "x-terminal-emulator"
editor = os.getenv("EDITOR") or "editor"
editor_cmd = terminal .. " -e " .. editor

-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"

-- Table of layouts to cover with awful.layout.inc, order matters.
layouts =
{
awful.layout.suit.floating,
awful.layout.suit.tile,
awful.layout.suit.tile.left,
awful.layout.suit.tile.bottom,
awful.layout.suit.tile.top,
awful.layout.suit.fair,
awful.layout.suit.fair.horizontal,
awful.layout.suit.spiral,
awful.layout.suit.spiral.dwindle,
awful.layout.suit.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier
}
-- }}}

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {}
for s = 1, screen.count() do
-- Each screen has its own tag table.
tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
end
-- }}}

-- {{{ Menu
-- Create a laucher widget and a main menu
myawesomemenu = {
{ "manual", terminal .. " -e man awesome" },
{ "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" },
{ "restart", awesome.restart },
{ "quit", awesome.quit }
}

mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
{ "Debian", debian.menu.Debian_menu.Debian },
{ "open terminal", terminal }
}
})

mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
menu = mymainmenu })
-- }}}

-- {{{ Wibox
-- Create a textclock widget
mytextclock = awful.widget.textclock({ align = "right" })

-- Create a systray
mysystray = widget({ type = "systray" })

-- BEGIN OF AWESOMPD WIDGET DECLARATION

require('awesompd/awesompd')

musicwidget = awesompd:create() -- Create awesompd widget
musicwidget.font = "Liberation Mono" -- Set widget font
musicwidget.scrolling = true -- If true, the text in the widget will be scrolled
musicwidget.output_size = 30 -- Set the size of widget in symbols
musicwidget.update_interval = 10 -- Set the update interval in seconds

-- Set the folder where icons are located (change username to your login name)
musicwidget.path_to_icons = "/home/username/.config/awesome/icons"

-- Set the default music format for Jamendo streams. You can change
-- 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.
musicwidget.show_album_cover = true

-- Specify how big in pixels should an album cover be. Maximum value
-- is 100.
musicwidget.album_cover_size = 50
-- This option is necessary if you want the album covers to be shown
-- for your local tracks.
musicwidget.mpd_config = "/home/username/.mpdconf"
-- Specify decorators on the left and the right side of the
-- widget. Or just leave empty strings if you decorate the widget
-- from outside.
musicwidget.ldecorator = " "
musicwidget.rdecorator = " "

-- Set all the servers to work with (here can be any servers you use)
musicwidget.servers = {
{ server = "localhost",
port = 6600 },
{ server = "192.168.0.72",
port = 6600 }
}

-- Set the buttons of the widget. Keyboard keys are working in the
-- entire Awesome environment. Also look at the line 352.
musicwidget:register_buttons({ { "", awesompd.MOUSE_LEFT, musicwidget:command_playpause() },
{ "Control", awesompd.MOUSE_SCROLL_UP, musicwidget:command_prev_track() },
{ "Control", awesompd.MOUSE_SCROLL_DOWN, musicwidget:command_next_track() },
{ "", awesompd.MOUSE_SCROLL_UP, musicwidget:command_volume_up() },
{ "", awesompd.MOUSE_SCROLL_DOWN, musicwidget:command_volume_down() },
{ "", awesompd.MOUSE_RIGHT, musicwidget:command_show_menu() },
{ "", "XF86AudioLowerVolume", musicwidget:command_volume_down() },
{ "", "XF86AudioRaiseVolume", musicwidget:command_volume_up() },
{ modkey, "Pause", musicwidget:command_playpause() } })

musicwidget:run() -- After all configuration is done, run the widget

-- END OF AWESOMPD WIDGET DECLARATION
-- Don't forget to add the widget to the wibox. It is done on the line 216.

mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
awful.button({ }, 1, awful.tag.viewonly),
awful.button({ modkey }, 1, awful.client.movetotag),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ modkey }, 3, awful.client.toggletag),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
)
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
client.focus = c
c:raise()
end),
awful.button({ }, 3, function ()
if instance then
instance:hide()
instance = nil
else
instance = awful.menu.clients({ width=250 })
end
end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(1)
if client.focus then client.focus:raise() end
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end))

for s = 1, screen.count() do
-- Create a promptbox for each screen
mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright })
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
mylayoutbox[s] = awful.widget.layoutbox(s)
mylayoutbox[s]:buttons(awful.util.table.join(
awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
-- Create a taglist widget
mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons)

-- Create a tasklist widget
mytasklist[s] = awful.widget.tasklist(function(c)
return awful.widget.tasklist.label.currenttags(c, s)
end, mytasklist.buttons)

-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", screen = s })
-- Add widgets to the wibox - order matters
mywibox[s].widgets = {
{
mylauncher,
mytaglist[s],
mypromptbox[s],
layout = awful.widget.layout.horizontal.leftright
},
mylayoutbox[s],
mytextclock,
musicwidget.widget, -- Awesompd widget is added like this
s == 1 and mysystray or nil,
mytasklist[s],
layout = awful.widget.layout.horizontal.rightleft
}
end
-- }}}

-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}

-- {{{ Key bindings
globalkeys = awful.util.table.join(
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
awful.key({ modkey, }, "Right", awful.tag.viewnext ),
awful.key({ modkey, }, "Escape", awful.tag.history.restore),

awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "w", function () mymainmenu:show({keygrabber=true}) end),

-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end),

-- Standard program
awful.key({ modkey, }, "Return", function () awful.util.spawn(terminal) end),
awful.key({ modkey, "Control" }, "r", awesome.restart),
awful.key({ modkey, "Shift" }, "q", awesome.quit),

awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),

-- Prompt
awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),

awful.key({ modkey }, "x",
function ()
awful.prompt.run({ prompt = "Run Lua code: " },
mypromptbox[mouse.screen].widget,
awful.util.eval, nil,
awful.util.getdir("cache") .. "/history_eval")
end)
)

clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, "Shift" }, "r", function (c) c:redraw() end),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end),
awful.key({ modkey, }, "n", function (c) c.minimized = not c.minimized end),
awful.key({ modkey, }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end)
)

-- Compute the maximum number of digit we need, limited to 9
keynumber = 0
for s = 1, screen.count() do
keynumber = math.min(9, math.max(#tags[s], keynumber));
end

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, keynumber do
globalkeys = awful.util.table.join(globalkeys,
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = mouse.screen
if tags[screen][i] then
awful.tag.viewonly(tags[screen][i])
end
end),
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local screen = mouse.screen
if tags[screen][i] then
awful.tag.viewtoggle(tags[screen][i])
end
end),
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.movetotag(tags[client.focus.screen][i])
end
end),
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.toggletag(tags[client.focus.screen][i])
end
end))
end

clientbuttons = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 3, awful.mouse.client.resize))

-- Set keys
-- Add this line before root.keys(globalkeys).
musicwidget:append_global_keys()

root.keys(globalkeys)
-- }}}

-- {{{ Rules
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = true,
keys = clientkeys,
buttons = clientbuttons } },
{ rule = { class = "MPlayer" },
properties = { floating = true } },
{ rule = { class = "pinentry" },
properties = { floating = true } },
{ rule = { class = "gimp" },
properties = { floating = true } },
-- Set Firefox to always map on tags number 2 of screen 1.
-- { rule = { class = "Firefox" },
-- properties = { tag = tags[1][2] } },
}
-- }}}

-- {{{ Signals
-- Signal function to execute when a new client appears.
client.add_signal("manage", function (c, startup)
-- Add a titlebar
-- awful.titlebar.add(c, { modkey = modkey })

-- Enable sloppy focus
c:add_signal("mouse::enter", function(c)
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and awful.client.focus.filter(c) then
client.focus = c
end
end)

if not startup then
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- awful.client.setslave(c)

-- Put windows in a smart way, only if they does not set an initial position.
if not c.size_hints.user_position and not c.size_hints.program_position then
awful.placement.no_overlap(c)
awful.placement.no_offscreen(c)
end
end
end)

client.add_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.add_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
-- }}}

+ 158
- 0
awesompd/utf8.lua View File

@@ -0,0 +1,158 @@
-- Provides UTF-8 aware string functions implemented in pure lua:
-- * string.utf8len(s)
-- * string.utf8sub(s, i, j)
--
-- All functions behave as their non UTF-8 aware counterparts with the exception
-- that UTF-8 characters are used instead of bytes for all units.
--
-- Note: all validations had been removed due to awesome usage specifics.
--[[
Copyright (c) 2006-2007, Kyle Smith
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--]]

-- ABNF from RFC 3629
--
-- UTF8-octets = *( UTF8-char )
-- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
-- UTF8-1 = %x00-7F
-- UTF8-2 = %xC2-DF UTF8-tail
-- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
-- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
-- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
-- %xF4 %x80-8F 2( UTF8-tail )
-- UTF8-tail = %x80-BF
--

-- returns the number of bytes used by the UTF-8 character at byte i in s
-- also doubles as a UTF-8 character validator
function utf8charbytes (s, i)
-- argument defaults
i = i or 1
local c = string.byte(s, i)
-- determine bytes needed for character, based on RFC 3629
if c > 0 and c <= 127 then
-- UTF8-1
return 1
elseif c >= 194 and c <= 223 then
-- UTF8-2
local c2 = string.byte(s, i + 1)
return 2
elseif c >= 224 and c <= 239 then
-- UTF8-3
local c2 = s:byte(i + 1)
local c3 = s:byte(i + 2)
return 3
elseif c >= 240 and c <= 244 then
-- UTF8-4
local c2 = s:byte(i + 1)
local c3 = s:byte(i + 2)
local c4 = s:byte(i + 3)
return 4
end
end

-- returns the number of characters in a UTF-8 string
function utf8len (s)
local pos = 1
local bytes = string.len(s)
local len = 0
while pos <= bytes and len ~= chars do
local c = string.byte(s,pos)
len = len + 1
pos = pos + utf8charbytes(s, pos)
end
if chars ~= nil then
return pos - 1
end
return len
end

-- functions identically to string.sub except that i and j are UTF-8 characters
-- instead of bytes
function utf8sub (s, i, j)
j = j or -1

if i == nil then
return ""
end
local pos = 1
local bytes = string.len(s)
local len = 0

-- only set l if i or j is negative
local l = (i >= 0 and j >= 0) or utf8len(s)
local startChar = (i >= 0) and i or l + i + 1
local endChar = (j >= 0) and j or l + j + 1

-- can't have start before end!
if startChar > endChar then
return ""
end
-- byte offsets to pass to string.sub
local startByte, endByte = 1, bytes
while pos <= bytes do
len = len + 1
if len == startChar then
startByte = pos
end
pos = pos + utf8charbytes(s, pos)
if len == endChar then
endByte = pos - 1
break
end
end
return string.sub(s, startByte, endByte)
end

-- replace UTF-8 characters based on a mapping table
function utf8replace (s, mapping)
local pos = 1
local bytes = string.len(s)
local charbytes
local newstr = ""

while pos <= bytes do
charbytes = utf8charbytes(s, pos)
local c = string.sub(s, pos, pos + charbytes - 1)
newstr = newstr .. (mapping[c] or c)
pos = pos + charbytes
end

return newstr
end

+ 50
- 0
bitcoin.lua View File

@@ -0,0 +1,50 @@
-- {{{ init environment
local wakka = {}
local capi = {
mouse = mouse,
screen = screen
}

-- {{{ display
-- formats the lines for the notify
local function display()
local lines = "<u>Bitcoin:</u>\n"
local tick = "<u>MtGox:</u>\n"
local f = io.popen("bitcoind getbalance", "r")
local t = io.popen("curl -q -s https://mtgox.com/code/data/ticker.php", "r")
local s = f:read('*all')
local g = t:read('*all')
line = lines .. "\n" .. s .. "\n"
ticker = tick .. "\n" .. g .. "\n"
f:close()
t:close()
-- return line, ticker
return string.format('%s%s',line, ticker)
end

--local function ticker()
-- local ticker = "<u>Ticker:</u>\n"
-- local t = io.popen("curl -q -s https://mtgox.com/code/data/ticker.php", "r")
-- local q = t:read('*all')
-- line1 = ticker .. "\n" .. q .. "\n"
-- t:close()
-- return line1
--end

-- }}}
-- }}}

function wakka.addToWidget(mywidget)
mywidget:add_signal('mouse::enter', function ()
run_display = display()
usage = naughty.notify({
text = string.format('<span font_desc="%s">%s</span>', "monospace", run_display),
timeout = 0,
hover_timeout = 0.5,
screen = capi.mouse.screen
})
end)
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
end

return wakka

+ 133
- 0
diskusage.lua View File

@@ -0,0 +1,133 @@
-- @author Peter J. Kranz (Absurd-Mind, peter@myref.net)
-- Any questions, criticism or praise just drop me an email

-- {{{ init environment
local M = {}
local capi = {
mouse = mouse,
screen = screen
}
units = {"KB", "MB", "GB", "TB", "PB", "EB"}
local usage = {}
-- }}}

-- {{{ local functions
-- {{{ Unit formatter
-- formats a value to the corresponding unit
local function uformat(value)
local ret = tonumber(value)
for i, u in pairs(units) do
if ret < 1024 then
return string.format("%.1f" .. u, ret)
end
ret = ret / 1024;
end
return "N/A"
end
-- }}}

-- {{{ getData
-- gets the required data from df
local function getData(onlyLocal)
-- Fallback to listing local filesystems
local warg = ""
if onlyLocal == true then
warg = "-l"
end

local fs_info = {} -- Get data from df
local f = io.popen("LC_ALL=C df -kP " .. warg)

for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount)
local s = string.match(line, "^.-[%s]([%d]+)")
local u,a,p = string.match(line, "([%d]+)[%D]+([%d]+)[%D]+([%d]+)%%")
local m = string.match(line, "%%[%s]([%p%w]+)")

if u and m then -- Handle 1st line and broken regexp
fs_info[m] = {}
fs_info[m]["size"] = s
fs_info[m]["used"] = u
fs_info[m]["avail"] = a
fs_info[m]["used_p"] = tonumber(p)
fs_info[m]["avail_p"] = 100 - tonumber(p)
end
end
f:close()
return fs_info
end
-- }}}

-- {{{ display
-- formats the lines for the notify
local function display(orange, red, onlyLocal)
data = getData(onlyLocal)
local lines = "<u>diskusage:</u>\n"

local longest = 0
local longestSize = 0;
local longestUsed = 0;
for i, m in pairs(data) do
if i:len() > longest then
longest = i:len()
end

local s = uformat(m["size"])
if s:len() > longestSize then
longestSize = s:len()
end

local u = uformat(m["used"])
if u:len() > longestUsed then
longestUsed = u:len()
end
end
longest = longest + 8

for i, m in pairs(data) do
local u = uformat(m["used"])
local s = uformat(m["size"])

if m["used_p"] >= red then
lines = lines .. "<span color='darkred'>"
elseif m["used_p"] >= orange then
lines = lines .. "<span color='orange'>"
else
lines = lines .. "<span color='darkgreen'>"
end

lines = lines
.. "\n"
.. i
.. string.rep(" ", longest + longestSize - i:len() - u:len())
.. u
.. " / "
.. s
.. string.rep(" ", longestUsed - s:len())
.. " ("
.. m["used_p"]
.. "%)</span>"
end

return lines
end
-- }}}
-- }}}

-- {{{ global functions
function M.addToWidget(mywidget, orange, red, onlyLocal)

mywidget:add_signal('mouse::enter', function ()
usage = naughty.notify({
text = string.format('<span font_desc="%s">%s</span>', "monospace", display(orange, red, onlyLocal)),
timeout = 0,
hover_timeout = 0.5,
screen = capi.mouse.screen
})
end)
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
end
-- }}}

return M

+ 126
- 0
freedesktop/desktop.lua View File

@@ -0,0 +1,126 @@
local wibox = wibox
local widget = widget
local screen = screen
local image = image
local button = button
local table = table
local ipairs = ipairs
local awful = require("awful")
local utils = require("freedesktop.utils")

module("freedesktop.desktop")

local current_pos = {}
local iconsize = { width = 48, height = 48 }
local labelsize = { width = 130, height = 20 }
local margin = { x = 20, y = 20 }

function add_icon(settings)

local s = settings.screen

if not current_pos[s] then
current_pos[s] = { x = (screen[s].geometry.width - iconsize.width - margin.x), y = 40 }
end

local totheight = (settings.icon and iconsize.height or 0) + (settings.label and labelsize.height or 0)
if totheight == 0 then return end

if current_pos[s].y + totheight > screen[s].geometry.height - 40 then
current_pos[s].x = current_pos[s].x - labelsize.width - iconsize.width - margin.x
current_pos[s].y = 40
end

if (settings.icon) then
icon = awful.widget.button({ image = settings.icon })
local newbuttons = icon:buttons()
table.insert(newbuttons, button({}, 1, nil, settings.click));
icon:buttons(newbuttons)

icon_container = wibox({ position = "floating", screen = s, bg = "#00000000" })
icon_container.widgets = { icon }
icon_container:geometry({
width = iconsize.width,
height = iconsize.height,
y = current_pos[s].y,
x = current_pos[s].x
})
icon_container.screen = s

current_pos[s].y = current_pos[s].y + iconsize.height + 5
end

if (settings.label) then
caption = widget({ type="textbox", align="right", width=labelsize.width })
caption.ellipsize = "middle"
caption.text = settings.label
caption:buttons({
button({ }, 1, settings.click)
})

caption_container = wibox({ position = "floating", screen = s, bg = "#00000000" })
caption_container.widgets = { caption }
caption_container:geometry({
width = labelsize.width,
height = labelsize.height,
y = current_pos[s].y,
x = current_pos[s].x - labelsize.width + iconsize.width
})
caption_container.screen = s
end

current_pos[s].y = current_pos[s].y + labelsize.height + margin.y
end

--- Adds subdirs and files icons to the desktop
-- @param dir The directory to parse, (default is ~/Desktop)
-- @param showlabels Shows icon captions (default is false)
function add_applications_icons(arg)
for i, program in ipairs(utils.parse_desktop_files({
dir = arg.dir or '~/Desktop/',
icon_sizes = {
iconsize.width .. "x" .. iconsize.height,
"128x128", "96x96", "72x72", "64x64", "48x48",
"36x36", "32x32", "24x24", "22x22", "16x6"
}
})) do
if program.show then
add_icon({
label = arg.showlabels and program.Name or nil,
icon = program.icon_path,
screen = arg.screen,
click = function () awful.util.spawn(program.cmdline) end
})
end
end
end

--- Adds subdirs and files icons to the desktop
-- @param dir The directory to parse
-- @param showlabels Shows icon captions
-- @param open_with The program to use to open clicked files and dirs (i.e. xdg_open, thunar, etc.)
function add_dirs_and_files_icons(arg)
arg.open_with = arg.open_width or 'thunar'
for i, file in ipairs(utils.parse_dirs_and_files({
dir = arg.dir or '~/Desktop/',
icon_sizes = {
iconsize.width .. "x" .. iconsize.height,
"128x128", "96x96", "72x72", "64x64", "48x48",
"36x36", "32x32", "24x24", "22x22", "16x6"
}
})) do
if file.show then
add_icon({
label = arg.showlabels and file.filename or nil,
icon = file.icon,
screen = arg.screen,
click = function () awful.util.spawn(arg.open_with .. ' ' .. file.path) end
})
end
end
end

function add_desktop_icons(args)
add_applications_icons(args)
add_dirs_and_files_icons(args)
end

+ 97
- 0
freedesktop/menu.lua View File

@@ -0,0 +1,97 @@
-- Grab environment
local utils = require("freedesktop.utils")
local io = io
local string = string
local table = table
local os = os
local ipairs = ipairs
local pairs = pairs

module("freedesktop.menu")

all_menu_dirs = {
'/usr/share/applications/',
'/usr/local/share/applications/',
'~/.local/share/applications/'
}

show_generic_name = false

--- Create menus for applications
-- @param menu_dirs A list of application directories (optional).
-- @return A prepared menu w/ categories
function new(arg)
-- the categories and their synonyms where shamelessly copied from lxpanel
-- source code.
local programs = {}
local config = arg or {}

programs['AudioVideo'] = {}
programs['Development'] = {}
programs['Education'] = {}
programs['Game'] = {}
programs['Graphics'] = {}
programs['Network'] = {}
programs['Office'] = {}
programs['Settings'] = {}
programs['System'] = {}
programs['Utility'] = {}
programs['Other'] = {}

for i, dir in ipairs(config.menu_dirs or all_menu_dirs) do
local entries = utils.parse_desktop_files({dir = dir})
for j, program in ipairs(entries) do
-- check whether to include in the menu
if program.show and program.Name and program.cmdline then
if show_generic_name and program.GenericName then
program.Name = program.Name .. ' (' .. program.GenericName .. ')'
end
local target_category = nil
if program.categories then
for _, category in ipairs(program.categories) do
if programs[category] then
target_category = category
break
end
end
end
if not target_category then
target_category = 'Other'
end
if target_category then
table.insert(programs[target_category], { program.Name, program.cmdline, program.icon_path })
end
end
end
end

-- sort each submenu alphabetically case insensitive
for k, v in pairs(programs) do
table.sort(v, function(a, b) return a[1]:lower() < b[1]:lower() end)
end

local menu = {
{ "Accessories", programs["Utility"], utils.lookup_icon({ icon = 'applications-accessories.png' }) },
{ "Development", programs["Development"], utils.lookup_icon({ icon = 'applications-development.png' }) },
{ "Education", programs["Education"], utils.lookup_icon({ icon = 'applications-science.png' }) },
{ "Games", programs["Game"], utils.lookup_icon({ icon = 'applications-games.png' }) },
{ "Graphics", programs["Graphics"], utils.lookup_icon({ icon = 'applications-graphics.png' }) },
{ "Internet", programs["Network"], utils.lookup_icon({ icon = 'applications-internet.png' }) },
{ "Multimedia", programs["AudioVideo"], utils.lookup_icon({ icon = 'applications-multimedia.png' }) },
{ "Office", programs["Office"], utils.lookup_icon({ icon = 'applications-office.png' }) },
{ "Other", programs["Other"], utils.lookup_icon({ icon = 'applications-other.png' }) },
{ "Settings", programs["Settings"], utils.lookup_icon({ icon = 'preferences-desktop.png' }) },
{ "System Tools", programs["System"], utils.lookup_icon({ icon = 'applications-system.png' }) },
}

-- Removing empty entries from menu
local cleanedMenu = {}
for index, item in ipairs(menu) do
itemTester = item[2]
if itemTester[1] then
table.insert(cleanedMenu, item)
end
end

return cleanedMenu
end

+ 255
- 0
freedesktop/utils.lua View File

@@ -0,0 +1,255 @@
-- Grab environment

local io = io
local os = os
local table = table
local type = type
local ipairs = ipairs
local pairs = pairs

module("freedesktop.utils")

terminal = 'xterm'

icon_theme = nil

all_icon_sizes = {
'128x128',
'96x96',
'72x72',
'64x64',
'48x48',
'36x36',
'32x32',
'24x24',
'22x22',
'16x16'
}
all_icon_types = {
'apps',
'actions',
'devices',
'places',
'categories',
'status',
'mimetypes'
}
all_icon_paths = { os.getenv("HOME") .. '/.icons/', '/usr/share/icons/' }

icon_sizes = {}

local mime_types = {}

function get_lines(...)
local f = io.popen(...)
return function () -- iterator
local data = f:read()
if data == nil then f:close() end
return data
end
end

function file_exists(filename)
local file = io.open(filename, 'r')
local result = (file ~= nil)
if result then
file:close()
end
return result
end

function lookup_icon(arg)
if arg.icon:sub(1, 1) == '/' and (arg.icon:find('.+%.png') or arg.icon:find('.+%.xpm')) then
-- icons with absolute path and supported (AFAICT) formats
return arg.icon
else
local icon_path = {}
local icon_themes = {}
local icon_theme_paths = {}
if icon_theme and type(icon_theme) == 'table' then
icon_themes = icon_theme
elseif icon_theme then
icon_themes = { icon_theme }
end
for i, theme in ipairs(icon_themes) do
for j, path in ipairs(all_icon_paths) do
table.insert(icon_theme_paths, path .. theme .. '/')
end
-- TODO also look in parent icon themes, as in freedesktop.org specification
end
table.insert(icon_theme_paths, '/usr/share/icons/hicolor/') -- fallback theme cf spec

local isizes = icon_sizes
for i, sz in ipairs(all_icon_sizes) do
table.insert(isizes, sz)
end

for i, icon_theme_directory in ipairs(icon_theme_paths) do
for j, size in ipairs(arg.icon_sizes or isizes) do
for k, icon_type in ipairs(all_icon_types) do
table.insert(icon_path, icon_theme_directory .. size .. '/' .. icon_type .. '/')
end
end
end
-- lowest priority fallbacks
table.insert(icon_path, '/usr/share/pixmaps/')
table.insert(icon_path, '/usr/share/icons/')
table.insert(icon_path, '/usr/share/app-install/icons/')

for i, directory in ipairs(icon_path) do
if (arg.icon:find('.+%.png') or arg.icon:find('.+%.xpm')) and file_exists(directory .. arg.icon) then
return directory .. arg.icon
elseif file_exists(directory .. arg.icon .. '.png') then
return directory .. arg.icon .. '.png'
elseif file_exists(directory .. arg.icon .. '.xpm') then
return directory .. arg.icon .. '.xpm'
end
end
end
end

function lookup_file_icon(arg)
load_mime_types()

local extension = arg.filename:match('%a+$')
local mime = mime_types[extension] or ''
local mime_family = mime:match('^%a+') or ''

-- possible icons in a typical gnome theme (i.e. Tango icons)
local possible_filenames = {
mime,
'gnome-mime-' .. mime,
mime_family,
'gnome-mime-' .. mime_family,
extension
}

for i, filename in ipairs(possible_filenames) do
local icon = lookup_icon({icon = filename, icon_sizes = (arg.icon_sizes or all_icon_sizes)})
if icon then
return icon
end
end

-- If we don't find ad icon, then pretend is a plain text file
return lookup_icon({ icon = 'txt', icon_sizes = arg.icon_sizes or all_icon_sizes })
end

--- Load system MIME types
-- @return A table with file extension <--> MIME type mapping
function load_mime_types()
if #mime_types == 0 then
for line in io.lines('/etc/mime.types') do
if not line:find('^#') then
local parsed = {}
for w in line:gmatch('[^%s]+') do
table.insert(parsed, w)
end
if #parsed > 1 then
for i = 2, #parsed do
mime_types[parsed[i]] = parsed[1]:gsub('/', '-')
end
end
end
end
end
end

--- Parse a .desktop file
-- @param file The .desktop file
-- @param requested_icon_sizes A list of icon sizes (optional). If this list is given, it will be used as a priority list for icon sizes when looking up for icons. If you want large icons, for example, you can put '128x128' as the first item in the list.
-- @return A table with file entries.
function parse_desktop_file(arg)
local program = { show = true, file = arg.file }
for line in io.lines(arg.file) do
for key, value in line:gmatch("(%w+)=(.+)") do
program[key] = value
end
end

-- Don't show the program if NoDisplay is true
-- Only show the program if there is not OnlyShowIn attribute
-- or if it's equal to 'awesome'
if program.NoDisplay == "true" or program.OnlyShowIn ~= nil and program.OnlyShowIn ~= "awesome" then
program.show = false
end

-- Look up for a icon.
if program.Icon then
program.icon_path = lookup_icon({ icon = program.Icon, icon_sizes = (arg.icon_sizes or all_icon_sizes) })
if program.icon_path ~= nil and not file_exists(program.icon_path) then
program.icon_path = nil
end
end

-- Split categories into a table.
if program.Categories then
program.categories = {}
for category in program.Categories:gmatch('[^;]+') do
table.insert(program.categories, category)
end
end

if program.Exec then
local cmdline = program.Exec:gsub('%%c', program.Name)
cmdline = cmdline:gsub('%%[fmuFMU]', '')
cmdline = cmdline:gsub('%%k', program.file)
if program.icon_path then
cmdline = cmdline:gsub('%%i', '--icon ' .. program.icon_path)
else
cmdline = cmdline:gsub('%%i', '')
end
if program.Terminal == "true" then
cmdline = terminal .. ' -e ' .. cmdline
end
program.cmdline = cmdline
end

return program
end

--- Parse a directory with .desktop files
-- @param dir The directory.
-- @param icons_size, The icons sizes, optional.
-- @return A table with all .desktop entries.
function parse_desktop_files(arg)
local programs = {}
local files = get_lines('find '.. arg.dir ..' -name "*.desktop" 2>/dev/null')
for file in files do
arg.file = file
table.insert(programs, parse_desktop_file(arg))
end
return programs
end

--- Parse a directory files and subdirs
-- @param dir The directory.
-- @param icons_size, The icons sizes, optional.
-- @return A table with all .desktop entries.
function parse_dirs_and_files(arg)
local files = {}
local paths = get_lines('find '..arg.dir..' -maxdepth 1 -type d')
for path in paths do
if path:match("[^/]+$") then
local file = {}
file.filename = path:match("[^/]+$")
file.path = path
file.show = true
file.icon = lookup_icon({ icon = "folder", icon_sizes = (arg.icon_sizes or all_icon_sizes) })
table.insert(files, file)
end
end
local paths = get_lines('find '..arg.dir..' -maxdepth 1 -type f')
for path in paths do
if not path:find("%.desktop$") then
local file = {}
file.filename = path:match("[^/]+$")
file.path = path
file.show = true
file.icon = lookup_file_icon({ filename = file.filename, icon_sizes = (arg.icon_sizes or all_icon_sizes) })
table.insert(files, file)
end
end
return files
end


+ 33
- 0
gfxtemp.lua View File

@@ -0,0 +1,33 @@
-- {{{ init environment
local wakka = {}
local capi = {
mouse = mouse,
screen = screen
}

-- {{{ display
-- formats the lines for the notify
local function display()
local lines = "<u>GFX Temp:</u>\n"
local f = io.popen("ssh setkeh@192.168.1.8 /opt/bin/aticonfig --odgt | grep Temperature | cut -c 43-52", "r")
local s = f:read('*all')
line = lines .. "\n" .. s .. "\n"
f:close()
return line
end
-- }}}
-- }}}

function wakka.addToWidget(mywidget)
mywidget:add_signal('mouse::enter', function ()
usage = naughty.notify({
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
timeout = 0,
hover_timeout = 0.5,
screen = capi.mouse.screen
})
end)
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
end

return wakka

+ 47
- 0
gmail_parser.py View File

@@ -0,0 +1,47 @@
## check-gmail.py -- A command line util to check GMail -*- Python -*-
## modified to display mailbox summary for conky

# ======================================================================
# Copyright (C) 2006 Baishampayan Ghose <b.ghose@ubuntu.com>
# Modified 2008 Hunter Loftis <hbloftis@uncc.edu>
# Time-stamp: Mon Jul 31, 2006 20:45+0530
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# ======================================================================

import sys
import urllib # For BasicHTTPAuthentication
import feedparser # For parsing the feed
from textwrap import wrap

_URL = "https://mail.google.com/gmail/feed/atom"

uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]

urllib.FancyURLopener.prompt_user_passwd = lambda self, host, realm: (uname, password)
def auth():
'''The method to do HTTPBasicAuthentication'''
opener = urllib.FancyURLopener()
f = opener.open(_URL)
feed = f.read()
return feed


def readmail(feed, maxlen):
'''Parse the Atom feed and print a summary'''
atom = feedparser.parse(feed)
print '${color1} %s new email(s)\n' % (len(atom.entries))
for i in range(min(len(atom.entries), maxlen)):
print ' ${color2}%s' % atom.entries[i].title
#uncomment the following line if you want to show the name of the sender
# print ' ${color2}%s' % atom.entries[i].author
if len(atom.entries) > maxlen:
print ' ${color}more...'

if __name__ == "__main__":
f = auth() # Do auth and then get the feed
readmail(f, int(maxlen)) # Let the feed be chewed by feedparser

+ 95
- 0
html.lua View File

@@ -0,0 +1,95 @@
function HTML_ToText (text)
-- Declare variables, load the file. Make tags lowercase.
text = string.gsub (text,"(%b<>)",
function (tag)
return tag:lower()
end)
--[[
First we kill the developer formatting (tabs, CR, LF)
and produce a long string with no newlines and tabs.
We also kill repeated spaces as browsers ignore them anyway.
]]
local devkill=
{
["("..string.char(10)..")"] = " ",
["("..string.char(13)..")"] = " ",