]> 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:

148f547524cd92dc217caa618cfa6b36f16c129e
[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*$*)[.]") or "en_US" -- if LANG is not set
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 yawn_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 3 '" .. url .. "'" )
51     local text = f:read("*a")
52     f:close()
53
54     -- In case of no connection or invalid city ID
55     -- widgets won't display
56     if text == "" or text:match("City not found")
57     then
58         yawn.icon:set_image(icon_path .. "na.png")
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") or ""
74
75     -- may still happens in case of bad connectivity
76     if weather_data == "" then
77         yawn.icon:set_image(icon_path .. "na.png")
78         yawn.widget:set_text(" ? ")
79         return
80     end
81
82     weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
83     weather_data = weather_data:gsub("Forecast:.-\n", "")
84     weather_data = weather_data:gsub("\nFull", "")
85     weather_data = weather_data:gsub("[\n]$", "")
86     weather_data = weather_data:gsub(" [-] " , ": ")
87     weather_data = weather_data:gsub("[.]", ",")
88     weather_data = weather_data:gsub("High: ", "")
89     weather_data = weather_data:gsub(" Low: ", " - ")
90
91     -- Getting info for text widget
92     local now      = weather_data:sub(weather_data:find("Now:")+5,
93                      weather_data:find("\n")-1)
94     forecast       = now:sub(1, now:find(",")-1)
95     units          = now:sub(now:find(",")+2, -2)
96
97     -- Day/Night icon change
98     local hour = tonumber(os.date("%H"))
99     sky = icon_path
100
101     if forecast == "Clear"         or
102        forecast == "Fair"          or
103        forecast == "Partly Cloudy" or
104        forecast == "Mostly Cloudy"
105        then
106            if hour >= 6 and hour <= 18
107            then
108                sky = sky .. "Day"
109            else
110                sky = sky .. "Night"
111            end
112     end
113
114     sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
115
116     -- In case there's no defined icon for current forecast
117     if io.open(sky) == nil then
118         sky = icon_path .. "na.png"
119     end
120
121     -- Localization
122     local f = io.open(localizations_path .. language, "r")
123     if language:find("en_") == nil and f ~= nil
124     then
125         f:close()
126         for line in io.lines(localizations_path .. language)
127         do
128             word = string.sub(line, 1, line:find("|")-1)
129             translation = string.sub(line, line:find("|")+1)
130             weather_data = string.gsub(weather_data, word, translation)
131         end
132     end
133
134     -- Finally setting infos
135     yawn.icon:set_image(sky)
136     widget = yawn.widget
137
138     _data = weather_data:match(": %S.-,") or weather_data
139     forecast = _data:gsub(": ", ""):gsub(",", "")
140     units = units:gsub(" ", "")
141
142     settings()
143 end
144
145 function yawn.hide()
146     if notification ~= nil then
147         naughty.destroy(notification)
148         notification = nil
149     end
150 end
151
152 function yawn.show(t_out)
153     if yawn.widget._layout.text:match("?")
154     then
155         fetch_weather(settings)
156     end
157
158     yawn.hide()
159
160     notification = naughty.notify({
161         preset = yawn_notification_preset,
162         text = weather_data,
163         icon = sky,
164         timeout = t_out,
165         screen = client.focus and client.focus.screen or 1
166     })
167 end
168
169 function yawn.register(id, args)
170     local args     = args or {}
171     local timeout  = args.timeout or 600
172     settings       = args.settings or function() end
173
174     if args.u == "f" then units_set = '?u=f&w=' end
175
176     city_id = id
177
178     newtimer("yawn", timeout, fetch_weather)
179
180     yawn.icon:connect_signal("mouse::enter", function()
181         yawn.show(0)
182     end)
183     yawn.icon:connect_signal("mouse::leave", function()
184         yawn.hide()
185     end)
186
187     return yawn
188 end
189
190 function yawn.attach(widget, id, args)
191     yawn.register(id, args)
192
193     widget:connect_signal("mouse::enter", function()
194         yawn.show(0)
195     end)
196
197     widget:connect_signal("mouse::leave", function()
198         yawn.hide()
199     end)
200 end
201
202 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })