Add JQLPrompt class
This commit is contained in:
		@@ -47,7 +47,7 @@ class JQLLexer(RegexLexer):
 | 
				
			|||||||
                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|Description|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|affectedVersion)\b",
 | 
					                r"timespent|Voter|Watcher)\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),
 | 
				
			||||||
@@ -105,120 +105,120 @@ completion_styles = {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
completions = {
 | 
					completions ={
 | 
				
			||||||
    "Keywords": [
 | 
					            "Keywords": [
 | 
				
			||||||
        "A",
 | 
					                "A",
 | 
				
			||||||
        "AND",
 | 
					                "AND",
 | 
				
			||||||
        "ARE",
 | 
					                "ARE",
 | 
				
			||||||
        "AS",
 | 
					                "AS",
 | 
				
			||||||
        "AT",
 | 
					                "AT",
 | 
				
			||||||
        "BE",
 | 
					                "BE",
 | 
				
			||||||
        "BUT",
 | 
					                "BUT",
 | 
				
			||||||
        "BY",
 | 
					                "BY",
 | 
				
			||||||
        "FOR",
 | 
					                "FOR",
 | 
				
			||||||
        "IF",
 | 
					                "IF",
 | 
				
			||||||
        "INTO",
 | 
					                "INTO",
 | 
				
			||||||
        "IT",
 | 
					                "IT",
 | 
				
			||||||
        "NO",
 | 
					                "NO",
 | 
				
			||||||
        "NOT",
 | 
					                "NOT",
 | 
				
			||||||
        "OF",
 | 
					                "OF",
 | 
				
			||||||
        "ON",
 | 
					                "ON",
 | 
				
			||||||
        "OR",
 | 
					                "OR",
 | 
				
			||||||
        "S",
 | 
					                "S",
 | 
				
			||||||
        "SUCH",
 | 
					                "SUCH",
 | 
				
			||||||
        "T",
 | 
					                "T",
 | 
				
			||||||
        "THAT",
 | 
					                "THAT",
 | 
				
			||||||
        "THE",
 | 
					                "THE",
 | 
				
			||||||
        "THEIR",
 | 
					                "THEIR",
 | 
				
			||||||
        "THEN",
 | 
					                "THEN",
 | 
				
			||||||
        "THERE",
 | 
					                "THERE",
 | 
				
			||||||
        "THESE",
 | 
					                "THESE",
 | 
				
			||||||
        "THEY",
 | 
					                "THEY",
 | 
				
			||||||
        "THIS",
 | 
					                "THIS",
 | 
				
			||||||
        "TO",
 | 
					                "TO",
 | 
				
			||||||
        "WILL",
 | 
					                "WILL",
 | 
				
			||||||
        "WITH",
 | 
					                "WITH"
 | 
				
			||||||
    ],
 | 
					            ],
 | 
				
			||||||
    "Functions": [
 | 
					            "Functions": [
 | 
				
			||||||
        "issueHistory",
 | 
					                "issueHistory",
 | 
				
			||||||
        "openSprints",
 | 
					                "openSprints",
 | 
				
			||||||
        "watchedIssues",
 | 
					                "watchedIssues",
 | 
				
			||||||
        "myApproval",
 | 
					                "myApproval",
 | 
				
			||||||
        "myPending",
 | 
					                "myPending",
 | 
				
			||||||
        "currentLogin",
 | 
					                "currentLogin",
 | 
				
			||||||
        "currentUser",
 | 
					                "currentUser",
 | 
				
			||||||
        "membersOf",
 | 
					                "membersOf",
 | 
				
			||||||
        "lastLogin",
 | 
					                "lastLogin",
 | 
				
			||||||
        "now",
 | 
					                "now",
 | 
				
			||||||
        "startOfDay",
 | 
					                "startOfDay",
 | 
				
			||||||
        "endOfDay",
 | 
					                "endOfDay",
 | 
				
			||||||
        "startOfWeek",
 | 
					                "startOfWeek",
 | 
				
			||||||
        "endOfWeek",
 | 
					                "endOfWeek",
 | 
				
			||||||
        "startOfMonth",
 | 
					                "startOfMonth",
 | 
				
			||||||
        "endOfMonth",
 | 
					                "endOfMonth",
 | 
				
			||||||
        "startOfYear",
 | 
					                "startOfYear",
 | 
				
			||||||
        "endOfYear",
 | 
					                "endOfYear"
 | 
				
			||||||
    ],
 | 
					            ],
 | 
				
			||||||
    "Attributes": [
 | 
					            "Attributes": [
 | 
				
			||||||
        "assignee",
 | 
					                "assignee",
 | 
				
			||||||
        "affectedVersion",
 | 
					                "affectedVersion",
 | 
				
			||||||
        "attachments",
 | 
					                "attachments",
 | 
				
			||||||
        "comment",
 | 
					                "comment",
 | 
				
			||||||
        "component",
 | 
					                "component",
 | 
				
			||||||
        "created",
 | 
					                "created",
 | 
				
			||||||
        "creator",
 | 
					                "creator",
 | 
				
			||||||
        "description",
 | 
					                "description",
 | 
				
			||||||
        "due",
 | 
					                "due",
 | 
				
			||||||
        "duedate",
 | 
					                "duedate",
 | 
				
			||||||
        "filter",
 | 
					                "filter",
 | 
				
			||||||
        "fixVersion",
 | 
					                "fixVersion",
 | 
				
			||||||
        "issuekey",
 | 
					                "issuekey",
 | 
				
			||||||
        "labels",
 | 
					                "labels",
 | 
				
			||||||
        "lastViewed",
 | 
					                "lastViewed",
 | 
				
			||||||
        "priority",
 | 
					                "priority",
 | 
				
			||||||
        "project",
 | 
					                "project",
 | 
				
			||||||
        "reporter",
 | 
					                "reporter",
 | 
				
			||||||
        "resolved",
 | 
					                "resolved",
 | 
				
			||||||
        "sprint",
 | 
					                "sprint",
 | 
				
			||||||
        "status",
 | 
					                "status",
 | 
				
			||||||
        "statusCategory",
 | 
					                "statusCategory",
 | 
				
			||||||
        "summary",
 | 
					                "summary",
 | 
				
			||||||
        "text",
 | 
					                "text",
 | 
				
			||||||
        "timespent",
 | 
					                "timespent",
 | 
				
			||||||
        "voter",
 | 
					                "voter",
 | 
				
			||||||
        "watcher",
 | 
					                "watcher"
 | 
				
			||||||
    ],
 | 
					            ],
 | 
				
			||||||
    "Operators": [
 | 
					            "Operators": [
 | 
				
			||||||
        "=",
 | 
					                "=",
 | 
				
			||||||
        "!=",
 | 
					                "!=",
 | 
				
			||||||
        "<",
 | 
					                "<",
 | 
				
			||||||
        ">",
 | 
					                ">",
 | 
				
			||||||
        "<=",
 | 
					                "<=",
 | 
				
			||||||
        ">=",
 | 
					                ">=",
 | 
				
			||||||
        "~",
 | 
					                "~",
 | 
				
			||||||
        "!~",
 | 
					                "!~",
 | 
				
			||||||
        "IN",
 | 
					                "IN",
 | 
				
			||||||
        "NOT IN",
 | 
					                "NOT IN",
 | 
				
			||||||
        "IS",
 | 
					                "IS",
 | 
				
			||||||
        "IS NOT",
 | 
					                "IS NOT",
 | 
				
			||||||
        "WAS",
 | 
					                "WAS",
 | 
				
			||||||
        "WAS IN",
 | 
					                "WAS IN",
 | 
				
			||||||
        "WAS NOT IN",
 | 
					                "WAS NOT IN",
 | 
				
			||||||
        "WAS NOT",
 | 
					                "WAS NOT"
 | 
				
			||||||
    ],
 | 
					            ],
 | 
				
			||||||
    "Projects": [
 | 
					            "Projects": [
 | 
				
			||||||
        "QUANTUM",
 | 
					                "QUANTUM",
 | 
				
			||||||
        "NEBULA",
 | 
					                "NEBULA",
 | 
				
			||||||
        "GALACTIC",
 | 
					                "GALACTIC",
 | 
				
			||||||
        "STELLAR",
 | 
					                "STELLAR",
 | 
				
			||||||
        "AETHER",
 | 
					                "AETHER",
 | 
				
			||||||
        "NOVA",
 | 
					                "NOVA",
 | 
				
			||||||
        "COSMIC",
 | 
					                "COSMIC",
 | 
				
			||||||
        "LUNAR",
 | 
					                "LUNAR",
 | 
				
			||||||
        "ASTRAL",
 | 
					                "ASTRAL",
 | 
				
			||||||
        "PHOTON",
 | 
					                "PHOTON"
 | 
				
			||||||
    ],
 | 
					            ]
 | 
				
			||||||
}
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class JQLPrinter:
 | 
					class JQLPrinter:
 | 
				
			||||||
@@ -274,25 +274,6 @@ class JQLCompleter(Completer):
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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(
 | 
					 | 
				
			||||||
        lexer=PygmentsLexer(JQLLexer),
 | 
					 | 
				
			||||||
        style=nord_style,
 | 
					 | 
				
			||||||
        completer=completer,
 | 
					 | 
				
			||||||
        validator=JQLValidator(jira),
 | 
					 | 
				
			||||||
        rprompt="[b] Back [exit] Exit",
 | 
					 | 
				
			||||||
        bottom_toolbar=get_query_count,
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def load_config():
 | 
					def load_config():
 | 
				
			||||||
    with open("config.json") as json_file:
 | 
					    with open("config.json") as json_file:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -306,38 +287,65 @@ def load_config():
 | 
				
			|||||||
            exit(1)
 | 
					            exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class JQLPrompt:
 | 
				
			||||||
 | 
					    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 // 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(completions)
 | 
				
			||||||
 | 
					        return PromptSession(
 | 
				
			||||||
 | 
					            lexer=PygmentsLexer(JQLLexer),
 | 
				
			||||||
 | 
					            style=nord_style,
 | 
				
			||||||
 | 
					            completer=completer,
 | 
				
			||||||
 | 
					            validator=JQLValidator(self.jira),
 | 
				
			||||||
 | 
					            rprompt="[b] Back [exit] Exit",
 | 
				
			||||||
 | 
					            bottom_toolbar=self.get_query_count,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_input(self):
 | 
				
			||||||
 | 
					        user_input = self.session.prompt("Enter JQL: ", validate_while_typing=False)
 | 
				
			||||||
 | 
					        if user_input.lower() == "b":
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        if user_input.lower() == "exit":
 | 
				
			||||||
 | 
					            exit(0)
 | 
				
			||||||
 | 
					        issues = self.jira.search_issues(user_input)
 | 
				
			||||||
 | 
					        if issues:
 | 
				
			||||||
 | 
					            self.query_count += 1
 | 
				
			||||||
 | 
					            self.console.print(
 | 
				
			||||||
 | 
					                RichText.assemble(
 | 
				
			||||||
 | 
					                    (f"[+] Found {len(issues)} issues from JQL query: ", "green bold"),
 | 
				
			||||||
 | 
					                    self.jql.pygments_to_rich(user_input),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                end="",
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            for issue in issues:
 | 
				
			||||||
 | 
					                self.console.print(f"{issue.key}: {issue.fields.summary}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                self.get_input()
 | 
				
			||||||
 | 
					            except (EOFError, KeyboardInterrupt):
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					        self.console.print("Goodbye!", style="#BF616A bold")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    global query_count
 | 
					 | 
				
			||||||
    config = load_config()
 | 
					    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)
 | 
					    prompt = JQLPrompt(jira, console)
 | 
				
			||||||
    session = create_jql_prompt_session(jira)
 | 
					    prompt.run()
 | 
				
			||||||
    while True:
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            user_input = session.prompt("Enter JQL: ", validate_while_typing=False)
 | 
					 | 
				
			||||||
            if user_input.lower() == "b":
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            if user_input.lower() == "exit":
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
            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:
 | 
					 | 
				
			||||||
            continue
 | 
					 | 
				
			||||||
        except EOFError:
 | 
					 | 
				
			||||||
            break
 | 
					 | 
				
			||||||
    console.print("Goodbye!", style="#BF616A bold")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user