Compare commits

..

No commits in common. "6c50bd267e780ff5164ac46baa6848962fcb2766" and "50e0eb839ed62dd8ec3a5fd19e97cbe6b158ab77" have entirely different histories.

3 changed files with 99 additions and 76 deletions

View File

@ -1,21 +0,0 @@
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")

70
cli/jql_lexer.py Executable file
View File

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