Compare commits

...

2 Commits

Author SHA1 Message Date
Roland Thomas Jr 6c50bd267e
formatting 2024-06-09 15:17:09 -04:00
Roland Thomas Jr 7b872484e9
Add get_issues, logging 2024-06-09 15:08:36 -04:00
3 changed files with 76 additions and 99 deletions

21
cli/get_issues.py Normal file
View File

@ -0,0 +1,21 @@
from jira import JIRA
from rich.console import Console
from jql_utils import JQLPrompt, load_config
config = load_config()
console = Console(color_system="truecolor")
jira = JIRA(server=config["server"], basic_auth=(config["username"], config["token"]))
jql_prompt = JQLPrompt(jira)
issues = jql_prompt.prompt()
console.print("[] Getting more issues... 🚀", style="#A3BE8C bold")
more_issues = jql_prompt.multi_prompt()
if issues or more_issues:
console.print("[] Saving logs... 🚀", style="#A3BE8C bold")
jql_prompt.save_log()
console.print("Exiting... 🚀", style="bold green")

View File

@ -1,70 +0,0 @@
from prompt_toolkit.lexers import Lexer
from prompt_toolkit.styles import Style
from prompt_toolkit.document import Document
from prompt_toolkit.formatted_text import StyleAndTextTuples
from typing import Callable
class JQLLexer(Lexer):
def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]:
text = document.text
tokens = []
keywords = {
"AND", "OR", "NOT", "IN", "ORDER BY", "ASC", "DESC",
"IS", "NULL", "TRUE", "FALSE", "EMPTY"
}
operators = {
"=", "!", ">", "<", ">=", "<=", "~", "!~", "!="
}
punctuations = {"(", ")", ",", ":", " "}
pos = 0
word = ''
while pos < len(text):
char = text[pos]
if char.isalpha():
word += char
else:
if word:
if word.upper() in keywords:
tokens.append(('class:keyword', word))
else:
tokens.append(('class:name', word))
word = ''
if char in operators:
tokens.append(('class:operator', char))
elif char in punctuations:
tokens.append(('class:punctuation', char))
elif char.isspace():
tokens.append(('class:text', char))
else:
tokens.append(('class:error', char))
pos += 1
if word:
if word.upper() in keywords:
tokens.append(('class:keyword', word))
else:
tokens.append(('class:name', word))
return lambda i: tokens
# Example usage
from prompt_toolkit import PromptSession
custom_style = Style.from_dict({
'keyword': '#ff0066 bold',
'operator': '#00ff00',
'name': '#0000ff',
'punctuation': '#00ffff',
'text': '#ffffff',
'error': '#ff0000 bold',
})
session = PromptSession(lexer=JQLLexer(), style=custom_style)
text = session.prompt('Enter JQL: ')
print(f'You entered: {text}')

View File

