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

d37fc44738d547426ef3a216ed907d4100ea51ed
[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 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         yawn.icon:set_image(icon_path .. "na.png")
60         if text == "" then
61             weather_data = "Service not available at the moment."
62             yawn.widget:set_text("N/A")
63         else
64             weather_data = "City not found!\n" ..
65                            "Are you sure " .. city_id ..
66                            " is your Yahoo city ID?"
67             yawn.widget:set_text("?")
68         end
69         return
70     end
71
72     -- Processing raw data
73     weather_data = text:gsub("<.->", "")
74     weather_data = weather_data:match("Current Conditions:.-Full")
75     weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
76     weather_data = weather_data:gsub("Forecast:.-\n", "")
77     weather_data = weather_data:gsub("\nFull", "")
78     weather_data = weather_data:gsub("[\n]$", "")
79     weather_data = weather_data:gsub(" [-] " , ": ")
80     weather_data = weather_data:gsub("[.]", ",")
81     weather_data = weather_data:gsub("High: ", "")
82     weather_data = weather_data:gsub(" Low: ", " - ")
83
84     -- Getting info for text widget
85     local now      = weather_data:sub(weather_data:find("Now:")+5,
86                      weather_data:find("\n")-1)
87     forecast       = now:sub(1, now:find(",")-1)
88     units          = now:sub(now:find(",")+2, -2)
89
90     -- Day/Night icon change
91     local hour = tonumber(os.date("%H"))
92     sky = icon_path
93
94     if forecast == "Clear"         or
95        forecast == "Fair"          or
96        forecast == "Partly Cloudy" or
97        forecast == "Mostly Cloudy"
98        then
99            if hour >= 6 and hour <= 18
100            then
101                sky = sky .. "Day"
102            else
103                sky = sky .. "Night"
104            end
105     end
106
107     sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
108
109     -- In case there's no defined icon for current forecast
110     f = io.popen(sky)
111     if f == nil then
112         sky = icon_path .. "na.png"
113     else
114         io.close(f)
115     end
116
117     -- Localization
118     local f = io.open(localizations_path .. language, "r")
119     if language:find("en_") == nil and f ~= nil
120     then
121         f:close()
122         for line in io.lines(localizations_path .. language)
123         do
124             word = string.sub(line, 1, line:find("|")-1)
125             translation = string.sub(line, line:find("|")+1)
126             weather_data = string.gsub(weather_data, word, translation)
127         end
128     end
129
130     -- Finally setting infos
131     yawn.icon:set_image(sky)
132     widget = yawn.widget
133
134     forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "")
135     units = units:gsub(" ", "")
136
137     naughty.notify({text=forecast, timeout=10})
138     naughty.notify({text=units, timeout=10})
139     settings()
140 end
141
142 function yawn.hide()
143     if notification ~= nil then
144         naughty.destroy(notification)
145         notification = nil
146     end
147 end
148
149 function yawn.show(t_out)
150     if yawn.widget._layout.text == "?"
151     then
152         fetch_weather(settings)
153     end
154
155     yawn.hide()
156
157     notification = naughty.notify({
158         preset = yawn_notification_preset,
159         text = weather_data,
160         icon = sky,
161         timeout = t_out
162     })
163 end
164
165 function yawn.register(id, args)
166     local args     = args or {}
167     local timeout  = args.timeout or 600
168     settings       = args.settings or function() end
169
170     if args.u == "f" then units_set = '?u=f&w=' end
171
172     city_id = id
173
174     newtimer("yawn", timeout, fetch_weather)
175
176     yawn.icon:connect_signal("mouse::enter", function()
177         yawn.show(0)
178     end)
179     yawn.icon:connect_signal("mouse::leave", function()
180         yawn.hide()
181     end)
182
183     return yawn
184 end
185
186 function yawn.attach(widget, id, args)
187     yawn.register(id, args)
188
189     widget:connect_signal("mouse::enter", function()
190         yawn.show(0)
191     end)
192
193     widget:connect_signal("mouse::leave", function()
194         yawn.hide()
195     end)
196 end
197
198 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })