]> git.madduck.net Git - etc/awesome.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

merging with upstream
authoraajjbb <jefersonlsiq@gmail.com>
Tue, 18 Aug 2015 13:52:05 +0000 (10:52 -0300)
committeraajjbb <jefersonlsiq@gmail.com>
Tue, 18 Aug 2015 13:52:05 +0000 (10:52 -0300)
27 files changed:
1  2 
README.rst.orig
asyncshell.lua.orig
asyncshell_BACKUP_1080.lua
asyncshell_BACKUP_32072.lua
asyncshell_BASE_1080.lua
asyncshell_BASE_32072.lua
asyncshell_LOCAL_1080.lua
asyncshell_LOCAL_32072.lua
asyncshell_REMOTE_1080.lua
asyncshell_REMOTE_32072.lua
helpers.lua.orig
widgets/abase.lua.orig
widgets/alsa.lua.orig
widgets/alsabar.lua.orig
widgets/base.lua.orig
widgets/calendar.lua.orig
widgets/contrib/init.lua.orig
widgets/contrib/moc.lua.orig
widgets/contrib/task.lua.orig
widgets/fs.lua.orig
widgets/imap.lua.orig
widgets/maildir.lua.orig
widgets/mpd.lua.orig
widgets/net.lua.orig
widgets/sysload.lua.orig
widgets/temp.lua.orig
widgets/weather.lua.orig

