Skip to content

Commit

Permalink
Merge pull request #18 from szn/convert-issues-to-links
Browse files Browse the repository at this point in the history
convrert [issue] to links
  • Loading branch information
szn authored Mar 29, 2024
2 parents 71b7210 + 9683ef6 commit 9550f05
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
27 changes: 27 additions & 0 deletions sample.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## 1.1 Pipeline Configuration Overview

### 1.1.1 Description

The pipeline configuration includes several key components designed to enhance functionality, manage dependencies, and streamline processes. Each component plays a crucial role in ensuring the smooth execution of the pipeline.

### 1.1.2 Included Configuration Files

The pipeline configuration leverages modularization by including various configuration files from a centralized location. These files contribute to different aspects of the pipeline:

[SJI-1010]

1. **Show Dependencies**
- Provides transparency into project dependencies.
- Configuration file: [.show-dependencies.yml](https://xxxxxx.yml)

```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```

https://dirtyagil.atlassian.net/browse/AD-120

https://dirtyagile.atlassian.net/browse/AD-121
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = confluence.md
version = 0.2.10
version = 0.3.1
author = Szymon Nieradka
description = Markdown to Confluence - upload any .md files to your Confluence cloud page
long_description = file: README.md
Expand Down
16 changes: 12 additions & 4 deletions src/md2cf/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ def wrapper(args):
return wrapper

def init_confluence(args):
return ConfluenceMD(username=args.user, token=args.token,
password=args.password, md_file=args.file.name, url=args.url,
verify_ssl=(not args.no_verify_ssl), add_meta=args.add_meta,
add_info_panel=args.add_info, add_label=args.add_label)
return ConfluenceMD(username=args.user,
token=args.token,
password=args.password,
md_file=args.file.name,
url=args.url,
verify_ssl=(not args.no_verify_ssl),
add_meta=args.add_meta,
add_info_panel=args.add_info,
add_label=args.add_label,
convert_jira=args.convert_jira)

@register_action
def update(args):
Expand Down Expand Up @@ -118,6 +124,8 @@ def main():
help="adds info panel **automatic content** do not edit on top of the page")
parser.add_argument("--add_label", action="store",
help="adds label to page")
parser.add_argument("--convert_jira", action="store_true",
help="convert all Jira links to issue snippets (either short [KEY-ID] format or full URL)")

parser.add_argument("-v", "--verbose", action="store_true",
help="verbose mode")
Expand Down
48 changes: 47 additions & 1 deletion src/md2cf/utils/confluencemd.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import markdown2

from .log import logger
from pprint import pprint

CF_URL = re.compile(r"(?P<host>https?://[^/]+)/.*/(?P<page_id>\d+)")
IMAGE_PATTERN = re.compile(r"\!\[(?P<alt>.*)\]\((?P<path>[^:)]+)\)")

ISSUE_PATTERN = re.compile(r"\[(?P<key>\w[\w\d]*-\d+)\]")
ISSUE_PATTERN_URL = re.compile(r"(?P<domain>https:\/\/\w+\.atlassian\.net)\/browse\/(?P<key>\w[\w\d]*-\d+)")

class ConfluenceMD(atlassian.Confluence):
def __init__(
Expand All @@ -24,6 +26,7 @@ def __init__(
add_meta: bool = False,
add_info_panel: bool = False,
add_label: str = None,
convert_jira: bool = False
) -> None:

super().__init__(
Expand All @@ -34,11 +37,53 @@ def __init__(
cloud=bool(token),
token=token,
)
self.jira = atlassian.Jira(
url=url,
username=username,
password=(password or token),
verify_ssl=verify_ssl,
cloud=bool(token),
token=token
)
self.md_file = md_file
self.add_meta = add_meta
self.add_info_panel = add_info_panel
self.add_label = add_label
self.md_file_dir = os.path.dirname(md_file)
self.convert_jira = convert_jira

def rewrite_issues(self, html):
if not self.convert_jira:
return
logger.debug("Replacing [ISSUE-KEY] with html links")
issues = []
for issue in ISSUE_PATTERN.finditer(html):
issues.append((issue.group(), issue.group("key")))
for issue in ISSUE_PATTERN_URL.finditer(html):
if self.url.startswith(issue.group("domain")):
issues.append((issue.group(), issue.group("key")))
else:
logger.info("Ignoring %s - domain mismatch (%s != %s)", issue.group(), issue.group("domain"), self.url)

for (replace, key) in issues:
logger.debug(f" - [{key}] with html link")
(summary, status, issuetypeurl) = self.get_jira_issue(key)
if summary:
html = html.replace(replace,
f"<a href=\"{self.url}/browse/{key}\"><ac:image><ri:url ri:value=\"{issuetypeurl}\" /></ac:image> {key}: {summary} [{status}]</a>")
return html

def get_jira_issue(self, key: str) -> tuple:
try:
issue = self.jira.issue(key)
summary = issue['fields']['summary']
status = issue['fields']['status']['name']
issuetypeurl = issue['fields']['issuetype']['iconUrl']
return (summary, status, issuetypeurl)
except (RuntimeError, AssertionError, Exception) as error:
logger.info("Unable to convert %s to Jira link: %s", key, error)
return (None, None, None)


def rewrite_images(
self, page_id: str, html: str, images: List[Tuple[str, str]]
Expand Down Expand Up @@ -241,6 +286,7 @@ def md_file_to_html(self, page_id: Optional[str]) -> Tuple[Any, Optional[str], O
if self.add_info_panel:
html = self.get_info_panel() + html

html = self.rewrite_issues(html)
html = self.rewrite_images(page_id if page_id else page_id_from_meta, html, images)
return html, page_id_from_meta, url, len(images) > 0

Expand Down

0 comments on commit 9550f05

Please sign in to comment.