My configuration files for Debian/Ubuntu applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

147 line
5.5 KiB

  1. --[[
  2. Licensed under GNU General Public License v2
  3. * (c) 2015, Luca CPZ
  4. --]]
  5. local helpers = require("lain.helpers")
  6. local json = require("lain.util").dkjson
  7. local focused = require("awful.screen").focused
  8. local naughty = require("naughty")
  9. local wibox = require("wibox")
  10. local math = math
  11. local os = os
  12. local string = string
  13. local type = type
  14. local tonumber = tonumber
  15. -- OpenWeatherMap
  16. -- current weather and X-days forecast
  17. -- lain.widget.weather
  18. local function factory(args)
  19. args = args or {}
  20. local weather = { widget = args.widget or wibox.widget.textbox() }
  21. local APPID = args.APPID -- mandatory
  22. local timeout = args.timeout or 60 * 15 -- 15 min
  23. local current_call = args.current_call or "curl -s 'https://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s&APPID=%s'"
  24. local forecast_call = args.forecast_call or "curl -s 'https://api.openweathermap.org/data/2.5/forecast?id=%s&units=%s&lang=%s&APPID=%s'"
  25. local city_id = args.city_id or 0 -- placeholder
  26. local units = args.units or "metric"
  27. local lang = args.lang or "en"
  28. local cnt = args.cnt or 5
  29. local icons_path = args.icons_path or helpers.icons_dir .. "openweathermap/"
  30. local notification_preset = args.notification_preset or {}
  31. local notification_text_fun = args.notification_text_fun or
  32. function (wn)
  33. local day = os.date("%a %d", wn["dt"])
  34. local temp = math.floor(wn["main"]["temp"])
  35. local desc = wn["weather"][1]["description"]
  36. return string.format("<b>%s</b>: %s, %d ", day, desc, temp)
  37. end
  38. local weather_na_markup = args.weather_na_markup or " N/A "
  39. local followtag = args.followtag or false
  40. local showpopup = args.showpopup or "on"
  41. local settings = args.settings or function() end
  42. weather.widget:set_markup(weather_na_markup)
  43. weather.icon_path = icons_path .. "na.png"
  44. weather.icon = wibox.widget.imagebox(weather.icon_path)
  45. function weather.show(seconds)
  46. weather.hide()
  47. if followtag then
  48. notification_preset.screen = focused()
  49. end
  50. if not weather.notification_text then
  51. weather.update()
  52. weather.forecast_update()
  53. end
  54. weather.notification = naughty.notify {
  55. preset = notification_preset,
  56. text = weather.notification_text,
  57. icon = weather.icon_path,
  58. timeout = type(seconds) == "number" and seconds or notification_preset.timeout
  59. }
  60. end
  61. function weather.hide()
  62. if weather.notification then
  63. naughty.destroy(weather.notification)
  64. weather.notification = nil
  65. end
  66. end
  67. function weather.attach(obj)
  68. obj:connect_signal("mouse::enter", function()
  69. weather.show(0)
  70. end)
  71. obj:connect_signal("mouse::leave", function()
  72. weather.hide()
  73. end)
  74. end
  75. function weather.forecast_update()
  76. local cmd = string.format(forecast_call, city_id, units, lang, APPID)
  77. helpers.async(cmd, function(f)
  78. local err
  79. weather_now, _, err = json.decode(f, 1, nil)
  80. if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
  81. weather.notification_text = ""
  82. for i = 1, weather_now["cnt"], weather_now["cnt"]//cnt do
  83. weather.notification_text = weather.notification_text ..
  84. notification_text_fun(weather_now["list"][i])
  85. if i < weather_now["cnt"] then
  86. weather.notification_text = weather.notification_text .. "\n"
  87. end
  88. end
  89. end
  90. end)
  91. end
  92. function weather.update()
  93. local cmd = string.format(current_call, city_id, units, lang, APPID)
  94. helpers.async(cmd, function(f)
  95. local err
  96. weather_now, _, err = json.decode(f, 1, nil)
  97. if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
  98. local sunrise = tonumber(weather_now["sys"]["sunrise"])
  99. local sunset = tonumber(weather_now["sys"]["sunset"])
  100. local icon = weather_now["weather"][1]["icon"]
  101. local loc_now = os.time()
  102. if sunrise <= loc_now and loc_now <= sunset then
  103. icon = string.gsub(icon, "n", "d")
  104. else
  105. icon = string.gsub(icon, "d", "n")
  106. end
  107. weather.icon_path = icons_path .. icon .. ".png"
  108. widget = weather.widget
  109. settings()
  110. else
  111. weather.icon_path = icons_path .. "na.png"
  112. weather.widget:set_markup(weather_na_markup)
  113. end
  114. weather.icon:set_image(weather.icon_path)
  115. end)
  116. end
  117. if showpopup == "on" then weather.attach(weather.widget) end
  118. weather.timer = helpers.newtimer("weather-" .. city_id, timeout, weather.update, false, true)
  119. weather.timer_forecast = helpers.newtimer("weather_forecast-" .. city_id, timeout, weather.forecast_update, false, true)
  120. return weather
  121. end
  122. return factory