diff --cc README.rst.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7c6d7863dd81165a8994e567d82298a35b1ef69c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,55 @@@
++Lain
++====
++
++--------------------------------------------------
++Layouts, widgets and utilities for Awesome WM 3.5+
++--------------------------------------------------
++
++:Author: Luke Bonham <dada [at] archlinux [dot] info>
++:Version: git
++<<<<<<< HEAD
++:License: GNU-GPLv2_
++=======
++:License: GNU-GPL2_
++>>>>>>> upstream/master
++:Source: https://github.com/copycat-killer/lain
++
++Description
++-----------
++
++Successor of awesome-vain_, this module provides new layouts, a set of widgets and utility functions, in order to improve Awesome_ usability and configurability.
++
++Read the wiki_ for all the info.
++
++Contributions
++-------------
++
++Any contribution is welcome! Feel free to make a pull request.
++
++Just make sure that:
++
++- Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines.
++
++- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using ``lain.helpers``. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment.
++
++- You test your changes before submitting to make sure that not only your code works, but did not break other parts of the module too!
++
++- You eventually update ``wiki`` submodule with a thorough section.
++
++Contributed widgets have to be put in ``lain/widgets/contrib``.
++
++Screenshots
++-----------
++
++.. image:: http://i.imgur.com/8D9A7lW.png
++.. image:: http://i.imgur.com/9Iv3OR3.png
++.. image:: http://i.imgur.com/STCPcaJ.png
++
++<<<<<<< HEAD
++.. _GNU-GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
++=======
++.. _GNU-GPL2: http://www.gnu.org/licenses/gpl-2.0.html
++>>>>>>> upstream/master
++.. _awesome-vain: https://github.com/vain/awesome-vain
++.. _Awesome: http://awesome.naquadah.org/
++.. _wiki: https://github.com/copycat-killer/lain/wiki
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5c6e7e8e7fab0eb07fd5724780d72ef431a41d61
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,145 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++<<<<<<< HEAD
++=======
++      * (c) 2015, worron                          
++>>>>>>> upstream/master
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++<<<<<<< HEAD
++-- How to use...
++-- ...asynchronously:
++-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
++-- ...synchronously:
++-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
++
++local spawn = require('awful.util').spawn
++
++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("sh -c '%s > %s; " ..
++                    'echo "asyncshell.deliver(%s)" | ' ..
++                    "awesome-client' 2> /dev/null",
++                    string.gsub(command, "'", "'\\''"), tmpfname, id)
++   spawn(req, false)
++   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
++=======
++-- How to use:
++-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
++
++-- Grab environment
++local awful = require('awful')
++
++-- Initialize tables for module
++asyncshell = { request_table = {}, id_counter = 0 }
++
++-- Request counter
++local function next_id()
++    asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
++    return asyncshell.id_counter
++end
++
++-- Remove given request
++function asyncshell.clear(id)
++    if asyncshell.request_table[id] then
++        if asyncshell.request_table[id].timer then
++            asyncshell.request_table[id].timer:stop()
++            asyncshell.request_table[id].timer = nil
++        end
++        asyncshell.request_table[id] = nil
++    end
++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
++-- @param timeout Maximum amount of time to wait for the result (optional)
++function asyncshell.request(command, callback, timeout)
++    local id = next_id()
++    asyncshell.request_table[id] = { callback = callback }
++
++    local formatted_command = string.gsub(command, '"','\"')
++
++    local req = string.format(
++        "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
++        id, formatted_command
++    )
++
++    awful.util.spawn_with_shell(req)
++
++    if timeout then
++        asyncshell.request_table[id].timer = timer({ timeout = timeout })
++        asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
++        asyncshell.request_table[id].timer:start()
++    end
++end
++
++-- Calls the remembered callback function on the output of the shell command
++-- @param id Request ID
++-- @param output Shell command output to be delievered
++function asyncshell.deliver(id, output)
++    local output = string.sub(output, 2, -2)
++    if asyncshell.request_table[id] then
++        asyncshell.request_table[id].callback(output)
++        asyncshell.clear(id)
++    end
++>>>>>>> upstream/master
++end
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5c6e7e8e7fab0eb07fd5724780d72ef431a41d61
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,145 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++<<<<<<< HEAD
++=======
++      * (c) 2015, worron                          
++>>>>>>> upstream/master
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++<<<<<<< HEAD
++-- How to use...
++-- ...asynchronously:
++-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
++-- ...synchronously:
++-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
++
++local spawn = require('awful.util').spawn
++
++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("sh -c '%s > %s; " ..
++                    'echo "asyncshell.deliver(%s)" | ' ..
++                    "awesome-client' 2> /dev/null",
++                    string.gsub(command, "'", "'\\''"), tmpfname, id)
++   spawn(req, false)
++   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
++=======
++-- How to use:
++-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
++
++-- Grab environment
++local awful = require('awful')
++
++-- Initialize tables for module
++asyncshell = { request_table = {}, id_counter = 0 }
++
++-- Request counter
++local function next_id()
++    asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
++    return asyncshell.id_counter
++end
++
++-- Remove given request
++function asyncshell.clear(id)
++    if asyncshell.request_table[id] then
++        if asyncshell.request_table[id].timer then
++            asyncshell.request_table[id].timer:stop()
++            asyncshell.request_table[id].timer = nil
++        end
++        asyncshell.request_table[id] = nil
++    end
++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
++-- @param timeout Maximum amount of time to wait for the result (optional)
++function asyncshell.request(command, callback, timeout)
++    local id = next_id()
++    asyncshell.request_table[id] = { callback = callback }
++
++    local formatted_command = string.gsub(command, '"','\"')
++
++    local req = string.format(
++        "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
++        id, formatted_command
++    )
++
++    awful.util.spawn_with_shell(req)
++
++    if timeout then
++        asyncshell.request_table[id].timer = timer({ timeout = timeout })
++        asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
++        asyncshell.request_table[id].timer:start()
++    end
++end
++
++-- Calls the remembered callback function on the output of the shell command
++-- @param id Request ID
++-- @param output Shell command output to be delievered
++function asyncshell.deliver(id, output)
++    local output = string.sub(output, 2, -2)
++    if asyncshell.request_table[id] then
++        asyncshell.request_table[id].callback(output)
++        asyncshell.clear(id)
++    end
++>>>>>>> upstream/master
++end
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5c6e7e8e7fab0eb07fd5724780d72ef431a41d61
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,145 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++<<<<<<< HEAD
++=======
++      * (c) 2015, worron                          
++>>>>>>> upstream/master
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++<<<<<<< HEAD
++-- How to use...
++-- ...asynchronously:
++-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
++-- ...synchronously:
++-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
++
++local spawn = require('awful.util').spawn
++
++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("sh -c '%s > %s; " ..
++                    'echo "asyncshell.deliver(%s)" | ' ..
++                    "awesome-client' 2> /dev/null",
++                    string.gsub(command, "'", "'\\''"), tmpfname, id)
++   spawn(req, false)
++   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
++=======
++-- How to use:
++-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
++
++-- Grab environment
++local awful = require('awful')
++
++-- Initialize tables for module
++asyncshell = { request_table = {}, id_counter = 0 }
++
++-- Request counter
++local function next_id()
++    asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
++    return asyncshell.id_counter
++end
++
++-- Remove given request
++function asyncshell.clear(id)
++    if asyncshell.request_table[id] then
++        if asyncshell.request_table[id].timer then
++            asyncshell.request_table[id].timer:stop()
++            asyncshell.request_table[id].timer = nil
++        end
++        asyncshell.request_table[id] = nil
++    end
++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
++-- @param timeout Maximum amount of time to wait for the result (optional)
++function asyncshell.request(command, callback, timeout)
++    local id = next_id()
++    asyncshell.request_table[id] = { callback = callback }
++
++    local formatted_command = string.gsub(command, '"','\"')
++
++    local req = string.format(
++        "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
++        id, formatted_command
++    )
++
++    awful.util.spawn_with_shell(req)
++
++    if timeout then
++        asyncshell.request_table[id].timer = timer({ timeout = timeout })
++        asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
++        asyncshell.request_table[id].timer:start()
++    end
++end
++
++-- Calls the remembered callback function on the output of the shell command
++-- @param id Request ID
++-- @param output Shell command output to be delievered
++function asyncshell.deliver(id, output)
++    local output = string.sub(output, 2, -2)
++    if asyncshell.request_table[id] then
++        asyncshell.request_table[id].callback(output)
++        asyncshell.clear(id)
++    end
++>>>>>>> upstream/master
++end
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100644 (file)
--- /dev/null
--- /dev/null
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100644 (file)
--- /dev/null
--- /dev/null
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0aafa17e7df9ffb2194c4ee76baa25575af65774
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,79 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++-- How to use...
++-- ...asynchronously:
++-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
++-- ...synchronously:
++-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
++
++local spawn = require('awful.util').spawn
++
++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("sh -c '%s > %s; " ..
++                    'echo "asyncshell.deliver(%s)" | ' ..
++                    "awesome-client' 2> /dev/null",
++                    string.gsub(command, "'", "'\\''"), tmpfname, id)
++   spawn(req, false)
++   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
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0aafa17e7df9ffb2194c4ee76baa25575af65774
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,79 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++-- How to use...
++-- ...asynchronously:
++-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
++-- ...synchronously:
++-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
++
++local spawn = require('awful.util').spawn
++
++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("sh -c '%s > %s; " ..
++                    'echo "asyncshell.deliver(%s)" | ' ..
++                    "awesome-client' 2> /dev/null",
++                    string.gsub(command, "'", "'\\''"), tmpfname, id)
++   spawn(req, false)
++   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
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..827cf4be4b0f500174ba2279429039d5f39516aa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,72 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2015, worron                          
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++-- How to use:
++-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
++
++-- Grab environment
++local awful = require('awful')
++
++-- Initialize tables for module
++asyncshell = { request_table = {}, id_counter = 0 }
++
++-- Request counter
++local function next_id()
++    asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
++    return asyncshell.id_counter
++end
++
++-- Remove given request
++function asyncshell.clear(id)
++    if asyncshell.request_table[id] then
++        if asyncshell.request_table[id].timer then
++            asyncshell.request_table[id].timer:stop()
++            asyncshell.request_table[id].timer = nil
++        end
++        asyncshell.request_table[id] = nil
++    end
++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
++-- @param timeout Maximum amount of time to wait for the result (optional)
++function asyncshell.request(command, callback, timeout)
++    local id = next_id()
++    asyncshell.request_table[id] = { callback = callback }
++
++    local formatted_command = string.gsub(command, '"','\"')
++
++    local req = string.format(
++        "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
++        id, formatted_command
++    )
++
++    awful.util.spawn_with_shell(req)
++
++    if timeout then
++        asyncshell.request_table[id].timer = timer({ timeout = timeout })
++        asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
++        asyncshell.request_table[id].timer:start()
++    end
++end
++
++-- Calls the remembered callback function on the output of the shell command
++-- @param id Request ID
++-- @param output Shell command output to be delievered
++function asyncshell.deliver(id, output)
++    local output = string.sub(output, 2, -2)
++    if asyncshell.request_table[id] then
++        asyncshell.request_table[id].callback(output)
++        asyncshell.clear(id)
++    end
++end
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..827cf4be4b0f500174ba2279429039d5f39516aa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,72 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2015, worron                          
++      * (c) 2013, Alexander Yakushev              
++                                                  
++--]]
++
++-- Asynchronous io.popen for Awesome WM.
++-- How to use:
++-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
++
++-- Grab environment
++local awful = require('awful')
++
++-- Initialize tables for module
++asyncshell = { request_table = {}, id_counter = 0 }
++
++-- Request counter
++local function next_id()
++    asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
++    return asyncshell.id_counter
++end
++
++-- Remove given request
++function asyncshell.clear(id)
++    if asyncshell.request_table[id] then
++        if asyncshell.request_table[id].timer then
++            asyncshell.request_table[id].timer:stop()
++            asyncshell.request_table[id].timer = nil
++        end
++        asyncshell.request_table[id] = nil
++    end
++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
++-- @param timeout Maximum amount of time to wait for the result (optional)
++function asyncshell.request(command, callback, timeout)
++    local id = next_id()
++    asyncshell.request_table[id] = { callback = callback }
++
++    local formatted_command = string.gsub(command, '"','\"')
++
++    local req = string.format(
++        "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
++        id, formatted_command
++    )
++
++    awful.util.spawn_with_shell(req)
++
++    if timeout then
++        asyncshell.request_table[id].timer = timer({ timeout = timeout })
++        asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
++        asyncshell.request_table[id].timer:start()
++    end
++end
++
++-- Calls the remembered callback function on the output of the shell command
++-- @param id Request ID
++-- @param output Shell command output to be delievered
++function asyncshell.deliver(id, output)
++    local output = string.sub(output, 2, -2)
++    if asyncshell.request_table[id] then
++        asyncshell.request_table[id].callback(output)
++        asyncshell.clear(id)
++    end
++end
++
++return asyncshell
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f88c0427c60866d96a4b17101c291dd5c7ec60ff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,123 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++                                                  
++--]]
++
++local debug  = require("debug")
++
++local capi   = { timer = timer }
++local io     = { open  = io.open,
++<<<<<<< HEAD
++                 lines = io.lines }
++=======
++                 lines = io.lines,
++                 popen = io.popen }
++>>>>>>> upstream/master
++local rawget = rawget
++
++-- Lain helper functions for internal use
++-- lain.helpers
++local helpers = {}
++
++helpers.lain_dir    = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
++helpers.icons_dir   = helpers.lain_dir .. 'icons/'
++helpers.scripts_dir = helpers.lain_dir .. 'scripts/'
++
++-- {{{ Modules loader
++
++function helpers.wrequire(table, key)
++    local module = rawget(table, key)
++    return module or require(table._NAME .. '.' .. key)
++end
++
++-- }}}
++
++-- {{{ File operations
++
++-- see if the file exists and is readable
++function helpers.file_exists(file)
++  local f = io.open(file)
++  if f then
++      local s = f:read()
++      f:close()
++      f = s
++  end
++  return f ~= nil
++end
++
++-- get all lines from a file, returns an empty
++-- list/table if the file does not exist
++function helpers.lines_from(file)
++  if not helpers.file_exists(file) then return {} end
++  lines = {}
++  for line in io.lines(file) do
++    lines[#lines + 1] = line
++  end
++  return lines
++end
++
++-- get first line of a file, return nil if
++-- the file does not exist
++function helpers.first_line(file)
++    return helpers.lines_from(file)[1]
++end
++
++-- get first non empty line from a file,
++-- returns nil otherwise
++function helpers.first_nonempty_line(file)
++  for k,v in pairs(helpers.lines_from(file)) do
++    if #v then return v end
++  end
++  return nil
++end
++
++-- }}}
++
++-- {{{ Timer maker
++
++helpers.timer_table = {}
++
++function helpers.newtimer(name, timeout, fun, nostart)
++    helpers.timer_table[name] = capi.timer({ timeout = timeout })
++    helpers.timer_table[name]:connect_signal("timeout", fun)
++    helpers.timer_table[name]:start()
++    if not nostart then
++        helpers.timer_table[name]:emit_signal("timeout")
++    end
++end
++
++-- }}}
++
++<<<<<<< HEAD
++=======
++-- {{{ Pipe operations
++
++-- read the full output of a pipe (command)
++function helpers.read_pipe(cmd)
++   local f = assert(io.popen(cmd))
++   local output = f:read("*all")
++   f:close()
++   return output
++end
++
++-- }}}
++
++>>>>>>> upstream/master
++-- {{{ A map utility
++
++helpers.map_table = {}
++
++function helpers.set_map(element, value)
++    helpers.map_table[element] = value
++end
++
++function helpers.get_map(element)
++    return helpers.map_table[element]
++end
++
++-- }}}
++
++return helpers
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..98f7818d844fe2b2c7c004b2ed39a9abacd91eb9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,41 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2014, Luke Bonham                     
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++local async        = require("lain.asyncshell")
++local wibox        = require("wibox")
++
++local setmetatable = setmetatable
++
++-- Basic template for custom widgets
++-- Asynchronous version
++-- lain.widgets.abase
++
++local function worker(args)
++    local abase    = {}
++    local args     = args or {}
++    local timeout  = args.timeout or 5
++    local cmd      = args.cmd or ""
++    local settings = args.settings or function() end
++
++    abase.widget = wibox.widget.textbox('')
++
++    function abase.update()
++        async.request(cmd, function(f)
++            output = f
++            widget = abase.widget
++            settings()
++        end)
++    end
++
++    newtimer(cmd, timeout, abase.update)
++
++    return setmetatable(abase, { __index = abase.widget })
++end
++
++return setmetatable({}, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0ed11c723dcb887bf3b433ad034736860878ddc5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,81 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++      * (c) 2010, Adrian C. <anrxc@sysphere.org>  
++                                                  
++--]]
++
++local newtimer        = require("lain.helpers").newtimer
++<<<<<<< HEAD
++
++local wibox           = require("wibox")
++
++local io              = { popen  = io.popen }
++=======
++local read_pipe       = require("lain.helpers").read_pipe
++
++local wibox           = require("wibox")
++
++>>>>>>> upstream/master
++local string          = { match  = string.match,
++                          format = string.format }
++
++local setmetatable    = setmetatable
++
++-- ALSA volume
++-- lain.widgets.alsa
++local alsa = {}
++
++local function worker(args)
++    local args     = args or {}
++    local timeout  = args.timeout or 5
++    local settings = args.settings or function() end
++
++    alsa.cmd     = args.cmd or "amixer"
++    alsa.channel = args.channel or "Master"
++
++    alsa.widget = wibox.widget.textbox('')
++
++    function alsa.update()
++<<<<<<< HEAD
++        local f = assert(io.popen(string.format("%s get %s", alsa.cmd, alsa.channel)))
++        local mixer = f:read("*a")
++        f:close()
++=======
++        local mixer = read_pipe(string.format("%s get %s", alsa.cmd, alsa.channel))
++>>>>>>> upstream/master
++
++        volume_now = {}
++
++        volume_now.level, volume_now.status = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
++
++        if volume_now.level == nil
++        then
++            volume_now.level  = "0"
++            volume_now.status = "off"
++        end
++
++        if volume_now.status == ""
++        then
++            if volume_now.level == "0"
++            then
++                volume_now.status = "off"
++            else
++                volume_now.status = "on"
++            end
++        end
++
++        widget = alsa.widget
++        settings()
++    end
++
++    timer_id = string.format("alsa-%s-%s", alsa.cmd, alsa.channel)
++
++    newtimer(timer_id, timeout, alsa.update)
++
++    return setmetatable(alsa, { __index = alsa.widget })
++end
++
++return setmetatable(alsa, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3cda6393fa049d4d4639ee84d7aebf44eb4f5294
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,215 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++      * (c) 2013, Rman                            
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++<<<<<<< HEAD
++=======
++local read_pipe    = require("lain.helpers").read_pipe
++>>>>>>> upstream/master
++
++local awful        = require("awful")
++local beautiful    = require("beautiful")
++local naughty      = require("naughty")
++
++<<<<<<< HEAD
++local io           = { popen  = io.popen }
++local math         = { modf   = math.modf }
++=======
++local math         = { modf   = math.modf }
++local mouse        = mouse
++>>>>>>> upstream/master
++local string       = { format = string.format,
++                       match  = string.match,
++                       rep    = string.rep }
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- ALSA volume bar
++-- lain.widgets.alsabar
++local alsabar = {
++<<<<<<< HEAD
++    card    = "0",
++=======
++>>>>>>> upstream/master
++    channel = "Master",
++    step    = "2%",
++
++    colors = {
++        background = beautiful.bg_normal,
++        mute       = "#EB8F8F",
++        unmute     = "#A4CE8A"
++    },
++
++    terminal = terminal or "xterm",
++    mixer    = terminal .. " -e alsamixer",
++
++    notifications = {
++        font      = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")),
++        font_size = "11",
++        color     = beautiful.fg_normal,
++        bar_size  = 18,
++        screen    = 1
++    },
++
++    _current_level = 0,
++    _muted         = false
++}
++
++function alsabar.notify()
++    alsabar.update()
++
++    local preset = {
++        title   = "",
++        text    = "",
++        timeout = 5,
++        screen  = alsabar.notifications.screen,
++        font    = alsabar.notifications.font .. " " ..
++                  alsabar.notifications.font_size,
++        fg      = alsabar.notifications.color
++    }
++
++    if alsabar._muted
++    then
++        preset.title = alsabar.channel .. " - Muted"
++    else
++        preset.title = alsabar.channel .. " - " .. alsabar._current_level .. "%"
++    end
++
++    int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size)
++    preset.text = "["
++                .. string.rep("|", int)
++                .. string.rep(" ", alsabar.notifications.bar_size - int)
++                .. "]"
++
++<<<<<<< HEAD
++=======
++    if alsabar.followmouse then
++        preset.screen = mouse.screen
++    end
++
++>>>>>>> upstream/master
++    if alsabar._notify ~= nil then
++        alsabar._notify = naughty.notify ({
++            replaces_id = alsabar._notify.id,
++            preset      = preset,
++        })
++    else
++        alsabar._notify = naughty.notify ({
++            preset = preset,
++        })
++    end
++end
++
++local function worker(args)
++    local args       = args or {}
++    local timeout    = args.timeout or 5
++    local settings   = args.settings or function() end
++    local width      = args.width or 63
++    local height     = args.heigth or 1
++    local ticks      = args.ticks or false
++    local ticks_size = args.ticks_size or 7
++    local vertical   = args.vertical or false
++
++    alsabar.cmd           = args.cmd or "amixer"
++    alsabar.channel       = args.channel or alsabar.channel
++    alsabar.step          = args.step or alsabar.step
++    alsabar.colors        = args.colors or alsabar.colors
++    alsabar.notifications = args.notifications or alsabar.notifications
++<<<<<<< HEAD
++=======
++    alsabar.followmouse   = args.followmouse or false
++>>>>>>> upstream/master
++
++    alsabar.bar = awful.widget.progressbar()
++
++    alsabar.bar:set_background_color(alsabar.colors.background)
++    alsabar.bar:set_color(alsabar.colors.unmute)
++    alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
++    alsabar.bar:set_width(width)
++    alsabar.bar:set_height(height)
++    alsabar.bar:set_ticks(ticks)
++    alsabar.bar:set_ticks_size(ticks_size)
++    alsabar.bar:set_vertical(vertical)
++
++    function alsabar.update()
++        -- Get mixer control contents
++<<<<<<< HEAD
++        local f = assert(io.popen(string.format("%s get %s", alsabar.cmd, alsabar.channel)))
++        local mixer = f:read("*a")
++        f:close()
++=======
++        local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel))
++>>>>>>> upstream/master
++
++        -- Capture mixer control state:          [5%] ... ... [on]
++        local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
++
++        if volu == nil then
++            volu = 0
++            mute = "off"
++        end
++
++        alsabar._current_level = tonumber(volu)
++        alsabar.bar:set_value(alsabar._current_level / 100)
++        if not mute and tonumber(volu) == 0 or mute == "off"
++        then
++            alsabar._muted = true
++            alsabar.tooltip:set_text (" [Muted] ")
++            alsabar.bar:set_color(alsabar.colors.mute)
++        else
++            alsabar._muted = false
++            alsabar.tooltip:set_text(string.format(" %s:%s ", alsabar.channel, volu))
++            alsabar.bar:set_color(alsabar.colors.unmute)
++        end
++
++        volume_now = {}
++        volume_now.level = tonumber(volu)
++        volume_now.status = mute
++        settings()
++    end
++
++    alsabar.bar:buttons (awful.util.table.join (
++          awful.button ({}, 1, function()
++            awful.util.spawn(alsabar.mixer)
++          end),
++          awful.button ({}, 3, function()
++<<<<<<< HEAD
++            awful.util.spawn(string.format("amixer -c %s set %s toggle", alsabar.card, alsabar.channel))
++            alsabar.update()
++          end),
++          awful.button ({}, 4, function()
++            awful.util.spawn(string.format("amixer -c %s set %s %s+", alsabar.card, alsabar.channel, alsabar.step))
++            alsabar.update()
++          end),
++          awful.button ({}, 5, function()
++            awful.util.spawn(string.format("amixer -c %s set %s %s-", alsabar.card, alsabar.channel, alsabar.step))
++=======
++            awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.channel))
++            alsabar.update()
++          end),
++          awful.button ({}, 4, function()
++            awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step))
++            alsabar.update()
++          end),
++          awful.button ({}, 5, function()
++            awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step))
++>>>>>>> upstream/master
++            alsabar.update()
++          end)
++    ))
++
++    timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel)
++
++    newtimer(timer_id, timeout, alsabar.update)
++
++    return alsabar
++end
++
++return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ae9dd10de9267aa531387310d1d08a5017d12ce8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,51 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2014, Luke Bonham                     
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++<<<<<<< HEAD
++local wibox        = require("wibox")
++
++local io           = { popen = io.popen }
++=======
++local read_pipe    = require("lain.helpers").read_pipe
++
++local wibox        = require("wibox")
++
++>>>>>>> upstream/master
++local setmetatable = setmetatable
++
++-- Basic template for custom widgets
++-- lain.widgets.base
++
++local function worker(args)
++    local base     = {}
++    local args     = args or {}
++    local timeout  = args.timeout or 5
++    local cmd      = args.cmd or ""
++    local settings = args.settings or function() end
++
++    base.widget = wibox.widget.textbox('')
++
++    function base.update()
++<<<<<<< HEAD
++        local f = assert(io.popen(cmd))
++        output = f:read("*a")
++        f:close()
++=======
++        output = read_pipe(cmd)
++>>>>>>> upstream/master
++        widget = base.widget
++        settings()
++    end
++
++    newtimer(cmd, timeout, base.update)
++
++    return setmetatable(base, { __index = base.widget })
++end
++
++return setmetatable({}, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..187fdc0f2267e171659eb11aa786d7d6cf76891b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,181 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++                                                  
++--]]
++
++local icons_dir    = require("lain.helpers").icons_dir
++
++local awful        = require("awful")
++local beautiful    = require("beautiful")
++local naughty      = require("naughty")
++
++local io           = { popen = io.popen }
++local os           = { date = os.date }
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- Calendar notification
++-- lain.widgets.calendar
++local calendar = {}
++local cal_notification = nil
++
++function calendar:hide()
++    if cal_notification ~= nil then
++        naughty.destroy(cal_notification)
++        cal_notification = nil
++    end
++end
++
++function calendar:show(t_out, inc_offset, scr)
++    calendar:hide()
++
++    local offs = inc_offset or 0
++    local tims = t_out or 0
++    local f, c_text
++    local today = tonumber(os.date('%d'))
++    local init_t = calendar.cal .. ' ' .. calendar.post_cal  .. ' ' ..
++        ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )('
++
++    calendar.offset = calendar.offset + offs
++
++    if offs == 0 or calendar.offset == 0
++    then -- current month showing, today highlighted
++        calendar.offset = 0
++        calendar.notify_icon = calendar.icons .. today .. ".png"
++
++        -- bg and fg inverted to highlight today
++        f = io.popen( init_t .. today ..
++                      ')($| )/\\1<b><span foreground=\\"'
++                      .. calendar.bg ..
++                      '\\" background=\\"'
++                      .. calendar.fg ..
++                      '\\">\\2<\\/span><\\/b>\\3/"' )
++
++    else -- no current month showing, no day to highlight
++       local month = tonumber(os.date('%m'))
++       local year = tonumber(os.date('%Y'))
++
++       month = month + calendar.offset
++
++       if month > 12 then
++           month = month % 12
++           year = year + 1
++           if month <= 0 then
++               month = 12
++           end
++       elseif month < 1 then
++           month = month + 12
++           year = year - 1
++           if month <= 0 then
++               month = 1
++           end
++       end
++
++       calendar.notify_icon = nil
++
++       f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year .. ' ' ..
++            calendar.post_cal)
++    end
++
++    c_text = "<tt><span font='" .. calendar.font .. " "
++             .. calendar.font_size .. "'><b>"
++             .. f:read() .. "</b>\n\n"
++             .. f:read() .. "\n"
++<<<<<<< HEAD
++             .. f:read("*a"):gsub("\n*$", "")
++             .. "</span></tt>"
++    f:close()
++
++=======
++             .. f:read("*all"):gsub("\n*$", "")
++             .. "</span></tt>"
++    f:close()
++
++    if calendar.followmouse then
++        scrp = mouse.screen
++    else
++        scrp = scr or calendar.scr_pos
++    end
++
++>>>>>>> upstream/master
++    cal_notification = naughty.notify({
++        text = c_text,
++        icon = calendar.notify_icon,
++        position = calendar.position,
++        fg = calendar.fg,
++        bg = calendar.bg,
++        timeout = tims,
++<<<<<<< HEAD
++        screen = scr or 1
++=======
++        screen = scrp
++>>>>>>> upstream/master
++    })
++end
++
++function calendar:attach(widget, args)
++    local args = args or {}
++<<<<<<< HEAD
++    calendar.cal       = args.cal or "/usr/bin/cal"
++    calendar.post_cal  = args.post_cal or ""
++    calendar.icons     = args.icons or icons_dir .. "cal/white/"
++    calendar.font      = args.font or beautiful.font:sub(beautiful.font:find(""),
++                         beautiful.font:find(" "))
++    calendar.font_size = tonumber(args.font_size) or 11
++    calendar.fg        = args.fg or beautiful.fg_normal or "#FFFFFF"
++    calendar.bg        = args.bg or beautiful.bg_normal or "#FFFFFF"
++    calendar.position  = args.position or "top_right"
++    calendar.scr_pos   = args.scr_pos or 1
++
++    calendar.offset = 0
++    calendar.notify_icon = nil
++
++    widget:connect_signal("mouse::enter", function () calendar:show(0, 0, scr_pos) end)
++    widget:connect_signal("mouse::leave", function () calendar:hide() end)
++    widget:buttons(awful.util.table.join( awful.button({ }, 1, function ()
++                                              calendar:show(0, -1, scr_pos) end),
++                                          awful.button({ }, 3, function ()
++                                              calendar:show(0, 1, scr_pos) end),
++                                          awful.button({ }, 4, function ()
++                                              calendar:show(0, -1, scr_pos) end),
++                                          awful.button({ }, 5, function ()
++                                              calendar:show(0, 1, scr_pos) end)))
++=======
++
++    calendar.cal         = args.cal or "/usr/bin/cal"
++    calendar.post_cal    = args.post_cal or ""
++    calendar.icons       = args.icons or icons_dir .. "cal/white/"
++    calendar.font        = args.font or beautiful.font:sub(beautiful.font:find(""),
++                           beautiful.font:find(" "))
++    calendar.font_size   = tonumber(args.font_size) or 11
++    calendar.fg          = args.fg or beautiful.fg_normal or "#FFFFFF"
++    calendar.bg          = args.bg or beautiful.bg_normal or "#FFFFFF"
++    calendar.position    = args.position or "top_right"
++    calendar.scr_pos     = args.scr_pos or 1
++    calendar.followmouse = args.followmouse or false
++
++    calendar.offset      = 0
++    calendar.notify_icon = nil
++
++    widget:connect_signal("mouse::enter", function () calendar:show(0, 0, calendar.scr_pos) end)
++    widget:connect_signal("mouse::leave", function () calendar:hide() end)
++    widget:buttons(awful.util.table.join(awful.button({ }, 1, function ()
++                                             calendar:show(0, -1, calendar.scr_pos) end),
++                                         awful.button({ }, 3, function ()
++                                             calendar:show(0, 1, calendar.scr_pos) end),
++                                         awful.button({ }, 4, function ()
++                                             calendar:show(0, -1, calendar.scr_pos) end),
++                                         awful.button({ }, 5, function ()
++                                             calendar:show(0, 1, calendar.scr_pos) end)))
++>>>>>>> upstream/master
++end
++
++return setmetatable(calendar, { __call = function(_, ...) return create(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3ad083573d1ec6e35cd2444054c3326129e6a139
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,23 @@@
++
++--[[
++                                                   
++     Lain                                          
++     Layouts, widgets and utilities for Awesome WM 
++                                                   
++     Users contributed widgets section             
++                                                   
++     Licensed under GNU General Public License v2  
++<<<<<<< HEAD
++      * (c) 2013,      Luke Bonham                 
++=======
++      * (c) 2013, Luke Bonham                      
++>>>>>>> upstream/master
++                                                   
++--]]
++
++local wrequire     = require("lain.helpers").wrequire
++local setmetatable = setmetatable
++
++local widgets = { _NAME = "lain.widgets.contrib" }
++
++return setmetatable(widgets, { __index = wrequire })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fb8afec34c165426141de6d88b7cf5e842419aeb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,117 @@@
++
++--[[
++                                                                  
++     Licensed under GNU General Public License v2                 
++      * (c) 2014, anticlockwise <http://github.com/anticlockwise> 
++                                                                  
++--]]
++
++local helpers = require("lain.helpers")
++local async   = require("lain.asyncshell")
++
++local escape_f = require("awful.util").escape
++local naughty  = require("naughty")
++local wibox    = require("wibox")
++
++local io     = { popen   = io.popen }
++local os     = { execute = os.execute,
++                 getenv  = os.getenv }
++local string = { format  = string.format,
++                 gmatch  = string.gmatch }
++
++local setmetatable = setmetatable
++
++local moc = {}
++
++local function worker(args)
++    local args        = args or {}
++    local timeout     = args.timeout or 2
++    local music_dir   = args.music_dir or os.getenv("HOME") .. "/Music"
++    local cover_size  = args.cover_size or 100
++    local default_art = args.default_art or ""
++<<<<<<< HEAD
++=======
++    local followmouse = args.followmouse or false
++>>>>>>> upstream/master
++    local settings    = args.settings or function() end
++
++    local mpdcover = helpers.scripts_dir .. "mpdcover"
++
++    moc.widget = wibox.widget.textbox('')
++
++    moc_notification_preset = {
++        title   = "Now playing",
++        timeout = 6
++    }
++
++    helpers.set_map("current moc track", nil)
++
++    function moc.update()
++        -- mocp -i will produce output like:
++        -- Artist: Travis
++        -- Album: The Man Who
++        -- etc.
++        async.request("mocp -i", function(f)
++            moc_now = {
++                state   = "N/A",
++                file    = "N/A",
++                artist  = "N/A",
++                title   = "N/A",
++                album   = "N/A",
++                elapsed = "N/A",
++                total   = "N/A"
++            }
++
++<<<<<<< HEAD
++            for line in f:lines() do
++=======
++            for line in string.gmatch(f, "[^\n]+") do
++>>>>>>> upstream/master
++                for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
++                    if k == "State" then moc_now.state = v
++                    elseif k == "File" then moc_now.file = v
++                    elseif k == "Artist" then moc_now.artist = escape_f(v)
++                    elseif k == "SongTitle" then moc_now.title = escape_f(v)
++                    elseif k == "Album" then moc_now.album = escape_f(v)
++                    elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v)
++                    elseif k == "TotalTime" then moc_now.total = escape_f(v)
++                    end
++                end
++            end
++
++            moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist,
++                                           moc_now.album, moc_now.total, moc_now.title)
++            widget = moc.widget
++            settings()
++
++            if moc_now.state == "PLAY" then
++                if moc_now.title ~= helpers.get_map("current moc track") then
++                    helpers.set_map("current moc track", moc_now.title)
++                    os.execute(string.format("%s %q %q %d %q", mpdcover, "",
++                               moc_now.file, cover_size, default_art))
++
++<<<<<<< HEAD
++=======
++                    if followmouse then
++                        moc_notification_preset.screen = mouse.screen
++                    end
++
++>>>>>>> upstream/master
++                    moc.id = naughty.notify({
++                        preset = moc_notification_preset,
++                        icon = "/tmp/mpdcover.png",
++                        replaces_id = moc.id,
++                    }).id
++                end
++            elseif  moc_now.state ~= "PAUSE" then
++                helpers.set_map("current moc track", nil)
++            end
++        end)
++    end
++
++    helpers.newtimer("moc", timeout, moc.update)
++
++    return setmetatable(moc, { __index = moc.widget })
++end
++
++return setmetatable(moc, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d84e55f10712a99b05796fb590bb5fbe54a2379c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,176 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Jan Xie                         
++                                                  
++--]]
++
++local icons_dir    = require("lain.helpers").icons_dir
++
++local awful        = require("awful")
++local beautiful    = require("beautiful")
++local naughty      = require("naughty")
++
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local io           = io
++local string       = { len = string.len }
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- Taskwarrior notification
++-- lain.widgets.contrib.task
++local task = {}
++
++local task_notification = nil
++
++function task:hide()
++    if task_notification ~= nil then
++        naughty.destroy(task_notification)
++        task_notification = nil
++    end
++end
++
++<<<<<<< HEAD
++function task:show()
++=======
++function task:show(scr_pos)
++>>>>>>> upstream/master
++    task:hide()
++
++    local f, c_text
++
++<<<<<<< HEAD
++=======
++    if task.followmouse then
++        local scrp = mouse.screen
++    else
++        local scrp = scr_pos or task.scr_pos
++    end
++
++>>>>>>> upstream/master
++    f = io.popen('task')
++    c_text = "<span font='"
++             .. task.font .. " "
++             .. task.font_size .. "'>"
++             .. f:read("*all"):gsub("\n*$", "")
++             .. "</span>"
++    f:close()
++
++    task_notification = naughty.notify({ title = "[task next]",
++                                         text = c_text,
++                                         icon = task.notify_icon,
++                                         position = task.position,
++                                         fg = task.fg,
++                                         bg = task.bg,
++                                         timeout = task.timeout,
++<<<<<<< HEAD
++=======
++                                         screen = scrp
++>>>>>>> upstream/master
++                                     })
++end
++
++function task:prompt_add()
++  awful.prompt.run({ prompt = "Add task: " },
++      mypromptbox[mouse.screen].widget,
++      function (...)
++          local f = io.popen("task add " .. ...)
++          c_text = "\n<span font='"
++                   .. task.font .. " "
++                   .. task.font_size .. "'>"
++                   .. f:read("*all")
++                   .. "</span>"
++          f:close()
++
++          naughty.notify({
++              text     = c_text,
++              icon     = task.notify_icon,
++              position = task.position,
++              fg       = task.fg,
++              bg       = task.bg,
++              timeout  = task.timeout,
++          })
++      end,
++      nil,
++      awful.util.getdir("cache") .. "/history_task_add")
++end
++
++function task:prompt_search()
++  awful.prompt.run({ prompt = "Search task: " },
++      mypromptbox[mouse.screen].widget,
++      function (...)
++          local f = io.popen("task " .. ...)
++          c_text = f:read("*all"):gsub(" \n*$", "")
++          f:close()
++
++          if string.len(c_text) == 0
++          then
++              c_text = "No results found."
++          else
++              c_text = "<span font='"
++                       .. task.font .. " "
++                       .. task.font_size .. "'>"
++                       .. c_text
++                       .. "</span>"
++          end
++
++          naughty.notify({
++              title    = "[task next " .. ... .. "]",
++              text     = c_text,
++              icon     = task.notify_icon,
++              position = task.position,
++              fg       = task.fg,
++              bg       = task.bg,
++              timeout  = task.timeout,
++<<<<<<< HEAD
++=======
++              screen   = mouse.screen
++>>>>>>> upstream/master
++          })
++      end,
++      nil,
++      awful.util.getdir("cache") .. "/history_task")
++end
++
++function task:attach(widget, args)
++<<<<<<< HEAD
++    local args     = args or {}
++
++    task.font_size = tonumber(args.font_size) or 12
++    task.font      = beautiful.font:sub(beautiful.font:find(""),
++                     beautiful.font:find(" "))
++    task.fg        = args.fg or beautiful.fg_normal or "#FFFFFF"
++    task.bg        = args.bg or beautiful.bg_normal or "#FFFFFF"
++    task.position  = args.position or "top_right"
++    task.timeout   = args.timeout or 7
++=======
++    local args       = args or {}
++
++    task.font_size   = tonumber(args.font_size) or 12
++    task.font        = beautiful.font:sub(beautiful.font:find(""),
++                       beautiful.font:find(" "))
++    task.fg          = args.fg or beautiful.fg_normal or "#FFFFFF"
++    task.bg          = args.bg or beautiful.bg_normal or "#FFFFFF"
++    task.position    = args.position or "top_right"
++    task.timeout     = args.timeout or 7
++    task.scr_pos     = args.scr_pos or 1
++    task.followmouse = args.followmouse or false
++>>>>>>> upstream/master
++
++    task.notify_icon = icons_dir .. "/taskwarrior/task.png"
++    task.notify_icon_small = icons_dir .. "/taskwarrior/tasksmall.png"
++
++<<<<<<< HEAD
++    widget:connect_signal("mouse::enter", function () task:show() end)
++=======
++    widget:connect_signal("mouse::enter", function () task:show(task.scr_pos) end)
++>>>>>>> upstream/master
++    widget:connect_signal("mouse::leave", function () task:hide() end)
++end
++
++return setmetatable(task, { __call = function(_, ...) return create(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c1a3ab7131766d00f0961cd52e802dda65b42adb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,153 @@@
++
++--[[
++                                                      
++     Licensed under GNU General Public License v2     
++      * (c) 2013, Luke Bonham                         
++      * (c) 2010, Adrian C.      <anrxc@sysphere.org> 
++      * (c) 2009, Lucas de Vries <lucas@glacicle.com> 
++                                                      
++--]]
++
++local helpers      = require("lain.helpers")
++
++local beautiful    = require("beautiful")
++local wibox        = require("wibox")
++local naughty      = require("naughty")
++
++local io           = { popen  = io.popen }
++local pairs        = pairs
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local string       = { match  = string.match,
++                       format = string.format }
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- File system disk space usage
++-- lain.widgets.fs
++local fs = {}
++<<<<<<< HEAD
++
++local notification  = nil
++fs_notification_preset = { fg = beautiful.fg_normal }
++
++function fs:hide()
++    if notification ~= nil then
++        naughty.destroy(notification)
++        notification = nil
++=======
++local fs_notification  = nil
++
++function fs:hide()
++    if fs_notification ~= nil then
++        naughty.destroy(fs_notification)
++        fs_notification = nil
++>>>>>>> upstream/master
++    end
++end
++
++function fs:show(t_out)
++    fs:hide()
++
++<<<<<<< HEAD
++    local f = io.popen(helpers.scripts_dir .. "dfs")
++    ws = f:read("*a"):gsub("\n*$", "")
++    f:close()
++
++    notification = naughty.notify({
++        preset = fs_notification_preset,
++        text = ws,
++        timeout = t_out,
++=======
++    local ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "")
++
++    if fs.followmouse then
++        fs.notification_preset.screen = mouse.screen
++    end
++
++    fs_notification = naughty.notify({
++        preset  = fs.notification_preset,
++        text    = ws,
++        timeout = t_out
++>>>>>>> upstream/master
++    })
++end
++
++-- Unit definitions
++local unit = { ["mb"] = 1024, ["gb"] = 1024^2 }
++
++local function worker(args)
++<<<<<<< HEAD
++    local args      = args or {}
++    local timeout   = args.timeout or 600
++    local partition = args.partition or "/"
++    local settings  = args.settings or function() end
++=======
++    local args             = args or {}
++    local timeout          = args.timeout or 600
++    local partition        = args.partition or "/"
++    local settings         = args.settings or function() end
++
++    fs.followmouse         = args.followmouse or false
++    fs.notification_preset = args.notification_preset or { fg = beautiful.fg_normal }
++>>>>>>> upstream/master
++
++    fs.widget = wibox.widget.textbox('')
++
++    helpers.set_map(partition, false)
++
++    function update()
++        fs_info = {}
++        fs_now  = {}
++        local f = assert(io.popen("LC_ALL=C df -kP"))
++
++        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 .. " size_mb"]  = string.format("%.1f", tonumber(s) / unit["mb"])
++                fs_info[m .. " size_gb"]  = string.format("%.1f", tonumber(s) / unit["gb"])
++                fs_info[m .. " used_p"]   = tonumber(p)
++                fs_info[m .. " avail_p"]  = 100 - tonumber(p)
++            end
++        end
++
++        f:close()
++
++        fs_now.used      = tonumber(fs_info[partition .. " used_p"])  or 0
++        fs_now.available = tonumber(fs_info[partition .. " avail_p"]) or 0
++        fs_now.size_mb   = tonumber(fs_info[partition .. " size_mb"]) or 0
++        fs_now.size_gb   = tonumber(fs_info[partition .. " size_gb"]) or 0
++
++        widget = fs.widget
++        settings()
++
++        if fs_now.used >= 99 and not helpers.get_map(partition)
++        then
++            naughty.notify({
++                title = "warning",
++                text = partition .. " ran out!\nmake some room",
++                timeout = 8,
++                fg = "#000000",
++                bg = "#FFFFFF",
++            })
++            helpers.set_map(partition, true)
++        else
++            helpers.set_map(partition, false)
++        end
++    end
++
++    fs.widget:connect_signal('mouse::enter', function () fs:show(0) end)
++    fs.widget:connect_signal('mouse::leave', function () fs:hide() end)
++
++    helpers.newtimer(partition, timeout, update)
++
++    return setmetatable(fs, { __index = fs.widget })
++end
++
++return setmetatable(fs, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1121f1a67399ca676a9bfa3ceb823b307d87321e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,131 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++                                                  
++--]]
++
++local helpers      = require("lain.helpers")
++local async        = require("lain.asyncshell")
++
++local naughty      = require("naughty")
++local wibox        = require("wibox")
++
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local string       = { format = string.format,
++                       gsub   = string.gsub }
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- Mail IMAP check
++-- lain.widgets.imap
++
++local function worker(args)
++<<<<<<< HEAD
++    local imap     = {}
++    local args     = args or {}
++
++    local server   = args.server
++    local mail     = args.mail
++    local password = args.password
++
++    local port     = args.port or 993
++    local timeout  = args.timeout or 60
++    local is_plain = args.is_plain or false
++    local settings = args.settings or function() end
++=======
++    local imap        = {}
++    local args        = args or {}
++
++    local server      = args.server
++    local mail        = args.mail
++    local password    = args.password
++
++    local port        = args.port or 993
++    local timeout     = args.timeout or 60
++    local is_plain    = args.is_plain or false
++    local followmouse = args.followmouse or false
++    local settings    = args.settings or function() end
++>>>>>>> upstream/master
++
++    local head_command  = "curl --connect-timeout 3 -fsm 3"
++    local request = "-X 'SEARCH (UNSEEN)'"
++
++    helpers.set_map(mail, 0)
++
++    if not is_plain
++    then
++<<<<<<< HEAD
++        local f = io.popen(password)
++        password = f:read("*a"):gsub("\n", "")
++        f:close()
++=======
++        password = helpers.read_pipe(password):gsub("\n", "")
++>>>>>>> upstream/master
++    end
++
++    imap.widget = wibox.widget.textbox('')
++
++    function update()
++        mail_notification_preset = {
++            icon     = helpers.icons_dir .. "mail.png",
++            position = "top_left"
++        }
++
++<<<<<<< HEAD
++=======
++        if followmouse then
++            mail_notification_preset.screen = mouse.screen
++        end
++
++>>>>>>> upstream/master
++        curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%q %s -k",
++               head_command, server, port, mail, password, request)
++
++        async.request(curl, function(f)
++<<<<<<< HEAD
++            ws = f:read("*a")
++            f:close()
++
++            _, mailcount = string.gsub(ws, "%d+", "")
++=======
++            _, mailcount = string.gsub(f, "%d+", "")
++>>>>>>> upstream/master
++            _ = nil
++
++            widget = imap.widget
++            settings()
++
++            if mailcount >= 1 and mailcount > helpers.get_map(mail)
++            then
++                if mailcount == 1 then
++                    nt = mail .. " has one new message"
++                else
++                    nt = mail .. " has <b>" .. mailcount .. "</b> new messages"
++                end
++                naughty.notify({
++                    preset = mail_notification_preset,
++<<<<<<< HEAD
++                    text = nt,
++=======
++                    text = nt
++>>>>>>> upstream/master
++                })
++            end
++
++            helpers.set_map(mail, mailcount)
++        end)
++
++    end
++
++    helpers.newtimer(mail, timeout, update, true)
++
++    return setmetatable(imap, { __index = imap.widget })
++end
++
++return setmetatable({}, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a0d5e8c36ce587f42961d4309c3f213c1d4ed874
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,116 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013,      Luke Bonham                
++      * (c) 2010-2012, Peter Hofmann              
++                                                  
++--]]
++
++local newtimer        = require("lain.helpers").newtimer
++<<<<<<< HEAD
++=======
++local read_pipe       = require("lain.helpers").read_pipe
++>>>>>>> upstream/master
++
++local wibox           = require("wibox")
++
++local util            = require("lain.util")
++
++local io              = { popen  = io.popen }
++local os              = { getenv = os.getenv }
++local pairs           = pairs
++local string          = { len    = string.len,
++                          match  = string.match }
++local table           = { sort   = table.sort }
++
++local setmetatable    = setmetatable
++
++-- Maildir check
++-- lain.widgets.maildir
++local maildir = {}
++
++local function worker(args)
++    local args         = args or {}
++    local timeout      = args.timeout or 60
++    local mailpath     = args.mailpath or os.getenv("HOME") .. "/Mail"
++    local ignore_boxes = args.ignore_boxes or {}
++    local settings     = args.settings or function() end
++
++    maildir.widget = wibox.widget.textbox('')
++
++    function update()
++        -- Find pathes to mailboxes.
++        local p = io.popen("find " .. mailpath ..
++                           " -mindepth 1 -maxdepth 1 -type d" ..
++                           " -not -name .git")
++        local boxes = {}
++        repeat
++            line = p:read("*l")
++            if line ~= nil
++            then
++                -- Find all files in the "new" subdirectory. For each
++                -- file, print a single character (no newline). Don't
++                -- match files that begin with a dot.
++                -- Afterwards the length of this string is the number of
++                -- new mails in that box.
++<<<<<<< HEAD
++                local np = io.popen("find " .. line ..
++                                    "/new -mindepth 1 -type f " ..
++                                    "-not -name '.*' -printf a")
++                local mailstring = np:read("*a")
++=======
++                local mailstring = read_pipe("find " .. line ..
++                                    "/new -mindepth 1 -type f " ..
++                                    "-not -name '.*' -printf a")
++>>>>>>> upstream/master
++
++                -- Strip off leading mailpath.
++                local box = string.match(line, mailpath .. "/*([^/]+)")
++                local nummails = string.len(mailstring)
++                if nummails > 0
++                then
++                    boxes[box] = nummails
++                end
++            end
++        until line == nil
++
++<<<<<<< HEAD
++        table.sort(boxes)
++
++        newmail = "no mail"
++        --Count the total number of mails irrespective of where it was found
++=======
++      p:close()
++        table.sort(boxes)
++
++        newmail = "no mail"
++        -- Count the total number of mails irrespective of where it was found
++>>>>>>> upstream/master
++        total = 0
++
++        for box, number in pairs(boxes)
++        do
++            -- Add this box only if it's not to be ignored.
++            if not util.element_in_table(box, ignore_boxes)
++            then
++                total = total + number
++                if newmail == "no mail"
++                then
++                    newmail = box .. "(" .. number .. ")"
++                else
++                    newmail = newmail .. ", " ..
++                              box .. "(" .. number .. ")"
++                end
++            end
++        end
++
++        widget = maildir.widget
++        settings()
++    end
++
++    newtimer(mailpath, timeout, update, true)
++    return maildir.widget
++end
++
++return setmetatable(maildir, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9207b15a747acfb76480d21870d39baa3fb3a9f8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,147 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++      * (c) 2010, Adrian C. <anrxc@sysphere.org>  
++                                                  
++--]]
++
++local helpers      = require("lain.helpers")
++local async        = require("lain.asyncshell")
++
++local escape_f     = require("awful.util").escape
++local naughty      = require("naughty")
++local wibox        = require("wibox")
++
++local os           = { execute  = os.execute,
++                       getenv   = os.getenv }
++local math         = { floor    = math.floor }
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local string       = { format   = string.format,
++                       match    = string.match,
++                       gmatch   = string.gmatch }
++
++local setmetatable = setmetatable
++
++-- MPD infos
++-- lain.widgets.mpd
++local mpd = {}
++
++local function worker(args)
++    local args        = args or {}
++    local timeout     = args.timeout or 2
++    local password    = args.password or ""
++    local host        = args.host or "127.0.0.1"
++    local port        = args.port or "6600"
++    local music_dir   = args.music_dir or os.getenv("HOME") .. "/Music"
++    local cover_size  = args.cover_size or 100
++    local default_art = args.default_art or ""
++<<<<<<< HEAD
++=======
++    local followmouse = args.followmouse or false
++    local echo_cmd    = args.echo_cmd or "echo"
++>>>>>>> upstream/master
++    local settings    = args.settings or function() end
++
++    local mpdcover = helpers.scripts_dir .. "mpdcover"
++    local mpdh = "telnet://" .. host .. ":" .. port
++<<<<<<< HEAD
++    local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'"
++=======
++    local echo = echo_cmd .. " 'password " .. password .. "\nstatus\ncurrentsong\nclose'"
++>>>>>>> upstream/master
++
++    mpd.widget = wibox.widget.textbox('')
++
++    mpd_notification_preset = {
++        title   = "Now playing",
++        timeout = 6
++    }
++
++    helpers.set_map("current mpd track", nil)
++
++    function mpd.update()
++        async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f)
++            mpd_now = {
++                state   = "N/A",
++                file    = "N/A",
++                artist  = "N/A",
++                title   = "N/A",
++                album   = "N/A",
++                date    = "N/A",
++                time    = "N/A",
++                elapsed = "N/A"
++            }
++
++<<<<<<< HEAD
++            for line in f:lines() do
++=======
++            for line in string.gmatch(f, "[^\n]+") do
++>>>>>>> upstream/master
++                for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
++                    if     k == "state"   then mpd_now.state   = v
++                    elseif k == "file"    then mpd_now.file    = v
++                    elseif k == "Artist"  then mpd_now.artist  = escape_f(v)
++                    elseif k == "Title"   then mpd_now.title   = escape_f(v)
++                    elseif k == "Album"   then mpd_now.album   = escape_f(v)
++                    elseif k == "Date"    then mpd_now.date    = escape_f(v)
++                    elseif k == "Time"    then mpd_now.time    = v
++                    elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+")
++                    end
++                end
++            end
++
++            mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
++                                           mpd_now.album, mpd_now.date, mpd_now.title)
++            widget = mpd.widget
++            settings()
++
++            if mpd_now.state == "play"
++            then
++                if mpd_now.title ~= helpers.get_map("current mpd track")
++                then
++                    helpers.set_map("current mpd track", mpd_now.title)
++
++<<<<<<< HEAD
++                    if string.match(mpd_now.file, "http://") == nil
++=======
++                    if string.match(mpd_now.file, "http.*://") == nil
++>>>>>>> upstream/master
++                    then -- local file
++                        os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir,
++                                   mpd_now.file, cover_size, default_art))
++                        current_icon = "/tmp/mpdcover.png"
++                    else -- http stream
++                        current_icon = default_art
++                    end
++
++<<<<<<< HEAD
++=======
++                    if followmouse then
++                        mpd_notification_preset.screen = mouse.screen
++                    end
++
++>>>>>>> upstream/master
++                    mpd.id = naughty.notify({
++                        preset = mpd_notification_preset,
++                        icon = current_icon,
++                        replaces_id = mpd.id,
++                    }).id
++                end
++            elseif mpd_now.state ~= "pause"
++            then
++                helpers.set_map("current mpd track", nil)
++            end
++        end)
++    end
++
++    helpers.newtimer("mpd", timeout, mpd.update)
++
++    return setmetatable(mpd, { __index = mpd.widget })
++end
++
++return setmetatable(mpd, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..efd1386b361b28f37a58420afafca6ada48cb1ff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,116 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013,      Luke Bonham                
++      * (c) 2010-2012, Peter Hofmann              
++                                                  
++--]]
++
++local helpers      = require("lain.helpers")
++
++local notify_fg    = require("beautiful").fg_focus
++local naughty      = require("naughty")
++local wibox        = require("wibox")
++
++<<<<<<< HEAD
++local io           = { popen  = io.popen }
++=======
++>>>>>>> upstream/master
++local string       = { format = string.format,
++                       gsub   = string.gsub,
++                       match  = string.match }
++
++local setmetatable = setmetatable
++
++-- Network infos
++-- lain.widgets.net
++local net = {
++    last_t = 0,
++    last_r = 0
++}
++
++function net.get_device()
++<<<<<<< HEAD
++    f = io.popen("ip link show | cut -d' ' -f2,9")
++    ws = f:read("*a")
++    f:close()
++=======
++    local ws = helpers.read_pipe("ip link show | cut -d' ' -f2,9")
++>>>>>>> upstream/master
++    ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN")
++    if ws ~= nil then
++        return ws:match("(%w+):")
++    else
++        return "network off"
++    end
++end
++
++local function worker(args)
++    local args = args or {}
++    local timeout = args.timeout or 2
++    local units = args.units or 1024 --kb
++    local notify = args.notify or "on"
++    local screen = args.screen or 1
++    local settings = args.settings or function() end
++
++    iface = args.iface or net.get_device()
++
++    net.widget = wibox.widget.textbox('')
++
++    helpers.set_map(iface, true)
++
++    function update()
++        net_now = {}
++
++        if iface == "" or string.match(iface, "network off")
++        then
++            iface = net.get_device()
++        end
++
++        net_now.carrier = helpers.first_line('/sys/class/net/' .. iface ..
++                                           '/carrier') or "0"
++        net_now.state = helpers.first_line('/sys/class/net/' .. iface ..
++                                           '/operstate') or "down"
++        local now_t = helpers.first_line('/sys/class/net/' .. iface ..
++                                           '/statistics/tx_bytes') or 0
++        local now_r = helpers.first_line('/sys/class/net/' .. iface ..
++                                           '/statistics/rx_bytes') or 0
++
++        net_now.sent = (now_t - net.last_t) / timeout / units
++        net_now.sent = string.gsub(string.format('%.1f', net_now.sent), ",", ".")
++
++        net_now.received = (now_r - net.last_r) / timeout / units
++        net_now.received = string.gsub(string.format('%.1f', net_now.received), ",", ".")
++
++        widget = net.widget
++        settings()
++
++        net.last_t = now_t
++        net.last_r = now_r
++
++        if net_now.carrier ~= "1" and notify == "on"
++        then
++            if helpers.get_map(iface)
++            then
++                naughty.notify({
++                    title    = iface,
++                    text     = "no carrier",
++                    timeout  = 7,
++                    position = "top_left",
++                    icon     = helpers.icons_dir .. "no_net.png",
++                    fg       = notify_fg or "#FFFFFF",
++                    screen   = screen
++                })
++                helpers.set_map(iface, false)
++            end
++        else
++            helpers.set_map(iface, true)
++        end
++    end
++
++    helpers.newtimer(iface, timeout, update)
++    return net.widget
++end
++
++return setmetatable(net, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..64ddd00f8bf99d4ecbfb84bfdc7a5354b9457b40
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,49 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013,      Luke Bonham                
++      * (c) 2010-2012, Peter Hofmann              
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++
++local wibox        = require("wibox")
++
++local io           = { open = io.open }
++local string       = { match  = string.match }
++
++local setmetatable = setmetatable
++
++-- System load
++-- lain.widgets.sysload
++local sysload = {}
++
++local function worker(args)
++    local args = args or {}
++    local timeout = args.timeout or 2
++    local settings = args.settings or function() end
++
++    sysload.widget = wibox.widget.textbox('')
++
++    function update()
++        local f = io.open("/proc/loadavg")
++<<<<<<< HEAD
++        local ret = f:read("*a")
++=======
++        local ret = f:read("*all")
++>>>>>>> upstream/master
++        f:close()
++
++        load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
++
++        widget = sysload.widget
++        settings()
++    end
++
++    newtimer("sysload", timeout, update)
++    return sysload.widget
++end
++
++return setmetatable(sysload, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93f72af872bc52ddd161622a8b031667186ae0f9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,52 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2013, Luke Bonham                     
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++
++local wibox        = require("wibox")
++
++local io           = { open = io.open }
++local tonumber     = tonumber
++
++local setmetatable = setmetatable
++
++-- coretemp
++-- lain.widgets.temp
++local temp = {}
++
++local function worker(args)
++    local args     = args or {}
++    local timeout  = args.timeout or 2
++    local tempfile = args.tempfile or "/sys/class/thermal/thermal_zone0/temp"
++    local settings = args.settings or function() end
++
++    temp.widget = wibox.widget.textbox('')
++
++    function update()
++        local f = io.open(tempfile)
++        if f ~= nil
++        then
++<<<<<<< HEAD
++            coretemp_now = tonumber(f:read("*a")) / 1000
++=======
++            coretemp_now = tonumber(f:read("*all")) / 1000
++>>>>>>> upstream/master
++            f:close()
++        else
++            coretemp_now = "N/A"
++        end
++
++        widget = temp.widget
++        settings()
++    end
++
++    newtimer("coretemp", timeout, update)
++    return temp.widget
++end
++
++return setmetatable(temp, { __call = function(_, ...) return worker(...) end })
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ce6715675aab38fe96048a7b607cf04408e4270c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,185 @@@
++
++--[[
++                                                  
++     Licensed under GNU General Public License v2 
++      * (c) 2015, Luke Bonham                     
++                                                  
++--]]
++
++local newtimer     = require("lain.helpers").newtimer
++<<<<<<< HEAD
++local async        = require("lain.asyncshell")
++local json         = require("lain.util").dkjson
++local lain_icons   = require("lain.helpers").icons_dir
++=======
++local read_pipe    = require("lain.helpers").read_pipe
++
++local async        = require("lain.asyncshell")
++local json         = require("lain.util").dkjson
++local lain_icons   = require("lain.helpers").icons_dir
++
++>>>>>>> upstream/master
++local naughty      = require("naughty")
++local wibox        = require("wibox")
++
++local math         = { floor  = math.floor }
++<<<<<<< HEAD
++=======
++local mouse        = mouse
++>>>>>>> upstream/master
++local string       = { format = string.format,
++                       gsub   = string.gsub }
++
++local setmetatable = setmetatable
++
++-- OpenWeatherMap
++-- current weather and X-days forecast
++-- lain.widgets.weather
++
++local function worker(args)
++<<<<<<< HEAD
++    local weather               = {}
++    local args                  = args or {}
++    local timeout               = args.timeout or 900   -- 15 min
++    local timeout_forecast      = args.timeout or 86400 -- 24 hrs
++    local current_call          = "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'"
++    local forecast_call         = "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'"
++    local city_id               = args.city_id or 0 -- placeholder
++    local units                 = args.units or "metric"
++    local lang                  = args.lang or "en"
++    local cnt                   = args.cnt or 7
++    local date_cmd              = args.date_cmd or "date -u -d @%d +'%%a %%d'"
++    local icons_path            = args.icons_path or lain_icons .. "openweathermap/"
++    local w_notification_preset = args.w_notification_preset or {}
++    local settings              = args.settings or function() end
++=======
++    local weather             = {}
++    local args                = args or {}
++    local timeout             = args.timeout or 900   -- 15 min
++    local timeout_forecast    = args.timeout or 86400 -- 24 hrs
++    local current_call        = "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'"
++    local forecast_call       = "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'"
++    local city_id             = args.city_id or 0 -- placeholder
++    local units               = args.units or "metric"
++    local lang                = args.lang or "en"
++    local cnt                 = args.cnt or 7
++    local date_cmd            = args.date_cmd or "date -u -d @%d +'%%a %%d'"
++    local icons_path          = args.icons_path or lain_icons .. "openweathermap/"
++    local notification_preset = args.notification_preset or {}
++    local followmouse         = args.followmouse or false
++    local settings            = args.settings or function() end
++>>>>>>> upstream/master
++
++    weather.widget = wibox.widget.textbox('')
++    weather.icon   = wibox.widget.imagebox()
++
++    function weather.show(t_out)
++        weather.hide()
++<<<<<<< HEAD
++=======
++
++        if followmouse then
++            notification_preset.screen = mouse.screen
++        end
++
++>>>>>>> upstream/master
++        weather.notification = naughty.notify({
++            text    = weather.notification_text,
++            icon    = weather.icon_path,
++            timeout = t_out,
++<<<<<<< HEAD
++            preset  = w_notification_preset
++=======
++            preset  = notification_preset
++>>>>>>> upstream/master
++        })
++    end
++
++    function weather.hide()
++        if weather.notification ~= nil then
++            naughty.destroy(weather.notification)
++            weather.notification = nil
++        end
++    end
++
++    function weather.attach(obj)
++        obj:connect_signal("mouse::enter", function()
++            weather.show(0)
++        end)
++        obj:connect_signal("mouse::leave", function()
++            weather.hide()
++        end)
++    end
++
++    function weather.forecast_update()
++        local cmd = string.format(forecast_call, city_id, units, lang, cnt)
++        async.request(cmd, function(f)
++<<<<<<< HEAD
++            j = f:read("*a")
++            f:close()
++            weather_now, pos, err = json.decode(j, 1, nil)
++=======
++            weather_now, pos, err = json.decode(f, 1, nil)
++>>>>>>> upstream/master
++
++            if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then
++                weather.notification_text = ''
++                for i = 1, weather_now["cnt"] do
++<<<<<<< HEAD
++                    local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"])))
++                    day = string.gsub(f:read("a"), "\n", "")
++                    f:close()
++=======
++                    day = string.gsub(read_pipe(string.format(date_cmd, weather_now["list"][i]["dt"])), "\n", "")
++>>>>>>> upstream/master
++
++                    tmin = math.floor(weather_now["list"][i]["temp"]["min"])
++                    tmax = math.floor(weather_now["list"][i]["temp"]["max"])
++                    desc = weather_now["list"][i]["weather"][1]["description"]
++
++                    weather.notification_text = weather.notification_text ..
++                                                string.format("<b>%s</b>: %s, %d - %d  ", day, desc, tmin, tmax)
++
++                    if i < weather_now["cnt"] then
++                        weather.notification_text = weather.notification_text .. "\n"
++                    end
++                end
++            else
++                weather.icon_path = icons_path .. "na.png"
++                weather.notification_text = "API/connection error or bad/not set city ID"
++            end
++        end)
++    end
++
++    function weather.update()
++        local cmd = string.format(current_call, city_id, units, lang)
++        async.request(cmd, function(f)
++<<<<<<< HEAD
++            j = f:read("*a")
++            f:close()
++            weather_now, pos, err = json.decode(j, 1, nil)
++=======
++            weather_now, pos, err = json.decode(f, 1, nil)
++>>>>>>> upstream/master
++
++            if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then
++                weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png"
++                weather.icon:set_image(weather.icon_path)
++                widget = weather.widget
++                settings()
++            else
++                weather.widget._layout.text = " N/A " -- tries to avoid textbox bugs
++                weather.icon:set_image(icons_path .. "na.png")
++            end
++        end)
++    end
++
++    weather.attach(weather.widget)
++
++    newtimer("weather-" .. city_id, timeout, weather.update)
++    newtimer("weather_forecast" .. city_id, timeout, weather.forecast_update)
++
++    return setmetatable(weather, { __index = weather.widget })
++end
++
++return setmetatable({}, { __call = function(_, ...) return worker(...) end })