]> 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                                                   
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     notification_preset = {}
33 }
34
35 local project_path       = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
36 local localizations_path = project_path .. 'localizations/'
37 local icon_path          = project_path .. 'icons/'
38 local api_url            = 'http://weather.yahooapis.com/forecastrss'
39 local units_set          = '?u=c&w=' -- Default is Celsius
40 local language           = string.match(os.getenv("LANG"), "(%S*$*)[.]")
41 local weather_data       = nil
42 local notification       = nil
43 local city_id            = nil
44 local sky                = nil
45 local settings           = function() end
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 2 '"
50                        .. url .. "'" )
51     local text = f:read("*all")
52     f:close()
53
54     -- handle no suitable icon found
55     yawn.icon:set_image(icon_path .. "na.png")
56
57     -- In case of no connection or invalid city ID
58     -- widgets won't display
59     if text == "" or text:match("City not found")
60     then
61         if text == "" then
62             weather_data = "Service not available at the moment."
63             yawn.widget:set_text("N/A")
64         else
65             weather_data = "City not found!\n" ..
66                            "Are you sure " .. city_id ..
67                            " is your Yahoo city ID?"
68             yawn.widget:set_text("?")
69         end
70         return
71     end
72
73     -- Processing raw data
74     weather_data = text:gsub("<.->", "")
75     weather_data = weather_data:match("Current Conditions:.-Full")
76     weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
77     weather_data = weather_data:gsub("Forecast:.-\n", "")
78     weather_data = weather_data:gsub("\nFull", "")
79     weather_data = weather_data:gsub("[\n]$", "")
80     weather_data = weather_data:gsub(" [-] " , ": ")
81     weather_data = weather_data:gsub("[.]", ",")
82     weather_data = weather_data:gsub("High: ", "")
83     weather_data = weather_data:gsub(" Low: ", " - ")
84
85     -- Getting info for text widget
86     local now      = weather_data:sub(weather_data:find("Now:")+5,
87                      weather_data:find("\n")-1)
88     forecast       = now:sub(1, now:find(",")-1)
89     units          = now:sub(now:find(",")+2, -2)
90
91     -- Day/Night icon change
92     local hour = tonumber(os.date("%H"))
93     sky = icon_path
94
95     if forecast == "Clear"         or
96        forecast == "Fair"          or
97        forecast == "Partly Cloudy" or
98        forecast == "Mostly Cloudy"
99        then
100            if hour >= 6 and hour <= 18
101            then
102                sky = sky .. "Day"
103            else
104                sky = sky .. "Night"
105            end
106     end
107
108     sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
109
110     -- Localization
111     local f = io.open(localizations_path .. language, "r")
112     if language:find("en_") == nil and f ~= nil
113     then
114         f:close()
115         for line in io.lines(localizations_path .. language)
116         do
117             word = string.sub(line, 1, line:find("|")-1)
118             translation = string.sub(line, line:find("|")+1)
119             weather_data = string.gsub(weather_data, word, translation)
120         end
121     end
122
123     -- Finally setting infos
124     yawn.icon:set_image(sky)
125     widget = wibox.widget.textbox()
126
127     forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n")
128     units = units:gsub(" ", "")
129     notification_preset = {}
130     -- anche notification preset, con fg, bg e position
131
132     settings()
133
134     yawn.widget = widget
135     yawn.notification_preset = notification_preset 
136 end
137
138 function yawn.hide()
139     if notification ~= nil then
140         naughty.destroy(notification)
141         notification = nil
142     end
143 end
144
145 function yawn.show(t_out)
146     if yawn.widget._layout.text == "?"
147     then
148         fetch_weather(settings)
149     end
150
151     yawn.hide()
152
153     notification = naughty.notify({
154         preset = yawn.notification_preset,
155         text = weather_data,
156         icon = sky,
157         timeout = t_out
158     })
159 end
160
161 function yawn.register(id, args)
162     local args     = args or {}
163     local timeout  = args.timeout or 600
164     settings       = args.settings or function() end
165
166     if args.u == "f" then units_set = '?u=f&w=' end
167
168     city_id = id
169
170     newtimer("yawn", timeout, fetch_weather)
171
172     yawn.icon:connect_signal("mouse::enter", function()
173         yawn.show(0)
174     end)
175     yawn.icon:connect_signal("mouse::leave", function()
176         yawn.hide()
177     end)
178
179     return { icon = yawn.icon, widget = yawn.widget }
180 end
181
182 function yawn.attach(widget, id, args)
183     yawn.register(id, args)
184
185     widget:connect_signal("mouse::enter", function()
186         yawn.show(0)
187     end)
188
189     widget:connect_signal("mouse::leave", function()
190         yawn.hide()
191     end)
192 end
193
194 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })