summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--batteryarc-widget/README.md2
-rw-r--r--batteryarc-widget/batteryarc.lua2
-rw-r--r--bitbucket-widget/bitbucket.lua150
-rw-r--r--bitbucket-widget/check.svg1
-rw-r--r--bitbucket-widget/clipboard.svg1
-rw-r--r--bitbucket-widget/copy.svg1
-rw-r--r--bitbucket-widget/git-pull-request.svg1
-rw-r--r--bitbucket-widget/message-circle.svg1
-rw-r--r--bitbucket-widget/user.svg1
-rw-r--r--cpu-widget/README.md2
-rw-r--r--cpu-widget/cpu-widget.lua2
-rw-r--r--experiments/volume/arc-widget.lua37
-rw-r--r--experiments/volume/icon-and-text-widget.lua46
-rw-r--r--experiments/volume/icons/audio-volume-high-symbolic.svg88
-rw-r--r--experiments/volume/icons/audio-volume-low-symbolic.svg88
-rw-r--r--experiments/volume/icons/audio-volume-medium-symbolic.svg88
-rw-r--r--experiments/volume/icons/audio-volume-muted-symbolic.svg88
-rw-r--r--experiments/volume/utils.lua107
-rw-r--r--experiments/volume/volume-2.svg1
-rw-r--r--experiments/volume/volume.lua171
-rw-r--r--fs-widget/README.md10
-rw-r--r--gitlab-widget/gitlab.lua353
-rw-r--r--gitlab-widget/icons/check.svg1
-rw-r--r--gitlab-widget/icons/gitlab-icon.svg1
-rw-r--r--gitlab-widget/icons/message-circle.svg1
-rw-r--r--logout-widget/README.md16
-rw-r--r--logout-widget/logout-dracula.pngbin0 -> 44660 bytes
-rw-r--r--logout-widget/logout-outrun.pngbin26151 -> 49973 bytes
-rw-r--r--logout-widget/logout.lua39
-rw-r--r--logout-widget/screenshot.gifbin172152 -> 446468 bytes
-rw-r--r--weather-widget/README.md34
-rw-r--r--weather-widget/both.pngbin0 -> 31867 bytes
-rw-r--r--weather-widget/example1.png (renamed from weather-widget/screenshots/example1.png)bin46387 -> 46387 bytes
-rw-r--r--weather-widget/example2.png (renamed from weather-widget/screenshots/example2.png)bin26446 -> 26446 bytes
-rw-r--r--weather-widget/example_response.json1419
-rw-r--r--weather-widget/negative.pngbin0 -> 32058 bytes
-rw-r--r--weather-widget/screenshots/weather-widget.pngbin26906 -> 0 bytes
-rw-r--r--weather-widget/weather-widget.pngbin22673 -> 26906 bytes
-rw-r--r--weather-widget/weather.json1224
-rw-r--r--weather-widget/weather.lua119
40 files changed, 2791 insertions, 1304 deletions
diff --git a/batteryarc-widget/README.md b/batteryarc-widget/README.md
index de9255c..1a2a397 100644
--- a/batteryarc-widget/README.md
+++ b/batteryarc-widget/README.md
@@ -1,5 +1,7 @@
# Batteryarc widget
+[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/batteryarc)](https://github.com/streetturtle/awesome-wm-widgets/labels/batteryarc)
+
This widget is more informative version of [battery widget](https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget).
Depending of the battery status it could look following ways:
diff --git a/batteryarc-widget/batteryarc.lua b/batteryarc-widget/batteryarc.lua
index a4bb357..916c7b1 100644
--- a/batteryarc-widget/batteryarc.lua
+++ b/batteryarc-widget/batteryarc.lua
@@ -34,7 +34,7 @@ local function worker(args)
local medium_level_color = args.medium_level_color or '#c0ca33'
local charging_color = args.charging_color or '#43a047'
- local warning_msg_title = args.warning_msg_title or 'Huston, we have a problem'
+ local warning_msg_title = args.warning_msg_title or 'Houston, we have a problem'
local warning_msg_text = args.warning_msg_text or 'Battery is dying'
local warning_msg_position = args.warning_msg_position or 'bottom_right'
local warning_msg_icon = args.warning_msg_icon or HOME .. '/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg'
diff --git a/bitbucket-widget/bitbucket.lua b/bitbucket-widget/bitbucket.lua
index b871d6e..dc7a34d 100644
--- a/bitbucket-widget/bitbucket.lua
+++ b/bitbucket-widget/bitbucket.lua
@@ -19,8 +19,9 @@ local beautiful = require("beautiful")
local gfs = require("gears.filesystem")
local HOME_DIR = os.getenv("HOME")
+local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/bitbucket-widget/'
-local GET_PRS_CMD= [[bash -c "curl -s --show-error -n '%s/2.0/repositories/%s/%s/pullrequests?fields=values.title,values.links.html,values.author.display_name,values.author.uuid,values.author.links.avatar,values.source.branch,values.destination.branch&q=%%28author.uuid+%%3D+%%22%s%%22+OR+reviewers.uuid+%%3D+%%22%s%%22+%%29+AND+state+%%3D+%%22OPEN%%22' | jq '.[] | unique'"]]
+local GET_PRS_CMD= [[bash -c "curl -s --show-error -n '%s/2.0/repositories/%s/%s/pullrequests?fields=values.participants.approved,values.title,values.links.html,values.author.display_name,values.author.uuid,values.author.links.avatar,values.source.branch,values.destination.branch,values.comment_count,values.created_on&q=reviewers.uuid+%%3D+%%22%s%%22+AND+state+%%3D+%%22OPEN%%22' | jq '.[] '"]]
local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -L -n --create-dirs -o %s/.cache/awmw/bitbucket-widget/avatars/%s %s"]]
local bitbucket_widget = wibox.widget {
@@ -67,11 +68,54 @@ local popup = awful.popup{
widget = {}
}
+--- Converts string representation of date (2020-06-02T11:25:27Z) to date
+local function parse_date(date_str)
+ local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%Z"
+ local y, m, d, h, min, sec, mil = date_str:match(pattern)
+
+ return os.time{year = y, month = m, day = d, hour = h, min = min, sec = sec}
+end
+
+--- Converts seconds to "time ago" represenation, like '1 hour ago'
+local function to_time_ago(seconds)
+ local days = seconds / 86400
+ if days > 1 then
+ days = math.floor(days + 0.5)
+ return days .. (days == 1 and ' day' or ' days') .. ' ago'
+ end
+
+ local hours = (seconds % 86400) / 3600
+ if hours > 1 then
+ hours = math.floor(hours + 0.5)
+ return hours .. (hours == 1 and ' hour' or ' hours') .. ' ago'
+ end
+
+ local minutes = ((seconds % 86400) % 3600) / 60
+ if minutes > 1 then
+ minutes = math.floor(minutes + 0.5)
+ return minutes .. (minutes == 1 and ' minute' or ' minutes') .. ' ago'
+ end
+end
+
+local function ellipsize(text, length)
+ return (text:len() > length and length > 0)
+ and text:sub(0, length - 3) .. '...'
+ or text
+end
+
+local function count_approves(participants)
+ local res = 0
+ for i = 1, #participants do
+ if participants[i]['approved'] then res = res + 1 end
+ end
+ return res
+end
+
local function worker(args)
local args = args or {}
- local icon = args.icon or HOME_DIR .. '/.config/awesome/awesome-wm-widgets/bitbucket-widget/bitbucket-icon-gradient-blue.svg'
+ local icon = args.icon or WIDGET_DIR .. '/bitbucket-icon-gradient-blue.svg'
local host = args.host or show_warning('Bitbucket host is not set')
local uuid = args.uuid or show_warning('UUID is not set')
local workspace = args.workspace or show_warning('Workspace is not set')
@@ -129,52 +173,100 @@ local function worker(args)
bg = beautiful.bg_normal,
widget = wibox.container.background
})
+ local current_time = os.time(os.date("!*t"))
for _, pr in ipairs(result) do
local path_to_avatar = os.getenv("HOME") ..'/.cache/awmw/bitbucket-widget/avatars/' .. pr.author.uuid
+ local number_of_approves = count_approves(pr.participants)
local row = wibox.widget {
{
{
{
- {
- resize = true,
- image = path_to_avatar,
- forced_width = 40,
- forced_height = 40,
- widget = wibox.widget.imagebox
- },
- id = 'avatar',
- margins = 8,
- layout = wibox.container.margin
+ {
+ resize = true,
+ image = path_to_avatar,
+ forced_width = 40,
+ forced_height = 40,
+ widget = wibox.widget.imagebox
+ },
+ id = 'avatar',
+ margins = 8,
+ layout = wibox.container.margin
},
{
{
id = 'title',
- markup = '<b>' .. pr.title .. '</b>',
- widget = wibox.widget.textbox
+ markup = '<b>' .. ellipsize(pr.title, 50) .. '</b>',
+ widget = wibox.widget.textbox,
+ forced_width = 400
},
{
{
- text = pr.source.branch.name,
- widget = wibox.widget.textbox
- },
- {
- text = '->',
- widget = wibox.widget.textbox
+ {
+ {
+ text = ellipsize(pr.source.branch.name, 30),
+ widget = wibox.widget.textbox
+ },
+ {
+ text = '->',
+ widget = wibox.widget.textbox
+ },
+ {
+ text = pr.destination.branch.name,
+ widget = wibox.widget.textbox
+ },
+ spacing = 8,
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ {
+ text = pr.author.display_name,
+ widget = wibox.widget.textbox
+ },
+ {
+ text = to_time_ago(os.difftime(current_time, parse_date(pr.created_on))),
+ widget = wibox.widget.textbox
+ },
+ spacing = 8,
+ expand = 'none',
+ layout = wibox.layout.fixed.horizontal
+ },
+ forced_width = 285,
+ layout = wibox.layout.fixed.vertical
},
{
- text = pr.destination.branch.name,
- widget = wibox.widget.textbox
+ {
+ {
+ image = number_of_approves > 0 and WIDGET_DIR .. '/check.svg' or '',
+ resize = false,
+ widget = wibox.widget.imagebox
+ },
+ {
+ text = number_of_approves,
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ {
+ image = WIDGET_DIR .. '/message-circle.svg',
+ resize = false,
+ widget = wibox.widget.imagebox
+ },
+ {
+ text = pr.comment_count,
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal
+ },
+ layout = wibox.layout.fixed.vertical
},
- spacing = 8,
layout = wibox.layout.fixed.horizontal
},
- {
- text = pr.author.display_name,
- widget = wibox.widget.textbox
- },
- layout = wibox.layout.align.vertical
+
+ spacing = 8,
+ layout = wibox.layout.fixed.vertical
},
spacing = 8,
layout = wibox.layout.fixed.horizontal
@@ -250,7 +342,7 @@ local function worker(args)
table.insert(rows, to_review_rows)
if (#my_review_rows > 1) then
- table.insert(rows, my_review_rows)
+ table.insert(rows, my_review_rows)
end
popup:setup(rows)
end
diff --git a/bitbucket-widget/check.svg b/bitbucket-widget/check.svg
new file mode 100644
index 0000000..e9e44ac
--- /dev/null
+++ b/bitbucket-widget/check.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#A3BE8C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg> \ No newline at end of file
diff --git a/bitbucket-widget/clipboard.svg b/bitbucket-widget/clipboard.svg
new file mode 100644
index 0000000..5c6dfd3
--- /dev/null
+++ b/bitbucket-widget/clipboard.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg> \ No newline at end of file
diff --git a/bitbucket-widget/copy.svg b/bitbucket-widget/copy.svg
new file mode 100644
index 0000000..bab2098
--- /dev/null
+++ b/bitbucket-widget/copy.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-copy"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg> \ No newline at end of file
diff --git a/bitbucket-widget/git-pull-request.svg b/bitbucket-widget/git-pull-request.svg
new file mode 100644
index 0000000..c2e2867
--- /dev/null
+++ b/bitbucket-widget/git-pull-request.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-git-pull-request"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M13 6h3a2 2 0 0 1 2 2v7"></path><line x1="6" y1="9" x2="6" y2="21"></line></svg> \ No newline at end of file
diff --git a/bitbucket-widget/message-circle.svg b/bitbucket-widget/message-circle.svg
new file mode 100644
index 0000000..43eacbb
--- /dev/null
+++ b/bitbucket-widget/message-circle.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-circle"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg> \ No newline at end of file
diff --git a/bitbucket-widget/user.svg b/bitbucket-widget/user.svg
new file mode 100644
index 0000000..4058dee
--- /dev/null
+++ b/bitbucket-widget/user.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg> \ No newline at end of file
diff --git a/cpu-widget/README.md b/cpu-widget/README.md
index 8c4528c..b323f9b 100644
--- a/cpu-widget/README.md
+++ b/cpu-widget/README.md
@@ -1,5 +1,7 @@
# CPU widget
+[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/cpu)](https://github.com/streetturtle/awesome-wm-widgets/labels/cpu)
+
This widget shows the average CPU load among all cores of the machine:
![screenshot](./cpu.gif)
diff --git a/cpu-widget/cpu-widget.lua b/cpu-widget/cpu-widget.lua
index 8d5f497..317ef0a 100644
--- a/cpu-widget/cpu-widget.lua
+++ b/cpu-widget/cpu-widget.lua
@@ -139,7 +139,7 @@ local function worker(args)
local cpu_widget = wibox.container.margin(wibox.container.mirror(cpugraph_widget, { horizontal = true }), 0, 0, 0, 2)
local cpus = {}
- watch([[bash -c "cat /proc/stat | grep '^cpu.' ; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu | head -11 | tail -n +2"]], timeout,
+ watch([[bash -c "grep '^cpu.' /proc/stat; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu | head -11 | tail -n +2"]], timeout,
function(widget, stdout)
local i = 1
local j = 1
diff --git a/experiments/volume/arc-widget.lua b/experiments/volume/arc-widget.lua
new file mode 100644
index 0000000..fb56518
--- /dev/null
+++ b/experiments/volume/arc-widget.lua
@@ -0,0 +1,37 @@
+local wibox = require("wibox")
+local beautiful = require('beautiful')
+
+local widget = {}
+
+function widget.get_widget()
+
+ return wibox.widget {
+ {
+ id = "icon",
+ image = '/usr/share/icons/Arc/status/symbolic/audio-volume-muted-symbolic.svg',
+ resize = true,
+ widget = wibox.widget.imagebox,
+ },
+ max_value = 100,
+ thickness = 2,
+ start_angle = 4.71238898, -- 2pi*3/4
+ forced_height = 18,
+ forced_width = 18,
+ bg = '#ffffff11',
+ paddings = 2,
+ widget = wibox.container.arcchart,
+ set_volume_level = function(self, new_value)
+ self.value = new_value
+ end,
+ mute = function(self)
+ self.colors = {'#BF616A'}
+ end,
+ unmute = function(self)
+ self.colors = {beautiful.fg_color}
+ end
+ }
+
+end
+
+
+return widget \ No newline at end of file
diff --git a/experiments/volume/icon-and-text-widget.lua b/experiments/volume/icon-and-text-widget.lua
new file mode 100644
index 0000000..929d32d
--- /dev/null
+++ b/experiments/volume/icon-and-text-widget.lua
@@ -0,0 +1,46 @@
+local wibox = require("wibox")
+
+local widget = {}
+
+local WIDGET_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/'
+
+function widget.get_widget()
+
+ return wibox.widget {
+ {
+ {
+ id = "icon",
+ image = '/usr/share/icons/Arc/status/symbolic/audio-volume-muted-symbolic.svg',
+ resize = false,
+ widget = wibox.widget.imagebox,
+ },
+ valign = 'center',
+ layout = wibox.container.place
+ },
+ {
+ id = 'txt',
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal,
+ set_volume_level = function(self, new_value)
+ self:get_children_by_id('txt')[1]:set_text(new_value)
+ local new_value_num = tonumber(new_value)
+ local volume_icon_name = ''
+ if (new_value_num >= 0 and new_value_num < 33) then
+ volume_icon_name="audio-volume-low-symbolic"
+ elseif (new_value_num < 66) then
+ volume_icon_name="audio-volume-medium-symbolic"
+ else
+ volume_icon_name="audio-volume-high-symbolic"
+ end
+ self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. volume_icon_name .. '.svg')
+ end,
+ mute = function(self) self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. 'audio-volume-muted-symbolic.svg') end,
+ unmute = function() end,
+
+ }
+
+end
+
+
+return widget \ No newline at end of file
diff --git a/experiments/volume/icons/audio-volume-high-symbolic.svg b/experiments/volume/icons/audio-volume-high-symbolic.svg
new file mode 100644
index 0000000..985c107
--- /dev/null
+++ b/experiments/volume/icons/audio-volume-high-symbolic.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ viewBox="0 0 16 16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r"
+ sodipodi:docname="audio-volume-high-symbolic.svg">
+ <metadata
+ id="metadata30">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1215"
+ inkscape:window-height="776"
+ id="namedview28"
+ showgrid="true"
+ inkscape:zoom="38.125"
+ inkscape:cx="8"
+ inkscape:cy="8"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2"
+ showguides="true"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-paths="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4158" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4" />
+ <path
+ d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
+ id="path18"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
+ id="path20"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="ssssccs" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
+ id="path4508"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
+ id="path4529"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
+ id="path4569"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccc" />
+</svg>
diff --git a/experiments/volume/icons/audio-volume-low-symbolic.svg b/experiments/volume/icons/audio-volume-low-symbolic.svg
new file mode 100644
index 0000000..7eb4531
--- /dev/null
+++ b/experiments/volume/icons/audio-volume-low-symbolic.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ viewBox="0 0 16 16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r"
+ sodipodi:docname="audio-volume-low-symbolic.svg">
+ <metadata
+ id="metadata30">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1215"
+ inkscape:window-height="776"
+ id="namedview28"
+ showgrid="true"
+ inkscape:zoom="38.125"
+ inkscape:cx="8"
+ inkscape:cy="8"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2"
+ showguides="true"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-paths="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4158" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4" />
+ <path
+ d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
+ id="path18"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
+ id="path20"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="ssssccs" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
+ id="path4508"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
+ id="path4529"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
+ id="path4569"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccc" />
+</svg>
diff --git a/experiments/volume/icons/audio-volume-medium-symbolic.svg b/experiments/volume/icons/audio-volume-medium-symbolic.svg
new file mode 100644
index 0000000..11e44fe
--- /dev/null
+++ b/experiments/volume/icons/audio-volume-medium-symbolic.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ viewBox="0 0 16 16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r"
+ sodipodi:docname="audio-volume-medium-symbolic.svg">
+ <metadata
+ id="metadata30">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1215"
+ inkscape:window-height="776"
+ id="namedview28"
+ showgrid="true"
+ inkscape:zoom="38.125"
+ inkscape:cx="8"
+ inkscape:cy="8"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2"
+ showguides="true"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-paths="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4158" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4" />
+ <path
+ d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
+ id="path18"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
+ id="path20"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="ssssccs" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
+ id="path4508"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
+ id="path4529"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
+ id="path4569"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccc" />
+</svg>
diff --git a/experiments/volume/icons/audio-volume-muted-symbolic.svg b/experiments/volume/icons/audio-volume-muted-symbolic.svg
new file mode 100644
index 0000000..e577d05
--- /dev/null
+++ b/experiments/volume/icons/audio-volume-muted-symbolic.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ viewBox="0 0 16 16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="audio-volume-muted-symbolic.svg">
+ <metadata
+ id="metadata30">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1215"
+ inkscape:window-height="776"
+ id="namedview28"
+ showgrid="true"
+ inkscape:zoom="38.125"
+ inkscape:cx="3.4229508"
+ inkscape:cy="7.947541"
+ inkscape:window-x="65"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2"
+ showguides="true"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-paths="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4158" />
+ </sodipodi:namedview>
+ <defs
+ id="defs4" />
+ <path
+ d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
+ id="path18"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
+ id="path20"
+ inkscape:connector-curvature="0"
+ style="fill:#bebebe"
+ sodipodi:nodetypes="ssssccs" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
+ id="path4508"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
+ id="path4529"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
+ id="path4569"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccc" />
+</svg>
diff --git a/experiments/volume/utils.lua b/experiments/volume/utils.lua
new file mode 100644
index 0000000..02742ec
--- /dev/null
+++ b/experiments/volume/utils.lua
@@ -0,0 +1,107 @@
+
+local json = require("json")
+
+local utils = {}
+
+local function split(string_to_split, separator)
+ if separator == nil then separator = "%s" end
+ local t = {}
+
+ for str in string.gmatch(string_to_split, "([^".. separator .."]+)") do
+ table.insert(t, str)
+ end
+
+ return t
+end
+
+function utils.extract_sinks_and_sources(pacmd_output)
+ local sinks = {}
+ local sources = {}
+ local device
+ local properties
+ local ports
+ local in_sink = false
+ local in_source = false
+ local in_device = false
+ local in_properties = false
+ local in_ports = false
+ for line in pacmd_output:gmatch("[^\r\n]+") do
+ if string.match(line, 'source%(s%) available.') then
+ in_sink = false
+ in_source = true
+ end
+ if string.match(line, 'sink%(s%) available.') then
+ in_sink = true
+ in_source = false
+ end
+
+ if string.match(line, 'index:') then
+ in_device = true
+ in_properties = false
+ device = {
+ id = line:match(': (%d+)'),
+ is_default = string.match(line, '*') ~= nil
+ }
+ if in_sink then
+ table.insert(sinks, device)
+ elseif in_source then
+ table.insert(sources, device)
+ end
+ end
+
+ if string.match(line, '^\tproperties:') then
+ in_device = false
+ in_properties = true
+ properties = {}
+ device['properties'] = properties
+ end
+
+ if string.match(line, 'ports:') then
+ in_device = false
+ in_properties = false
+ in_ports = true
+ ports = {}
+ device['ports'] = ports
+ end
+
+ if string.match(line, 'active port:') then
+ in_device = false
+ in_properties = false
+ in_ports = false
+ device['active_port'] = line:match(': (.+)'):gsub('<',''):gsub('>','')
+ end
+
+ if in_device then
+ local t = split(line, ': ')
+ local key = t[1]:gsub('\t+', ''):lower()
+ local value = t[2]:gsub('^<', ''):gsub('>$', '')
+ device[key] = value
+ end
+
+ if in_properties then
+ local t = split(line, '=')
+ local key = t[1]:gsub('\t+', ''):gsub('%.', '_'):gsub('-', '_'):gsub(':', ''):gsub("%s+$", "")
+ local value
+ if t[2] == nil then
+ value = t[2]
+ else
+ value = t[2]:gsub('"', ''):gsub("^%s+", ""):gsub(' Analog Stereo', '')
+ end
+ properties[key] = value
+ end
+
+ if in_ports then
+ local t = split(line, ': ')
+ local key = t[1]
+ if key ~= nil then
+ key = key:gsub('\t+', '')
+ end
+ ports[key] = t[2]
+ end
+ end
+ print(json.encode(sources))
+
+ return sinks, sources
+end
+
+return utils \ No newline at end of file
diff --git a/experiments/volume/volume-2.svg b/experiments/volume/volume-2.svg
new file mode 100644
index 0000000..10f1c67
--- /dev/null
+++ b/experiments/volume/volume-2.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-volume-2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg> \ No newline at end of file
diff --git a/experiments/volume/volume.lua b/experiments/volume/volume.lua
new file mode 100644
index 0000000..ae7605e
--- /dev/null
+++ b/experiments/volume/volume.lua
@@ -0,0 +1,171 @@
+-------------------------------------------------
+-- The Ultimate Volume Widget for Awesome Window Manager
+-- More details could be found here:
+-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/volume-widget
+
+-- @author Pavel Makhov
+-- @copyright 2020 Pavel Makhov
+-------------------------------------------------
+
+local awful = require("awful")
+local wibox = require("wibox")
+local spawn = require("awful.spawn")
+local gears = require("gears")
+local beautiful = require("beautiful")
+local watch = require("awful.widget.watch")
+local utils = require("awesome-wm-widgets.experiments.volume.utils")
+local arc_widget = require("awesome-wm-widgets.experiments.volume.arc-widget")
+local icon_and_text_widget = require("awesome-wm-widgets.experiments.volume.icon-and-text-widget")
+
+
+local LIST_DEVICES_CMD = [[sh -c "pacmd list-sinks; pacmd list-sources"]]
+local GET_VOLUME_CMD = 'amixer -D pulse sget Master'
+local INC_VOLUME_CMD = 'amixer -q -D pulse sset Master 5%+'
+local DEC_VOLUME_CMD = 'amixer -q -D pulse sset Master 5%-'
+local TOG_VOLUME_CMD = 'amixer -q -D pulse sset Master toggle'
+
+
+local volume_widget = wibox.widget{}
+
+local rows = { layout = wibox.layout.fixed.vertical }
+
+local popup = awful.popup{
+ bg = beautiful.bg_normal,
+ ontop = true,
+ visible = false,
+ shape = gears.shape.rounded_rect,
+ border_width = 1,
+ border_color = beautiful.bg_focus,
+ maximum_width = 400,
+ offset = { y = 5 },
+ widget = {}
+}
+
+local function build_main_line(device)
+ if device.active_port ~= nil and device.ports[device.active_port] ~= nil then
+ return device.properties.device_description .. ' - ' .. device.ports[device.active_port]
+ else
+ return device.properties.device_description
+ end
+end
+
+local function build_rows(devices, on_checkbox_click, device_type)
+ local device_rows = { layout = wibox.layout.fixed.vertical }
+ for _, device in pairs(devices) do
+
+ local checkbox = wibox.widget {
+ checked = device.is_default,
+ color = beautiful.bg_normal,
+ paddings = 2,
+ shape = gears.shape.circle,
+ forced_width = 20,
+ forced_height = 20,
+ check_color = beautiful.fg_urgent,
+ widget = wibox.widget.checkbox
+ }
+
+ checkbox:connect_signal("button::press", function(c)
+ spawn.easy_async(string.format([[sh -c 'pacmd set-default-%s "%s"']], device_type, device.name), function()
+ on_checkbox_click()
+ end)
+ end)
+
+ local row = wibox.widget {
+ {
+ {
+ {
+ checkbox,
+ valign = 'center',
+ layout = wibox.container.place,
+ },
+ {
+ {
+ text = build_main_line(device),
+ align = 'left',
+ widget = wibox.widget.textbox
+ },
+ left = 10,
+ layout = wibox.container.margin
+ },
+ spacing = 8,
+ layout = wibox.layout.align.horizontal
+ },
+ margins = 8,
+ layout = wibox.container.margin
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ }
+
+ table.insert(device_rows, row)
+ end
+
+ return device_rows
+end
+
+local function build_header_row(text)
+ return wibox.widget{
+ {
+ markup = "<b>" .. text .. "</b>",
+ align = 'center',
+ widget = wibox.widget.textbox
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ }
+end
+
+local function rebuild_popup()
+ spawn.easy_async(LIST_DEVICES_CMD, function(stdout)
+
+ local sinks, sources = utils.extract_sinks_and_sources(stdout)
+
+ for i = 0, #rows do rows[i]=nil end
+
+ table.insert(rows, build_header_row("SINKS"))
+ table.insert(rows, build_rows(sinks, function() rebuild_popup() end, "sink"))
+ table.insert(rows, build_header_row("SOURCES"))
+ table.insert(rows, build_rows(sources, function() rebuild_popup() end, "source"))
+
+ popup:setup(rows)
+ end)
+end
+
+
+local function worker(args)
+
+ volume_widget = arc_widget.get_widget()
+ -- volume_widget = icon_and_text_widget.get_widget()
+
+ volume_widget:buttons(
+ awful.util.table.join(
+ awful.button({}, 3, function()
+ if popup.visible then
+ popup.visible = not popup.visible
+ else
+ rebuild_popup()
+ popup:move_next_to(mouse.current_widget_geometry)
+ end
+ end),
+ awful.button({}, 4, function() awful.spawn(INC_VOLUME_CMD, false) end),
+ awful.button({}, 5, function() awful.spawn(DEC_VOLUME_CMD, false) end),
+ awful.button({}, 1, function() awful.spawn(TOG_VOLUME_CMD, false) end)
+ )
+ )
+
+ local function update_graphic(widget, stdout)
+ local mute = string.match(stdout, "%[(o%D%D?)%]") -- \[(o\D\D?)\] - [on] or [off]
+ if mute == 'off' then volume_widget:mute()
+ elseif mute == 'on' then volume_widget:unmute()
+ end
+ local volume = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%)
+ volume = string.format("% 3d", volume)
+ widget:set_volume_level(volume)
+ end
+
+ watch(GET_VOLUME_CMD, 1, update_graphic, volume_widget)
+
+ return volume_widget
+end
+
+return setmetatable(volume_widget, { __call = function(_, ...) return worker(...) end })
diff --git a/fs-widget/README.md b/fs-widget/README.md
index 48d2ffe..5cda048 100644
--- a/fs-widget/README.md
+++ b/fs-widget/README.md
@@ -1,20 +1,20 @@
-# Storage Widget
+# Filesystem Widget
This widget shows disk usage. When clicked another widget appears with more detailed information. By default it monitors the "/" mount. It can be configured with a
list of mounts to monitor though only the first will show in the wibar. To have
-multiple mounts displayed on the wibar simply define multiple `storage_widgets`
+multiple mounts displayed on the wibar simply define multiple `fs_widgets`
with different mounts as arguments.
```lua
- local storage_widget = require("awesome-wm-widgets.storage-widget.storage-widget")
+ local fs_widget = require("awesome-wm-widgets.fs-widget.fs-widget")
...
s.mywibox:setup {
s.mytasklist, -- Middle widget
{ -- Right widgets
- storage_widget(), --default
+ fs_widget(), --default
wibox.widget.textbox(':'),
- storage_widget({ mounts = { '/', '/mnt/musicj' } }), -- multiple mounts
+ fs_widget({ mounts = { '/', '/mnt/musicj' } }), -- multiple mounts
...
```
diff --git a/gitlab-widget/gitlab.lua b/gitlab-widget/gitlab.lua
new file mode 100644
index 0000000..7a70113
--- /dev/null
+++ b/gitlab-widget/gitlab.lua
@@ -0,0 +1,353 @@
+-------------------------------------------------
+-- Gitlab Widget for Awesome Window Manager
+-- Shows the number of currently assigned pull requests
+-- More details could be found here:
+-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/gitlab-widget
+
+-- @author Pavel Makhov
+-- @copyright 2020 Pavel Makhov
+-------------------------------------------------
+
+local awful = require("awful")
+local wibox = require("wibox")
+local watch = require("awful.widget.watch")
+local json = require("json")
+local spawn = require("awful.spawn")
+local naughty = require("naughty")
+local gears = require("gears")
+local beautiful = require("beautiful")
+local gfs = require("gears.filesystem")
+
+local HOME_DIR = os.getenv("HOME")
+local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/gitlab-widget/'
+local GET_PRS_CMD= [[bash -c "curl -s --show-error --header 'PRIVATE-TOKEN: %s' '%s/api/v4/merge_requests?state=opened'"]]
+local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -L -n --create-dirs -o %s/.cache/awmw/gitlab-widget/avatars/%s %s"]]
+
+local gitlab_widget = wibox.widget {
+ {
+ {
+ id = 'icon',
+ widget = wibox.widget.imagebox
+ },
+ margins = 4,
+ layout = wibox.container.margin
+ },
+ {
+ id = "txt",
+ widget = wibox.widget.textbox
+ },
+ {
+ id = "new_pr",
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal,
+ set_text = function(self, new_value)
+ self.txt.text = new_value
+ end,
+ set_icon = function(self, new_value)
+ self:get_children_by_id('icon')[1]:set_image(new_value)
+ end
+}
+
+local function show_warning(message)
+ naughty.notify{
+ preset = naughty.config.presets.critical,
+ title = 'Gitlab Widget',
+ text = message}
+end
+
+local popup = awful.popup{
+ ontop = true,
+ visible = false,
+ shape = gears.shape.rounded_rect,
+ border_width = 1,
+ border_color = beautiful.bg_focus,
+ maximum_width = 400,
+ offset = { y = 5 },
+ widget = {}
+}
+
+--- Converts string representation of date (2020-06-02T11:25:27Z) to date
+local function parse_date(date_str)
+ local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%Z"
+ local y, m, d, h, min, sec, mil = date_str:match(pattern)
+
+ return os.time{year = y, month = m, day = d, hour = h, min = min, sec = sec}
+end
+
+--- Converts seconds to "time ago" represenation, like '1 hour ago'
+local function to_time_ago(seconds)
+ local days = seconds / 86400
+ if days > 1 then
+ days = math.floor(days + 0.5)
+ return days .. (days == 1 and ' day' or ' days') .. ' ago'
+ end
+
+ local hours = (seconds % 86400) / 3600
+ if hours > 1 then
+ hours = math.floor(hours + 0.5)
+ return hours .. (hours == 1 and ' hour' or ' hours') .. ' ago'
+ end
+
+ local minutes = ((seconds % 86400) % 3600) / 60
+ if minutes > 1 then
+ minutes = math.floor(minutes + 0.5)
+ return minutes .. (minutes == 1 and ' minute' or ' minutes') .. ' ago'
+ end
+end
+
+local function ellipsize(text, length)
+ return (text:len() > length and length > 0)
+ and text:sub(0, length - 3) .. '...'
+ or text
+end
+
+local function worker(args)
+
+ local args = args or {}
+
+ local icon = args.icon or WIDGET_DIR .. '/icons/gitlab-icon.svg'
+ local api_token = args.api_token or show_warning('API Token is not set')
+ local host = args.host or show_warning('Gitlab host is not set')
+ local timeout = args.timeout or 60
+
+ local current_number_of_prs
+
+ local to_review_rows = {layout = wibox.layout.fixed.vertical}
+ local my_review_rows = {layout = wibox.layout.fixed.vertical}
+ local rows = {layout = wibox.layout.fixed.vertical}
+
+ gitlab_widget:set_icon(icon)
+
+ local update_widget = function(widget, stdout, stderr, _, _)
+
+ if stderr ~= '' then
+ show_warning(stderr)
+ return
+ end
+
+ local result = json.decode(stdout)
+
+ current_number_of_prs = rawlen(result)
+
+ if current_number_of_prs == 0 then
+ widget:set_visible(false)
+ return
+ end
+
+ widget:set_visible(true)
+ widget:set_text(current_number_of_prs)
+
+ for i = 0, #rows do rows[i]=nil end
+
+ for i = 0, #to_review_rows do to_review_rows[i]=nil end
+ table.insert(to_review_rows, {
+ {
+ markup = '<span size="large" color="#ffffff">PRs to review</span>',
+ align = 'center',
+ forced_height = 20,
+ widget = wibox.widget.textbox
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ })
+
+ for i = 0, #my_review_rows do my_review_rows[i]=nil end
+ table.insert(my_review_rows, {
+ {
+ markup = '<span size="large" color="#ffffff">My PRs</span>',
+ align = 'center',
+ forced_height = 20,
+ widget = wibox.widget.textbox
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ })
+ local current_time = os.time(os.date("!*t"))
+
+ for _, pr in ipairs(result) do
+ local path_to_avatar = os.getenv("HOME") ..'/.cache/awmw/gitlab-widget/avatars/' .. pr.author.id
+
+ local row = wibox.widget {
+ {
+ {
+ {
+ {
+ resize = true,
+ image = path_to_avatar,
+ forced_width = 40,
+ forced_height = 40,
+ widget = wibox.widget.imagebox
+ },
+ id = 'avatar',
+ margins = 8,
+ layout = wibox.container.margin
+ },
+ {
+ {
+ id = 'title',
+ markup = '<b>' .. ellipsize(pr.title, 50) .. '</b>',
+ widget = wibox.widget.textbox,
+ forced_width = 400
+ },
+ {
+ {
+ {
+ {
+ text = pr.source_branch,
+ widget = wibox.widget.textbox
+ },
+ {
+ text = '->',
+ widget = wibox.widget.textbox
+ },
+ {
+ text = pr.target_branch,
+ widget = wibox.widget.textbox
+ },
+ spacing = 8,
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ {
+ text = pr.author.name,
+ widget = wibox.widget.textbox
+ },
+ {
+ text = to_time_ago(os.difftime(current_time, parse_date(pr.created_at))),
+ widget = wibox.widget.textbox
+ },
+ spacing = 8,
+ expand = 'none',
+ layout = wibox.layout.fixed.horizontal
+ },
+ forced_width = 285,
+ layout = wibox.layout.fixed.vertical
+ },
+ {
+ {
+ {
+ -- image = number_of_approves > 0 and WIDGET_DIR .. '/check.svg' or '',
+ image = WIDGET_DIR .. '/icons/check.svg',
+ resize = false,
+ widget = wibox.widget.imagebox
+ },
+ {
+ text = pr.upvotes,
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal
+ },
+ {
+ {
+ image = WIDGET_DIR .. '/icons/message-circle.svg',
+ resize = false,
+ widget = wibox.widget.imagebox
+ },
+ {
+ text = pr.user_notes_count,
+ widget = wibox.widget.textbox
+ },
+ layout = wibox.layout.fixed.horizontal
+ },
+ layout = wibox.layout.fixed.vertical
+ },
+ layout = wibox.layout.fixed.horizontal
+ },
+
+ spacing = 8,
+ layout = wibox.layout.fixed.vertical
+ },
+ spacing = 8,
+ layout = wibox.layout.fixed.horizontal
+ },
+ margins = 8,
+ layout = wibox.container.margin
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background
+ }
+
+ if not gfs.file_readable(path_to_avatar) then
+ spawn.easy_async(string.format(
+ DOWNLOAD_AVATAR_CMD,
+ HOME_DIR,
+ pr.author.id,
+ pr.author.avatar_url), function() row:get_children_by_id('avatar')[1]:set_image(path_to_avatar) end)
+ end
+
+ row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
+ row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
+
+ row:get_children_by_id('title')[1]:buttons(
+ awful.util.table.join(
+ awful.button({}, 1, function()
+ spawn.with_shell("xdg-open " .. pr.web_url)
+ popup.visible = false
+ end)
+ )
+ )
+ row:get_children_by_id('avatar')[1]:buttons(
+ awful.util.table.join(
+ awful.button({}, 1, function()
+ spawn.with_shell("xdg-open " .. pr.author.web_url)
+ popup.visible = false
+ end)
+ )
+ )
+
+ local old_cursor, old_wibox
+ row:get_children_by_id('title')[1]:connect_signal("mouse::enter", function(c)
+ local wb = mouse.current_wibox
+ old_cursor, old_wibox = wb.cursor, wb
+ wb.cursor = "hand1"
+ end)
+ row:get_children_by_id('title')[1]:connect_signal("mouse::leave", function(c)
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end)
+
+ local old_cursor, old_wibox
+ row:get_children_by_id('avatar')[1]:connect_signal("mouse::enter", function(c)
+ local wb = mouse.current_wibox
+ old_cursor, old_wibox = wb.cursor, wb
+ wb.cursor = "hand1"
+ end)
+ row:get_children_by_id('avatar')[1]:connect_signal("mouse::leave", function(c)
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end)
+
+ table.insert(to_review_rows, row)
+ end
+
+ table.insert(rows, to_review_rows)
+ if (#my_review_rows > 1) then
+ table.insert(rows, my_review_rows)
+ end
+ popup:setup(rows)
+ end
+
+ gitlab_widget:buttons(
+ awful.util.table.join(
+ awful.button({}, 1, function()
+ if popup.visible then
+ popup.visible = not popup.visible
+ else
+ popup:move_next_to(mouse.current_widget_geometry)
+ end
+ end)
+ )
+ )
+
+ watch(string.format(GET_PRS_CMD, api_token, host),
+ -- string.format(GET_PRS_CMD, host, workspace, repo_slug, uuid, uuid),
+ timeout, update_widget, gitlab_widget)
+ return gitlab_widget
+end
+
+return setmetatable(gitlab_widget, { __call = function(_, ...) return worker(...) end })
diff --git a/gitlab-widget/icons/check.svg b/gitlab-widget/icons/check.svg
new file mode 100644
index 0000000..e9e44ac
--- /dev/null
+++ b/gitlab-widget/icons/check.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#A3BE8C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg> \ No newline at end of file
diff --git a/gitlab-widget/icons/gitlab-icon.svg b/gitlab-widget/icons/gitlab-icon.svg
new file mode 100644
index 0000000..abe3f37
--- /dev/null
+++ b/gitlab-widget/icons/gitlab-icon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill-rule="evenodd"><path d="M32 61.477L43.784 25.2H20.216z" fill="#e24329"/><path d="M32 61.477L20.216 25.2H3.7z" fill="#fc6d26"/><path d="M3.7 25.2L.12 36.23a2.44 2.44 0 0 0 .886 2.728L32 61.477z" fill="#fca326"/><path d="M3.7 25.2h16.515L13.118 3.366c-.365-1.124-1.955-1.124-2.32 0z" fill="#e24329"/><path d="M32 61.477L43.784 25.2H60.3z" fill="#fc6d26"/><path d="M60.3 25.2l3.58 11.02a2.44 2.44 0 0 1-.886 2.728L32 61.477z" fill="#fca326"/><path d="M60.3 25.2H43.784l7.098-21.844c.365-1.124 1.955-1.124 2.32 0z" fill="#e24329"/></svg> \ No newline at end of file
diff --git a/gitlab-widget/icons/message-circle.svg b/gitlab-widget/icons/message-circle.svg
new file mode 100644
index 0000000..43eacbb
--- /dev/null
+++ b/gitlab-widget/icons/message-circle.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-circle"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg> \ No newline at end of file
diff --git a/logout-widget/README.md b/logout-widget/README.md
index e835122..7d1673d 100644
--- a/logout-widget/README.md
+++ b/logout-widget/README.md
@@ -6,6 +6,14 @@ Widget which allows to perform lock, reboot, log out, power off and sleep action
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/logout-widget/screenshot.gif" alt="screenshot">
</p>
+When the widget is shown, following shortcuts can be used:
+ - <kbd>Escape</kbd> - hide widget
+ - <kbd>s</kbd> - shutdown
+ - <kbd>r</kbd> - reboot
+ - <kbd>u</kbd> - suspend
+ - <kbd>k</kbd> - lock
+ - <kbd>l</kbd> - log out
+
# Installation
Clone this (if not cloned yet) and the [awesome-buttons](https://github.com/streetturtle/awesome-buttons) repos under **./.config/awesome/**
@@ -45,10 +53,12 @@ Then
| Name | Default | Description |
|---|---|---|
| `icon` | `power.svg` | If used as widget - the path to the widget's icon |
+| `icon_size` | `40` | Size of the icon |
+| `icon_margin` | `16` | Margin around the icon |
| `bg_color` | `beautiful.bg_normal` | The color the background of the |
| `accent_color` | `beautiful.bg_focus` | The color of the buttons |
| `text_color` | `beautiful.fg_normal` | The color of text |
-| `phrases` | `{'Goodbye!'}` | The table with phrase(s) to show, if more than one provided, the phrase is chosen randomly |
+| `phrases` | `{'Goodbye!'}` | The table with phrase(s) to show, if more than one provided, the phrase is chosen randomly. Leave empty (`{}`) to hide the phrase |
| `onlogout` | `function() awesome.quit() end` | Function which is called when the logout button is pressed |
| `onlock` | `function() awful.spawn.with_shell("systemctl suspend") end` | Function which is called when the lock button is pressed |
| `onreboot` | `function() awful.spawn.with_shell("reboot") end` | Function which is called when the reboot button is pressed |
@@ -60,12 +70,14 @@ Some color themes for inspiration:
![nord](./logout-nord.png)
![outrun](./logout-outrun.png)
![dark](./logout-dark.png)
+![dracula](./logout-dracula.png)
```lua
logout.launch{
- bg_color = "#261447", accent_color = "#ff4365", text_color = '#f706cf', -- outrun
+ bg_color = "#261447", accent_color = "#ff4365", text_color = '#f706cf', icon_size = 40, icon_margin = 16, -- outrun
-- bg_color = "#0b0c10", accent_color = "#1f2833", text_color = '#66fce1', -- dark
-- bg_color = "#3B4252", accent_color = "#88C0D0", text_color = '#D8DEE9', -- nord
+ -- bg_color = "#282a36", accent_color = "#ff79c6", phrases = {}, -- dracula, no phrase
phrases = {"exit(0)", "Don't forget to be awesome.", "Yippee ki yay!"},
}
```
diff --git a/logout-widget/logout-dracula.png b/logout-widget/logout-dracula.png
new file mode 100644
index 0000000..3c61c46
--- /dev/null
+++ b/logout-widget/logout-dracula.png
Binary files differ
diff --git a/logout-widget/logout-outrun.png b/logout-widget/logout-outrun.png
index d711d02..9be68b5 100644
--- a/logout-widget/logout-outrun.png
+++ b/logout-widget/logout-outrun.png
Binary files differ
diff --git a/logout-widget/logout.lua b/logout-widget/logout.lua
index 98892f5..f4cae9e 100644
--- a/logout-widget/logout.lua
+++ b/logout-widget/logout.lua
@@ -40,12 +40,14 @@ local phrase_widget = wibox.widget{
widget = wibox.widget.textbox
}
-local function create_button(icon_name, action_name, color, onclick)
+local function create_button(icon_name, action_name, color, onclick, icon_size, icon_margin)
local button = awesomebuttons.with_icon {
type = 'basic',
icon = icon_name,
color = color,
+ icon_size = icon_size,
+ icon_margin = icon_margin,
onclick = function()
onclick()
w.visible = false
@@ -63,6 +65,8 @@ local function launch(args)
local accent_color = args.accent_color or beautiful.bg_focus
local text_color = args.text_color or beautiful.fg_normal
local phrases = args.phrases or {'Goodbye!'}
+ local icon_size = args.icon_size or 40
+ local icon_margin = args.icon_margin or 16
local onlogout = args.onlogout or function () awesome.quit() end
local onlock = args.onlock or function() awful.spawn.with_shell("systemctl suspend") end
@@ -71,18 +75,20 @@ local function launch(args)
local onpoweroff = args.onpoweroff or function() awful.spawn.with_shell("shutdown now") end
w:set_bg(bg_color)
- phrase_widget:set_markup('<span color="'.. text_color .. '" size="20000">' .. phrases[ math.random( #phrases ) ] .. '</span>')
+ if #phrases > 0 then
+ phrase_widget:set_markup('<span color="'.. text_color .. '" size="20000">' .. phrases[ math.random( #phrases ) ] .. '</span>')
+ end
w:setup {
{
phrase_widget,
{
{
- create_button('log-out', 'Log Out', accent_color, onlogout),
- create_button('lock', 'Lock', accent_color, onlock),
- create_button('refresh-cw', 'Reboot', accent_color, onreboot),
- create_button('moon', 'Suspend', accent_color, onsuspend),
- create_button('power', 'Power Off', accent_color, onpoweroff),
+ create_button('log-out', 'Log Out (l)', accent_color, onlogout, icon_size, icon_margin),
+ create_button('lock', 'Lock (k)', accent_color, onlock, icon_size, icon_margin),
+ create_button('refresh-cw', 'Reboot (r)', accent_color, onreboot, icon_size, icon_margin),
+ create_button('moon', 'Suspend (u)', accent_color, onsuspend, icon_size, icon_margin),
+ create_button('power', 'Power Off (s)', accent_color, onpoweroff, icon_size, icon_margin),
id = 'buttons',
spacing = 8,
layout = wibox.layout.fixed.horizontal
@@ -110,9 +116,22 @@ local function launch(args)
capi.keygrabber.run(function(_, key, event)
if event == "release" then return end
if key then
- phrase_widget:set_text('')
- capi.keygrabber.stop()
- w.visible = false
+ if key == 'Escape' then
+ phrase_widget:set_text('')
+ capi.keygrabber.stop()
+ w.visible = false
+ elseif key == 's' then onpoweroff()
+ elseif key == 'r' then onreboot()
+ elseif key == 'u' then onsuspend()
+ elseif key == 'k' then onlock()
+ elseif key == 'l' then onlogout()
+ end
+
+ if key == 'Escape' or string.match("srukl", key) then
+ phrase_widget:set_text('')
+ capi.keygrabber.stop()
+ w.visible = false
+ end
end
end)
end
diff --git a/logout-widget/screenshot.gif b/logout-widget/screenshot.gif
index 8fcf9ab..4975c19 100644
--- a/logout-widget/screenshot.gif
+++ b/logout-widget/screenshot.gif
Binary files differ
diff --git a/weather-widget/README.md b/weather-widget/README.md
index e573bd4..e801cfb 100644
--- a/weather-widget/README.md
+++ b/weather-widget/README.md
@@ -1,15 +1,20 @@
# Weather widget
-[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/weather)](https://github.com/streetturtle/awesome-wm-widgets/labels/weather)
-
+<p align="center">
+ <a href="https://github.com/streetturtle/awesome-wm-widgets/labels/weather" target="_blank"><img alt="GitHub issues by-label" src="https://img.shields.io/github/issues/streetturtle/awesome-wm-widgets/weather"></a>
+
+ <a href="https://twitter.com/intent/tweet?text=Check%20out%20this%20awesome%20weather%20widget%20for%20Awesome%20Window%20Manager%20&url=https://github.com/streetturtle/awesome-wm-widgets/blob/master/weather-widget" target="_blank">
+ <img alt="Twitter URL" src="https://img.shields.io/twitter/url?logo=twitter&style=social&url=https%3A%2F%2Fgithub.com%2Fstreetturtle%2Fawesome-wm-widgets%2Fblob%2Fmaster%2Fweather-widget">
+ </a>
+</p>
-Widget showing current, hourly and daily weather forecast.
+The widget showing current, hourly and daily weather forecast.
<p align="center">
- <img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/weather-widget/screenshots/weather-widget.png" alt="screenshot" style="max-width:100%;">
+ <img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/weather-widget/weather-widget.png" alt="screenshot" style="max-width:100%;">
</p>
-Widget consists of three sections:
+The widget consists of three sections:
- current weather, including humidity, wind speed, UV index
- hourly forecast for the next 24 hours
- daily forecast for the next five days
@@ -32,10 +37,9 @@ It is possible to customize widget by providing a table with all or some of the
| icons_extension | `.svg` | File extension of icons in the pack |
| timeout | 120 | How often in seconds the widget refreshes |
-
### Icons:
-Widget comes with two predefined icon packs:
+The widget comes with two predefined icon packs:
- weather-underground-icons taken from [here](https://github.com/manifestinteractive/weather-underground-icons)
- VitalyGorbachev taken from [here](https://www.flaticon.com/authors/vitaly-gorbachev)
@@ -44,10 +48,9 @@ To add your custom icons, create a folder with the pack name under `/icons` and
### Examples:
-
#### Custom font, icons
-![example1](./screenshots/example1.png)
+![example1](./example1.png)
```lua
weather_curl_widget({
@@ -65,7 +68,7 @@ weather_curl_widget({
#### Only current weather
-![example2](./screenshots/example2.png)
+![example2](./example2.png)
```lua
weather_curl_widget({
@@ -74,8 +77,6 @@ weather_curl_widget({
}),
```
-
-
## Installation
1. Download json parser for lua from [github.com/rxi/json.lua](https://github.com/rxi/json.lua) and place it under **~/.config/awesome/** (don't forget to star a repo <i class="fa fa-github-alt"></i> ):
@@ -126,6 +127,15 @@ weather_curl_widget({
...
```
+## More screenshots
+
+Only negative temperature:
+
+![negative](./negative.png)
+
+Both positive and negative tempertature:
+
+![both](./both.png)
## How it works
diff --git a/weather-widget/both.png b/weather-widget/both.png
new file mode 100644
index 0000000..0947a37
--- /dev/null
+++ b/weather-widget/both.png
Binary files differ
diff --git a/weather-widget/screenshots/example1.png b/weather-widget/example1.png
index 7074faa..7074faa 100644
--- a/weather-widget/screenshots/example1.png
+++ b/weather-widget/example1.png
Binary files differ
diff --git a/weather-widget/screenshots/example2.png b/weather-widget/example2.png
index 857274b..857274b 100644
--- a/weather-widget/screenshots/example2.png
+++ b/weather-widget/example2.png
Binary files differ
diff --git a/weather-widget/example_response.json b/weather-widget/example_response.json
new file mode 100644
index 0000000..2b90a6e
--- /dev/null
+++ b/weather-widget/example_response.json
@@ -0,0 +1,1419 @@
+{
+ "lat": 45.5,
+ "lon": -73.57,
+ "timezone": "America/Toronto",
+ "timezone_offset": -14400,
+ "current": {
+ "dt": 1603155313,
+ "sunrise": 1603106181,
+ "sunset": 1603144896,
+ "temp": 8.91,
+ "feels_like": 7.97,
+ "pressure": 1025,
+ "humidity": 100,
+ "dew_point": 8.91,
+ "uvi": 2.37,
+ "clouds": 90,
+ "visibility": 4828,
+ "wind_speed": 1,
+ "wind_deg": 40,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ },
+ {
+ "id": 701,
+ "main": "Mist",
+ "description": "mist",
+ "icon": "50n"
+ }
+ ],
+ "rain": {
+ "1h": 0.65
+ }
+ },
+ "hourly": [
+ {
+ "dt": 1603152000,
+ "temp": -8.91,
+ "feels_like": 7.95,
+ "pressure": 1025,
+ "humidity": 100,
+ "dew_point": 8.91,
+ "clouds": 90,
+ "visibility": 10000,
+ "wind_speed": 1.03,
+ "wind_deg": 32,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.4
+ }
+ },
+ {
+ "dt": 1603155600,
+ "temp": -9.16,
+ "feels_like": 7.7,
+ "pressure": 1025,
+ "humidity": 91,
+ "dew_point": 7.77,
+ "clouds": 95,
+ "visibility": 10000,
+ "wind_speed": 1.34,
+ "wind_deg": 67,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 0.29,
+ "rain": {
+ "1h": 0.87
+ }
+ },
+ {
+ "dt": 1603159200,
+ "temp": -9.24,
+ "feels_like": 7.7,
+ "pressure": 1024,
+ "humidity": 88,
+ "dew_point": 7.36,
+ "clouds": 98,
+ "visibility": 10000,
+ "wind_speed": 1.32,
+ "wind_deg": 48,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 0.59,
+ "rain": {
+ "1h": 0.42
+ }
+ },
+ {
+ "dt": 1603162800,
+ "temp": -9.18,
+ "feels_like": 6.91,
+ "pressure": 1023,
+ "humidity": 86,
+ "dew_point": 6.96,
+ "clouds": 99,
+ "visibility": 10000,
+ "wind_speed": 2.23,
+ "wind_deg": 42,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0.86
+ },
+ {
+ "dt": 1603166400,
+ "temp": -9.09,
+ "feels_like": 6.46,
+ "pressure": 1023,
+ "humidity": 88,
+ "dew_point": 7.21,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 2.83,
+ "wind_deg": 46,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 0.94,
+ "rain": {
+ "1h": 0.6
+ }
+ },
+ {
+ "dt": 1603170000,
+ "temp": -8.96,
+ "feels_like": 6.43,
+ "pressure": 1022,
+ "humidity": 91,
+ "dew_point": 7.62,
+ "clouds": 100,
+ "visibility": 5405,
+ "wind_speed": 2.81,
+ "wind_deg": 18,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.89
+ }
+ },
+ {
+ "dt": 1603173600,
+ "temp": -8.84,
+ "feels_like": 6.29,
+ "pressure": 1021,
+ "humidity": 91,
+ "dew_point": 7.6,
+ "clouds": 100,
+ "visibility": 7599,
+ "wind_speed": 2.8,
+ "wind_deg": 35,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 2.07
+ }
+ },
+ {
+ "dt": 1603177200,
+ "temp": -8.92,
+ "feels_like": 6.34,
+ "pressure": 1021,
+ "humidity": 92,
+ "dew_point": 7.78,
+ "clouds": 100,
+ "visibility": 8594,
+ "wind_speed": 2.91,
+ "wind_deg": 44,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.19
+ }
+ },
+ {
+ "dt": 1603180800,
+ "temp": -9.08,
+ "feels_like": 7.18,
+ "pressure": 1020,
+ "humidity": 93,
+ "dew_point": 8.06,
+ "clouds": 100,
+ "visibility": 9347,
+ "wind_speed": 2.06,
+ "wind_deg": 37,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.02
+ }
+ },
+ {
+ "dt": 1603184400,
+ "temp": -8.98,
+ "feels_like": 6.28,
+ "pressure": 1019,
+ "humidity": 93,
+ "dew_point": 8,
+ "clouds": 100,
+ "visibility": 6164,
+ "wind_speed": 3.16,
+ "wind_deg": 354,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.89
+ }
+ },
+ {
+ "dt": 1603188000,
+ "temp": -8.69,
+ "feels_like": 5.78,
+ "pressure": 1019,
+ "humidity": 92,
+ "dew_point": 7.58,
+ "clouds": 100,
+ "visibility": 5143,
+ "wind_speed": 3.31,
+ "wind_deg": 29,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 2.6
+ }
+ },
+ {
+ "dt": 1603191600,
+ "temp": -8.6,
+ "feels_like": 6.08,
+ "pressure": 1019,
+ "humidity": 92,
+ "dew_point": 7.42,
+ "clouds": 100,
+ "visibility": 6072,
+ "wind_speed": 2.73,
+ "wind_deg": 29,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 2.3
+ }
+ },
+ {
+ "dt": 1603195200,
+ "temp": -8.56,
+ "feels_like": 6.68,
+ "pressure": 1019,
+ "humidity": 92,
+ "dew_point": 7.45,
+ "clouds": 100,
+ "visibility": 6697,
+ "wind_speed": 1.8,
+ "wind_deg": 16,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 2.58
+ }
+ },
+ {
+ "dt": 1603198800,
+ "temp": -8.74,
+ "feels_like": 6.88,
+ "pressure": 1020,
+ "humidity": 91,
+ "dew_point": 7.38,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 1.77,
+ "wind_deg": 319,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.06
+ }
+ },
+ {
+ "dt": 1603202400,
+ "temp": -8.93,
+ "feels_like": 7.32,
+ "pressure": 1020,
+ "humidity": 90,
+ "dew_point": 7.48,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 1.42,
+ "wind_deg": 291,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.95
+ }
+ },
+ {
+ "dt": 1603206000,
+ "temp": -9.07,
+ "feels_like": 6.75,
+ "pressure": 1021,
+ "humidity": 89,
+ "dew_point": 7.43,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 2.43,
+ "wind_deg": 276,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.31
+ }
+ },
+ {
+ "dt": 1603209600,
+ "temp": -9.31,
+ "feels_like": 6.58,
+ "pressure": 1022,
+ "humidity": 86,
+ "dew_point": 7.17,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 2.93,
+ "wind_deg": 262,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0.8
+ },
+ {
+ "dt": 1603213200,
+ "temp": -10.07,
+ "feels_like": 6.68,
+ "pressure": 1023,
+ "humidity": 80,
+ "dew_point": 6.78,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 3.77,
+ "wind_deg": 269,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0.8
+ },
+ {
+ "dt": 1603216800,
+ "temp": -11.87,
+ "feels_like": 7.99,
+ "pressure": 1023,
+ "humidity": 67,
+ "dew_point": 6.15,
+ "clouds": 99,
+ "visibility": 10000,
+ "wind_speed": 4.21,
+ "wind_deg": 265,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0.8
+ },
+ {
+ "dt": 1603220400,
+ "temp": -12.05,
+ "feels_like": 7.95,
+ "pressure": 1024,
+ "humidity": 64,
+ "dew_point": 5.63,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 4.38,
+ "wind_deg": 270,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603224000,
+ "temp": -11.74,
+ "feels_like": 7.54,
+ "pressure": 1025,
+ "humidity": 63,
+ "dew_point": 5.08,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 4.38,
+ "wind_deg": 276,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603227600,
+ "temp": -11.09,
+ "feels_like": 7.13,
+ "pressure": 1026,
+ "humidity": 62,
+ "dew_point": 4.24,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 3.79,
+ "wind_deg": 293,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04d"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603231200,
+ "temp": -10.13,
+ "feels_like": 6.51,
+ "pressure": 1027,
+ "humidity": 63,
+ "dew_point": 3.43,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 3.13,
+ "wind_deg": 318,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603234800,
+ "temp": -9.53,
+ "feels_like": 7.02,
+ "pressure": 1028,
+ "humidity": 63,
+ "dew_point": 3.02,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 1.4,
+ "wind_deg": 329,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603238400,
+ "temp": -9.2,
+ "feels_like": 7.3,
+ "pressure": 1028,
+ "humidity": 65,
+ "dew_point": 3.03,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 0.56,
+ "wind_deg": 52,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603242000,
+ "temp": -8.73,
+ "feels_like": 6.57,
+ "pressure": 1029,
+ "humidity": 68,
+ "dew_point": 3.28,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 0.98,
+ "wind_deg": 75,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603245600,
+ "temp": -8.12,
+ "feels_like": 5.55,
+ "pressure": 1029,
+ "humidity": 71,
+ "dew_point": 3.27,
+ "clouds": 89,
+ "visibility": 10000,
+ "wind_speed": 1.57,
+ "wind_deg": 68,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603249200,
+ "temp": -7.83,
+ "feels_like": 4.86,
+ "pressure": 1029,
+ "humidity": 71,
+ "dew_point": 3.05,
+ "clouds": 93,
+ "visibility": 10000,
+ "wind_speed": 2.07,
+ "wind_deg": 68,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603252800,
+ "temp": -7.49,
+ "feels_like": 4.21,
+ "pressure": 1029,
+ "humidity": 72,
+ "dew_point": 2.8,
+ "clouds": 94,
+ "visibility": 10000,
+ "wind_speed": 2.48,
+ "wind_deg": 66,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603256400,
+ "temp": -6.92,
+ "feels_like": 3.31,
+ "pressure": 1029,
+ "humidity": 73,
+ "dew_point": 2.47,
+ "clouds": 96,
+ "visibility": 10000,
+ "wind_speed": 2.87,
+ "wind_deg": 81,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603260000,
+ "temp": -6.49,
+ "feels_like": 2.48,
+ "pressure": 1029,
+ "humidity": 74,
+ "dew_point": 2.22,
+ "clouds": 96,
+ "visibility": 10000,
+ "wind_speed": 3.38,
+ "wind_deg": 78,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603263600,
+ "temp": -6.3,
+ "feels_like": 1.81,
+ "pressure": 1028,
+ "humidity": 71,
+ "dew_point": 1.55,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 3.89,
+ "wind_deg": 84,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603267200,
+ "temp": -6.22,
+ "feels_like": 1.39,
+ "pressure": 1027,
+ "humidity": 69,
+ "dew_point": 0.99,
+ "clouds": 98,
+ "visibility": 10000,
+ "wind_speed": 4.27,
+ "wind_deg": 74,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0
+ },
+ {
+ "dt": 1603270800,
+ "temp": -6.69,
+ "feels_like": 1.66,
+ "pressure": 1026,
+ "humidity": 65,
+ "dew_point": 0.79,
+ "clouds": 96,
+ "visibility": 10000,
+ "wind_speed": 4.47,
+ "wind_deg": 69,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0.05
+ },
+ {
+ "dt": 1603274400,
+ "temp": -6.53,
+ "feels_like": 1.74,
+ "pressure": 1024,
+ "humidity": 68,
+ "dew_point": 1.07,
+ "clouds": 97,
+ "visibility": 10000,
+ "wind_speed": 4.23,
+ "wind_deg": 65,
+ "weather": [
+ {
+ "id": 804,
+ "main": "Clouds",
+ "description": "overcast clouds",
+ "icon": "04n"
+ }
+ ],
+ "pop": 0.28
+ },
+ {
+ "dt": 1603278000,
+ "temp": -6.41,
+ "feels_like": 1.87,
+ "pressure": 1023,
+ "humidity": 73,
+ "dew_point": 1.96,
+ "clouds": 97,
+ "visibility": 10000,
+ "wind_speed": 4.08,
+ "wind_deg": 73,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 0.35,
+ "rain": {
+ "1h": 0.17
+ }
+ },
+ {
+ "dt": 1603281600,
+ "temp": -6.42,
+ "feels_like": 2.71,
+ "pressure": 1022,
+ "humidity": 79,
+ "dew_point": 3.21,
+ "clouds": 98,
+ "visibility": 9620,
+ "wind_speed": 3.16,
+ "wind_deg": 71,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 0.62,
+ "rain": {
+ "1h": 0.37
+ }
+ },
+ {
+ "dt": 1603285200,
+ "temp": -6.67,
+ "feels_like": 3.38,
+ "pressure": 1021,
+ "humidity": 86,
+ "dew_point": 4.59,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 2.95,
+ "wind_deg": 84,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 0.9,
+ "rain": {
+ "1h": 1.08
+ }
+ },
+ {
+ "dt": 1603288800,
+ "temp": -8.55,
+ "feels_like": 5.61,
+ "pressure": 1019,
+ "humidity": 87,
+ "dew_point": 6.64,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 3.05,
+ "wind_deg": 135,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.23
+ }
+ },
+ {
+ "dt": 1603292400,
+ "temp": -10.85,
+ "feels_like": 8.09,
+ "pressure": 1018,
+ "humidity": 95,
+ "dew_point": 10.13,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 4.04,
+ "wind_deg": 150,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.31
+ }
+ },
+ {
+ "dt": 1603296000,
+ "temp": -13.37,
+ "feels_like": 10.29,
+ "pressure": 1017,
+ "humidity": 90,
+ "dew_point": 11.93,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 5.19,
+ "wind_deg": 170,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.32
+ }
+ },
+ {
+ "dt": 1603299600,
+ "temp": -13.92,
+ "feels_like": 11.34,
+ "pressure": 1015,
+ "humidity": 94,
+ "dew_point": 13.07,
+ "clouds": 100,
+ "visibility": 6450,
+ "wind_speed": 5.01,
+ "wind_deg": 177,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 3.08
+ }
+ },
+ {
+ "dt": 1603303200,
+ "temp": -14.85,
+ "feels_like": 12.78,
+ "pressure": 1014,
+ "humidity": 95,
+ "dew_point": 14.1,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 4.79,
+ "wind_deg": 183,
+ "weather": [
+ {
+ "id": 502,
+ "main": "Rain",
+ "description": "heavy intensity rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 4.94
+ }
+ },
+ {
+ "dt": 1603306800,
+ "temp": -15.94,
+ "feels_like": 13.56,
+ "pressure": 1014,
+ "humidity": 93,
+ "dew_point": 14.96,
+ "clouds": 100,
+ "visibility": 7138,
+ "wind_speed": 5.61,
+ "wind_deg": 207,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 2.71
+ }
+ },
+ {
+ "dt": 1603310400,
+ "temp": -16.72,
+ "feels_like": 14.6,
+ "pressure": 1014,
+ "humidity": 93,
+ "dew_point": 15.66,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 5.64,
+ "wind_deg": 208,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 1.33
+ }
+ },
+ {
+ "dt": 1603314000,
+ "temp": -16.74,
+ "feels_like": 14.61,
+ "pressure": 1014,
+ "humidity": 94,
+ "dew_point": 15.81,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 5.75,
+ "wind_deg": 216,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.89
+ }
+ },
+ {
+ "dt": 1603317600,
+ "temp": -17.05,
+ "feels_like": 14.53,
+ "pressure": 1015,
+ "humidity": 92,
+ "dew_point": 15.83,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 6.3,
+ "wind_deg": 234,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.51
+ }
+ },
+ {
+ "dt": 1603321200,
+ "temp": -16.74,
+ "feels_like": 14.18,
+ "pressure": 1016,
+ "humidity": 87,
+ "dew_point": 14.65,
+ "clouds": 100,
+ "visibility": 10000,
+ "wind_speed": 5.74,
+ "wind_deg": 257,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10n"
+ }
+ ],
+ "pop": 1,
+ "rain": {
+ "1h": 0.22
+ }
+ }
+ ],
+ "daily": [
+ {
+ "dt": 1603123200,
+ "sunrise": 1603106181,
+ "sunset": 1603144896,
+ "temp": {
+ "day": 12,
+ "min": 8.91,
+ "max": 12.73,
+ "night": 9.05,
+ "eve": 9.72,
+ "morn": 12.73
+ },
+ "feels_like": {
+ "day": 9.92,
+ "night": 7.02,
+ "eve": 7.88,
+ "morn": 8.02
+ },
+ "pressure": 1025,
+ "humidity": 78,
+ "dew_point": 8.34,
+ "wind_speed": 2.41,
+ "wind_deg": 242,
+ "weather": [
+ {
+ "id": 501,
+ "main": "Rain",
+ "description": "moderate rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 100,
+ "pop": 1,
+ "rain": 8.77,
+ "uvi": 2.37
+ },
+ {
+ "dt": 1603209600,
+ "sunrise": 1603192663,
+ "sunset": 1603231195,
+ "temp": {
+ "day": 9.07,
+ "min": 7.83,
+ "max": 11.87,
+ "night": 7.83,
+ "eve": 11.09,
+ "morn": 8.98
+ },
+ "feels_like": {
+ "day": 6.75,
+ "night": 4.86,
+ "eve": 7.13,
+ "morn": 6.28
+ },
+ "pressure": 1021,
+ "humidity": 89,
+ "dew_point": 7.43,
+ "wind_speed": 2.43,
+ "wind_deg": 276,
+ "weather": [
+ {
+ "id": 502,
+ "main": "Rain",
+ "description": "heavy intensity rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 100,
+ "pop": 1,
+ "rain": 18.46,
+ "uvi": 2.3
+ },
+ {
+ "dt": 1603296000,
+ "sunrise": 1603279145,
+ "sunset": 1603317495,
+ "temp": {
+ "day": 10.85,
+ "min": 6.42,
+ "max": 16.74,
+ "night": 12.25,
+ "eve": 16.74,
+ "morn": 6.69
+ },
+ "feels_like": {
+ "day": 8.09,
+ "night": 8.59,
+ "eve": 14.61,
+ "morn": 1.66
+ },
+ "pressure": 1018,
+ "humidity": 95,
+ "dew_point": 10.13,
+ "wind_speed": 4.04,
+ "wind_deg": 150,
+ "weather": [
+ {
+ "id": 502,
+ "main": "Rain",
+ "description": "heavy intensity rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 100,
+ "pop": 1,
+ "rain": 16.19,
+ "uvi": 2.32
+ },
+ {
+ "dt": 1603382400,
+ "sunrise": 1603365627,
+ "sunset": 1603403795,
+ "temp": {
+ "day": 9.95,
+ "min": 7.29,
+ "max": 11.27,
+ "night": 7.29,
+ "eve": 11.01,
+ "morn": 9.44
+ },
+ "feels_like": {
+ "day": 5.45,
+ "night": 2.63,
+ "eve": 8.07,
+ "morn": 5.65
+ },
+ "pressure": 1027,
+ "humidity": 57,
+ "dew_point": 2.03,
+ "wind_speed": 4,
+ "wind_deg": 283,
+ "weather": [
+ {
+ "id": 802,
+ "main": "Clouds",
+ "description": "scattered clouds",
+ "icon": "03d"
+ }
+ ],
+ "clouds": 27,
+ "pop": 0,
+ "uvi": 2.36
+ },
+ {
+ "dt": 1603468800,
+ "sunrise": 1603452109,
+ "sunset": 1603490097,
+ "temp": {
+ "day": 12.02,
+ "min": 6.62,
+ "max": 17.04,
+ "night": 15.91,
+ "eve": 17.04,
+ "morn": 7.09
+ },
+ "feels_like": {
+ "day": 8.48,
+ "night": 11.82,
+ "eve": 12.58,
+ "morn": 3.07
+ },
+ "pressure": 1022,
+ "humidity": 72,
+ "dew_point": 7.29,
+ "wind_speed": 4.1,
+ "wind_deg": 147,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 99,
+ "pop": 0.29,
+ "rain": 0.22,
+ "uvi": 2.2
+ },
+ {
+ "dt": 1603555200,
+ "sunrise": 1603538592,
+ "sunset": 1603576400,
+ "temp": {
+ "day": 8.39,
+ "min": 6.83,
+ "max": 15.86,
+ "night": 6.83,
+ "eve": 9.56,
+ "morn": 12.99
+ },
+ "feels_like": {
+ "day": 3.79,
+ "night": 3.04,
+ "eve": 6.58,
+ "morn": 10.39
+ },
+ "pressure": 1022,
+ "humidity": 58,
+ "dew_point": 0.71,
+ "wind_speed": 3.87,
+ "wind_deg": 10,
+ "weather": [
+ {
+ "id": 500,
+ "main": "Rain",
+ "description": "light rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 72,
+ "pop": 0.9,
+ "rain": 2.54,
+ "uvi": 2.07
+ },
+ {
+ "dt": 1603641600,
+ "sunrise": 1603625075,
+ "sunset": 1603662705,
+ "temp": {
+ "day": 5.33,
+ "min": 3.23,
+ "max": 7.24,
+ "night": 4.97,
+ "eve": 6.59,
+ "morn": 3.97
+ },
+ "feels_like": {
+ "day": 1.26,
+ "night": 0.02,
+ "eve": 2.58,
+ "morn": -0.34
+ },
+ "pressure": 1025,
+ "humidity": 61,
+ "dew_point": -5.56,
+ "wind_speed": 2.67,
+ "wind_deg": 37,
+ "weather": [
+ {
+ "id": 803,
+ "main": "Clouds",
+ "description": "broken clouds",
+ "icon": "04d"
+ }
+ ],
+ "clouds": 74,
+ "pop": 0.08,
+ "uvi": 2.25
+ },
+ {
+ "dt": 1603728000,
+ "sunrise": 1603711558,
+ "sunset": 1603749010,
+ "temp": {
+ "day": 3.7,
+ "min": 2.09,
+ "max": 3.88,
+ "night": 3.54,
+ "eve": 3.54,
+ "morn": 2.09
+ },
+ "feels_like": {
+ "day": -0.28,
+ "night": -0.76,
+ "eve": -0.86,
+ "morn": -2.81
+ },
+ "pressure": 1021,
+ "humidity": 90,
+ "dew_point": 2.33,
+ "wind_speed": 3.35,
+ "wind_deg": 32,
+ "weather": [
+ {
+ "id": 502,
+ "main": "Rain",
+ "description": "heavy intensity rain",
+ "icon": "10d"
+ }
+ ],
+ "clouds": 100,
+ "pop": 1,
+ "rain": 12.43
+ }
+ ]
+} \ No newline at end of file
diff --git a/weather-widget/negative.png b/weather-widget/negative.png
new file mode 100644
index 0000000..afcf567
--- /dev/null
+++ b/weather-widget/negative.png
Binary files differ
diff --git a/weather-widget/screenshots/weather-widget.png b/weather-widget/screenshots/weather-widget.png
deleted file mode 100644
index c7fc37e..0000000
--- a/weather-widget/screenshots/weather-widget.png
+++ /dev/null
Binary files differ
diff --git a/weather-widget/weather-widget.png b/weather-widget/weather-widget.png
index 177b350..c7fc37e 100644
--- a/weather-widget/weather-widget.png
+++ b/weather-widget/weather-widget.png
Binary files differ
diff --git a/weather-widget/weather.json b/weather-widget/weather.json
deleted file mode 100644
index 4a18714..0000000
--- a/weather-widget/weather.json
+++ /dev/null
@@ -1,1224 +0,0 @@
-{
- "lat": 33.44,
- "lon": -94.04,
- "timezone": "America/Chicago",
- "timezone_offset": -18000,
- "current": {
- "dt": 1594490161,
- "sunrise": 1594466108,
- "sunset": 1594517275,
- "temp": 32.69,
- "feels_like": 36.81,
- "pressure": 1017,
- "humidity": 59,
- "dew_point": 23.63,
- "uvi": 7.94,
- "clouds": 40,
- "visibility": 16093,
- "wind_speed": 2.1,
- "wind_deg": 250,
- "weather": [
- {
- "id": 802,
- "main": "Clear Sky",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- "hourly": [
- {
- "dt": 1594486800,
- "temp": 32.69,
- "feels_like": 36.4,
- "pressure": 1017,
- "humidity": 59,
- "dew_point": 23.63,
- "clouds": 40,
- "wind_speed": 2.68,
- "wind_deg": 242,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ]
- },
- {
- "dt": 1594490400,
- "temp": 33.38,
- "feels_like": 37.27,
- "pressure": 1017,
- "humidity": 59,
- "dew_point": 24.27,
- "clouds": 21,
- "wind_speed": 2.97,
- "wind_deg": 248,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02d"
- }
- ]
- },
- {
- "dt": 1594494000,
- "temp": 34.44,
- "feels_like": 38.38,
- "pressure": 1015,
- "humidity": 55,
- "dew_point": 24.09,
- "clouds": 28,
- "wind_speed": 2.74,
- "wind_deg": 254,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ]
- },
- {
- "dt": 1594497600,
- "temp": 35.32,
- "feels_like": 39.58,
- "pressure": 1014,
- "humidity": 53,
- "dew_point": 24.28,
- "clouds": 18,
- "wind_speed": 2.45,
- "wind_deg": 260,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02d"
- }
- ]
- },
- {
- "dt": 1594501200,
- "temp": 35.57,
- "feels_like": 39.73,
- "pressure": 1013,
- "humidity": 52,
- "dew_point": 24.19,
- "clouds": 16,
- "wind_speed": 2.52,
- "wind_deg": 259,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02d"
- }
- ]
- },
- {
- "dt": 1594504800,
- "temp": 35.34,
- "feels_like": 39.82,
- "pressure": 1012,
- "humidity": 55,
- "dew_point": 25.07,
- "clouds": 13,
- "wind_speed": 2.68,
- "wind_deg": 256,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02d"
- }
- ]
- },
- {
- "dt": 1594508400,
- "temp": 34.85,
- "feels_like": 40.34,
- "pressure": 1012,
- "humidity": 61,
- "dew_point": 26.36,
- "clouds": 10,
- "wind_speed": 2.42,
- "wind_deg": 249,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594512000,
- "temp": 33.39,
- "feels_like": 39.08,
- "pressure": 1012,
- "humidity": 67,
- "dew_point": 26.53,
- "clouds": 9,
- "wind_speed": 2.34,
- "wind_deg": 246,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594515600,
- "temp": 30.82,
- "feels_like": 35.85,
- "pressure": 1012,
- "humidity": 73,
- "dew_point": 25.61,
- "clouds": 0,
- "wind_speed": 2.35,
- "wind_deg": 240,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594519200,
- "temp": 29.56,
- "feels_like": 33.64,
- "pressure": 1012,
- "humidity": 73,
- "dew_point": 24.34,
- "clouds": 0,
- "wind_speed": 2.65,
- "wind_deg": 227,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594522800,
- "temp": 28.72,
- "feels_like": 32.55,
- "pressure": 1012,
- "humidity": 75,
- "dew_point": 23.97,
- "clouds": 0,
- "wind_speed": 2.7,
- "wind_deg": 223,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594526400,
- "temp": 27.79,
- "feels_like": 31.42,
- "pressure": 1012,
- "humidity": 77,
- "dew_point": 23.56,
- "clouds": 0,
- "wind_speed": 2.61,
- "wind_deg": 211,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594530000,
- "temp": 27.27,
- "feels_like": 30.91,
- "pressure": 1012,
- "humidity": 79,
- "dew_point": 23.39,
- "clouds": 0,
- "wind_speed": 2.54,
- "wind_deg": 226,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594533600,
- "temp": 27.17,
- "feels_like": 30.72,
- "pressure": 1012,
- "humidity": 79,
- "dew_point": 23.23,
- "clouds": 0,
- "wind_speed": 2.58,
- "wind_deg": 213,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594537200,
- "temp": 26.91,
- "feels_like": 30.06,
- "pressure": 1012,
- "humidity": 78,
- "dew_point": 22.95,
- "clouds": 0,
- "wind_speed": 2.79,
- "wind_deg": 225,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594540800,
- "temp": 26.57,
- "feels_like": 29.76,
- "pressure": 1011,
- "humidity": 79,
- "dew_point": 22.68,
- "clouds": 33,
- "wind_speed": 2.63,
- "wind_deg": 217,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03n"
- }
- ]
- },
- {
- "dt": 1594544400,
- "temp": 26.39,
- "feels_like": 28.98,
- "pressure": 1011,
- "humidity": 78,
- "dew_point": 22.36,
- "clouds": 56,
- "wind_speed": 3.19,
- "wind_deg": 191,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04n"
- }
- ]
- },
- {
- "dt": 1594548000,
- "temp": 25.97,
- "feels_like": 29.15,
- "pressure": 1011,
- "humidity": 79,
- "dew_point": 22.12,
- "clouds": 67,
- "wind_speed": 2.2,
- "wind_deg": 211,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04n"
- }
- ]
- },
- {
- "dt": 1594551600,
- "temp": 25.6,
- "feels_like": 28.65,
- "pressure": 1012,
- "humidity": 79,
- "dew_point": 21.77,
- "clouds": 72,
- "wind_speed": 2.12,
- "wind_deg": 257,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04n"
- }
- ]
- },
- {
- "dt": 1594555200,
- "temp": 25.25,
- "feels_like": 29.31,
- "pressure": 1012,
- "humidity": 84,
- "dew_point": 22.42,
- "clouds": 74,
- "wind_speed": 1.18,
- "wind_deg": 276,
- "weather": [
- {
- "id": 500,
- "main": "Rain",
- "description": "light rain",
- "icon": "10d"
- }
- ],
- "rain": {
- "1h": 0.66
- }
- },
- {
- "dt": 1594558800,
- "temp": 26.51,
- "feels_like": 31.02,
- "pressure": 1013,
- "humidity": 82,
- "dew_point": 23.22,
- "clouds": 91,
- "wind_speed": 1.19,
- "wind_deg": 227,
- "weather": [
- {
- "id": 500,
- "main": "Rain",
- "description": "light rain",
- "icon": "10d"
- }
- ],
- "rain": {
- "1h": 0.5
- }
- },
- {
- "dt": 1594562400,
- "temp": 27.99,
- "feels_like": 31.34,
- "pressure": 1012,
- "humidity": 75,
- "dew_point": 23.26,
- "clouds": 87,
- "wind_speed": 2.82,
- "wind_deg": 223,
- "weather": [
- {
- "id": 804,
- "main": "Clouds",
- "description": "overcast clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594566000,
- "temp": 29.6,
- "feels_like": 32.28,
- "pressure": 1012,
- "humidity": 67,
- "dew_point": 23.02,
- "clouds": 63,
- "wind_speed": 3.51,
- "wind_deg": 236,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594569600,
- "temp": 31.12,
- "feels_like": 33.49,
- "pressure": 1011,
- "humidity": 62,
- "dew_point": 23.22,
- "clouds": 52,
- "wind_speed": 4.08,
- "wind_deg": 239,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594573200,
- "temp": 32.66,
- "feels_like": 35.05,
- "pressure": 1011,
- "humidity": 58,
- "dew_point": 23.6,
- "clouds": 46,
- "wind_speed": 4.31,
- "wind_deg": 238,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ]
- },
- {
- "dt": 1594576800,
- "temp": 34.15,
- "feels_like": 36.59,
- "pressure": 1011,
- "humidity": 54,
- "dew_point": 23.74,
- "clouds": 40,
- "wind_speed": 4.4,
- "wind_deg": 236,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ]
- },
- {
- "dt": 1594580400,
- "temp": 35.24,
- "feels_like": 37.8,
- "pressure": 1010,
- "humidity": 51,
- "dew_point": 23.83,
- "clouds": 0,
- "wind_speed": 4.27,
- "wind_deg": 246,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594584000,
- "temp": 35.73,
- "feels_like": 38.39,
- "pressure": 1009,
- "humidity": 50,
- "dew_point": 23.92,
- "clouds": 0,
- "wind_speed": 4.23,
- "wind_deg": 262,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594587600,
- "temp": 35.89,
- "feels_like": 38.87,
- "pressure": 1008,
- "humidity": 51,
- "dew_point": 24.29,
- "clouds": 0,
- "wind_speed": 4.17,
- "wind_deg": 267,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594591200,
- "temp": 35.63,
- "feels_like": 39.46,
- "pressure": 1008,
- "humidity": 55,
- "dew_point": 25.31,
- "clouds": 0,
- "wind_speed": 3.85,
- "wind_deg": 266,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594594800,
- "temp": 35,
- "feels_like": 39.97,
- "pressure": 1007,
- "humidity": 61,
- "dew_point": 26.37,
- "clouds": 0,
- "wind_speed": 3.3,
- "wind_deg": 262,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594598400,
- "temp": 33.25,
- "feels_like": 38.23,
- "pressure": 1007,
- "humidity": 66,
- "dew_point": 26.08,
- "clouds": 0,
- "wind_speed": 2.98,
- "wind_deg": 259,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594602000,
- "temp": 30.86,
- "feels_like": 35.71,
- "pressure": 1008,
- "humidity": 72,
- "dew_point": 25.37,
- "clouds": 0,
- "wind_speed": 2.44,
- "wind_deg": 254,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ]
- },
- {
- "dt": 1594605600,
- "temp": 29.71,
- "feels_like": 34.14,
- "pressure": 1008,
- "humidity": 72,
- "dew_point": 24.24,
- "clouds": 0,
- "wind_speed": 2.07,
- "wind_deg": 246,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594609200,
- "temp": 29.09,
- "feels_like": 33.6,
- "pressure": 1009,
- "humidity": 73,
- "dew_point": 23.92,
- "clouds": 0,
- "wind_speed": 1.65,
- "wind_deg": 239,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594612800,
- "temp": 28.41,
- "feels_like": 33.33,
- "pressure": 1009,
- "humidity": 75,
- "dew_point": 23.77,
- "clouds": 0,
- "wind_speed": 0.9,
- "wind_deg": 301,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594616400,
- "temp": 27.65,
- "feels_like": 31.94,
- "pressure": 1010,
- "humidity": 79,
- "dew_point": 23.7,
- "clouds": 0,
- "wind_speed": 1.9,
- "wind_deg": 342,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594620000,
- "temp": 26.81,
- "feels_like": 30.18,
- "pressure": 1010,
- "humidity": 78,
- "dew_point": 22.81,
- "clouds": 0,
- "wind_speed": 2.39,
- "wind_deg": 13,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594623600,
- "temp": 25.86,
- "feels_like": 28.37,
- "pressure": 1010,
- "humidity": 75,
- "dew_point": 21.3,
- "clouds": 0,
- "wind_speed": 2.45,
- "wind_deg": 41,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594627200,
- "temp": 24.94,
- "feels_like": 26.96,
- "pressure": 1010,
- "humidity": 75,
- "dew_point": 20.36,
- "clouds": 0,
- "wind_speed": 2.53,
- "wind_deg": 49,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594630800,
- "temp": 23.94,
- "feels_like": 25.44,
- "pressure": 1010,
- "humidity": 78,
- "dew_point": 19.9,
- "clouds": 2,
- "wind_speed": 3.05,
- "wind_deg": 56,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01n"
- }
- ]
- },
- {
- "dt": 1594634400,
- "temp": 23.22,
- "feels_like": 25.05,
- "pressure": 1011,
- "humidity": 81,
- "dew_point": 19.94,
- "clouds": 14,
- "wind_speed": 2.51,
- "wind_deg": 65,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02n"
- }
- ]
- },
- {
- "dt": 1594638000,
- "temp": 22.87,
- "feels_like": 24.56,
- "pressure": 1011,
- "humidity": 81,
- "dew_point": 19.61,
- "clouds": 17,
- "wind_speed": 2.48,
- "wind_deg": 74,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02n"
- }
- ]
- },
- {
- "dt": 1594641600,
- "temp": 22.82,
- "feels_like": 24.7,
- "pressure": 1012,
- "humidity": 83,
- "dew_point": 19.8,
- "clouds": 29,
- "wind_speed": 2.44,
- "wind_deg": 63,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ]
- },
- {
- "dt": 1594645200,
- "temp": 23.84,
- "feels_like": 25.88,
- "pressure": 1013,
- "humidity": 80,
- "dew_point": 20.21,
- "clouds": 100,
- "wind_speed": 2.48,
- "wind_deg": 62,
- "weather": [
- {
- "id": 804,
- "main": "Clouds",
- "description": "overcast clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594648800,
- "temp": 25,
- "feels_like": 27,
- "pressure": 1013,
- "humidity": 75,
- "dew_point": 20.37,
- "clouds": 100,
- "wind_speed": 2.59,
- "wind_deg": 67,
- "weather": [
- {
- "id": 804,
- "main": "Clouds",
- "description": "overcast clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594652400,
- "temp": 26.18,
- "feels_like": 27.69,
- "pressure": 1012,
- "humidity": 73,
- "dew_point": 21.06,
- "clouds": 100,
- "wind_speed": 3.79,
- "wind_deg": 101,
- "weather": [
- {
- "id": 804,
- "main": "Clouds",
- "description": "overcast clouds",
- "icon": "04d"
- }
- ]
- },
- {
- "dt": 1594656000,
- "temp": 28.36,
- "feels_like": 30.56,
- "pressure": 1012,
- "humidity": 69,
- "dew_point": 22.32,
- "clouds": 83,
- "wind_speed": 3.66,
- "wind_deg": 128,
- "weather": [
- {
- "id": 803,
- "main": "Clouds",
- "description": "broken clouds",
- "icon": "04d"
- }
- ]
- }
- ],
- "daily": [
- {
- "dt": 1594490400,
- "sunrise": 1594466108,
- "sunset": 1594517275,
- "temp": {
- "day": 33.38,
- "min": 27.17,
- "max": 34.96,
- "night": 27.17,
- "eve": 33.35,
- "morn": 32.69
- },
- "feels_like": {
- "day": 37.27,
- "night": 30.72,
- "eve": 39.01,
- "morn": 36.67
- },
- "pressure": 1017,
- "humidity": 59,
- "dew_point": 24.27,
- "wind_speed": 2.97,
- "wind_deg": 248,
- "weather": [
- {
- "id": 801,
- "main": "Clouds",
- "description": "few clouds",
- "icon": "02d"
- }
- ],
- "clouds": 21,
- "uvi": 11.94
- },
- {
- "dt": 1594576800,
- "sunrise": 1594552543,
- "sunset": 1594603655,
- "temp": {
- "day": 34.15,
- "min": 25.25,
- "max": 35.89,
- "night": 26.81,
- "eve": 33.25,
- "morn": 25.25
- },
- "feels_like": {
- "day": 36.59,
- "night": 30.18,
- "eve": 38.23,
- "morn": 29.31
- },
- "pressure": 1011,
- "humidity": 54,
- "dew_point": 23.74,
- "wind_speed": 4.4,
- "wind_deg": 236,
- "weather": [
- {
- "id": 500,
- "main": "Rain",
- "description": "light rain",
- "icon": "10d"
- }
- ],
- "clouds": 40,
- "rain": 1.16,
- "uvi": 11.61
- },
- {
- "dt": 1594663200,
- "sunrise": 1594638978,
- "sunset": 1594690034,
- "temp": {
- "day": 29.22,
- "min": 22.82,
- "max": 29.22,
- "night": 26.71,
- "eve": 28.98,
- "morn": 22.82
- },
- "feels_like": {
- "day": 34.31,
- "night": 28.82,
- "eve": 34.45,
- "morn": 24.7
- },
- "pressure": 1012,
- "humidity": 72,
- "dew_point": 23.66,
- "wind_speed": 0.74,
- "wind_deg": 287,
- "weather": [
- {
- "id": 804,
- "main": "Clouds",
- "description": "overcast clouds",
- "icon": "04d"
- }
- ],
- "clouds": 85,
- "uvi": 12.72
- },
- {
- "dt": 1594749600,
- "sunrise": 1594725414,
- "sunset": 1594776411,
- "temp": {
- "day": 33.67,
- "min": 24.06,
- "max": 35.68,
- "night": 25.94,
- "eve": 32.24,
- "morn": 24.06
- },
- "feels_like": {
- "day": 35.84,
- "night": 27.78,
- "eve": 35.66,
- "morn": 27.28
- },
- "pressure": 1012,
- "humidity": 50,
- "dew_point": 21.95,
- "wind_speed": 3.45,
- "wind_deg": 183,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ],
- "clouds": 9,
- "uvi": 11.67
- },
- {
- "dt": 1594836000,
- "sunrise": 1594811851,
- "sunset": 1594862786,
- "temp": {
- "day": 32.79,
- "min": 24.61,
- "max": 35.24,
- "night": 26.42,
- "eve": 31.72,
- "morn": 24.61
- },
- "feels_like": {
- "day": 34.67,
- "night": 28.57,
- "eve": 35.11,
- "morn": 27.47
- },
- "pressure": 1014,
- "humidity": 53,
- "dew_point": 22.04,
- "wind_speed": 3.97,
- "wind_deg": 208,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ],
- "clouds": 35,
- "uvi": 11.55
- },
- {
- "dt": 1594922400,
- "sunrise": 1594898288,
- "sunset": 1594949160,
- "temp": {
- "day": 33.89,
- "min": 24.07,
- "max": 35.5,
- "night": 26.61,
- "eve": 32.58,
- "morn": 24.07
- },
- "feels_like": {
- "day": 35.74,
- "night": 29.39,
- "eve": 36.52,
- "morn": 27.33
- },
- "pressure": 1015,
- "humidity": 49,
- "dew_point": 22.01,
- "wind_speed": 3.81,
- "wind_deg": 225,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ],
- "clouds": 29,
- "uvi": 11.67
- },
- {
- "dt": 1595008800,
- "sunrise": 1594984726,
- "sunset": 1595035532,
- "temp": {
- "day": 34.95,
- "min": 24.45,
- "max": 36.42,
- "night": 26.97,
- "eve": 33.81,
- "morn": 24.45
- },
- "feels_like": {
- "day": 38.11,
- "night": 29.69,
- "eve": 38.22,
- "morn": 26.84
- },
- "pressure": 1016,
- "humidity": 50,
- "dew_point": 23.17,
- "wind_speed": 2.94,
- "wind_deg": 230,
- "weather": [
- {
- "id": 802,
- "main": "Clouds",
- "description": "scattered clouds",
- "icon": "03d"
- }
- ],
- "clouds": 46,
- "uvi": 11.86
- },
- {
- "dt": 1595095200,
- "sunrise": 1595071164,
- "sunset": 1595121903,
- "temp": {
- "day": 35.47,
- "min": 24.4,
- "max": 37.04,
- "night": 28.18,
- "eve": 34.23,
- "morn": 24.4
- },
- "feels_like": {
- "day": 38.15,
- "night": 30.61,
- "eve": 38.67,
- "morn": 26.95
- },
- "pressure": 1015,
- "humidity": 46,
- "dew_point": 22.36,
- "wind_speed": 2.93,
- "wind_deg": 238,
- "weather": [
- {
- "id": 800,
- "main": "Clear",
- "description": "clear sky",
- "icon": "01d"
- }
- ],
- "clouds": 2,
- "uvi": 11.67
- }
- ]
-} \ No newline at end of file
diff --git a/weather-widget/weather.lua b/weather-widget/weather.lua
index 3d3b8e0..1465c0c 100644
--- a/weather-widget/weather.lua
+++ b/weather-widget/weather.lua
@@ -140,7 +140,7 @@ local function worker(args)
local timeout = args.timeout or 120
local owm_one_cal_api =
- ('https://api.openweathermap.org/data/2.5/onecall' ..
+ ('https://api.openweathermap.org/data/2.5/onecall' ..
'?lat=' .. coordinates[1] .. '&lon=' .. coordinates[2] .. '&appid=' .. api_key ..
'&units=' .. units .. '&exclude=minutely' ..
(show_hourly_forecast == false and ',hourly' or '') ..
@@ -325,12 +325,27 @@ local function worker(args)
self.min_value = new_min_value
end
}
+ local hourly_forecast_negative_graph = wibox.widget {
+ step_width = 12,
+ color = '#5E81AC',
+ background_color = beautiful.bg_normal,
+ forced_height = 100,
+ forced_width = 300,
+ widget = wibox.widget.graph,
+ set_max_value = function(self, new_max_value)
+ self.max_value = new_max_value
+ end,
+ set_min_value = function(self, new_min_value)
+ self.min_value = new_min_value
+ end
+ }
local hourly_forecast_widget = {
layout = wibox.layout.fixed.vertical,
update = function(self, hourly)
local hours_below = {
id = 'hours',
+ forced_width = 300,
layout = wibox.layout.flex.horizontal
}
local temp_below = {
@@ -355,37 +370,101 @@ local function worker(args)
widget = wibox.widget.textbox
})
table.insert(temp_below, wibox.widget {
- markup = '<span foreground="#2E3440">' .. string.format('%.0f', hour.temp) .. '°' .. '</span>',
+ markup = '<span >' .. string.format('%.0f', hour.temp) .. '°' .. '</span>',
align = 'center',
font = font_name .. ' 9',
widget = wibox.widget.textbox
})
end
end
- hourly_forecast_graph:set_max_value(max_temp)
- hourly_forecast_graph:set_min_value(min_temp * 0.7) -- move graph a bit up
+
+ hourly_forecast_graph:set_max_value(math.max(max_temp, math.abs(min_temp)))
+ hourly_forecast_graph:set_min_value(min_temp > 0 and min_temp * 0.7 or 0) -- move graph a bit up
+
+ hourly_forecast_negative_graph:set_max_value(math.abs(min_temp))
+ hourly_forecast_negative_graph:set_min_value(max_temp < 0 and math.abs(max_temp) * 0.7 or 0)
+
for i, value in ipairs(values) do
- hourly_forecast_graph:add_value(value)
+ print(value)
+ if value >= 0 then
+ hourly_forecast_graph:add_value(value)
+ hourly_forecast_negative_graph:add_value(0)
+ else
+ hourly_forecast_graph:add_value(0)
+ hourly_forecast_negative_graph:add_value(math.abs(value))
+ end
end
local count = #self
for i = 0, count do self[i]=nil end
- table.insert(self, wibox.widget{
- {
- hourly_forecast_graph,
- reflection = {horizontal = true},
- widget = wibox.container.mirror
- },
- {
- temp_below,
- valign = 'bottom',
- widget = wibox.container.place
- },
- id = 'graph',
- layout = wibox.layout.stack
- })
- table.insert(self, hours_below)
+ -- all temperatures are positive
+ if min_temp > 0 then
+ table.insert(self, wibox.widget{
+ {
+ hourly_forecast_graph,
+ reflection = {horizontal = true},
+ widget = wibox.container.mirror
+ },
+ {
+ temp_below,
+ valign = 'bottom',
+ widget = wibox.container.place
+ },
+ id = 'graph',
+ layout = wibox.layout.stack
+ })
+ table.insert(self, hours_below)
+
+ -- all temperatures are negative
+ elseif max_temp < 0 then
+ table.insert(self, hours_below)
+ table.insert(self, wibox.widget{
+ {
+ hourly_forecast_negative_graph,
+ reflection = {horizontal = true, vertical = true},
+ widget = wibox.container.mirror
+ },
+ {
+ temp_below,
+ valign = 'top',
+ widget = wibox.container.place
+ },
+ id = 'graph',
+ layout = wibox.layout.stack
+ })
+
+ -- there are both negative and positive temperatures
+ else
+ table.insert(self, wibox.widget{
+ {
+ hourly_forecast_graph,
+ reflection = {horizontal = true},
+ widget = wibox.container.mirror
+ },
+ {
+ temp_below,
+ valign = 'bottom',
+ widget = wibox.container.place
+ },
+ id = 'graph',
+ layout = wibox.layout.stack
+ })
+ table.insert(self, wibox.widget{
+ {
+ hourly_forecast_negative_graph,
+ reflection = {horizontal = true, vertical = true},
+ widget = wibox.container.mirror
+ },
+ {
+ hours_below,
+ valign = 'top',
+ widget = wibox.container.place
+ },
+ id = 'graph',
+ layout = wibox.layout.stack
+ })
+ end
end
}