@ -1,17 +1,19 @@
import json import json
from typing import Dict, List from datetime import datetime
from typing import Dict, List, Optional
from jira import JIRA from jira import JIRA
from jira.exceptions import JIRAError from jira.exceptions import JIRAError
from jira.resources import Issue
from prompt_toolkit import PromptSession from prompt_toolkit import PromptSession
from prompt_toolkit.completion import Completer, Completion from prompt_toolkit.completion import Completer, Completion
from prompt_toolkit.lexers import PygmentsLexer from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.shortcuts import confirm
from prompt_toolkit.styles import Style from prompt_toolkit.styles import Style
from prompt_toolkit.validation import ValidationError, Validator from prompt_toolkit.validation import ValidationError, Validator
from prompt_toolkit.shortcuts import confirm
from pygments.lexer import RegexLexer from pygments.lexer import RegexLexer
from pygments.token import Error, Keyword, Name, Operator, Punctuation, String, Text, Whitespace, _TokenType from pygments.token import (Error, Keyword, Name, Operator, Punctuation,
String, Text, Whitespace, _TokenType)
from rich.console import Console from rich.console import Console
from rich.text import Text as RichText from rich.text import Text as RichText
@ -38,10 +40,10 @@ class JQLLexer(RegexLexer):
Keyword, Keyword,
), ),
( (
r"(?i)\b(?:Assignee|affectedVersion|Attachments|Category|Comment|Component|Created|createdDate|" r"(?i)\b(?:assignee|affectedVersion|attachments|category|comment|component|created|createdDate|"
r"Creator|Description|Due|duedate|Filter|fixVersion|issuekey|issuetype|issueLinkType|Labels|" r"creator|cescription|due|duedate|filter|fixVersion|issuekey|issuetype|issueLinkType|labels|"
r"lastViewed|Priority|Project|Reporter|Resolved|Sprint|Status|statusCategory|Summary|Text|" r"lastViewed|priority|project|reporter|resolved|Sprint|status|statusCategory|summary|text|"
r"timespent|Voter|Watcher)\b", r"timespent|updated|updatedDate|voter|watcher|watchers)\b",
Name.Attribute, Name.Attribute,
), ),
(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),
@ -178,6 +180,7 @@ completions: Dict[str, List[str]] = {
"summary", "summary",
"text", "text",
"timespent", "timespent",
"updated",
"voter", "voter",
"watcher", "watcher",
], ],
@ -281,21 +284,26 @@ def load_config():
class JQLPrompt: class JQLPrompt:
def __init__(self, jira, console): def __init__(self, jira):
self.jira = jira self.jira: JIRA = jira
self.console = console self.console: Console = Console(color_system="truecolor", record=True)
self.session = self.create_jql_prompt_session() self.session: PromptSession = self.create_jql_prompt_session()
self.jql = JQLPrinter(console) self.jql: JQLPrinter = JQLPrinter(self.console)
self.query_count = 0 self.query_count: int = 0
self.issue_count: int = 0
self.total_issue_count: int = 0
self.issues: List[Issue] = []
def get_query_count(self): def get_query_count(self):
space = self.console.width // 4 space = self.console.width // 3
query_count_str = f"Query count: {self.query_count}" query_count_str = f"Query Count: {self.query_count}" if self.query_count else ""
plain_text = f"{query_count_str:^{space}}{query_count_str:^{space}}{query_count_str:^{space}}{query_count_str:^{space}}" issue_count_str = f"Issues Added: {self.issue_count}" if self.issue_count else ""
total_issue_count_str = f"Total Issues: {self.total_issue_count}" if self.total_issue_count else ""
plain_text = f"{query_count_str:^{space}}{issue_count_str:^{space}}{total_issue_count_str:^{space}}"
return [("bg:#2E3440 #D8DEE9", plain_text)] return [("bg:#2E3440 #D8DEE9", plain_text)]
def create_jql_prompt_session(self): def create_jql_prompt_session(self):
completer = JQLCompleter(completions) completer: JQLCompleter = JQLCompleter(completions)
return PromptSession( return PromptSession(
message=[("#B48EAD", "JQL \u276f ")], message=[("#B48EAD", "JQL \u276f ")],
lexer=PygmentsLexer(JQLLexer), lexer=PygmentsLexer(JQLLexer),
@ -310,8 +318,9 @@ class JQLPrompt:
validate_while_typing=False, validate_while_typing=False,
) )
def get_input(self): def prompt(self) -> Optional[List[Issue]]:
user_input = self.session.prompt() user_input: str = self.session.prompt()
self.issue_count = 0
if not user_input: if not user_input:
do_empty_query = confirm( do_empty_query = confirm(
[("#EBCB8B bold", "[?] "), ("#D8DEE9 bold", "Do you want to perform an empty query?")], [("#EBCB8B bold", "[?] "), ("#D8DEE9 bold", "Do you want to perform an empty query?")],
@ -328,21 +337,39 @@ class JQLPrompt:
self.query_count += 1 self.query_count += 1
self.console.print( self.console.print(
RichText.assemble( RichText.assemble(
(f"[+] Found {len(issues)} issues from JQL query: ", "green bold"), (f"[+] Found {len(issues)} issues from JQL query: ", "#A3BE8C bold"),
self.jql.pygments_to_rich(user_input), self.jql.pygments_to_rich(user_input),
), ),
end="", end="",
) )
for issue in issues: return issues
self.console.print(f"{issue.key}: {issue.fields.summary}") self.console.print("[!] No issues found.", style="#BF616A bold")
def run(self): def multi_prompt(self) -> Optional[List[Issue]]:
self.issues = []
while True: while True:
try: try:
self.get_input() issues = self.prompt()
if issues:
issues = [issue for issue in issues if issue not in self.issues]
self.issues.extend(issues)
self.issue_count += len(issues)
self.total_issue_count += len(issues)
self.console.print(f"[] Total issues: {len(self.issues)}", style="#D8DEE9")
get_more = confirm([("#A3BE8C", "[?] Get more issues?")], suffix=[("#81A1C1 bold", " (Y/n) ")])
if not get_more:
break
except (EOFError, KeyboardInterrupt): except (EOFError, KeyboardInterrupt):
break break
self.console.print("Goodbye!", style="#BF616A bold") if self.issues:
self.console.print(f"[+] Issues added: {self.total_issue_count}", style="#A3BE8C bold")
return self.issues
self.console.print("[!] No issues added.", style="#BF616A bold")
def save_log(self):
log_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
with open(f"jql_{log_time}.txt", "w") as log_file:
log_file.write(self.console.export_text())
""" """
@ -362,10 +389,9 @@ class JQLPrompt:
def main(): def main():
config = load_config() config = load_config()
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"]))
prompt = JQLPrompt(jira, console) prompt = JQLPrompt(jira)
prompt.run() prompt.multi_prompt()
if __name__ == "__main__": if __name__ == "__main__":