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

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