aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE339
-rw-r--r--bat.lua44
-rw-r--r--cpu.lua95
-rw-r--r--date.lua24
-rw-r--r--dio.lua73
-rw-r--r--entropy.lua37
-rw-r--r--fs.lua56
-rw-r--r--helpers.lua115
-rw-r--r--init.lua274
-rw-r--r--load.lua28
-rw-r--r--mbox.lua45
-rw-r--r--mdir.lua41
-rw-r--r--mem.lua76
-rw-r--r--mpd.lua42
-rw-r--r--net.lua115
-rw-r--r--org.lua70
-rw-r--r--pacman.lua38
-rw-r--r--thermal.lua27
-rw-r--r--uptime.lua51
-rw-r--r--volume.lua33
-rw-r--r--wifi.lua62
21 files changed, 1685 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/bat.lua b/bat.lua
new file mode 100644
index 0000000..e6caacf
--- /dev/null
+++ b/bat.lua
@@ -0,0 +1,44 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { popen = io.popen }
+local table = { insert = table.insert }
+-- }}}
+
+
+-- Bat: provides state, charge, and remaining time for all batteries
+module("vicious.bat")
+
+
+-- {{{ Battery widget type
+function worker(format)
+ -- Initialise tables
+ local battery_info = {}
+ local battery_state = {
+ ["charged"] = "+",
+ ["charging"] = "+",
+ ["discharging"] = "-"
+ }
+
+ -- Get data from acpitool
+ local f = io.popen("acpitool -b")
+
+ -- Format data
+ for line in f:lines() do
+ -- Check if the battery is present
+ if line:match("^[%s]+Battery.*") then
+ -- Store state and charge information
+ table.insert(battery_info, battery_state[line:match("([%a]*),")])
+ table.insert(battery_info, line:match("([%d]?[%d]?[%d])%."))
+ -- Store remaining time information if the battery supports it
+ table.insert(battery_info, (line:match("%%,%s(.*)") or "/"))
+ end
+ end
+ f:close()
+
+ return battery_info
+end
+-- }}}
diff --git a/cpu.lua b/cpu.lua
new file mode 100644
index 0000000..5112253
--- /dev/null
+++ b/cpu.lua
@@ -0,0 +1,95 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local type = type
+local pairs = pairs
+local ipairs = ipairs
+local io = { open = io.open }
+local math = { floor = math.floor }
+local table = { insert = table.insert }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Cpu: provides CPU usage for all available CPUs/cores
+module("vicious.cpu")
+
+
+-- Initialise function tables
+local cpu_usage = {}
+local cpu_total = {}
+local cpu_active = {}
+
+-- {{{ CPU widget type
+function worker(format, padding)
+ -- Get /proc/stat
+ local f = io.open("/proc/stat")
+ local cpu_lines = {}
+
+ -- Format data
+ for line in f:lines() do
+ if line:find("^cpu") then
+ if #cpu_lines < 1 then cpuid = 1
+ else cpuid = #cpu_lines + 1 end
+
+ cpu_lines[cpuid] = {}
+ for match in line:gmatch("[%s]+([%d]+)") do
+ table.insert(cpu_lines[cpuid], match)
+ end
+ end
+ end
+ f:close()
+
+ -- Ensure tables are initialized correctly
+ while #cpu_total < #cpu_lines do
+ table.insert(cpu_total, 0)
+ end
+ while #cpu_active < #cpu_lines do
+ table.insert(cpu_active, 0)
+ end
+ while #cpu_usage < #cpu_lines do
+ table.insert(cpu_usage, 0)
+ end
+
+ -- Setup tables
+ local total_new = {}
+ local active_new = {}
+ local diff_total = {}
+ local diff_active = {}
+
+ for i, v in ipairs(cpu_lines) do
+ -- Calculate totals
+ total_new[i] = 0
+ for j = 1, #v do
+ total_new[i] = total_new[i] + v[j]
+ end
+ active_new[i] = v[1] + v[2] + v[3]
+
+ -- Calculate percentage
+ diff_total[i] = total_new[i] - cpu_total[i]
+ diff_active[i] = active_new[i] - cpu_active[i]
+ cpu_usage[i] = math.floor(diff_active[i] / diff_total[i] * 100)
+
+ -- Store totals
+ cpu_total[i] = total_new[i]
+ cpu_active[i] = active_new[i]
+ end
+
+ if padding ~= nil then
+ for k, v in pairs(cpu_usage) do
+ if type(padding) == "table" then
+ p = padding[k]
+ else
+ p = padding
+ end
+
+ cpu_usage[k] = helpers.padd(cpu_usage[k], p)
+ end
+ end
+
+ return cpu_usage
+end
+-- }}}
diff --git a/date.lua b/date.lua
new file mode 100644
index 0000000..e6ea108
--- /dev/null
+++ b/date.lua
@@ -0,0 +1,24 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local os = { date = os.date }
+-- }}}
+
+
+-- Date: provides access to os.date with optional custom formatting
+module("vicious.date")
+
+
+-- {{{ Date widget type
+function worker(format)
+ -- Get format
+ if format == nil then
+ return os.date()
+ else
+ return os.date(format)
+ end
+end
+-- }}}
diff --git a/dio.lua b/dio.lua
new file mode 100644
index 0000000..12a3961
--- /dev/null
+++ b/dio.lua
@@ -0,0 +1,73 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local type = type
+local ipairs = ipairs
+local io = { open = io.open }
+local math = { floor = math.floor }
+local table = { insert = table.insert }
+-- }}}
+
+
+-- Disk I/O: provides I/O statistics for requsted storage devices
+module("vicious.dio")
+
+
+-- Initialise function tables
+local disk_usage = {}
+local disk_total = {}
+
+-- {{{ Disk I/O widget type
+function worker(format, disk)
+ -- Get /proc/diskstats
+ local f = io.open("/proc/diskstats")
+ local disk_lines = {}
+
+ -- Format data
+ for line in f:lines() do
+ if line:match("("..disk..")%s") then
+ -- Todo: find a way to do this
+ --for stat in line:gmatch("%s([%d]+)") do
+ -- table.insert(disk_lines, stat)
+ --end
+ --
+ -- Skip first two matches
+ local stat = line:gmatch("%s([%d]+)")
+ stat()
+ stat()
+ -- Store the rest
+ for i = 1, 11 do
+ table.insert(disk_lines, stat())
+ end
+ end
+ end
+ f:close()
+
+ -- Ensure tables are initialized correctly
+ while #disk_total < #disk_lines do
+ table.insert(disk_total, 0)
+ end
+
+ -- Setup tables
+ local diff_total = {}
+
+ for i, v in ipairs(disk_lines) do
+ -- Diskstats are absolute, substract our last reading
+ diff_total[i] = v - disk_total[i]
+
+ -- Store totals
+ disk_total[i] = v
+ end
+
+ -- Calculate I/O
+ disk_usage["{raw}"] = diff_total[7] + diff_total[3]
+ -- Divide "sectors read" by 2 and 1024 to get KB and MB
+ disk_usage["{kb}"] = math.floor(diff_total[7] + diff_total[3])/2
+ disk_usage["{mb}"] = math.floor(diff_total[7] + diff_total[3])/1024
+
+ return disk_usage
+end
+-- }}}
diff --git a/entropy.lua b/entropy.lua
new file mode 100644
index 0000000..43bdb80
--- /dev/null
+++ b/entropy.lua
@@ -0,0 +1,37 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { open = io.open }
+local math = { floor = math.floor }
+local string = { format = string.format }
+-- }}}
+
+
+-- Entropy: provides available system entropy
+module("vicious.entropy")
+
+
+-- {{{ Entropy widget type
+function worker(format, poolsize)
+ -- Don't waste time opening the poolsize, Linux 2.6 has a default
+ -- entropy pool of 4096-bits, if needed specify otherwise
+ if poolsize == nil then
+ poolsize = 4096
+ end
+
+ -- Get available entropy
+ local f = io.open("/proc/sys/kernel/random/entropy_avail")
+ local ent_avail = f:read()
+ f:close()
+
+ -- Calculate percentage
+ ent_avail_percent = math.floor(ent_avail * 100 / poolsize)
+ -- This data is intended for a progressbar
+ ent_avail_percent = string.format("%0d", ent_avail_percent)
+
+ return {ent_avail, ent_avail_percent}
+end
+-- }}}
diff --git a/fs.lua b/fs.lua
new file mode 100644
index 0000000..3afe801
--- /dev/null
+++ b/fs.lua
@@ -0,0 +1,56 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local type = type
+local io = { popen = io.popen }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- FS: provides usage statistics for requested mount points
+module("vicious.fs")
+
+
+-- {{{ Filesystem widget type
+function worker(format, padding)
+ -- Get data from df
+ local f = io.popen("df -hP")
+ local args = {}
+
+ -- Format data
+ for line in f:lines() do
+ if not line:match("^Filesystem.*") then
+ -- Format helper can't deal with matrices, so don't setup a
+ -- table for each mount point with gmatch
+ local size, used, avail, usep, mount =
+ -- Instead match all at once, including network file systems
+ line:match("^[%w/-:%.]+[%s]+([%d%.]+)[%a]?[%s]+([%d%.]+)[%a]?[%s]+([%d%.]+)[%a]?[%s]+([%d]+)%%[%s]+([-/%w]+)$")
+
+ if padding then
+ if type(padding) == "table" then
+ size = helpers.padd(size, padding[1])
+ used = helpers.padd(used, padding[2])
+ avail = helpers.padd(avail, padding[3])
+ usep = helpers.padd(usep, padding[4])
+ else
+ size = helpers.padd(size, padding)
+ used = helpers.padd(used, padding)
+ avail = helpers.padd(avail, padding)
+ usep = helpers.padd(usep, padding)
+ end
+ end
+
+ args["{"..mount.." size}"] = size
+ args["{"..mount.." used}"] = used
+ args["{"..mount.." avail}"] = avail
+ args["{"..mount.." usep}"] = usep
+ end
+ end
+ f:close()
+
+ return args
+end
+-- }}}
diff --git a/helpers.lua b/helpers.lua
new file mode 100644
index 0000000..d2bfc9f
--- /dev/null
+++ b/helpers.lua
@@ -0,0 +1,115 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local pairs = pairs
+local tonumber = tonumber
+local tostring = tostring
+local table = { insert = table.insert }
+local math = {
+ pow = math.pow,
+ floor = math.floor
+}
+local string = {
+ sub = string.sub,
+ gsub = string.gsub,
+ find = string.find
+}
+-- }}}
+
+
+-- Helpers: provides helper functions for vicious widgets
+module("vicious.helpers")
+
+
+-- {{{ Helper functions
+-- {{{ Format a string with args
+function format(format, args)
+ -- TODO: Find a more efficient way to do this
+
+ -- Format a string
+ for var, val in pairs(args) do
+ format = string.gsub(format, "$"..var, val)
+ end
+
+ -- Return formatted string
+ return format
+end
+-- }}}
+
+-- {{{ Padd a number to a minimum amount of digits
+function padd(number, padding)
+ s = tostring(number)
+
+ if padding == nil then
+ return s
+ end
+
+ for i=1, padding do
+ if math.floor(number/math.pow(10,(i-1))) == 0 then
+ s = "0"..s
+ end
+ end
+
+ if number == 0 then
+ s = s:sub(2)
+ end
+
+ return s
+end
+-- }}}
+
+-- {{{ Convert amount of bytes to string
+function bytes_to_string(bytes, sec, padding)
+ if bytes == nil or tonumber(bytes) == nil then
+ return ""
+ end
+
+ bytes = tonumber(bytes)
+
+ local signs = {}
+ signs[1] = " b"
+ signs[2] = "KiB"
+ signs[3] = "MiB"
+ signs[4] = "GiB"
+ signs[5] = "TiB"
+
+ sign = 1
+
+ while bytes/1024 > 1 and signs[sign+1] ~= nil do
+ bytes = bytes/1024
+ sign = sign+1
+ end
+
+ bytes = bytes*10
+ bytes = math.floor(bytes)/10
+
+ if padding then
+ bytes = padd(bytes*10, padding+1)
+ bytes = bytes:sub(1, bytes:len()-1).."."..bytes:sub(bytes:len())
+ end
+
+ if sec then
+ return tostring(bytes)..signs[sign].."ps"
+ else
+ return tostring(bytes)..signs[sign]
+ end
+end
+-- }}}
+
+--{{{ Escape a string
+function escape(text)
+ if text then
+ text = text:gsub("&", "&amp;")
+ text = text:gsub("<", "&lt;")
+ text = text:gsub(">", "&gt;")
+ text = text:gsub("'", "&apos;")
+ text = text:gsub("\"", "&quot;")
+ end
+
+ return text
+end
+-- }}}
+-- }}}
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..8c74560
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,274 @@
+----------------------------------------------------------------
+-- Vicious widgets for the awesome window manager
+-- * FAQ: http://sysphere.org/~anrxc/local/scr/sources/vicious
+----------------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+--
+-- To view a human-readable summary of the license, visit:
+-- * http://creativecommons.org/licenses/GPL/2.0/
+----------------------------------------------------------------
+-- Derived from Wicked, by Lucas de Vries <lucas_glacicle_com>
+-- * Wicked is licensed under the WTFPL v2
+----------------------------------------------------------------
+
+-- {{{ Grab environment
+require("awful")
+require("vicious.helpers")
+
+local type = type
+local pairs = pairs
+local awful = awful
+local tonumber = tonumber
+local os = { time = os.time }
+local table = {
+ insert = table.insert,
+ remove = table.remove
+}
+
+-- Grab C API
+local capi = {
+ hooks = hooks,
+ widget = widget,
+ awesome = awesome,
+}
+-- }}}
+
+
+-- {{{ Configure widgets
+require("vicious.cpu")
+require("vicious.thermal")
+require("vicious.load")
+require("vicious.uptime")
+require("vicious.bat")
+require("vicious.mem")
+require("vicious.fs")
+require("vicious.dio")
+require("vicious.net")
+require("vicious.wifi")
+require("vicious.mbox")
+require("vicious.mdir")
+require("vicious.entropy")
+require("vicious.org")
+require("vicious.pacman")
+require("vicious.mpd")
+require("vicious.volume")
+require("vicious.date")
+-- }}}
+
+-- Vicious: widgets for the awesome window manager
+module("vicious")
+
+
+-- {{{ Initialise variables
+local registered = {}
+local widget_cache = {}
+
+-- Initialise the function table
+widgets = {}
+-- }}}
+
+-- {{{ Widget types
+for w, i in pairs(_M) do
+ -- Ensure we don't call ourselves
+ if i and i ~= _M and type(i) == "table" then
+ -- Ignore the function table and helpers
+ if w ~= "widgets" and w ~= "helpers" then
+ -- Place functions in the namespace table
+ widgets[w] = i.worker
+ -- Enable caching for all widget types
+ widget_cache[i.worker] = {}
+ end
+ end
+end
+-- }}}
+
+-- {{{ Main functions
+-- {{{ Register widget
+function register(widget, wtype, format, timer, field, padd)
+ local reg = {}
+ local widget = widget
+
+ -- Set properties
+ reg.type = wtype
+ reg.format = format
+ reg.timer = timer
+ reg.field = field
+ reg.padd = padd
+ reg.widget = widget
+
+ -- Update function
+ reg.update = function ()
+ update(widget, reg)
+ end
+
+ -- Default to timer=1
+ if reg.timer == nil then
+ reg.timer = 1
+ end
+
+ -- Allow using a string widget type
+ if type(reg.type) == "string" then
+ reg.type = widgets[reg.type]
+ end
+
+ -- Register reg object
+ regregister(reg)
+
+ -- Return reg object for reuse
+ return reg
+end
+-- }}}
+
+-- {{{ Register from reg object
+function regregister(reg)
+ if not reg.running then
+ -- Put widget in table
+ if registered[reg.widget] == nil then
+ registered[reg.widget] = {}
+ table.insert(registered[reg.widget], reg)
+ else
+ already = false
+
+ for w, i in pairs(registered) do
+ if w == reg.widget then
+ for k, v in pairs(i) do
+ if v == reg then
+ already = true
+ break
+ end
+ end
+
+ if already then
+ break
+ end
+ end
+ end
+
+ if not already then
+ table.insert(registered[reg.widget], reg)
+ end
+ end
+
+ -- Start timer
+ if reg.timer > 0 then
+ awful.hooks.timer.register(reg.timer, reg.update)
+ end
+
+ -- Initial update
+ reg.update()
+
+ -- Set running
+ reg.running = true
+ end
+end
+-- }}}
+
+-- {{{ Unregister widget
+function unregister(widget, keep, reg)
+ if reg == nil then
+ for w, i in pairs(registered) do
+ if w == widget then
+ for k, v in pairs(i) do
+ reg = unregister(w, keep, v)
+ end
+ end
+ end
+
+ return reg
+ end
+
+ if not keep then
+ for w, i in pairs(registered) do
+ if w == widget then
+ for k, v in pairs(i) do
+ if v == reg then
+ table.remove(registered[w], k)
+ end
+ end
+ end
+ end
+ end
+
+ awful.hooks.timer.unregister(reg.update)
+ reg.running = false
+
+ return reg
+end
+-- }}}
+
+-- {{{ Suspend vicious, halt all widget updates
+function suspend()
+ for w, i in pairs(registered) do
+ for k, v in pairs(i) do
+ unregister(w, true, v)
+ end
+ end
+end
+-- }}}
+
+-- {{{ Activate vicious, restart all widget updates
+function activate(widget)
+ for w, i in pairs(registered) do
+ if widget == nil or w == widget then
+ for k, v in pairs(i) do
+ regregister(v)
+ end
+ end
+ end
+end
+-- }}}
+
+-- {{{ Update widget
+function update(widget, reg, disablecache)
+ -- Check if there are any equal widgets
+ if reg == nil then
+ for w, i in pairs(registered) do
+ if w == widget then
+ for k, v in pairs(i) do
+ update(w, v, disablecache)
+ end
+ end
+ end
+
+ return
+ end
+
+ local t = os.time()
+ local data = {}
+
+ -- Check if we have output chached for this widget newer than last
+ -- widget update
+ if widget_cache[reg.type] ~= nil then
+ local c = widget_cache[reg.type]
+
+ if c.time == nil or c.time <= t-reg.timer or disablecache then
+ c.time = t
+ c.data = reg.type(reg.format, reg.padd)
+ end
+
+ data = c.data
+ else
+ data = reg.type(reg.format, reg.padd)
+ end
+
+ if type(data) == "table" then
+ if type(reg.format) == "string" then
+ data = helpers.format(reg.format, data)
+ elseif type(reg.format) == "function" then
+ data = reg.format(widget, data)
+ end
+ end
+
+ if reg.field == nil then
+ widget.text = data
+ elseif widget.plot_data_add ~= nil then
+ widget:plot_data_add(reg.field, tonumber(data))
+ elseif widget.bar_data_add ~= nil then
+ widget:bar_data_add(reg.field, tonumber(data))
+ end
+
+ return data
+end
+-- }}}
+-- }}}
diff --git a/load.lua b/load.lua
new file mode 100644
index 0000000..50e1a22
--- /dev/null
+++ b/load.lua
@@ -0,0 +1,28 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { open = io.open }
+-- }}}
+
+
+-- Load: provides system load averages for the past 1, 5, and 15 minutes
+module("vicious.load")
+
+
+-- {{{ Load widget type
+function worker(format)
+ -- Get load averages
+ local f = io.open('/proc/loadavg')
+ local line = f:read()
+ f:close()
+
+ -- Get load data
+ local avg1, avg5, avg15 =
+ line:match("([%d]*%.[%d]*)%s([%d]*%.[%d]*)%s([%d]*%.[%d]*)")
+
+ return {avg1, avg5, avg15}
+end
+-- }}}
diff --git a/mbox.lua b/mbox.lua
new file mode 100644
index 0000000..fae3355
--- /dev/null
+++ b/mbox.lua
@@ -0,0 +1,45 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { open = io.open }
+local string = { gfind = string.gfind }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Mbox: provides the subject of last e-mail in a mbox file
+module("vicious.mbox")
+
+
+-- {{{ Mailbox widget type
+function worker(format, mbox)
+ local f = io.open(mbox)
+ -- mbox could be huge, get a 15kb chunk from EOF
+ -- * attachments could be much bigger than this
+ f:seek("end", -15360)
+
+ -- Get data
+ local text = f:read("*all")
+ f:close()
+
+ -- Find subject lines
+ for match in string.gfind(text, "Subject: ([^\n]*)") do
+ subject = match
+ end
+
+ if subject then
+ -- Spam sanitize only the last subject
+ subject = helpers.escape(subject)
+
+ -- Don't abuse the wibox, truncate
+ if subject:len() > 22 then
+ subject = subject:sub(1, 19) .. "..."
+ end
+
+ return {subject}
+ end
+end
+-- }}}
diff --git a/mdir.lua b/mdir.lua
new file mode 100644
index 0000000..e0fe392
--- /dev/null
+++ b/mdir.lua
@@ -0,0 +1,41 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+-- * Derived from Maildir Biff Widget, by Fredrik Ax
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { popen = io.popen }
+-- }}}
+
+
+-- Mdir: provides a number of new and unread messages in a Maildir structure
+module("vicious.mdir")
+
+
+-- {{{ Maildir widget type
+function worker(format, mdir)
+ -- Widgets like this one are not agressive like CPU or NET, so we
+ -- can keep it simple, find is OK with me if we execute every >60s
+ --
+ -- Initialise counters
+ local newcount = 0
+ local curcount = 0
+
+ -- Recursively find new messages
+ local fnew = io.popen("find " .. mdir .. " -type f -wholename '*/new/*'")
+ for line in fnew:lines() do
+ newcount = newcount + 1
+ end
+ fnew:close()
+
+ -- Recursively find "old" messages lacking the Seen flag
+ local fcur = io.popen("find " .. mdir .. " -type f -regex '.*/cur/.*2,[^S]*$'")
+ for line in fcur:lines() do
+ curcount = curcount + 1
+ end
+ fcur:close()
+
+ return {newcount, curcount}
+end
+-- }}}
diff --git a/mem.lua b/mem.lua
new file mode 100644
index 0000000..818e501
--- /dev/null
+++ b/mem.lua
@@ -0,0 +1,76 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local type = type
+local tonumber = tonumber
+local io = { open = io.open }
+local math = { floor = math.floor }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Mem: provides RAM and Swap usage statistics
+module("vicious.mem")
+
+
+-- {{{ Memory widget type
+function worker(format, padding)
+ -- Get meminfo
+ local f = io.open("/proc/meminfo")
+
+ -- Get data
+ for line in f:lines() do
+ if line:match("^MemTotal.*") then
+ mem_total = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ elseif line:match("^MemFree.*") then
+ free = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ elseif line:match("^Buffers.*") then
+ buffers = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ elseif line:match("^Cached.*") then
+ cached = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ -- Get swap stats while we're at it
+ elseif line:match("^SwapTotal.*") then
+ swap_total = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ elseif line:match("^SwapFree.*") then
+ swap_free = math.floor(tonumber(line:match("([%d]+)")) / 1024)
+ end
+ end
+ f:close()
+
+ -- Calculate percentage
+ mem_free = free + buffers + cached
+ mem_inuse = mem_total - mem_free
+ mem_usepercent = math.floor(mem_inuse/mem_total*100)
+ -- Calculate swap percentage
+ swap_inuse = swap_total - swap_free
+ swap_usepercent = math.floor(swap_inuse/swap_total*100)
+
+ if padding then
+ if type(padding) == "table" then
+ mem_usepercent = helpers.padd(mem_usepercent, padding[1])
+ mem_inuse = helpers.padd(mem_inuse, padding[2])
+ mem_total = helpers.padd(mem_total, padding[3])
+ mem_free = helpers.padd(mem_free, padding[4])
+ swap_usepercent = helpers.padd(swap_usepercent, padding[1])
+ swap_inuse = helpers.padd(swap_inuse, padding[2])
+ swap_total = helpers.padd(swap_total, padding[3])
+ swap_free = helpers.padd(swap_free, padding[4])
+ else
+ mem_usepercent = helpers.padd(mem_usepercent, padding)
+ mem_inuse = helpers.padd(mem_inuse, padding)
+ mem_total = helpers.padd(mem_total, padding)
+ mem_free = helpers.padd(mem_free, padding)
+ swap_usepercent = helpers.padd(swap_usepercent, padding)
+ swap_inuse = helpers.padd(swap_inuse, padding)
+ swap_total = helpers.padd(swap_total, padding)
+ swap_free = helpers.padd(swap_free, padding)
+ end
+ end
+
+ return {mem_usepercent, mem_inuse, mem_total, mem_free,
+ swap_usepercent, swap_inuse, swap_total, swap_free}
+end
+-- }}}
diff --git a/mpd.lua b/mpd.lua
new file mode 100644
index 0000000..2dc95f8
--- /dev/null
+++ b/mpd.lua
@@ -0,0 +1,42 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { popen = io.popen }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Mpd: provides the currently playing song in MPD
+module("vicious.mpd")
+
+
+-- {{{ MPD widget type
+function worker()
+ -- This one is as simple as they come. Using sockets or expanding
+ -- it is a lost cause since there are already a few MPD Lua libs
+ -- written for awesome. Use them.
+ --
+ -- Get data from mpc
+ local f = io.popen("mpc")
+ local np = f:read("*line")
+ f:close()
+
+ -- Check if it's stopped, off or not installed
+ if np == nil or (np:find("MPD_HOST") or np:find("volume:")) then
+ return {"Stopped"}
+ end
+
+ -- Sanitize the song name
+ nowplaying = helpers.escape(np)
+
+ -- Don't abuse the wibox, truncate
+ if nowplaying:len() > 30 then
+ nowplaying = nowplaying:sub(1, 27) .. "..."
+ end
+
+ return {nowplaying}
+end
+-- }}}
diff --git a/net.lua b/net.lua
new file mode 100644
index 0000000..9428c5d
--- /dev/null
+++ b/net.lua
@@ -0,0 +1,115 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local tonumber = tonumber
+local os = { time = os.time }
+local io = { open = io.open }
+local math = { floor = math.floor }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Net: provides usage statistics for all network interfaces
+module("vicious.net")
+
+
+-- Initialise function tables
+local nets = {}
+
+-- {{{ Net widget type
+function worker(format, padding)
+ -- Get /proc/net/dev
+ local f = io.open("/proc/net/dev")
+ local args = {}
+
+ -- Format data
+ for line in f:lines() do
+ -- Match wmaster0 as well as rt0 (multiple leading spaces)
+ if line:match("^[%s]?[%s]?[%s]?[%s]?[%w]+:") then
+ name = line:match("^[%s]?[%s]?[%s]?[%s]?([%w]+):")
+ -- Received bytes, first value after the name
+ recv = tonumber(line:match(":[%s]*([%d]+)"))
+ -- Transmited bytes, 7 fields from end of the line
+ send = tonumber(line:match("([%d]+)%s+%d+%s+%d+%s+%d+%s+%d+%s+%d+%s+%d+%s+%d$"))
+
+ if padding then
+ args["{"..name.." rx}"] = helpers.bytes_to_string(recv, nil, padding)
+ args["{"..name.." tx}"] = helpers.bytes_to_string(send, nil, padding)
+ else
+ args["{"..name.." rx}"] = helpers.bytes_to_string(recv)
+ args["{"..name.." tx}"] = helpers.bytes_to_string(send)
+ end
+
+ args["{"..name.." rx_b}"] = math.floor(recv*10)/10
+ args["{"..name.." tx_b}"] = math.floor(send*10)/10
+
+ args["{"..name.." rx_kb}"] = math.floor(recv/1024*10)/10
+ args["{"..name.." tx_kb}"] = math.floor(send/1024*10)/10
+
+ args["{"..name.." rx_mb}"] = math.floor(recv/1024/1024*10)/10
+ args["{"..name.." tx_mb}"] = math.floor(send/1024/1024*10)/10
+
+ args["{"..name.." rx_gb}"] = math.floor(recv/1024/1024/1024*10)/10
+ args["{"..name.." tx_gb}"] = math.floor(send/1024/1024/1024*10)/10
+
+ if nets[name] == nil then
+ -- Default values on our first run
+ nets[name] = {}
+ args["{"..name.." down}"] = "n/a"
+ args["{"..name.." up}"] = "n/a"
+
+ args["{"..name.." down_b}"] = 0
+ args["{"..name.." up_b}"] = 0
+
+ args["{"..name.." down_kb}"] = 0
+ args["{"..name.." up_kb}"] = 0
+
+ args["{"..name.." down_mb}"] = 0
+ args["{"..name.." up_mb}"] = 0
+
+ args["{"..name.." down_gb}"] = 0
+ args["{"..name.." up_gb}"] = 0
+
+ nets[name].time = os.time()
+ else
+ -- Net stats are absolute, substract our last reading
+ interval = os.time() - nets[name].time
+ nets[name].time = os.time()
+
+ down = (recv - nets[name][1])/interval
+ up = (send - nets[name][2])/interval
+
+ if padding then
+ args["{"..name.." down}"] = helpers.bytes_to_string(down, true, padding)
+ args["{"..name.." up}"] = helpers.bytes_to_string(up, true, padding)
+ else
+ args["{"..name.." down}"] = helpers.bytes_to_string(down, true)
+ args["{"..name.." up}"] = helpers.bytes_to_string(up, true)
+ end
+
+ args["{"..name.." down_b}"] = math.floor(down*10)/10
+ args["{"..name.." up_b}"] = math.floor(up*10)/10
+
+ args["{"..name.." down_kb}"] = math.floor(down/1024*10)/10
+ args["{"..name.." up_kb}"] = math.floor(up/1024*10)/10
+
+ args["{"..name.." down_mb}"] = math.floor(down/1024/1024*10)/10
+ args["{"..name.." up_mb}"] = math.floor(up/1024/1024*10)/10
+
+ args["{"..name.." down_gb}"] = math.floor(down/1024/1024/1024*10)/10
+ args["{"..name.." up_gb}"] = math.floor(up/1024/1024/1024*10)/10
+ end
+
+ -- Store totals
+ nets[name][1] = recv
+ nets[name][2] = send
+ end
+ end
+ f:close()
+
+ return args
+end
+-- }}}
diff --git a/org.lua b/org.lua
new file mode 100644
index 0000000..5632179
--- /dev/null
+++ b/org.lua
@@ -0,0 +1,70 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+-- * Derived from org-awesome, copyright of Damien Leone
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { open = io.open }
+local string = { find = string.find }
+local os = {
+ time = os.time,
+ date = os.date
+}
+-- }}}
+
+
+-- Org: provides agenda statistics for Emacs org-mode
+module("vicious.org")
+
+
+-- {{{ OrgMode widget type
+function worker(format, files)
+ -- Compute delays
+ local today = os.time{ year=os.date("%Y"), month=os.date("%m"), day=os.date("%d") }
+ local soon = today + 24 * 3600 * 3 -- 3 days ahead is close
+ local future = today + 24 * 3600 * 7 -- 7 days ahead is maximum
+
+ -- Initialise count table
+ local count = {
+ past = 0,
+ today = 0,
+ soon = 0,
+ future = 0
+ }
+
+ -- Get data from agenda files
+ for i=1, #files do
+ local f = io.open(files[i])
+
+ -- Parse the agenda
+ for line in f:lines() do
+ local scheduled = string.find(line, "SCHEDULED:")
+ local closed = string.find(line, "CLOSED:")
+ local deadline = string.find(line, "DEADLINE:")
+
+ if (scheduled and not closed) or (deadline and not closed) then
+ local b, e, y, m, d = string.find(line, "(%d%d%d%d)-(%d%d)-(%d%d)")
+
+ -- Enumerate agenda items
+ if b then
+ local t = os.time{ year = y, month = m, day = d }
+
+ if t < today then
+ count.past = count.past + 1
+ elseif t == today then
+ count.today = count.today + 1
+ elseif t <= soon then
+ count.soon = count.soon + 1
+ elseif t <= future then
+ count.future = count.future + 1
+ end
+ end
+ end
+ end
+ f:close()
+ end
+
+ return {count.past, count.today, count.soon, count.future}
+end
+-- }}}
diff --git a/pacman.lua b/pacman.lua
new file mode 100644
index 0000000..0d8f80a
--- /dev/null
+++ b/pacman.lua
@@ -0,0 +1,38 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local tonumber = tonumber
+local io = { popen = io.popen }
+-- }}}
+
+
+-- Pacman: provides number of pending updates on Arch Linux
+module("vicious.pacman")
+
+
+-- {{{ Pacman widget type
+function worker(format)
+ -- Check if updates are available
+ local f = io.popen("pacman -Qu")
+
+ -- Initialise updates
+ local updates = nil
+
+ -- Get data
+ for line in f:lines() do
+ -- If there are 'Targets:' then updates are available,
+ -- number is provided, we don't have to count packages
+ updates = line:match("^Targets[%s]%(([%d]+)%)") or 0
+ -- If the count changed then break out of the loop
+ if tonumber(updates) > 0 then
+ break
+ end
+ end
+ f:close()
+
+ return {updates}
+end
+-- }}}
diff --git a/thermal.lua b/thermal.lua
new file mode 100644
index 0000000..02b1f54
--- /dev/null
+++ b/thermal.lua
@@ -0,0 +1,27 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { open = io.open }
+-- }}}
+
+
+-- Thermal: provides temperature levels of ACPI thermal zones
+module("vicious.thermal")
+
+
+-- {{{ Thermal widget type
+function worker(format, thermal_zone)
+ -- Get thermal zone
+ local f = io.open("/proc/acpi/thermal_zone/" .. thermal_zone .. "/temperature")
+ local line = f:read()
+ f:close()
+
+ -- Get temperature data
+ local temperature = line:match("[%d]?[%d]?[%d]")
+
+ return {temperature}
+end
+-- }}}
diff --git a/uptime.lua b/uptime.lua
new file mode 100644
index 0000000..eae1d35
--- /dev/null
+++ b/uptime.lua
@@ -0,0 +1,51 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local tonumber = tonumber
+local io = { open = io.open }
+local math = { floor = math.floor }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Uptime: provides system uptime information
+module("vicious.uptime")
+
+
+-- {{{ Uptime widget type
+function worker(format, padding)
+ -- Get /proc/uptime
+ local f = io.open("/proc/uptime")
+ local line = f:read()
+ f:close()
+
+ -- Format data
+ local total_uptime = math.floor(tonumber(line:match("[%d%.]+")))
+
+ local uptime_days = math.floor(total_uptime / (3600 * 24))
+ local uptime_hours = math.floor((total_uptime % (3600 * 24)) / 3600)
+ local uptime_minutes = math.floor(((total_uptime % (3600 * 24)) % 3600) / 60)
+ local uptime_seconds = math.floor(((total_uptime % (3600 * 24)) % 3600) % 60)
+
+ if padding then
+ if type(padding) == "table" then
+ total_uptime = helpers.padd(total_uptime, padding[1])
+ uptime_days = helpers.padd(uptime_days, padding[2])
+ uptime_hours = helpers.padd(uptime_hours, padding[3])
+ uptime_minutes = helpers.padd(uptime_minutes, padding[4])
+ uptime_seconds = helpers.padd(uptime_seconds, padding[5])
+ else
+ total_uptime = helpers.padd(total_uptime, padding)
+ uptime_days = helpers.padd(uptime_days, padding)
+ uptime_hours = helpers.padd(uptime_hours, padding)
+ uptime_minutes = helpers.padd(uptime_minutes, padding)
+ uptime_seconds = helpers.padd(uptime_seconds, padding)
+ end
+ end
+
+ return {total_uptime, uptime_days, uptime_hours, uptime_minutes, uptime_seconds}
+end
+-- }}}
diff --git a/volume.lua b/volume.lua
new file mode 100644
index 0000000..fd02b76
--- /dev/null
+++ b/volume.lua
@@ -0,0 +1,33 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { popen = io.popen }
+local string = { match = string.match }
+-- }}}
+
+
+-- Volume: provides volume levels of requested ALSA mixers
+module("vicious.volume")
+
+
+-- {{{ Volume widget type
+function worker(format, channel)
+ -- Get mixer data
+ local f = io.popen("amixer get " .. channel)
+ local mixer = f:read("*all")
+ f:close()
+
+ -- Get volume level
+ local volume_level = string.match(mixer, "([%d]?[%d]?[%d])%%")
+
+ -- Don't break progressbars
+ if volume_level == nil then
+ return {0}
+ end
+
+ return {volume_level}
+end
+-- }}}
diff --git a/wifi.lua b/wifi.lua
new file mode 100644
index 0000000..35289dd
--- /dev/null
+++ b/wifi.lua
@@ -0,0 +1,62 @@
+----------------------------------------------------------
+-- Licensed under the GNU General Public License version 2
+-- * Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
+----------------------------------------------------------
+
+-- {{{ Grab environment
+local io = { popen = io.popen }
+local string = {
+ find = string.find,
+ match = string.match
+}
+-- }}}
+
+
+-- Wifi: provides wireless information for a requested interface
+module("vicious.wifi")
+
+
+-- {{{ Wireless widget type
+function worker(format, iface)
+ -- Get data from iwconfig, on distributions where it is executable
+ -- by users, and /sbin or /usr/sbin is in their path
+ local f = io.popen("iwconfig " .. iface)
+ local iw = f:read("*all")
+ f:close()
+
+ -- Setup tables
+ local winfo = {
+ ["{ssid}"] = "N/A",
+ ["{mode}"] = "N/A",
+ ["{chan}"] = "N/A",
+ ["{rate}"] = "N/A",
+ ["{link}"] = "N/A",
+ ["{sign}"] = "N/A"
+ }
+
+ -- Check if iwconfig wasn't found, can't be executed or the
+ -- interface is not a wireless one
+ if iw == nil or string.find(iw, "No such device") then
+ return winfo
+ else
+ -- The output differs from system to system, some stats can
+ -- be separated by =, and not all drivers report all stats
+ winfo["{ssid}"] = -- SSID can have almost anything in it
+ string.match(iw, 'ESSID[=:]"([%w]+[%s]*[%w]*]*)"') or winfo["{ssid}"]
+ winfo["{mode}"] = -- Modes are simple, but also match the "-" in Ad-Hoc
+ string.match(iw, "Mode[=:]([%w%-]*)") or winfo["{mode}"]
+ winfo["{chan}"] = -- Channels are plain digits
+ string.match(iw, "Channel[=:]([%d]+)") or winfo["{chan}"]
+ winfo["{rate}"] = -- Bitrate can start with a space and we want to display Mb/s
+ string.match(iw, "Bit Rate[=:]([%s]?[%d%.]*[%s][%/%a]+)") or winfo["{rate}"]
+-- winfo["{link}"] = -- Link quality can contain a slash: 32/100
+-- string.match(iw, "Link Quality[=:]([%d]+[%/%d]*)") or winfo["{link}"]
+ winfo["{link}"] = -- * match only the first number, great data for a progressbar
+ string.match(iw, "Link Quality[=:]([%d]+)") or winfo["{link}"]
+ winfo["{sign}"] = -- Signal level can be a negative value, also display decibel notation
+ string.match(iw, "Signal level[=:]([%-%d]+[%s][%a]*)") or winfo["{sign}"]
+ end
+
+ return winfo
+end
+-- }}}