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

4109d6c90152903274b460405034d92152e02f47
[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("*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     _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     })
166 end
167
168 function yawn.register(id, args)
169     local args     = args or {}
170     local timeout  = args.timeout or 600
171     settings       = args.settings or function() end
172
173     if args.u == "f" then units_set = '?u=f&w=' end
174
175     city_id = id
176
177     newtimer("yawn", timeout, fetch_weather)
178
179     yawn.icon:connect_signal("mouse::enter", function()
180         yawn.show(0)
181     end)
182     yawn.icon:connect_signal("mouse::leave", function()
183         yawn.hide()
184     end)
185
186     return yawn
187 end
188
189 function yawn.attach(widget, id, args)
190     yawn.register(id, args)
191
192     widget:connect_signal("mouse::enter", function()
193         yawn.show(0)
194     end)
195
196     widget:connect_signal("mouse::leave", function()
197         yawn.hide()
198     end)
199 end
200
201 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })