Export Gitlab Issue ¶
file "export_gitlab_issues.py"
#!/usr/bin/env python3 import pprint import json import gitlab import argparse import markdown # Requirements # python-gitlab==4.11.1 # Markdown-3.7 GITLAB_URL = "https://gitlab.brainstorm.it" GITLAB_PRIVATE_TOKEN = "glpat-******************" GITLAB_PROJECT = 77 PAGE_BREAK_STRING = '<div style="page-break-after: always;"></div>' class GitlabClient(gitlab.Gitlab): def __init__(self, project_id): super().__init__(GITLAB_URL, GITLAB_PRIVATE_TOKEN, order_by='created_at') self.project = self.projects.get(project_id) def retrieve_issue(self, issue_id): issue = self.project.issues.get(issue_id) base_url = issue.web_url # Es: 'https://gitlab.brainstorm.it/group/project/-/issues/36' position = base_url.find('/-/') if position >= 0: base_url = base_url[:position] # Es: 'https://gitlab.brainstorm.it/group/project' data = json.loads(issue.to_json()) self.fix_image_links(data, base_url) data['notes'] = [] notes = issue.notes.list(all=True) notes = sorted([n for n in notes if not n.system], key=lambda k: k.created_at) for n in notes: note = json.loads(n.to_json()) self.fix_image_links(note, base_url) data['notes'].append(note) return data def fix_image_links(self, data, base_url): text = data.get('description', data.get('body')) text = text.replace('/uploads/', base_url+'/uploads/') if 'description' in data: data['description'] = text else: data['body'] = text def to_markdown(data): text = "" for k, v in data.items(): text += '\n# [%d] %s\n\n' % (k, v['title']) text += "### %s (%s)\n\n" % (v['author']['name'], v['created_at']) text += "**Link**: %s\n\n" % v['web_url'] text += v['description'] text += "\n\n" for n in v['notes']: text += "\n\n" + (80*'-') + "\n\n" text += "### %s (%s)\n\n" % (n['author']['name'], v['created_at']) text += n['body'] text += "\n\n" text += "\n\n" + PAGE_BREAK_STRING return text def markdown_to_html(md_text): extensions = [ "tables", "fenced_code", "codehilite", "toc" ] #safe_mode = True html = markdown.markdown( md_text, extensions=extensions, # safe_mode=safe_mode, # enable_attributes=(not safe_mode), ) return html def markdown_to_pdf(md_file, pdf_file, verbose=False): # Read Markdown file with open(md_file, "r", encoding="utf-8") as file: md_text = file.read() html_text = markdown_to_html(md_text) return html_to_pdf(html_text, pdf_file, verbose=False) def html_to_pdf(html_text, pdf_file, verbose=False): from weasyprint import HTML from pygments.formatters import HtmlFormatter # Generate Pygments CSS for styling pygments_css = HtmlFormatter().get_style_defs('.codehilite') # Custom CSS for better styling css = """ body { font-family: Arial, sans-serif; padding: 20px; } pre { background: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; font-size: 10px; } code { font-family: monospace; } img { display: block; max-width: 98%; height: auto; margin: 0 auto; border: 2px solid #ccc; } """ + pygments_css # Wrap HTML with styling html = f""" <html> <head> <style>{css}</style> </head> <body> {html_text} </body> </html>""" # Convert HTML to PDF if verbose: print(html) print('build "%s" ...' % pdf_file) HTML(string=html).write_pdf(pdf_file) print('done') def main(): parser = argparse.ArgumentParser(description="...") parser.add_argument('issue_ids', nargs="+", type=int) parser.add_argument("--project_id", "-p", type=int, default=GITLAB_PROJECT, help="Default: %d" % GITLAB_PROJECT) parser.add_argument("--format", type=str, choices=["", "json", "markdown", "html", "pdf", ], default="") parser.add_argument("--filename", type=str, default="result.pdf", help='filename when required (i.e.: PDF format); default: "result.pdf"') args = parser.parse_args() project_id = args.project_id client = GitlabClient(GITLAB_PROJECT) data = {} for issue_id in args.issue_ids: issue_data = client.retrieve_issue(issue_id) data[issue_id] = issue_data if args.format == 'json': print(json.dumps(data, indent=4)) if args.format == 'markdown': print(to_markdown(data)) elif args.format == 'html': md = to_markdown(data) html = markdown_to_html(md) print(html) elif args.format == 'pdf': md = to_markdown(data) html = markdown_to_html(md) html_to_pdf(html, args.filename, verbose=False) else: pprint.pprint(data) if __name__ == '__main__': main()