[bitbucket] add more information to the widget
added: - number of comments - number of approves - source/target branch - when was created (number of days ago) - creator
This commit is contained in:
parent
032cf6d7d7
commit
6de58c7700
|
@ -19,8 +19,9 @@ local beautiful = require("beautiful")
|
||||||
local gfs = require("gears.filesystem")
|
local gfs = require("gears.filesystem")
|
||||||
|
|
||||||
local HOME_DIR = os.getenv("HOME")
|
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 DOWNLOAD_AVATAR_CMD = [[bash -c "curl -L -n --create-dirs -o %s/.cache/awmw/bitbucket-widget/avatars/%s %s"]]
|
||||||
|
|
||||||
local bitbucket_widget = wibox.widget {
|
local bitbucket_widget = wibox.widget {
|
||||||
|
@ -67,11 +68,54 @@ local popup = awful.popup{
|
||||||
widget = {}
|
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 function worker(args)
|
||||||
|
|
||||||
local args = args or {}
|
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 host = args.host or show_warning('Bitbucket host is not set')
|
||||||
local uuid = args.uuid or show_warning('UUID 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')
|
local workspace = args.workspace or show_warning('Workspace is not set')
|
||||||
|
@ -129,52 +173,100 @@ local function worker(args)
|
||||||
bg = beautiful.bg_normal,
|
bg = beautiful.bg_normal,
|
||||||
widget = wibox.container.background
|
widget = wibox.container.background
|
||||||
})
|
})
|
||||||
|
local current_time = os.time(os.date("!*t"))
|
||||||
|
|
||||||
for _, pr in ipairs(result) do
|
for _, pr in ipairs(result) do
|
||||||
local path_to_avatar = os.getenv("HOME") ..'/.cache/awmw/bitbucket-widget/avatars/' .. pr.author.uuid
|
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 {
|
local row = wibox.widget {
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
resize = true,
|
resize = true,
|
||||||
image = path_to_avatar,
|
image = path_to_avatar,
|
||||||
forced_width = 40,
|
forced_width = 40,
|
||||||
forced_height = 40,
|
forced_height = 40,
|
||||||
widget = wibox.widget.imagebox
|
widget = wibox.widget.imagebox
|
||||||
},
|
},
|
||||||
id = 'avatar',
|
id = 'avatar',
|
||||||
margins = 8,
|
margins = 8,
|
||||||
layout = wibox.container.margin
|
layout = wibox.container.margin
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
id = 'title',
|
id = 'title',
|
||||||
markup = '<b>' .. pr.title .. '</b>',
|
markup = '<b>' .. ellipsize(pr.title, 50) .. '</b>',
|
||||||
widget = wibox.widget.textbox
|
widget = wibox.widget.textbox,
|
||||||
|
forced_width = 400
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
text = pr.source.branch.name,
|
{
|
||||||
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 = '->',
|
{
|
||||||
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
|
||||||
},
|
},
|
||||||
{
|
|
||||||
text = pr.destination.branch.name,
|
|
||||||
widget = wibox.widget.textbox
|
|
||||||
},
|
|
||||||
spacing = 8,
|
|
||||||
layout = wibox.layout.fixed.horizontal
|
layout = wibox.layout.fixed.horizontal
|
||||||
},
|
},
|
||||||
{
|
|
||||||
text = pr.author.display_name,
|
spacing = 8,
|
||||||
widget = wibox.widget.textbox
|
layout = wibox.layout.fixed.vertical
|
||||||
},
|
|
||||||
layout = wibox.layout.align.vertical
|
|
||||||
},
|
},
|
||||||
spacing = 8,
|
spacing = 8,
|
||||||
layout = wibox.layout.fixed.horizontal
|
layout = wibox.layout.fixed.horizontal
|
||||||
|
@ -250,7 +342,7 @@ local function worker(args)
|
||||||
|
|
||||||
table.insert(rows, to_review_rows)
|
table.insert(rows, to_review_rows)
|
||||||
if (#my_review_rows > 1) then
|
if (#my_review_rows > 1) then
|
||||||
table.insert(rows, my_review_rows)
|
table.insert(rows, my_review_rows)
|
||||||
end
|
end
|
||||||
popup:setup(rows)
|
popup:setup(rows)
|
||||||
end
|
end
|
||||||
|
|
|
@ -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>
|
After Width: | Height: | Size: 257 B |
|
@ -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>
|
After Width: | Height: | Size: 366 B |
|
@ -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>
|
After Width: | Height: | Size: 346 B |
|
@ -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>
|
After Width: | Height: | Size: 382 B |
|
@ -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>
|
After Width: | Height: | Size: 423 B |
|
@ -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>
|
After Width: | Height: | Size: 308 B |
Loading…
Reference in New Issue