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

af7befcd96e67ec9b578bb9230f4fe504ee30918
[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 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("*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     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     forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "")
139     units = units:gsub(" ", "")
140
141     settings()
142 end
143
144 function yawn.hide()
145     if notification ~= nil then
146         naughty.destroy(notification)
147         notification = nil
148     end
149 end
150
151 function yawn.show(t_out)
152     if yawn.widget._layout.text:match("?")
153     then
154         fetch_weather(settings)
155     end
156
157     yawn.hide()
158
159     notification = naughty.notify({
160         preset = yawn_notification_preset,
161         text = weather_data,
162         icon = sky,
163         timeout = t_out
164     })
165 end
166
167 function yawn.register(id, args)
168     local args     = args or {}
169     local timeout  = args.timeout or 600
170     settings       = args.settings or function() end
171
172     if args.u == "f" then units_set = '?u=f&w=' end
173
174     city_id = id
175
176     newtimer("yawn", timeout, fetch_weather)
177
178     yawn.icon:connect_signal("mouse::enter", function()
179         yawn.show(0)
180     end)
181     yawn.icon:connect_signal("mouse::leave", function()
182         yawn.hide()
183     end)
184
185     return yawn
186 end
187
188 function yawn.attach(widget, id, args)
189     yawn.register(id, args)
190
191     widget:connect_signal("mouse::enter", function()
192         yawn.show(0)
193     end)
194
195     widget:connect_signal("mouse::leave", function()
196         yawn.hide()
197     end)
198 end
199
200 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })