Paginator viewing for issues, merge requests, and milestones
This commit is contained in:
parent
2ba042aedc
commit
5622209f4d
2 changed files with 221 additions and 113 deletions
|
@ -34,7 +34,8 @@ class ErrorHandlerCog(commands.Cog):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"Error processing command:\n```{error}```", hidden=True
|
f"Error processing command:\n```{error}```",
|
||||||
|
hidden=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,36 +17,6 @@ from jarvis.utils.field import Field
|
||||||
guild_ids = [862402786116763668]
|
guild_ids = [862402786116763668]
|
||||||
|
|
||||||
|
|
||||||
def create_layout(command: str):
|
|
||||||
buttons = [
|
|
||||||
manage_components.create_button(
|
|
||||||
style=ButtonStyle.gray, emoji="◀", custom_id=f"back_{command}"
|
|
||||||
),
|
|
||||||
manage_components.create_button(
|
|
||||||
style=ButtonStyle.gray,
|
|
||||||
emoji="▶",
|
|
||||||
custom_id=f"next_{command}",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
action_row = manage_components.spread_to_rows(*buttons, max_in_row=2)
|
|
||||||
return action_row
|
|
||||||
|
|
||||||
|
|
||||||
def create_issues_layout():
|
|
||||||
return create_layout("issues")
|
|
||||||
|
|
||||||
|
|
||||||
def edit_paging_components(
|
|
||||||
components: list, disable_left: bool = False, disable_right: bool = False
|
|
||||||
):
|
|
||||||
components[0]["components"][0]["disabled"] = disable_left
|
|
||||||
components[0]["components"][1]["disabled"] = disable_right
|
|
||||||
return components
|
|
||||||
|
|
||||||
|
|
||||||
command_lookup = {"issues": create_issues_layout}
|
|
||||||
|
|
||||||
|
|
||||||
class GitlabCog(commands.Cog):
|
class GitlabCog(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -200,7 +170,7 @@ class GitlabCog(commands.Cog):
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(
|
@cog_ext.cog_subcommand(
|
||||||
base="gl",
|
base="gl",
|
||||||
name="mr",
|
name="mergerequest",
|
||||||
description="Get an merge request from GitLab",
|
description="Get an merge request from GitLab",
|
||||||
guild_ids=guild_ids,
|
guild_ids=guild_ids,
|
||||||
options=[
|
options=[
|
||||||
|
@ -212,7 +182,7 @@ class GitlabCog(commands.Cog):
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def _mr(self, ctx: SlashContext, id: int):
|
async def _mergerequest(self, ctx: SlashContext, id: int):
|
||||||
try:
|
try:
|
||||||
mr = self.project.mergerequests.get(int(id))
|
mr = self.project.mergerequests.get(int(id))
|
||||||
except gitlab.exceptions.GitlabGetError:
|
except gitlab.exceptions.GitlabGetError:
|
||||||
|
@ -283,23 +253,28 @@ class GitlabCog(commands.Cog):
|
||||||
)
|
)
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|
||||||
def build_embed_page(self, issues: list, t_state: str):
|
def build_embed_page(self, api_list: list, t_state: str, name: str):
|
||||||
|
title = ""
|
||||||
|
if t_state:
|
||||||
|
title = f"{t_state} "
|
||||||
|
title += f"J.A.R.V.I.S. {name}s"
|
||||||
fields = []
|
fields = []
|
||||||
for issue in issues:
|
for item in api_list:
|
||||||
fields.append(
|
fields.append(
|
||||||
Field(
|
Field(
|
||||||
name=f"[#{issue.iid}] {issue.title}",
|
name=f"[#{item.iid}] {item.title}",
|
||||||
value=issue.description
|
value=item.description
|
||||||
+ f"\n\n[View this issue]({issue.web_url})",
|
+ f"\n\n[View this {name}]({item.web_url})",
|
||||||
inline=False,
|
inline=False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
embed = build_embed(
|
embed = build_embed(
|
||||||
title=f"{t_state} J.A.R.V.I.S. issues",
|
title=title,
|
||||||
description="",
|
description="",
|
||||||
fields=fields,
|
fields=fields,
|
||||||
url="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./issues",
|
url="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./"
|
||||||
|
+ f"{name.replace(' ', '_')}s",
|
||||||
)
|
)
|
||||||
embed.set_author(
|
embed.set_author(
|
||||||
name="J.A.R.V.I.S.",
|
name="J.A.R.V.I.S.",
|
||||||
|
@ -313,6 +288,16 @@ class GitlabCog(commands.Cog):
|
||||||
)
|
)
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
def check_cache(self, ctx: SlashContext, **kwargs):
|
||||||
|
if not kwargs:
|
||||||
|
kwargs = {}
|
||||||
|
return find(
|
||||||
|
lambda x: x["command"] == ctx.subcommand_name
|
||||||
|
and x["user"] == ctx.author.id
|
||||||
|
and all(x[k] == v for k, v in kwargs.items()),
|
||||||
|
self.cache.values(),
|
||||||
|
)
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(
|
@cog_ext.cog_subcommand(
|
||||||
base="gl",
|
base="gl",
|
||||||
name="issues",
|
name="issues",
|
||||||
|
@ -333,17 +318,12 @@ class GitlabCog(commands.Cog):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def _issues(self, ctx: SlashContext, state: str = "opened"):
|
async def _issues(self, ctx: SlashContext, state: str = "opened"):
|
||||||
exists = find(
|
exists = self.check_cache(ctx, state=state)
|
||||||
lambda x: x["_command"] == "issues"
|
|
||||||
and x["user"] == ctx.author.id
|
|
||||||
and x["state"] == state,
|
|
||||||
self.cache.values(),
|
|
||||||
)
|
|
||||||
if exists:
|
if exists:
|
||||||
await ctx.defer(hidden=True)
|
await ctx.defer(hidden=True)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
"Please use existing interaction: "
|
"Please use existing interaction: "
|
||||||
+ f"{exists['_message'].jump_url}",
|
+ f"{exists['paginator']._message.jump_url}",
|
||||||
hidden=True,
|
hidden=True,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
@ -351,91 +331,221 @@ class GitlabCog(commands.Cog):
|
||||||
m_state = state
|
m_state = state
|
||||||
if m_state == "all":
|
if m_state == "all":
|
||||||
m_state = None
|
m_state = None
|
||||||
# issues = []
|
issues = []
|
||||||
# page = 1
|
page = 1
|
||||||
try:
|
try:
|
||||||
# issues += self.project.issues.list(page=page, state=m_state, order_by="created_at", sort="desc", per_page=100)
|
while curr_page := self.project.issues.list(
|
||||||
issues = self.project.issues.list(
|
page=page,
|
||||||
page=1,
|
|
||||||
state=m_state,
|
state=m_state,
|
||||||
order_by="created_at",
|
order_by="created_at",
|
||||||
sort="desc",
|
sort="desc",
|
||||||
per_page=5,
|
per_page=100,
|
||||||
)
|
):
|
||||||
next_issues = self.project.issues.list(
|
issues += curr_page
|
||||||
page=2,
|
page += 1
|
||||||
state=m_state,
|
|
||||||
order_by="created_at",
|
|
||||||
sort="desc",
|
|
||||||
per_page=5,
|
|
||||||
)
|
|
||||||
except gitlab.exceptions.GitlabGetError:
|
except gitlab.exceptions.GitlabGetError:
|
||||||
await ctx.send("Unable to get issues", hidden=True)
|
# Only send error on first page. Otherwise, use pages retrieved
|
||||||
|
if page == 1:
|
||||||
|
await ctx.send("Unable to get issues")
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(issues) == 0:
|
||||||
|
await ctx.send("No issues match that criteria")
|
||||||
return
|
return
|
||||||
|
|
||||||
t_state = state
|
t_state = state
|
||||||
if t_state == "opened":
|
if t_state == "opened":
|
||||||
t_state = "open"
|
t_state = "open"
|
||||||
|
pages = []
|
||||||
t_state = t_state[0].upper() + t_state[1:]
|
t_state = t_state[0].upper() + t_state[1:]
|
||||||
|
for i in range(0, len(issues), 5):
|
||||||
|
pages.append(
|
||||||
|
self.build_embed_page(
|
||||||
|
issues[i : i + 5], t_state=t_state, name="issue"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
components = create_issues_layout()
|
paginator = Paginator(
|
||||||
components = edit_paging_components(
|
bot=self.bot,
|
||||||
components, True, next_issues == []
|
ctx=ctx,
|
||||||
|
embeds=pages,
|
||||||
|
only=ctx.author,
|
||||||
|
timeout=60 * 5, # 5 minute timeout
|
||||||
|
disable_after_timeout=True,
|
||||||
|
use_extend=len(pages) > 2,
|
||||||
|
left_button_style=ButtonStyle.grey,
|
||||||
|
right_button_style=ButtonStyle.grey,
|
||||||
|
basic_buttons=["◀", "▶"],
|
||||||
)
|
)
|
||||||
embed = self.build_embed_page(issues, t_state=t_state)
|
|
||||||
message = await ctx.send(embed=embed, components=components)
|
self.cache[hash(paginator)] = {
|
||||||
self.cache[message.id] = {
|
|
||||||
"user": ctx.author.id,
|
"user": ctx.author.id,
|
||||||
"state": state,
|
|
||||||
"t_state": t_state,
|
|
||||||
"page": 1,
|
|
||||||
"timeout": datetime.utcnow() + timedelta(minutes=5),
|
"timeout": datetime.utcnow() + timedelta(minutes=5),
|
||||||
"_command": "issues",
|
"command": ctx.subcommand_name,
|
||||||
"_message": message,
|
"state": state,
|
||||||
|
"paginator": paginator,
|
||||||
}
|
}
|
||||||
|
|
||||||
@cog_ext.cog_component(components=create_issues_layout())
|
await paginator.start()
|
||||||
async def _process(self, ctx: ComponentContext):
|
|
||||||
await ctx.defer(edit_origin=True)
|
@cog_ext.cog_subcommand(
|
||||||
cache = self.cache[ctx.origin_message.id]
|
base="gl",
|
||||||
if ctx.author.id != cache["user"]:
|
name="mergerequests",
|
||||||
|
description="Get open issues from GitLab",
|
||||||
|
guild_ids=guild_ids,
|
||||||
|
options=[
|
||||||
|
create_option(
|
||||||
|
name="state",
|
||||||
|
description="State of issues to get",
|
||||||
|
option_type=3,
|
||||||
|
required=False,
|
||||||
|
choices=[
|
||||||
|
create_choice(name="Open", value="opened"),
|
||||||
|
create_choice(name="Closed", value="closed"),
|
||||||
|
create_choice(name="Merged", value="merged"),
|
||||||
|
create_choice(name="All", value="all"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def _mergerequests(self, ctx: SlashContext, state: str = "opened"):
|
||||||
|
exists = self.check_cache(ctx, state=state)
|
||||||
|
if exists:
|
||||||
|
await ctx.defer(hidden=True)
|
||||||
|
await ctx.send(
|
||||||
|
"Please use existing interaction: "
|
||||||
|
+ f"{exists['paginator']._message.jump_url}",
|
||||||
|
hidden=True,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
await ctx.defer()
|
||||||
|
m_state = state
|
||||||
|
if m_state == "all":
|
||||||
|
m_state = None
|
||||||
|
merges = []
|
||||||
|
page = 1
|
||||||
|
try:
|
||||||
|
while curr_page := self.project.mergerequests.list(
|
||||||
|
page=page,
|
||||||
|
state=m_state,
|
||||||
|
order_by="created_at",
|
||||||
|
sort="desc",
|
||||||
|
per_page=100,
|
||||||
|
):
|
||||||
|
merges += curr_page
|
||||||
|
page += 1
|
||||||
|
except gitlab.exceptions.GitlabGetError:
|
||||||
|
# Only send error on first page. Otherwise, use pages retrieved
|
||||||
|
if page == 1:
|
||||||
|
await ctx.send("Unable to get merge requests")
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(merges) == 0:
|
||||||
|
await ctx.send("No merge requests match that criteria")
|
||||||
return
|
return
|
||||||
|
|
||||||
state = cache["state"]
|
t_state = state
|
||||||
page = cache["page"]
|
if t_state == "opened":
|
||||||
if ctx.custom_id == "back":
|
t_state = "open"
|
||||||
page -= 1
|
pages = []
|
||||||
else:
|
t_state = t_state[0].upper() + t_state[1:]
|
||||||
page += 1
|
for i in range(0, len(merges), 5):
|
||||||
try:
|
pages.append(
|
||||||
issues = self.project.issues.list(
|
self.build_embed_page(
|
||||||
page=page,
|
merges[i : i + 5], t_state=t_state, name="merge request"
|
||||||
state=state,
|
)
|
||||||
order_by="created_at",
|
|
||||||
sort="desc",
|
|
||||||
per_page=5,
|
|
||||||
)
|
)
|
||||||
next_issues = self.project.issues.list(
|
|
||||||
page=page + 1,
|
paginator = Paginator(
|
||||||
state=state,
|
bot=self.bot,
|
||||||
order_by="created_at",
|
ctx=ctx,
|
||||||
sort="desc",
|
embeds=pages,
|
||||||
per_page=5,
|
only=ctx.author,
|
||||||
|
timeout=60 * 5, # 5 minute timeout
|
||||||
|
disable_after_timeout=True,
|
||||||
|
use_extend=len(pages) > 2,
|
||||||
|
left_button_style=ButtonStyle.grey,
|
||||||
|
right_button_style=ButtonStyle.grey,
|
||||||
|
basic_buttons=["◀", "▶"],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cache[hash(paginator)] = {
|
||||||
|
"user": ctx.author.id,
|
||||||
|
"timeout": datetime.utcnow() + timedelta(minutes=5),
|
||||||
|
"command": ctx.subcommand_name,
|
||||||
|
"state": state,
|
||||||
|
"paginator": paginator,
|
||||||
|
}
|
||||||
|
|
||||||
|
await paginator.start()
|
||||||
|
|
||||||
|
@cog_ext.cog_subcommand(
|
||||||
|
base="gl",
|
||||||
|
name="milestones",
|
||||||
|
description="Get open issues from GitLab",
|
||||||
|
guild_ids=guild_ids,
|
||||||
|
)
|
||||||
|
async def _milestones(self, ctx: SlashContext):
|
||||||
|
exists = self.check_cache(ctx)
|
||||||
|
if exists:
|
||||||
|
await ctx.defer(hidden=True)
|
||||||
|
await ctx.send(
|
||||||
|
"Please use existing interaction: "
|
||||||
|
+ f"{exists['paginator']._message.jump_url}",
|
||||||
|
hidden=True,
|
||||||
)
|
)
|
||||||
except gitlab.exceptions.GitlabGetError:
|
|
||||||
await ctx.edit_origin(content="Unable to get issues", hidden=True)
|
|
||||||
return
|
return
|
||||||
components = create_issues_layout()
|
await ctx.defer()
|
||||||
components = edit_paging_components(
|
milestones = []
|
||||||
components=components,
|
page = 1
|
||||||
disable_left=page == 1,
|
try:
|
||||||
disable_right=next_issues == [],
|
while curr_page := self.project.milestones.list(
|
||||||
|
page=page,
|
||||||
|
order_by="created_at",
|
||||||
|
sort="desc",
|
||||||
|
per_page=100,
|
||||||
|
):
|
||||||
|
milestones += curr_page
|
||||||
|
page += 1
|
||||||
|
except gitlab.exceptions.GitlabGetError:
|
||||||
|
# Only send error on first page. Otherwise, use pages retrieved
|
||||||
|
if page == 1:
|
||||||
|
await ctx.send("Unable to get milestones")
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(milestones) == 0:
|
||||||
|
await ctx.send("No milestones exist")
|
||||||
|
return
|
||||||
|
|
||||||
|
pages = []
|
||||||
|
for i in range(0, len(milestones), 5):
|
||||||
|
pages.append(
|
||||||
|
self.build_embed_page(
|
||||||
|
milestones[i : i + 5], t_state=None, name="milestone"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
paginator = Paginator(
|
||||||
|
bot=self.bot,
|
||||||
|
ctx=ctx,
|
||||||
|
embeds=pages,
|
||||||
|
only=ctx.author,
|
||||||
|
timeout=60 * 5, # 5 minute timeout
|
||||||
|
disable_after_timeout=True,
|
||||||
|
use_extend=len(pages) > 2,
|
||||||
|
left_button_style=ButtonStyle.grey,
|
||||||
|
right_button_style=ButtonStyle.grey,
|
||||||
|
basic_buttons=["◀", "▶"],
|
||||||
)
|
)
|
||||||
embed = self.build_embed_page(
|
|
||||||
issues=issues, t_state=self.cache[ctx.origin_message.id]["t_state"]
|
self.cache[hash(paginator)] = {
|
||||||
)
|
"user": ctx.author.id,
|
||||||
self.cache[ctx.origin_message.id]["page"] = page
|
"timeout": datetime.utcnow() + timedelta(minutes=5),
|
||||||
await ctx.edit_origin(embed=embed, components=components)
|
"command": ctx.subcommand_name,
|
||||||
|
"paginator": paginator,
|
||||||
|
}
|
||||||
|
|
||||||
|
await paginator.start()
|
||||||
|
|
||||||
@loop(minutes=1)
|
@loop(minutes=1)
|
||||||
async def _expire_interaction(self):
|
async def _expire_interaction(self):
|
||||||
|
@ -444,9 +554,6 @@ class GitlabCog(commands.Cog):
|
||||||
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(
|
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(
|
||||||
minutes=1
|
minutes=1
|
||||||
):
|
):
|
||||||
components = create_layout(self.cache[key]["_command"])
|
|
||||||
components = edit_paging_components(components, True, True)
|
|
||||||
await self.cache[key]["_message"].edit(components=components)
|
|
||||||
del self.cache[key]
|
del self.cache[key]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue