]> git.madduck.net Git - etc/awesome.git/blob - widgets/yawn/init.lua

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:

4d14966b17e827df82d1963ece8dd5989f3aaa00
[etc/awesome.git] / widgets / yawn / init.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013, Luke Bonham                     
6                                                   
7 --]]
8
9 local newtimer     = require("lain.helpers").newtimer
10
11 local naughty      = require("naughty")
12 local wibox        = require("wibox")
13
14 local debug        = { getinfo = debug.getinfo }
15 local io           = io
16 local os           = { date    = os.date,
17                        getenv  = os.getenv }
18 local string       = { find    = string.find,
19                        match   = string.match,
20                        gsub    = string.gsub,
21                        sub     = string.sub }
22 local tonumber     = tonumber
23
24 local setmetatable = setmetatable
25
26 -- YAhoo! Weather Notification
27 -- lain.widgets.yawn
28 local yawn =
29 {
30     icon   = wibox.widget.imagebox(),
31     widget = wibox.widget.textbox('')
32 }
33
34 local project_path        = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
35 local localizations_path  = project_path .. 'localizations/'
36 local icon_path           = project_path .. 'icons/'
37 local api_url             = 'http://weather.yahooapis.com/forecastrss'
38 local units_set           = '?u=c&w=' -- Default is Celsius
39 local language            = string.match(os.getenv("LANG"), "(%S*$*)[.]")
40 local weather_data        = nil
41 local notification        = nil
42 local city_id             = nil
43 local sky                 = nil
44 local settings            = function() end
45
46 notification_preset = {}
47
48 local function fetch_weather()
49     local url = api_url .. units_set .. city_id
50     local f = io.popen("curl --connect-timeout 1 -fsm 1 '"
51                        .. url .. "'" )
52     local text = f:read("*all")
53     f:close()
54
55     -- In case of no connection or invalid city ID
56     -- widgets won't display
57     if text == "" or text:match("City not found")
58     then
59         if text == "" then
60             weather_data = "Service not available at the moment."
61             yawn.widget:set_text("N/A")
62         else
63             weather_data = "City not found!\n" ..
64                            "Are you sure " .. city_id ..
65                            " is your Yahoo city ID?"
66             yawn.widget:set_text("?")
67         end
68         return
69     end
70
71     -- Processing raw data
72     weather_data = text:gsub("<.->", "")
73     weather_data = weather_data:match("Current Conditions:.-Full")
74     weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
75     weather_data = weather_data:gsub("Forecast:.-\n", "")
76     weather_data = weather_data:gsub("\nFull", "")
77     weather_data = weather_data:gsub("[\n]$", "")
78     weather_data = weather_data:gsub(" [-] " , ": ")
79     weather_data = weather_data:gsub("[.]", ",")
80     weather_data = weather_data:gsub("High: ", "")
81     weather_data = weather_data:gsub(" Low: ", " - ")
82
83     -- Getting info for text widget
84     local now      = weather_data:sub(weather_data:find("Now:")+5,
85                      weather_data:find("\n")-1)
86     forecast       = now:sub(1, now:find(",")-1)
87     units          = now:sub(now:find(",")+2, -2)
88
89     -- Day/Night icon change
90     local hour = tonumber(os.date("%H"))
91     sky = icon_path
92
93     if forecast == "Clear"         or
94        forecast == "Fair"          or
95        forecast == "Partly Cloudy" or
96        forecast == "Mostly Cloudy"
97        then
98            if hour >= 6 and hour <= 18
99            then
100                sky = sky .. "Day"
101            else
102                sky = sky .. "Night"
103            end
104     end
105
106     sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
107
108     -- In case there's no defined icon for current forecast
109     f = io.popen(sky)
110     if f == nil then
111         sky = icon_path .. "na.png"
112     else
113         io.close(f)
114     end
115
116     -- Localization
117     local f = io.open(localizations_path .. language, "r")
118     if language:find("en_") == nil and f ~= nil
119     then
120         f:close()
121         for line in io.lines(localizations_path .. language)
122         do
123             word = string.sub(line, 1, line:find("|")-1)
124             translation = string.sub(line, line:find("|")+1)
125             weather_data = string.gsub(weather_data, word, translation)
126         end
127     end
128
129     -- Finally setting infos
130     yawn.icon:set_image(sky)
131     widget = yawn.widget
132
133     forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n")
134     units = units:gsub(" ", "")
135
136     settings()
137 end
138
139 function yawn.hide()
140     if notification ~= nil then
141         naughty.destroy(notification)
142         notification = nil
143     end
144 end
145
146 function yawn.show(t_out)
147     if yawn.widget._layout.text == "?"
148     then
149         fetch_weather(settings)
150     end
151
152     yawn.hide()
153
154     notification = naughty.notify({
155         preset = notification_preset,
156         text = weather_data,
157         icon = sky,
158         timeout = t_out
159     })
160 end
161
162 function yawn.register(id, args)
163     local args     = args or {}
164     local timeout  = args.timeout or 600
165     settings       = args.settings or function() end
166
167     if args.u == "f" then units_set = '?u=f&w=' end
168
169     city_id = id
170
171     newtimer("yawn", timeout, fetch_weather)
172
173     yawn.icon:connect_signal("mouse::enter", function()
174         yawn.show(0)
175     end)
176     yawn.icon:connect_signal("mouse::leave", function()
177         yawn.hide()
178     end)
179
180     return yawn
181 end
182
183 function yawn.attach(widget, id, args)
184     yawn.register(id, args)
185
186     widget:connect_signal("mouse::enter", function()
187         yawn.show(0)
188     end)
189
190     widget:connect_signal("mouse::leave", function()
191         yawn.hide()
192     end)
193 end
194
195 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })