Add color completer, bottom-toolbar

This commit is contained in:
Roland Thomas Jr 2024-06-08 15:59:47 -04:00
parent f299a13ba6
commit 1e2ff25411
Signed by: roland
GPG Key ID: 7C3C2B085A4C2872
2 changed files with 227 additions and 85 deletions

34
cli/create_issues.py Normal file
View File

@ -0,0 +1,34 @@
from jira import JIRA
from jql_pygments import load_config
config = load_config()
jira_server = config["server"]
jira_username = config["username"]
jira_password = config["token"]
jira = JIRA(server=jira_server, basic_auth=(jira_username, jira_password))
projects = [
'QUANTUM', 'NEBULA', 'GALACTIC', 'STELLAR', 'AETHER', 'NOVA', 'COSMIC', 'LUNAR', 'ASTRAL', 'PHOTON'
]
issue_type = 'Task'
summary_template = 'Issue {0} for project {1}'
description_template = 'Description for issue {0} in project {1}'
def create_issues(project_key, num_issues=20):
for i in range(1, num_issues + 1):
issue_dict = {
'project': {'key': project_key},
'summary': summary_template.format(i, project_key),
'description': description_template.format(i, project_key),
'issuetype': {'name': issue_type},
}
jira.create_issue(fields=issue_dict)
print(f'Created issue {i} in project {project_key}')
for project in projects:
create_issues(project)
print("Issue creation completed.")

View File

