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

wiki updated
[etc/awesome.git] / widgets / yawn / init.lua
1 --[[
2                                                   
3      Licensed under GNU General Public License v2 
4       * (c) 2013, Luke Bonham                     
5                                                   
6 --]]
7
8 local newtimer     = require("lain.helpers").newtimer
9
10 local naughty      = require("naughty")
11 local wibox        = require("wibox")
12
13 local debug        = { getinfo = debug.getinfo }
14 local io           = io
15 local os           = { date    = os.date,
16                        getenv  = os.getenv }
17 local string       = { find    = string.find,
18                        match   = string.match,
19                        gsub    = string.gsub,
20                        sub     = string.sub }
21 local tonumber     = tonumber
22
23 local setmetatable = setmetatable
24
25 -- YAhoo! Weather Notification
26 -- lain.widgets.yawn
27 local yawn =
28 {
29     icon   = wibox.widget.imagebox(),
30     widget = wibox.widget.textbox('')
31 }
32
33 local project_path        = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
34 local localizations_path  = project_path .. 'localizations/'
35 local icon_path           = project_path .. 'icons/'
36 local api_url             = 'http://weather.yahooapis.com/forecastrss'
37 local units_set           = '?u=c&w=' -- Default is Celsius
38 local language            = string.match(os.getenv("LANG"), "(%S*$*)[.]")
39 local weather_data        = nil
40 local notification        = nil
41 local city_id             = nil
42 local sky                 = nil
43 local settings            = function() end
44
45 yawn_notification_preset = {}
46
47 local function fetch_weather()
48     local url = api_url .. units_set .. city_id
49     local f = io.popen("curl --connect-timeout 1 -fsm 1 '"
50                        .. url .. "'" )
51     local text = f:read("*all")
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     else
120         io.close(f)
121     end
122
123     -- Localization
124     local f = io.open(localizations_path .. language, "r")
125     if language:find("en_") == nil and f ~= nil
126     then
127         f:close()
128         for line in io.lines(localizations_path .. language)
129         do
130             word = string.sub(line, 1, line:find("|")-1)
131             translation = string.sub(line, line:find("|")+1)
132             weather_data = string.gsub(weather_data, word, translation)
133         end
134     end
135
136     -- Finally setting infos
137     yawn.icon:set_image(sky)
138     widget = yawn.widget
139
140     forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "")
141     units = units:gsub(" ", "")
142
143     settings()
144 end
145
146 function yawn.hide()
147     if notification ~= nil then
148         naughty.destroy(notification)
149         notification = nil
150     end
151 end
152
153 function yawn.show(t_out)
154     if yawn.widget._layout.text == "?"
155     then
156         fetch_weather(settings)
157     end
158
159     yawn.hide()
160
161     notification = naughty.notify({
162         preset = yawn_notification_preset,
163         text = weather_data,
164         icon = sky,
165         timeout = t_out
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 })