@ -14,7 +14,7 @@ from pygments.token import (
from prompt_toolkit import PromptSession from prompt_toolkit import PromptSession
from prompt_toolkit.lexers import PygmentsLexer from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.styles import Style from prompt_toolkit.styles import Style
from prompt_toolkit.completion import WordCompleter from prompt_toolkit.completion import Completer, Completion
from prompt_toolkit.validation import Validator, ValidationError from prompt_toolkit.validation import Validator, ValidationError
from rich.console import Console from rich.console import Console
from rich.text import Text as RichText from rich.text import Text as RichText
@ -52,6 +52,10 @@ class JQLLexer(RegexLexer):
), ),
(r"(?i)(=|!=|<|>|<=|>=|~|!~|IN|NOT IN|IS|IS NOT|WAS|WAS IN|WAS NOT IN|WAS NOT)", Operator), (r"(?i)(=|!=|<|>|<=|>=|~|!~|IN|NOT IN|IS|IS NOT|WAS|WAS IN|WAS NOT IN|WAS NOT)", Operator),
(r"[\*\(/\^\.@;:+%#\[\|\?\),\$]", Punctuation), (r"[\*\(/\^\.@;:+%#\[\|\?\),\$]", Punctuation),
(
r"(?i)\b(?:QUANTUM|NEBULA|GALACTIC|STELLAR|AETHER|NOVA|COSMIC|LUNAR|ASTRAL|PHOTON)\b",
Name.Other,
),
(r"[\w\.\-]+", Text), (r"[\w\.\-]+", Text),
], ],
"string": [ "string": [
@ -72,6 +76,8 @@ nord_style = Style.from_dict(
"pygments.name.function": "#A3BE8C", "pygments.name.function": "#A3BE8C",
"pygments.literal.string": "#D08770", "pygments.literal.string": "#D08770",
"pygments.text": "#D8DEE9", "pygments.text": "#D8DEE9",
"pygments.name.other": "#D08770",
"pygments.error": "#BF616A bold",
} }
) )
@ -86,86 +92,133 @@ token_styles = {
String: "#D08770", String: "#D08770",
Text: "#D8DEE9", Text: "#D8DEE9",
Error: "#BF616A bold", Error: "#BF616A bold",
Name.Other: "#D08770",
} }
completions = [ completion_styles = {
"assignee", "Keywords": "#81A1C1 bold",
"affectedVersion", "Functions": "#A3BE8C",
"attachments", "Attributes": "#B48EAD",
"comment", "Operators": "#EBCB8B bold",
"component", "Projects": "#D08770",
"created", }
"creator",
"description",
"due", completions = {
"duedate", "Keywords": [
"filter", "A",
"fixVersion", "AND",
"issuekey", "ARE",
"labels", "AS",
"lastViewed", "AT",
"priority", "BE",
"project", "BUT",
"reporter", "BY",
"resolved", "FOR",
"sprint", "IF",
"status", "INTO",
"statusCategory", "IT",
"summary", "NO",
"text", "NOT",
"timespent", "OF",
"voter", "ON",
"watcher", "OR",
"A", "S",
"AND", "SUCH",
"ARE", "T",
"AS", "THAT",
"AT", "THE",
"BE", "THEIR",
"BUT", "THEN",
"BY", "THERE",
"FOR", "THESE",
"IF", "THEY",
"INTO", "THIS",
"IT", "TO",
"NO", "WILL",
"NOT", "WITH",
"OF", ],
"ON", "Functions": [
"OR", "issueHistory",
"S", "openSprints",
"SUCH", "watchedIssues",
"T", "myApproval",
"THAT", "myPending",
"THE", "currentLogin",
"THEIR", "currentUser",
"THEN", "membersOf",
"THERE", "lastLogin",
"THESE", "now",
"THEY", "startOfDay",
"THIS", "endOfDay",
"TO", "startOfWeek",
"WILL", "endOfWeek",
"WITH", "startOfMonth",
"issueHistory", "endOfMonth",
"watchedIssues", "startOfYear",
"myApproval", "endOfYear",
"myPending", ],
"currentLogin", "Attributes": [
"currentUser", "assignee",
"membersOf", "affectedVersion",
"lastLogin", "attachments",
"now", "comment",
"startOfDay", "component",
"endOfDay", "created",
"startOfWeek", "creator",
"endOfWeek", "description",
"startOfMonth", "due",
"endOfMonth", "duedate",
"startOfYear", "filter",
"endOfYear", "fixVersion",
] "issuekey",
"labels",
"lastViewed",
"priority",
"project",
"reporter",
"resolved",
"sprint",
"status",
"statusCategory",
"summary",
"text",
"timespent",
"voter",
"watcher",
],
"Operators": [
"=",
"!=",
"<",
">",
"<=",
">=",
"~",
"!~",
"IN",
"NOT IN",
"IS",
"IS NOT",
"WAS",
"WAS IN",
"WAS NOT IN",
"WAS NOT",
],
"Projects": [
"QUANTUM",
"NEBULA",
"GALACTIC",
"STELLAR",
"AETHER",
"NOVA",
"COSMIC",
"LUNAR",
"ASTRAL",
"PHOTON",
],
}
class JQLPrinter: class JQLPrinter:
@ -173,7 +226,7 @@ class JQLPrinter:
self.console = console self.console = console
def print(self, text: str): def print(self, text: str):
self.console.print(self.pygments_to_rich(text)) self.console.print(self.pygments_to_rich(text), end="")
def pygments_to_rich(self, text): def pygments_to_rich(self, text):
tokens = list(JQLLexer().get_tokens(text)) tokens = list(JQLLexer().get_tokens(text))
@ -199,24 +252,67 @@ class JQLValidator(Validator):
raise ValidationError(message=f"[!] {error_text}", cursor_position=len(text)) raise ValidationError(message=f"[!] {error_text}", cursor_position=len(text))
def create_jira_prompt_session(jira): class JQLCompleter(Completer):
completer = WordCompleter(completions, ignore_case=True) """Custom JQL completer to categorize and color completions."""
def __init__(self, categorized_completions):
self.categorized_completions = categorized_completions
def get_completions(self, document, complete_event):
text = document.get_word_before_cursor().lower()
for category, words in self.categorized_completions.items():
for word in words:
if text in word.lower():
display_text = f"{word}"
yield Completion(
word,
start_position=-len(text),
display=display_text,
display_meta=category,
style=f"fg: #D8DEE9 bg: {completion_styles.get(category, 'white')}",
selected_style=f"fg: {completion_styles.get(category, 'white')} bg: #D8DEE9",
)
query_count = 0
def get_query_count():
return [("class:bottom-toolbar", f"Query count: {query_count}")]
def create_jql_prompt_session(jira):
completer = JQLCompleter(completions)
return PromptSession( return PromptSession(
lexer=PygmentsLexer(JQLLexer), lexer=PygmentsLexer(JQLLexer),
style=nord_style, style=nord_style,
completer=completer, completer=completer,
validator=JQLValidator(jira), validator=JQLValidator(jira),
rprompt="[b] Back [exit] Exit", rprompt="[b] Back [exit] Exit",
bottom_toolbar=get_query_count,
) )
with open("config.json") as json_file:
config = json.load(json_file) def load_config():
with open("config.json") as json_file:
try:
with open("config.json") as json_file:
return json.load(json_file)
except FileNotFoundError:
print("Configuration file not found.")
exit(1)
except json.JSONDecodeError:
print("Error decoding configuration file.")
exit(1)
def main(): def main():
global query_count
config = load_config()
console = Console(color_system="truecolor") console = Console(color_system="truecolor")
jira = JIRA(server=config["server"], basic_auth=(config["username"], config["token"])) jira = JIRA(server=config["server"], basic_auth=(config["username"], config["token"]))
jql = JQLPrinter(console) jql = JQLPrinter(console)
session = create_jira_prompt_session(jira) session = create_jql_prompt_session(jira)
while True: while True:
try: try:
user_input = session.prompt("Enter JQL: ", validate_while_typing=False) user_input = session.prompt("Enter JQL: ", validate_while_typing=False)
@ -224,7 +320,19 @@ def main():
continue continue
if user_input.lower() == "exit": if user_input.lower() == "exit":
break break
jql.print(user_input) issues = jira.search_issues(user_input)
if issues:
query_count += 1
console.print(
RichText.assemble(
(f"[+] Found {len(issues)} issues from JQL query: ", "green bold"),
jql.pygments_to_rich(user_input),
),
end="",
)
for issue in issues:
console.print(f"{issue.key}: {issue.fields.summary}")
except KeyboardInterrupt: except KeyboardInterrupt:
continue continue
except EOFError: except EOFError: